ARM7命令集提供了在汇编程序中将32位值正确旋转任意数量的有效方法。对于操作的第二个操作数,通过将 ror #n 指定为移位器操作数,它甚至是“免费”,但对于64位整数,不给出指令集的直接支持。除了通过1个,31个,33个或63个位置旋转的特殊情况(更不用说0或32),我只知道如何使用四个指令旋转64位值(这很容易,所以我不在这里写。)在这四种特殊情况下,我可以将其减少为三条指令,但我不知道如何一般地执行此操作。所以这是我的问题:
给定两个寄存器中的64位值,比如R0和R1,可以通过 n 位置(对于任意 n )正确旋转此值三个 ARM7指令?
答案 0 :(得分:2)
如果一个寄存器(例如r4)碰巧保持了正确的魔术常数(1向左移动了所需的左旋转量)我认为可以用两个指令来完成:
umull r3,r2,r1,r4 umlal r2,r3,r0,r4
比使用四个单周期指令慢,但即使必须使用适当的常量加载r4,它仍然比四指令方法更紧凑。
答案 1 :(得分:1)
如果有解决方法,gcc也无法识别它:
unsigned long long int reg64 = random_value;
unsigned int n = shift_value;
reg64 = (reg64 >> (n%64)) | (reg64 << ((64-n)%64));
导致以下结果:
n = 1时:
MOVS R2, R0, LSR #1
MOV R3, R1, RRX
ORR R2, R2, R1, ASL #31
N = 2-31:
MOV R2, R0, LSR #n
ORR R2, R2, R1, ASL #32-n
MOV R3, R0, ASL #32-n
ORR R3, R3, R1, LSR #n
N = 33-62:
MOV R3, R0, ASL #64-n
ORR R3, R3, R1, LSR #n-32
MOV R2, R0, LSR, #n-32
ORR R2, R2, R1, ASL #64-n
N = 63:
ADDS R2, R0, R0
ADC R3, R1, R1
ORR R2, R2, R1, LSR #31