来源:
unsigned long div1000(unsigned long a)
{
return a/1000;
}
优化代码(-O3):
srli a0, a0, 3 # divide parameter by 8
lui a1, 4194 #
addiw a1, a1, 1245 #
slli a1, a1, 13 #
addi a1, a1, 1507 # 8 instruction sequence to assemble a rather large number
slli a1, a1, 12 #
addi a1, a1, 1343 #
slli a1, a1, 12 #
addi a1, a1, 1999 #
mulhu a0, a0, a1 # multiply by large number and fetch high portion
srli a0, a0, 4 # divide by 16
ret
参考:
https://godbolt.org/z/mNNSM5
我们可以使用
lui
/
addi
pair,那么为什么不构建2个32位常量并将它们放在一起呢。这将需要另一个寄存器,但指令更少。
lui a1, ? #
addi a1, a1, ? #
slli a1, a1, 32 # 6 instruction sequence to assemble a 64-bit number
lui a2, ? #
addi a2, a2, ? #
add a1, a1, a2 #
(注意,在32位低位常数设置高位(MSB)的情况下(如这里),我假设
路易斯
在64位RISC V上产生一个32位常数,该常数被符号扩展为32位。因此,我们必须使用正常的技巧来创建高阶常数
a1
减1以抵消中的负值
a2
.)