RISC-V 在带有 LUI / ADDI 的寄存器中生成 -1 / 0xFFFFFFFF?
RISC-V generate -1 / 0xFFFFFFFF in a register with LUI / ADDI?
我正在学习如何为 RISC-V 处理器编写代码。我想将 0xFFFFFFFF
的值存储到内存/寄存器中。
我可以通过在addi
指令之前添加一个lui
来扩展addi
指令的12个立即位,
像这样:
lui t0, 0xFFFFF
addi t0, t0, 0x7FF
但结果会像 0xFFFFF7FF
.
那么,我怎样才能产生那个价值呢?
询问 C 编译器:
unsigned foo(){return 0xFFFFFFFF;}
使用 Clang -O3
为 RISC-V (on Godbolt):
编译成这个 asm
foo():
addi a0, zero, -1
ret
(gcc 只是使用了 li a0, -1
伪指令,而将细节留给了汇编程序。通常你应该这样做,除非你想考虑选择可以更有效地生成的常量。)
RISC-V addi
将其直接操作数符号扩展为 32(或 64)位,因此如果您想要第 12 位中的 1,则需要在您选择高位时考虑到这一点。
在这种情况下,高位的正确起始值为 0
,因此您可以完全优化掉 lui
。
RISC-V 使用 2 的补码有符号整数,因此符号扩展只是意味着在扩展时将符号位复制到所有更高的位置。
我们先分析一下你的代码哪里出了问题:
lui t0, 0xFFFFF
addi t0, t0, 0x7FF
lui
指令将 20 位立即数 0xFFFFF
左移 12 位后的值加载到 t0
中。因此,t0
结果为 0xFFFFF000
。
-
addi
sign extends 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
我正在学习如何为 RISC-V 处理器编写代码。我想将 0xFFFFFFFF
的值存储到内存/寄存器中。
我可以通过在addi
指令之前添加一个lui
来扩展addi
指令的12个立即位,
像这样:
lui t0, 0xFFFFF
addi t0, t0, 0x7FF
但结果会像 0xFFFFF7FF
.
那么,我怎样才能产生那个价值呢?
询问 C 编译器:
unsigned foo(){return 0xFFFFFFFF;}
使用 Clang -O3
为 RISC-V (on Godbolt):
foo():
addi a0, zero, -1
ret
(gcc 只是使用了 li a0, -1
伪指令,而将细节留给了汇编程序。通常你应该这样做,除非你想考虑选择可以更有效地生成的常量。)
RISC-V addi
将其直接操作数符号扩展为 32(或 64)位,因此如果您想要第 12 位中的 1,则需要在您选择高位时考虑到这一点。
在这种情况下,高位的正确起始值为 0
,因此您可以完全优化掉 lui
。
RISC-V 使用 2 的补码有符号整数,因此符号扩展只是意味着在扩展时将符号位复制到所有更高的位置。
我们先分析一下你的代码哪里出了问题:
lui t0, 0xFFFFF
addi t0, t0, 0x7FF
lui
指令将 20 位立即数0xFFFFF
左移 12 位后的值加载到t0
中。因此,t0
结果为0xFFFFF000
。-
addi
sign extends 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