diff --git a/src/compile.cpp b/src/compile.cpp index 35daee8124..9e2b4cfd95 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -518,6 +518,12 @@ isByte(int32_t v) return v == static_cast(v); } +inline bool +isInt32(uintptr_t v) +{ + return v == static_cast(static_cast(v)); +} + enum Register { rax = 0, rcx = 1, @@ -761,7 +767,7 @@ class Assembler { } void pushAddress(uintptr_t v) { - if (BytesPerWord == 8) { + if (BytesPerWord == 8 and not isInt32(v)) { mov(v, rsi); push(rsi); } else { @@ -812,6 +818,11 @@ class Assembler { } } + void add(Register src, Register dst, unsigned dstOffset) { + rex(); + offsetInstruction(0x01, 0, 0x40, 0x80, src, dst, dstOffset); + } + void adc(int32_t v, Register dst) { assert(code.s, isByte(v)); // todo @@ -997,6 +1008,7 @@ class Assembler { } void cmp(Register a, Register b) { + rex(); code.append(0x39); code.append(0xc0 | (a << 3) | b); } @@ -1133,6 +1145,12 @@ class Compiler: public Assembler { } } + void pushLong(Register r) { + assert(t, BytesPerWord == 8); + push(r); + sub(8, rsp); + } + void pushLong(Register low, Register high) { assert(t, BytesPerWord == 4); push(high); @@ -2226,8 +2244,8 @@ class Compiler: public Assembler { case lrem: if (BytesPerWord == 8) { - popLong(rax); popLong(rcx); + popLong(rax); cqo(); Assembler::idiv(rcx); pushLong(rdx);