Reputation: 167
As title says. My way to do this:
; eax holds 32bit integer
sal rax, 32
sar rax, 32
;after operation int is converted (rax holds the same value on 64 bits)
Is there more elegant/better/faster way to do this??
Upvotes: 2
Views: 1739
Reputation: 365832
TL;DR: movsxd
, or for the eax special-case, cdqe
.
Like I explained in one of your previous questions, you can answer these yourself by looking at compiler output. It's really easy to write a function that sign-extends an integer, then go look up the instruction it uses in the manual:
#include <stdint.h>
int64_t sign_extend(int32_t a) { return a; }
movsxd rax, edi
ret
From clang -O3 on the Godbolt compiler explorer.
Then you look up movsxd
in the instruction set reference, and you're done. (That's a conversion of Intel's PDF (links in the x86 tag wiki), which has a table-of-contents with a summary line for every instruction. Text searching in that will often find what you need.)
There's a special-case for rax, called cdqe
. 8086 didn't have movsx
until 386, just the al -> ax cbw
.
This is and other ax-only stuff is why Intel spent 8 opcodes on single-byte encodings for xchg ax, reg
in 8086. AMD arguably should have reclaimed these for AMD64, for use in future instruction-set extensions, since AMD64 was the first (and probably only for a very long time) opportunity to break backwards compatibility with 8086 opcodes, or 386's 32bit-mode machine-code.
This is where the single-byte NOP (90
) encoding comes from: xchg eax,eax
is recognized as a special-case that's executed efficiently (not free, but cheaper than mov eax,eax
for example). In 64bit mode, it doesn't zero-extend eax into rax. (Intel documents nop
as a separate instruction (along with the long-NOP encoding), and doesn't mention this special-case behaviour in the entry for xchg
)
Upvotes: 7