문제

The ARM7-command set offers efficient ways to right rotate 32-bit values by an arbitrary amount in assembler. For the 2nd operand of an operation it is even "for free" by specifying ror #n as shifter operand, but for 64-bit integers no direct support by the instruction set is given. Besides the special cases of rotating by 1, 31, 33 or 63 bit positions (not to mention 0 or 32), I only know how to rotate a 64-bit value using four instructions (it's quite easy, so I don't write it here). In the four special cases I can reduce this to three instructions, but I don't know how to do it in general. So here is my question:

Given a 64-bit value in two registers, say R0 and R1, is it possible to right rotate this value by n positions (for arbitrary n) with just three ARM7 instructions?

도움이 되었습니까?

해결책

If a register (e.g. r4) happens to hold the proper magic constant (1 shifted left by the desired left-rotate amount) I think one can do it in two instructions:

  umull r3,r2,r1,r4
  umlal r2,r3,r0,r4

Slower than using four single-cycle instructions, but even if one has to load r4 with the proper constant it's still more compact than the four-instruction methods.

다른 팁

If there is a solution to this, gcc also doesn't recognize it:

unsigned long long int reg64 = random_value;
unsigned int n = shift_value;
reg64 = (reg64 >> (n%64)) | (reg64 << ((64-n)%64));

results in the following:

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top