diff --git a/js/src/assembler/assembler/X86Assembler.h b/js/src/assembler/assembler/X86Assembler.h index 00f3a54d03d..7df7ed55587 100644 --- a/js/src/assembler/assembler/X86Assembler.h +++ b/js/src/assembler/assembler/X86Assembler.h @@ -561,6 +561,13 @@ public: m_formatter.oneByteOp64(OP_ADD_GvEv, dst, base, offset); } + void addq_mr(const void* addr, RegisterID dst) + { + spew("addq %p, %s", + addr, nameIReg(8, dst)); + m_formatter.oneByteOp64(OP_ADD_GvEv, dst, addr); + } + void addq_ir(int imm, RegisterID dst) { spew("addq $0x%x, %s", imm, nameIReg(8,dst)); @@ -585,10 +592,22 @@ public: m_formatter.immediate32(imm); } } -#else + + void addq_im(int imm, const void* addr) + { + spew("addq %d, %p", imm, addr); + if (CAN_SIGN_EXTEND_8_32(imm)) { + m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr); + m_formatter.immediate8(imm); + } else { + m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr); + m_formatter.immediate32(imm); + } + } +#endif void addl_im(int imm, const void* addr) { - FIXME_INSN_PRINTING; + spew("addl %d, %p", imm, addr); if (CAN_SIGN_EXTEND_8_32(imm)) { m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr); m_formatter.immediate8(imm); @@ -597,7 +616,6 @@ public: m_formatter.immediate32(imm); } } -#endif void andl_rr(RegisterID src, RegisterID dst) { @@ -665,6 +683,13 @@ public: m_formatter.oneByteOp64(OP_OR_GvEv, dst, base, offset); } + void orq_mr(const void* addr, RegisterID dst) + { + spew("orq %p, %s", + addr, nameIReg(8, dst)); + m_formatter.oneByteOp64(OP_OR_GvEv, dst, addr); + } + void andq_ir(int imm, RegisterID dst) { spew("andq $0x%x, %s", imm, nameIReg(8,dst)); @@ -878,6 +903,13 @@ public: m_formatter.oneByteOp64(OP_SUB_GvEv, dst, base, offset); } + void subq_mr(const void* addr, RegisterID dst) + { + spew("subq %p, %s", + addr, nameIReg(8, dst)); + m_formatter.oneByteOp64(OP_SUB_GvEv, dst, addr); + } + void subq_ir(int imm, RegisterID dst) { spew("subq $0x%x, %s", imm, nameIReg(8,dst)); @@ -1254,7 +1286,23 @@ public: m_formatter.immediate32(imm); } } -#else + void cmpq_im(int imm, const void* addr) + { + spew("cmpq $0x%x, %p", imm, addr); + if (CAN_SIGN_EXTEND_8_32(imm)) { + m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr); + m_formatter.immediate8(imm); + } else { + m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr); + m_formatter.immediate32(imm); + } + } + void cmpq_rm(RegisterID reg, const void* addr) + { + spew("cmpq %s, %p", nameIReg(8, reg), addr); + m_formatter.oneByteOp64(OP_CMP_EvGv, reg, addr); + } +#endif void cmpl_rm(RegisterID reg, const void* addr) { spew("cmpl %s, %p", @@ -1273,7 +1321,6 @@ public: m_formatter.immediate32(imm); } } -#endif void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale) { @@ -1558,14 +1605,14 @@ public: m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, base, offset); } -#if WTF_CPU_X86 void movl_mr(const void* base, RegisterID index, int scale, RegisterID dst) { + int32_t disp = addressImmediate(base); + spew("movl %d(,%s,%d), %s", - int(base), nameIReg(index), scale, nameIReg(dst)); - m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, index, scale, int(base)); + disp, nameIReg(index), scale, nameIReg(dst)); + m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, index, scale, disp); } -#endif void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) { @@ -1574,7 +1621,6 @@ public: m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, index, scale, offset); } -#if !WTF_CPU_X86_64 void movl_mr(const void* addr, RegisterID dst) { spew("movl %p, %s", @@ -1584,7 +1630,6 @@ public: else m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr); } -#endif void movl_i32r(int imm, RegisterID dst) { @@ -1683,6 +1728,16 @@ public: m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, index, scale, offset); } + void movq_rm(RegisterID src, const void* addr) + { + spew("movq %s, %p", + nameIReg(8, src), addr); + if (src == X86Registers::eax) + movq_EAXm(addr); + else + m_formatter.oneByteOp64(OP_MOV_EvGv, src, addr); + } + void movq_mEAX(const void* addr) { FIXME_INSN_PRINTING; @@ -1717,6 +1772,16 @@ public: m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, index, scale, offset); } + void movq_mr(const void* addr, RegisterID dst) + { + spew("movq %p, %s", + addr, nameIReg(8, dst)); + if (dst == X86Registers::eax) + movq_mEAX(addr); + else + m_formatter.oneByteOp64(OP_MOV_GvEv, dst, addr); + } + void leaq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) { spew("leaq %d(%s,%s,%d), %s", @@ -1739,6 +1804,12 @@ public: m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, index, scale, offset); m_formatter.immediate32(imm); } + void movq_i32m(int imm, const void* addr) + { + spew("movq %d, %p", imm, addr); + m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, addr); + m_formatter.immediate32(imm); + } // Note that this instruction sign-extends its 32-bit immediate field to 64 // bits and loads the 64-bit value into a 64-bit register. @@ -1791,7 +1862,7 @@ public: m_formatter.oneByteRipOp64(OP_MOV_GvEv, dst, 0); return JmpSrc(m_formatter.size()); } -#else +#endif void movl_rm(RegisterID src, const void* addr) { spew("movl %s, %p", @@ -1804,11 +1875,10 @@ public: void movl_i32m(int imm, const void* addr) { - FIXME_INSN_PRINTING; + spew("movl %d, %p", imm, addr); m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr); m_formatter.immediate32(imm); } -#endif void movb_rm(RegisterID src, int offset, RegisterID base) { @@ -2205,7 +2275,6 @@ public: m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset); } -#if !WTF_CPU_X86_64 void addsd_mr(const void* address, XMMRegisterID dst) { spew("addsd %p, %s", @@ -2220,7 +2289,6 @@ public: m_formatter.prefix(PRE_SSE_F3); m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, address); } -#endif void cvtss2sd_rr(XMMRegisterID src, XMMRegisterID dst) { @@ -3144,6 +3212,26 @@ public: reinterpret_cast(where)[-1] = value; } + // Test whether the given address will fit in an address immediate field. + // This is always true on x86, but on x64 it's only true for addreses + // which fit in the 32-bit immediate field. + static bool isAddressImmediate(const void *address) { + intptr_t value = reinterpret_cast(address); + int32_t immediate = static_cast(value); + return value == immediate; + } + + // Convert the given address to a 32-bit immediate field value. This is + // a no-op on x86, but on x64 it asserts that the address is actually + // a valid address immediate. + static int32_t addressImmediate(const void *address) { +#if WTF_CPU_X86_64 + // x64's 64-bit addresses don't all fit in the 32-bit immediate. + ASSERT(isAddressImmediate(address)); +#endif + return static_cast(reinterpret_cast(address)); + } + private: static int32_t getInt32(void* where) @@ -3237,14 +3325,13 @@ private: memoryModRM_disp32(reg, index, scale, offset); } -#if !WTF_CPU_X86_64 void oneByteOp(OneByteOpcodeID opcode, int reg, const void* address) { m_buffer.ensureSpace(maxInstructionSize); m_buffer.putByteUnchecked(opcode); memoryModRM(reg, address); } -#else +#if WTF_CPU_X86_64 void oneByteRipOp(OneByteOpcodeID opcode, int reg, int ripOffset) { m_buffer.ensureSpace(maxInstructionSize); @@ -3317,7 +3404,6 @@ private: memoryModRM(reg, base, index, scale, offset); } -#if !WTF_CPU_X86_64 void twoByteOp(TwoByteOpcodeID opcode, int reg, const void* address) { m_buffer.ensureSpace(maxInstructionSize); @@ -3325,7 +3411,6 @@ private: m_buffer.putByteUnchecked(opcode); memoryModRM(reg, address); } -#endif void threeByteOp(ThreeByteOpcodeID opcode, ThreeByteEscape escape, int reg, RegisterID rm) { @@ -3400,6 +3485,14 @@ private: memoryModRM(reg, base, index, scale, offset); } + void oneByteOp64(OneByteOpcodeID opcode, int reg, const void* address) + { + m_buffer.ensureSpace(maxInstructionSize); + emitRexW(reg, 0, 0); + m_buffer.putByteUnchecked(opcode); + memoryModRM(reg, address); + } + void twoByteOp64(TwoByteOpcodeID opcode, int reg, RegisterID rm) { m_buffer.ensureSpace(maxInstructionSize); @@ -3766,14 +3859,19 @@ private: m_buffer.putIntUnchecked(offset); } -#if !WTF_CPU_X86_64 void memoryModRM(int reg, const void* address) { + int32_t disp = addressImmediate(address); + +#if WTF_CPU_X86_64 + // On x64-64, non-RIP-relative absolute mode requires a SIB. + putModRmSib(ModRmMemoryNoDisp, reg, noBase, noIndex, 0); +#else // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32! putModRm(ModRmMemoryNoDisp, reg, noBase); - m_buffer.putIntUnchecked(reinterpret_cast(address)); - } #endif + m_buffer.putIntUnchecked(disp); + } AssemblerBuffer m_buffer; } m_formatter; diff --git a/js/src/jit/shared/Assembler-x86-shared.h b/js/src/jit/shared/Assembler-x86-shared.h index 55b247198f4..2850b43246f 100644 --- a/js/src/jit/shared/Assembler-x86-shared.h +++ b/js/src/jit/shared/Assembler-x86-shared.h @@ -248,11 +248,9 @@ class AssemblerX86Shared case Operand::MEM_SCALE: masm.movl_mr(src.disp(), src.base(), src.index(), src.scale(), dest.code()); break; -#ifdef JS_CPU_X86 - case Operand::MEM_ADDRESS: + case Operand::MEM_ADDRESS32: masm.movl_mr(src.address(), dest.code()); break; -#endif default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -268,11 +266,9 @@ class AssemblerX86Shared case Operand::MEM_SCALE: masm.movl_rm(src.code(), dest.disp(), dest.base(), dest.index(), dest.scale()); break; -#ifdef JS_CPU_X86 - case Operand::MEM_ADDRESS: + case Operand::MEM_ADDRESS32: masm.movl_rm(src.code(), dest.address()); break; -#endif default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -737,11 +733,9 @@ class AssemblerX86Shared case Operand::MEM_SCALE: masm.cmpl_im(imm.value, op.disp(), op.base(), op.index(), op.scale()); break; -#ifdef JS_CPU_X86 - case Operand::MEM_ADDRESS: + case Operand::MEM_ADDRESS32: masm.cmpl_im(imm.value, op.address()); break; -#endif default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -754,11 +748,9 @@ class AssemblerX86Shared case Operand::MEM_REG_DISP: masm.cmpl_rm(rhs.code(), lhs.disp(), lhs.base()); break; -#ifdef JS_CPU_X86 - case Operand::MEM_ADDRESS: + case Operand::MEM_ADDRESS32: masm.cmpl_rm(rhs.code(), lhs.address()); break; -#endif default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -771,11 +763,9 @@ class AssemblerX86Shared case Operand::MEM_REG_DISP: masm.cmpl_im(imm.value, op.disp(), op.base()); break; -#ifdef JS_CPU_X86 - case Operand::MEM_ADDRESS: + case Operand::MEM_ADDRESS32: masm.cmpl_im(imm.value, op.address()); break; -#endif default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -822,11 +812,9 @@ class AssemblerX86Shared case Operand::MEM_REG_DISP: masm.addl_im(imm.value, op.disp(), op.base()); break; -#ifdef JS_CPU_X86 - case Operand::MEM_ADDRESS: + case Operand::MEM_ADDRESS32: masm.addl_im(imm.value, op.address()); break; -#endif default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -1227,11 +1215,9 @@ class AssemblerX86Shared case Operand::MEM_REG_DISP: masm.addsd_mr(src.disp(), src.base(), dest.code()); break; -#ifdef JS_CPU_X86 - case Operand::MEM_ADDRESS: + case Operand::MEM_ADDRESS32: masm.addsd_mr(src.address(), dest.code()); break; -#endif default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -1245,11 +1231,9 @@ class AssemblerX86Shared case Operand::MEM_REG_DISP: masm.addss_mr(src.disp(), src.base(), dest.code()); break; -#ifdef JS_CPU_X86 - case Operand::MEM_ADDRESS: + case Operand::MEM_ADDRESS32: masm.addss_mr(src.address(), dest.code()); break; -#endif default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } diff --git a/js/src/jit/x64/Assembler-x64.h b/js/src/jit/x64/Assembler-x64.h index e06212a1ece..2e7d9fa5ca5 100644 --- a/js/src/jit/x64/Assembler-x64.h +++ b/js/src/jit/x64/Assembler-x64.h @@ -175,11 +175,12 @@ class Operand REG, MEM_REG_DISP, FPREG, - MEM_SCALE + MEM_SCALE, + MEM_ADDRESS32 }; private: - Kind kind_ : 3; + Kind kind_ : 4; int32_t base_ : 5; Scale scale_ : 3; int32_t index_ : 5; @@ -218,6 +219,11 @@ class Operand base_(reg.code()), disp_(disp) { } + explicit Operand(const AbsoluteAddress &address) + : kind_(MEM_ADDRESS32) + { + disp_ = JSC::X86Assembler::addressImmediate(address.addr); + } Address toAddress() const { JS_ASSERT(kind() == MEM_REG_DISP); @@ -256,6 +262,10 @@ class Operand JS_ASSERT(kind() == MEM_REG_DISP || kind() == MEM_SCALE); return disp_; } + void *address() const { + JS_ASSERT(kind() == MEM_ADDRESS32); + return reinterpret_cast(intptr_t(disp_)); + } }; } // namespace jit @@ -410,6 +420,9 @@ class Assembler : public AssemblerX86Shared case Operand::MEM_SCALE: masm.movq_mr(src.disp(), src.base(), src.index(), src.scale(), dest.code()); break; + case Operand::MEM_ADDRESS32: + masm.movq_mr(src.address(), dest.code()); + break; default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -425,6 +438,9 @@ class Assembler : public AssemblerX86Shared case Operand::MEM_SCALE: masm.movq_rm(src.code(), dest.disp(), dest.base(), dest.index(), dest.scale()); break; + case Operand::MEM_ADDRESS32: + masm.movq_rm(src.code(), dest.address()); + break; default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -440,6 +456,9 @@ class Assembler : public AssemblerX86Shared case Operand::MEM_SCALE: masm.movq_i32m(imm32.value, dest.disp(), dest.base(), dest.index(), dest.scale()); break; + case Operand::MEM_ADDRESS32: + masm.movq_i32m(imm32.value, dest.address()); + break; default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -476,6 +495,9 @@ class Assembler : public AssemblerX86Shared case Operand::MEM_REG_DISP: masm.addq_im(imm.value, dest.disp(), dest.base()); break; + case Operand::MEM_ADDRESS32: + masm.addq_im(imm.value, dest.address()); + break; default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -491,6 +513,9 @@ class Assembler : public AssemblerX86Shared case Operand::MEM_REG_DISP: masm.addq_mr(src.disp(), src.base(), dest.code()); break; + case Operand::MEM_ADDRESS32: + masm.addq_mr(src.address(), dest.code()); + break; default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -510,6 +535,9 @@ class Assembler : public AssemblerX86Shared case Operand::MEM_REG_DISP: masm.subq_mr(src.disp(), src.base(), dest.code()); break; + case Operand::MEM_ADDRESS32: + masm.subq_mr(src.address(), dest.code()); + break; default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -537,6 +565,9 @@ class Assembler : public AssemblerX86Shared case Operand::MEM_REG_DISP: masm.orq_mr(src.disp(), src.base(), dest.code()); break; + case Operand::MEM_ADDRESS32: + masm.orq_mr(src.address(), dest.code()); + break; default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -622,6 +653,9 @@ class Assembler : public AssemblerX86Shared case Operand::MEM_REG_DISP: masm.cmpq_rm(rhs.code(), lhs.disp(), lhs.base()); break; + case Operand::MEM_ADDRESS32: + masm.cmpq_rm(rhs.code(), lhs.address()); + break; default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } @@ -634,6 +668,9 @@ class Assembler : public AssemblerX86Shared case Operand::MEM_REG_DISP: masm.cmpq_im(rhs.value, lhs.disp(), lhs.base()); break; + case Operand::MEM_ADDRESS32: + masm.cmpq_im(rhs.value, lhs.address()); + break; default: MOZ_ASSUME_UNREACHABLE("unexpected operand kind"); } diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index 677ca6689fb..783350b527a 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -509,19 +509,31 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared } void branch32(Condition cond, const AbsoluteAddress &lhs, Imm32 rhs, Label *label) { - mov(ImmPtr(lhs.addr), ScratchReg); - branch32(cond, Address(ScratchReg, 0), rhs, label); + if (JSC::X86Assembler::isAddressImmediate(lhs.addr)) { + branch32(cond, Operand(lhs), rhs, label); + } else { + mov(ImmPtr(lhs.addr), ScratchReg); + branch32(cond, Address(ScratchReg, 0), rhs, label); + } } void branch32(Condition cond, const AbsoluteAddress &lhs, Register rhs, Label *label) { - mov(ImmPtr(lhs.addr), ScratchReg); - branch32(cond, Address(ScratchReg, 0), rhs, label); + if (JSC::X86Assembler::isAddressImmediate(lhs.addr)) { + branch32(cond, Operand(lhs), rhs, label); + } else { + mov(ImmPtr(lhs.addr), ScratchReg); + branch32(cond, Address(ScratchReg, 0), rhs, label); + } } // Specialization for AbsoluteAddress. void branchPtr(Condition cond, const AbsoluteAddress &addr, const Register &ptr, Label *label) { JS_ASSERT(ptr != ScratchReg); - mov(ImmPtr(addr.addr), ScratchReg); - branchPtr(cond, Operand(ScratchReg, 0x0), ptr, label); + if (JSC::X86Assembler::isAddressImmediate(addr.addr)) { + branchPtr(cond, Operand(addr), ptr, label); + } else { + mov(ImmPtr(addr.addr), ScratchReg); + branchPtr(cond, Operand(ScratchReg, 0x0), ptr, label); + } } void branchPrivatePtr(Condition cond, Address lhs, ImmPtr ptr, Label *label) { @@ -593,8 +605,12 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared movq(imm, dest); } void loadPtr(const AbsoluteAddress &address, Register dest) { - mov(ImmPtr(address.addr), ScratchReg); - movq(Operand(ScratchReg, 0x0), dest); + if (JSC::X86Assembler::isAddressImmediate(address.addr)) { + movq(Operand(address), dest); + } else { + mov(ImmPtr(address.addr), ScratchReg); + movq(Operand(ScratchReg, 0x0), dest); + } } void loadPtr(const Address &address, Register dest) { movq(Operand(address), dest); @@ -631,8 +647,12 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared movq(src, dest); } void storePtr(const Register &src, const AbsoluteAddress &address) { - mov(ImmPtr(address.addr), ScratchReg); - movq(src, Operand(ScratchReg, 0x0)); + if (JSC::X86Assembler::isAddressImmediate(address.addr)) { + movq(src, Operand(address)); + } else { + mov(ImmPtr(address.addr), ScratchReg); + movq(src, Operand(ScratchReg, 0x0)); + } } void rshiftPtr(Imm32 imm, Register dest) { shrq(imm, dest); @@ -1065,8 +1085,12 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared } void inc64(AbsoluteAddress dest) { - mov(ImmPtr(dest.addr), ScratchReg); - addPtr(Imm32(1), Address(ScratchReg, 0)); + if (JSC::X86Assembler::isAddressImmediate(dest.addr)) { + addPtr(Imm32(1), Operand(dest)); + } else { + mov(ImmPtr(dest.addr), ScratchReg); + addPtr(Imm32(1), Address(ScratchReg, 0)); + } } // If source is a double, load it into dest. If source is int32, diff --git a/js/src/jit/x86/Assembler-x86.h b/js/src/jit/x86/Assembler-x86.h index d27848a31c6..9aa997fd642 100644 --- a/js/src/jit/x86/Assembler-x86.h +++ b/js/src/jit/x86/Assembler-x86.h @@ -116,7 +116,7 @@ class Operand MEM_REG_DISP, FPREG, MEM_SCALE, - MEM_ADDRESS + MEM_ADDRESS32 }; private: @@ -160,11 +160,11 @@ class Operand disp_(disp) { } explicit Operand(const AbsoluteAddress &address) - : kind_(MEM_ADDRESS), + : kind_(MEM_ADDRESS32), disp_(reinterpret_cast(address.addr)) { } explicit Operand(const void *address) - : kind_(MEM_ADDRESS), + : kind_(MEM_ADDRESS32), disp_(reinterpret_cast(address)) { } @@ -206,7 +206,7 @@ class Operand return disp_; } void *address() const { - JS_ASSERT(kind() == MEM_ADDRESS); + JS_ASSERT(kind() == MEM_ADDRESS32); return reinterpret_cast(disp_); } }; @@ -386,7 +386,7 @@ class Assembler : public AssemblerX86Shared masm.cmpl_im_force32(imm.value, op.disp(), op.base()); writeDataRelocation(imm); break; - case Operand::MEM_ADDRESS: + case Operand::MEM_ADDRESS32: masm.cmpl_im(imm.value, op.address()); writeDataRelocation(imm); break;