如何在ARM7汇编程序中有效地旋转64位值?

时间:2011-03-21 14:40:32

标签: assembly arm bit-manipulation arm7

ARM7命令集提供了在汇编程序中将32位值正确旋转任意数量的有效方法。对于操作的第二个操作数,通过将 ror #n 指定为移位器操作数,它甚至是“免费”,但对于64位整数,不给出指令集的直接支持。除了通过1个,31个,33个或63个位置旋转的特殊情况(更不用说0或32),我只知道如何使用四个指令旋转64位值(这很容易,所以我不在这里写。)在这四种特殊情况下,我可以将其减少为三条指令,但我不知道如何一般地执行此操作。所以这是我的问题:

给定两个寄存器中的64位值,比如R0和R1,可以通过 n 位置(对于任意 n )正确旋转此值三个 ARM7指令?

2 个答案:

答案 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