summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h')
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h163
1 files changed, 145 insertions, 18 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h
index 745bc60a77..cbbaaa5a16 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h
@@ -38,12 +38,8 @@
namespace JSC {
inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(signed char)value; }
-#if PLATFORM(X86_64)
-inline bool CAN_SIGN_EXTEND_32_64(intptr_t value) { return value == (intptr_t)(int32_t)value; }
-inline bool CAN_SIGN_EXTEND_U32_64(intptr_t value) { return value == (intptr_t)(uint32_t)value; }
-#endif
-namespace X86 {
+namespace X86Registers {
typedef enum {
eax,
ecx,
@@ -80,8 +76,8 @@ namespace X86 {
class X86Assembler {
public:
- typedef X86::RegisterID RegisterID;
- typedef X86::XMMRegisterID XMMRegisterID;
+ typedef X86Registers::RegisterID RegisterID;
+ typedef X86Registers::XMMRegisterID XMMRegisterID;
typedef XMMRegisterID FPRegisterID;
typedef enum {
@@ -114,10 +110,12 @@ private:
OP_OR_GvEv = 0x0B,
OP_2BYTE_ESCAPE = 0x0F,
OP_AND_EvGv = 0x21,
+ OP_AND_GvEv = 0x23,
OP_SUB_EvGv = 0x29,
OP_SUB_GvEv = 0x2B,
PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E,
OP_XOR_EvGv = 0x31,
+ OP_XOR_GvEv = 0x33,
OP_CMP_EvGv = 0x39,
OP_CMP_GvEv = 0x3B,
#if PLATFORM(X86_64)
@@ -169,6 +167,8 @@ private:
OP2_ADDSD_VsdWsd = 0x58,
OP2_MULSD_VsdWsd = 0x59,
OP2_SUBSD_VsdWsd = 0x5C,
+ OP2_DIVSD_VsdWsd = 0x5E,
+ OP2_XORPD_VpdWpd = 0x57,
OP2_MOVD_VdEd = 0x6E,
OP2_MOVD_EdVd = 0x7E,
OP2_JCC_rel32 = 0x80,
@@ -205,6 +205,7 @@ private:
GROUP3_OP_TEST = 0,
GROUP3_OP_NOT = 2,
+ GROUP3_OP_NEG = 3,
GROUP3_OP_IDIV = 7,
GROUP5_OP_CALLN = 2,
@@ -226,7 +227,6 @@ public:
{
}
- void enableLatePatch() { }
private:
JmpSrc(int offset)
: m_offset(offset)
@@ -319,6 +319,11 @@ public:
m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset);
}
+ void addl_rm(RegisterID src, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_ADD_EvGv, src, base, offset);
+ }
+
void addl_ir(int imm, RegisterID dst)
{
if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -386,6 +391,16 @@ public:
m_formatter.oneByteOp(OP_AND_EvGv, src, dst);
}
+ void andl_mr(int offset, RegisterID base, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_AND_GvEv, dst, base, offset);
+ }
+
+ void andl_rm(RegisterID src, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_AND_EvGv, src, base, offset);
+ }
+
void andl_ir(int imm, RegisterID dst)
{
if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -437,11 +452,26 @@ public:
}
#endif
+ void negl_r(RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
+ }
+
+ void negl_m(int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, base, offset);
+ }
+
void notl_r(RegisterID dst)
{
m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
}
+ void notl_m(int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, base, offset);
+ }
+
void orl_rr(RegisterID src, RegisterID dst)
{
m_formatter.oneByteOp(OP_OR_EvGv, src, dst);
@@ -452,6 +482,11 @@ public:
m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset);
}
+ void orl_rm(RegisterID src, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_OR_EvGv, src, base, offset);
+ }
+
void orl_ir(int imm, RegisterID dst)
{
if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -513,6 +548,11 @@ public:
m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset);
}
+ void subl_rm(RegisterID src, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_SUB_EvGv, src, base, offset);
+ }
+
void subl_ir(int imm, RegisterID dst)
{
if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -569,6 +609,27 @@ public:
m_formatter.oneByteOp(OP_XOR_EvGv, src, dst);
}
+ void xorl_mr(int offset, RegisterID base, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_XOR_GvEv, dst, base, offset);
+ }
+
+ void xorl_rm(RegisterID src, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_XOR_EvGv, src, base, offset);
+ }
+
+ void xorl_im(int imm, int offset, RegisterID base)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, offset);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, offset);
+ m_formatter.immediate32(imm);
+ }
+ }
+
void xorl_ir(int imm, RegisterID dst)
{
if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -649,7 +710,12 @@ public:
{
m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
}
-
+
+ void imull_mr(int offset, RegisterID base, RegisterID dst)
+ {
+ m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, base, offset);
+ }
+
void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
{
m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src);
@@ -1048,7 +1114,7 @@ public:
#else
void movl_rm(RegisterID src, void* addr)
{
- if (src == X86::eax)
+ if (src == X86Registers::eax)
movl_EAXm(addr);
else
m_formatter.oneByteOp(OP_MOV_EvGv, src, addr);
@@ -1056,7 +1122,7 @@ public:
void movl_mr(void* addr, RegisterID dst)
{
- if (dst == X86::eax)
+ if (dst == X86Registers::eax)
movl_mEAX(addr);
else
m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr);
@@ -1154,6 +1220,11 @@ public:
return m_formatter.immediateRel32();
}
+ JmpSrc jz()
+ {
+ return je();
+ }
+
JmpSrc jl()
{
m_formatter.twoByteOp(jccRel32(ConditionL));
@@ -1246,6 +1317,20 @@ public:
m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
}
+ void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
+ }
+
+#if !PLATFORM(X86_64)
+ void cvtsi2sd_mr(void* address, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, address);
+ }
+#endif
+
void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
{
m_formatter.prefix(PRE_SSE_F2);
@@ -1284,6 +1369,14 @@ public:
m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
}
+#if !PLATFORM(X86_64)
+ void movsd_mr(void* address, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address);
+ }
+#endif
+
void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
{
m_formatter.prefix(PRE_SSE_F2);
@@ -1321,6 +1414,30 @@ public:
m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
}
+ void ucomisd_mr(int offset, RegisterID base, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_66);
+ m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, base, offset);
+ }
+
+ void divsd_rr(XMMRegisterID src, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
+ }
+
+ void divsd_mr(int offset, RegisterID base, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset);
+ }
+
+ void xorpd_rr(XMMRegisterID src, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_66);
+ m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
+ }
+
// Misc instructions:
void int3()
@@ -1605,6 +1722,16 @@ private:
memoryModRM(reg, base, index, scale, offset);
}
+#if !PLATFORM(X86_64)
+ void twoByteOp(TwoByteOpcodeID opcode, int reg, void* address)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
+ m_buffer.putByteUnchecked(opcode);
+ memoryModRM(reg, address);
+ }
+#endif
+
#if PLATFORM(X86_64)
// Quad-word-sized operands:
//
@@ -1761,23 +1888,23 @@ private:
// Internals; ModRm and REX formatters.
- static const RegisterID noBase = X86::ebp;
- static const RegisterID hasSib = X86::esp;
- static const RegisterID noIndex = X86::esp;
+ static const RegisterID noBase = X86Registers::ebp;
+ static const RegisterID hasSib = X86Registers::esp;
+ static const RegisterID noIndex = X86Registers::esp;
#if PLATFORM(X86_64)
- static const RegisterID noBase2 = X86::r13;
- static const RegisterID hasSib2 = X86::r12;
+ static const RegisterID noBase2 = X86Registers::r13;
+ static const RegisterID hasSib2 = X86Registers::r12;
// Registers r8 & above require a REX prefixe.
inline bool regRequiresRex(int reg)
{
- return (reg >= X86::r8);
+ return (reg >= X86Registers::r8);
}
// Byte operand register spl & above require a REX prefix (to prevent the 'H' registers be accessed).
inline bool byteRegRequiresRex(int reg)
{
- return (reg >= X86::esp);
+ return (reg >= X86Registers::esp);
}
// Format a REX prefix byte.