I want to move a 64-bit unsigned integer to a register using inline asm. What happens is the constant gets sign-extended if it in fact fits in 32 bits.
Here is my code:
#include "stdint.h"
uint64_t foo() {
uint64_t x;
asm ("movq %1, %0"
: "=q" (x)
: "i" (0x00000000faceffff) );
return x;
}
Now, clang -S code.c produces the following assembly:
#APP
movq $-87097345, %rax # imm = 0xFFFFFFFFFACEFFFF
#NO_APP
Same thing for gcc. Same thing for movabsq in place of movq. Same for "p" constraint instead of "i".
I get the result I expect if the constant is larger than 32 bits.