LoongArch-Documentation
LoongArch-Documentation copied to clipboard
缺失的指令 missing instructions
Describe the question:
类似x86下的mov指令和ret指令在手册中未查到 Describe the idea:
在编写loongarch64汇编时,发现传送指令(类似x86的mov),无条件跳转指令(类似ret)是缺失的,经过对一个c文件,在gcc下进行汇编编译,我们认为这几个指令是可能的: jr指令,对应ret指令,用法为 jr $r1 la.local指令,对应mov,用法为 la.local 寄存器操作数, 被传送内容(x86下通常是.data域定义的变量) 另外还看到一个la.global不知是何含义 以上三个指令,在《loongarch架构手册第一部分》内查不到,请帮忙核实一下。 Additional context:
用作寄存器-寄存器搬运的 "mov" 指令写法是 move rd, rj
(和 MIPS 一致),是 or rd, rj, zero
的语法糖;
用作过程调用返回的 "ret" 指令写法是 jr $ra
(也和 MIPS 一致),jr $foo
是 jirl $zero, $foo, 0
的语法糖。
这俩指令(和一票别的东西)都是伪指令,这本手册没有讲伪指令。不过这些东西确实龙芯文档团队需要考虑优化。
打错了,是jr指令,不是ja
感谢,另外问一下ll和sc这一对操作(即原子读写操作),只看到有字和双字的操作,字节和半字操作并没有,操作byte原子读写应该怎么写?
另外经过实际编译测试,jirl 0, 1, 0或jirl 0, $r1, 0 这一指令都会报错
感谢,另外问一下ll和sc这一对操作(即原子读写操作),只看到有字和双字的操作,字节和半字操作并没有,操作byte原子读写应该怎么写?
把操作 byte 原子读写的过程放 ll
和 sc
这一对操作中间。
另外经过实际编译测试,jirl 0, 1, 0或jirl 0, $r1, 0 这一指令都会报错
jirl
的指令格式是 jirl rd, rj, offs
。其中,rd
和 rj
是寄存器,因此常量 0
是非法的,需要使用 $zero/$r0
寄存器。
la
系列的指令都是伪指令,用于加载地址。
另外经过实际编译测试,jirl 0, 1, 0或jirl 0, $r1, 0 这一指令都会报错
jirl
的结构是 jirl 链接寄存器, 目标地址寄存器, 目标地址偏移 >> 2
因此前两个都是寄存器操作数,只有最后一个是立即数。
@FreeFlyingSheep 是否能详细说说byte原子操作。 我们有一个汇编代码段,他的代码是这样:
la464_lock_read_b:
dbar 0
// address is r4, return is r4
ll.w $r4, $r4, 0
jirl $r0, $r1, 0 //ret
另一个c原子会调用这个功能
//这是针对arm的代码,需要再写一段针对loongarch的
if(MODREG) { // reg / reg: no lock
tmp8u = GB;
GB = EB->byte[0];
EB->byte[0] = tmp8u;
} else {
do {
tmp8u = arm64_lock_read_b(EB);
} while(arm64_lock_write_b(EB, GB));
GB = tmp8u;
}
这是一个写的锁操作,需要原子写入一个byte,但是因为ll只有ll.w(字的原子写)和ll.d(双字的原子写),有没有ll.b这种写入byte的?或者怎么变相实现?
我一开始的表述不大准确,用 ll.w
/sc.w
模拟 ll.b
/sc.b
的过程比较复杂,大体思路是先对齐,然后用 ll.w
/sc.w
结合位运算操作需要写入的 byte,具体的例子可以参考内核的 __xchg_small(volatile void *ptr, unsigned long val, unsigned int size)
函数,该函数会把 size
大小的 val
变量原子写到 ptr
位置,并返回该位置的原始值。
又遇到一个奇怪的问题,在loongnix(dnf based,我不知道是不是fedora)和UOS(DEBIAN based)上,汇编的注释符并不一样,UOS上是//,loongnix是#,双方的gcc都是8.3.0
又遇到一个奇怪的问题,在loongnix(dnf based,我不知道是不是fedora)和UOS(DEBIAN based)上,汇编的注释符并不一样,UOS上是//,loongnix是#,双方的gcc都是8.3.0
两种注释方式都可以,/* */
也行。
友情提醒:工单系统不是技术支持论坛,这边的人也都不是技术支持工程师(我甚至不是龙芯员工)。类似的问题可以去社区 http://bbs.loongnix.cn 问。
额,明白
同时也欢迎各位开源大佬关注我们的项目,https://github.com/ptitSeb/box64 另一个x86二进制模拟器
我感觉 move 这个东西还是文档记录一下好,不然大家会自己乱写各种变体 (add $rd, $rs, $r0
, addi $rd, $rs, 0
, ori $rd, $rs, 0
, ...)。另外不知道不同变体会不会导致性能的变化 (我不是很熟悉 CPU 内部的流水线这些东西)。