Search code examples
assemblyarmbit-manipulationbit-shiftarm7

How to right rotate a 64-bit value efficiently in 32-bit ARM assembler?


The ARM7-command set (ARM7TDMI = ARMv4T) 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 (like compilers do for constant counts, using 2x ). 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? Or if any newer ARMv7 or even AArch32 ARMv8 instructions are available, that would also be interesting.


Solution

  • 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.