mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 915833 - SpiderMonkey: Add support for immediate addresses on x64. r=sstangl
This commit is contained in:
parent
2f0a25f9b6
commit
f679cd4daa
@ -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<const void**>(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<intptr_t>(address);
|
||||
int32_t immediate = static_cast<int32_t>(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<int32_t>(reinterpret_cast<intptr_t>(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<int32_t>(address));
|
||||
}
|
||||
#endif
|
||||
m_buffer.putIntUnchecked(disp);
|
||||
}
|
||||
|
||||
AssemblerBuffer m_buffer;
|
||||
} m_formatter;
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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<void *>(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");
|
||||
}
|
||||
|
@ -509,20 +509,32 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
}
|
||||
|
||||
void branch32(Condition cond, const AbsoluteAddress &lhs, Imm32 rhs, Label *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) {
|
||||
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);
|
||||
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) {
|
||||
branchPtr(cond, lhs, ImmWord(uintptr_t(ptr.value) >> 1), label);
|
||||
@ -593,9 +605,13 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
movq(imm, dest);
|
||||
}
|
||||
void loadPtr(const AbsoluteAddress &address, Register 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,9 +647,13 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
movq(src, dest);
|
||||
}
|
||||
void storePtr(const Register &src, const AbsoluteAddress &address) {
|
||||
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,9 +1085,13 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
}
|
||||
|
||||
void inc64(AbsoluteAddress dest) {
|
||||
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,
|
||||
// convert it to double. Else, branch to failure.
|
||||
|
@ -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<int32_t>(address.addr))
|
||||
{ }
|
||||
explicit Operand(const void *address)
|
||||
: kind_(MEM_ADDRESS),
|
||||
: kind_(MEM_ADDRESS32),
|
||||
disp_(reinterpret_cast<int32_t>(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<void *>(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;
|
||||
|
Loading…
Reference in New Issue
Block a user