[英]RISC-V generate -1 / 0xFFFFFFFF in a register with LUI / ADDI?
我正在学习如何为RISC-V处理器编写代码。 我想将0xFFFFFFFF
的值存储到内存/寄存器中。
我可以通过在其前面添加一个lui
来扩展addi
指令的12个立即数,如下所示:
lui t0, 0xFFFFF
addi t0, t0, 0x7FF
但是结果最终将类似于0xFFFFF7FF
。
那么,我该如何产生该价值呢?
询问C编译器:
unsigned foo(){return 0xFFFFFFFF;}
使用Clang -O3
针对RISC-V编译到此asm (在Godbolt上) :
foo():
addi a0, zero, -1
ret
(gcc仅使用li a0, -1
伪指令并将细节留给汇编器。通常,您应该执行相同的操作,除非您想考虑选择可以更高效地生成的常量。)
RISC-V addi
将其立即数符号扩展为32(或64)位 ,因此,如果要在第12位中添加一个,则需要在选择高位时加以考虑。
在这种情况下,高位的正确起始值为0
因此您可以完全优化lui
。
RISC-V使用2的补码有符号整数,因此符号扩展仅表示加宽时将符号位复制到所有较高位置。
首先让我们分析代码的问题所在:
lui t0, 0xFFFFF
addi t0, t0, 0x7FF
lui
指令将20位立即数0xFFFFF
左移12位后得到的值加载到t0
。 因此, t0
导致0xFFFFF000
。 addi
号扩展了12位立即数0x7FF
,并将其添加到寄存器t0
。 由于立即数的最高有效位(即符号位)为零,因此其符号扩展的32位值为0x000007FF
。 然后将此值添加到t0
,之前为0xFFFFF000
。 因此, t0
的结果值为0xFFFFF7FF
。 如该答案中已经解释的,您可以通过利用符号扩展的工作方式来优化lui
指令:符号扩展会传播符号位,这是最高有效位。
12位立即数0xFFF
由1
组成,包括最高有效位(即符号位)。 因此,其32位符号扩展名是0xFFFFFFFF
,它已经对应于您想要的值:
addi t0, zero, 0xFFF
如果您一直坚持使用lui
和addi
这两个指令,只需将所有0
加载到t0
的高位:
lui t0, 0
addi t0, t0, 0xFFF
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.