Commit 7a8dea0e authored by Marius Wachtler's avatar Marius Wachtler

assembler: Use 32bit moves if the immediate fits inside 32bit

makes the encoding 4-5byte shorter and works because the upper 32bit will get auto cleared
parent 1ee49a67
...@@ -145,18 +145,20 @@ void Assembler::emitSIB(uint8_t scalebits, uint8_t index, uint8_t base) { ...@@ -145,18 +145,20 @@ void Assembler::emitSIB(uint8_t scalebits, uint8_t index, uint8_t base) {
emitByte((scalebits << 6) | (index << 3) | base); emitByte((scalebits << 6) | (index << 3) | base);
} }
void Assembler::mov(Immediate val, Register dest) { void Assembler::mov(Immediate val, Register dest, bool force_64bit_load) {
int rex = REX_W; force_64bit_load = force_64bit_load || !val.fitsInto32Bit();
int rex = force_64bit_load ? REX_W : 0;
int dest_idx = dest.regnum; int dest_idx = dest.regnum;
if (dest_idx >= 8) { if (dest_idx >= 8) {
rex |= REX_B; rex |= REX_B;
dest_idx -= 8; dest_idx -= 8;
} }
emitRex(rex); if (rex)
emitRex(rex);
emitByte(0xb8 + dest_idx); emitByte(0xb8 + dest_idx);
emitInt(val.val, 8); emitInt(val.val, force_64bit_load ? 8 : 4);
} }
void Assembler::movq(Immediate src, Indirect dest) { void Assembler::movq(Immediate src, Indirect dest) {
...@@ -975,7 +977,9 @@ void Assembler::leave() { ...@@ -975,7 +977,9 @@ void Assembler::leave() {
} }
uint8_t* Assembler::emitCall(void* ptr, Register scratch) { uint8_t* Assembler::emitCall(void* ptr, Register scratch) {
mov(Immediate(ptr), scratch); // emit a 64bit movabs because some caller expect a fixed number of bytes.
// until they are fixed use the largest encoding.
mov(Immediate(ptr), scratch, true /* force_64bit_load */);
callq(scratch); callq(scratch);
return addr; return addr;
} }
......
...@@ -114,8 +114,8 @@ public: ...@@ -114,8 +114,8 @@ public:
void nop() { emitByte(0x90); } void nop() { emitByte(0x90); }
void trap() { emitByte(0xcc); } void trap() { emitByte(0xcc); }
// some things (such as objdump) call this "movabs" if the immediate is 64-bit // emits a movabs if the immediate is a 64bit value or force_64bit_load = true otherwise it emits a 32bit mov
void mov(Immediate imm, Register dest); void mov(Immediate imm, Register dest, bool force_64bit_load = false);
// not sure if we should use the 'q' suffix here, but this is the most ambiguous one; // not sure if we should use the 'q' suffix here, but this is the most ambiguous one;
// this does a 64-bit store of a 32-bit value. // this does a 64-bit store of a 32-bit value.
void movq(Immediate imm, Indirect dest); void movq(Immediate imm, Indirect dest);
......
...@@ -158,6 +158,11 @@ struct Immediate { ...@@ -158,6 +158,11 @@ struct Immediate {
explicit Immediate(uint64_t val) : val(val) {} explicit Immediate(uint64_t val) : val(val) {}
explicit Immediate(void* val) : val((uint64_t)val) {} explicit Immediate(void* val) : val((uint64_t)val) {}
bool fitsInto32Bit() const {
uint32_t val_32bit = (uint32_t)val;
return val_32bit == val;
}
}; };
struct JumpDestination { struct JumpDestination {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment