Arm mov 有一个限制,即立即数必须是 8 位旋转 2 的倍数,我们可以这样写:
mov ip, #0x5000
但是我们不能这样写:
mov ip, #0x5001
0x5000 可以拆分为 0x5000 + 1,我的意思是,一个有效的立即数和一个小数的和。
那么对于给定的 32 位数字,如何快速找到最接近的有效立即数呢?像这样:
uint32 find_imm(uint32 src, bool less_than_src) {
...
}
// x is 0x5000
uint32 x = find_imm(0x5001, true);
最佳答案
其实很简单,看他们之间的距离。 0x5001 = 0b101000000000001。 15 位有效数字,因此它会以 8 位立即数为您提供两条指令。还要记住在测试中进行旋转,如果有足够的零 0x80000001 并且你将它旋转到 0x88000000 或 0x00000003 周围,这与测量值之间的距离只有两位有效数字。因此,采取立即行动,执行类型测试之间的距离,旋转一步,再次执行测试,然后重复直到发生所有可能的(反向)旋转,并使用指令数量最少的一个/立即数。
gnu 已经这样做了,gas 是开源的,所以如果你愿意,你可以去获取他们的代码。当您使用加载地址技巧时:
ldr rd,=const
如果该 const 可以在单个移动立即指令中解析,则它将其编码为
mov rd,#const
如果它不能,那么它会尝试找到一个放置单词的位置并将其编码为 pc 相对负载:
ldr rd,[pc,#offset]
...
.word const
关于c++ - 为 arm mov 获取有效 imm num 的快速方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17760944/