Commit 5babbb14 authored by Travis Hance's avatar Travis Hance

Merge pull request #670 from undingen/rewriter_alloc

rewriter: use lea to allocate stack space
parents bbc95869 08266dc3
...@@ -145,6 +145,15 @@ void Assembler::emitSIB(uint8_t scalebits, uint8_t index, uint8_t base) { ...@@ -145,6 +145,15 @@ void Assembler::emitSIB(uint8_t scalebits, uint8_t index, uint8_t base) {
emitByte((scalebits << 6) | (index << 3) | base); emitByte((scalebits << 6) | (index << 3) | base);
} }
int Assembler::getModeFromOffset(int offset) const {
if (offset == 0)
return 0b00;
else if (-0x80 <= offset && offset < 0x80)
return 0b01;
else
return 0b10;
}
void Assembler::mov(Immediate val, Register dest, bool force_64bit_load) { void Assembler::mov(Immediate val, Register dest, bool force_64bit_load) {
force_64bit_load = force_64bit_load || !val.fitsInto32Bit(); force_64bit_load = force_64bit_load || !val.fitsInto32Bit();
...@@ -178,15 +187,7 @@ void Assembler::movq(Immediate src, Indirect dest) { ...@@ -178,15 +187,7 @@ void Assembler::movq(Immediate src, Indirect dest) {
emitByte(0xc7); emitByte(0xc7);
bool needssib = (dest_idx == 0b100); bool needssib = (dest_idx == 0b100);
int mode = getModeFromOffset(dest.offset);
int mode;
if (dest.offset == 0)
mode = 0b00;
else if (-0x80 <= dest.offset && dest.offset < 0x80)
mode = 0b01;
else
mode = 0b10;
emitModRM(mode, 0, dest_idx); emitModRM(mode, 0, dest_idx);
if (needssib) if (needssib)
...@@ -246,15 +247,7 @@ void Assembler::mov(Register src, Indirect dest) { ...@@ -246,15 +247,7 @@ void Assembler::mov(Register src, Indirect dest) {
emitByte(0x89); emitByte(0x89);
bool needssib = (dest_idx == 0b100); bool needssib = (dest_idx == 0b100);
int mode = getModeFromOffset(dest.offset);
int mode;
if (dest.offset == 0)
mode = 0b00;
else if (-0x80 <= dest.offset && dest.offset < 0x80)
mode = 0b01;
else
mode = 0b10;
emitModRM(mode, src_idx, dest_idx); emitModRM(mode, src_idx, dest_idx);
if (needssib) if (needssib)
...@@ -450,15 +443,7 @@ void Assembler::movsd(XMMRegister src, Indirect dest) { ...@@ -450,15 +443,7 @@ void Assembler::movsd(XMMRegister src, Indirect dest) {
emitByte(0x11); emitByte(0x11);
bool needssib = (dest_idx == 0b100); bool needssib = (dest_idx == 0b100);
int mode = getModeFromOffset(dest.offset);
int mode;
if (dest.offset == 0)
mode = 0b00;
else if (-0x80 <= dest.offset && dest.offset < 0x80)
mode = 0b01;
else
mode = 0b10;
emitModRM(mode, src_idx, dest_idx); emitModRM(mode, src_idx, dest_idx);
if (needssib) if (needssib)
...@@ -809,8 +794,6 @@ void Assembler::cmp(Indirect mem, Register reg) { ...@@ -809,8 +794,6 @@ void Assembler::cmp(Indirect mem, Register reg) {
} }
void Assembler::lea(Indirect mem, Register reg) { void Assembler::lea(Indirect mem, Register reg) {
RELEASE_ASSERT(mem.base != RSP && mem.base != R12, "We have to generate the SIB byte...");
int mem_idx = mem.base.regnum; int mem_idx = mem.base.regnum;
int reg_idx = reg.regnum; int reg_idx = reg.regnum;
...@@ -830,14 +813,17 @@ void Assembler::lea(Indirect mem, Register reg) { ...@@ -830,14 +813,17 @@ void Assembler::lea(Indirect mem, Register reg) {
emitRex(rex); emitRex(rex);
emitByte(0x8D); emitByte(0x8D);
if (mem.offset == 0) { bool needssib = (mem_idx == 0b100);
emitModRM(0b00, reg_idx, mem_idx); int mode = getModeFromOffset(mem.offset);
} else if (-0x80 <= mem.offset && mem.offset < 0x80) { emitModRM(mode, reg_idx, mem_idx);
emitModRM(0b01, reg_idx, mem_idx);
if (needssib)
emitSIB(0b00, 0b100, mem_idx);
if (mode == 0b01) {
emitByte(mem.offset); emitByte(mem.offset);
} else { } else if (mode == 0b10) {
assert((-1L << 31) <= mem.offset && mem.offset < (1L << 31) - 1); assert((-1L << 31) <= mem.offset && mem.offset < (1L << 31) - 1);
emitModRM(0b10, reg_idx, mem_idx);
emitInt(mem.offset, 4); emitInt(mem.offset, 4);
} }
} }
......
...@@ -88,6 +88,8 @@ private: ...@@ -88,6 +88,8 @@ private:
void emitSIB(uint8_t scalebits, uint8_t index, uint8_t base); void emitSIB(uint8_t scalebits, uint8_t index, uint8_t base);
void emitArith(Immediate imm, Register reg, int opcode); void emitArith(Immediate imm, Register reg, int opcode);
int getModeFromOffset(int offset) const;
public: public:
Assembler(uint8_t* start, int size) : start_addr(start), end_addr(start + size), addr(start_addr), failed(false) {} Assembler(uint8_t* start, int size) : start_addr(start), end_addr(start + size), addr(start_addr), failed(false) {}
......
...@@ -1358,11 +1358,9 @@ int Rewriter::_allocate(RewriterVar* result, int n) { ...@@ -1358,11 +1358,9 @@ int Rewriter::_allocate(RewriterVar* result, int n) {
assembler::Register r = result->initializeInReg(); assembler::Register r = result->initializeInReg();
// TODO should be a LEA instruction // TODO we could do something like we do for constants and only load
// In fact, we could do something like we do for constants and only load
// this when necessary, so it won't spill. Is that worth? // this when necessary, so it won't spill. Is that worth?
assembler->mov(assembler::RSP, r); assembler->lea(assembler::Indirect(assembler::RSP, 8 * a + rewrite->getScratchRspOffset()), r);
assembler->add(assembler::Immediate(8 * a + rewrite->getScratchRspOffset()), r);
assertConsistent(); assertConsistent();
result->releaseIfNoUses(); result->releaseIfNoUses();
......
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