assemblyx86-64bit-shiftextended-precision

Shift across registers efficiently


How can I efficiently fill the most significant bit of a register with the least significant bit of another register in x64-Assembly. The Intended use is efficient division of a 128bit value by two (essentially a cross-register shift).

RDX:RAX (result after MUL-Operation)

Solution

  • Use the shrd instruction to shift a bit from the src into the destination:

    shrd rax, rdx, 1   ; shift a bit from bottom of RDX into top of RAX
    shr  rdx, 1        ; and then shift the high half
    ; rdx:rax is shifted one bit to the right
    

    Alternatively, use a shr and a rcr instruction, but note that rcr is multiple uops so this is slower on most CPUs:

    shr rdx, 1          ; shift LSB of rdx into cf
    rcr rax, 1          ; shift CF into rax