#include <string.h>
-namespace KJS {
+namespace JSC {
class JITCodeBuffer {
public:
#define SIB(type, reg, rm) MODRM(type, reg, rm)
#define CAN_SIGN_EXTEND_8_32(value) (value == ((int)(signed char)value))
-class X86Assembler {
-public:
+namespace X86 {
typedef enum {
eax,
ecx,
esi,
edi,
- NO_BASE = ebp,
- HAS_SIB = esp,
- NO_SCALE = esp,
+ noBase = ebp,
+ hasSib = esp,
+ noScale = esp,
} RegisterID;
+}
+
+class X86Assembler {
+public:
+ typedef X86::RegisterID RegisterID;
typedef enum {
OP_ADD_EvGv = 0x01,
OP_PUSH_EAX = 0x50,
OP_POP_EAX = 0x58,
PRE_OPERAND_SIZE = 0x66,
+ OP_IMUL_GvEvIz = 0x69,
OP_GROUP1_EvIz = 0x81,
OP_GROUP1_EvIb = 0x83,
OP_TEST_EvGv = 0x85,
OP2_JL_rel32 = 0x8C,
OP2_JGE_rel32 = 0x8D,
OP2_JLE_rel32 = 0x8E,
- OP2_MUL_GvEv = 0xAF,
+ OP2_IMUL_GvEv = 0xAF,
OP2_MOVZX_GvEw = 0xB7,
GROUP1_OP_ADD = 0,
m_buffer->putByte(OP_INT3);
}
- void emitPushl_r(RegisterID reg)
+ void pushl_r(RegisterID reg)
{
m_buffer->putByte(OP_PUSH_EAX + reg);
}
- void emitPushl_m(int offset, RegisterID base)
+ void pushl_m(int offset, RegisterID base)
{
m_buffer->putByte(OP_GROUP5_Ev);
emitModRm_opm(GROUP5_OP_PUSH, base, offset);
}
- void emitPopl_r(RegisterID reg)
+ void popl_r(RegisterID reg)
{
m_buffer->putByte(OP_POP_EAX + reg);
}
- void emitPopl_m(int offset, RegisterID base)
+ void popl_m(int offset, RegisterID base)
{
m_buffer->putByte(OP_GROUP1A_Ev);
emitModRm_opm(GROUP1A_OP_POP, base, offset);
}
- void emitMovl_rr(RegisterID src, RegisterID dst)
+ void movl_rr(RegisterID src, RegisterID dst)
{
m_buffer->putByte(OP_MOV_EvGv);
emitModRm_rr(src, dst);
}
- void emitAddl_rr(RegisterID src, RegisterID dst)
+ void addl_rr(RegisterID src, RegisterID dst)
{
m_buffer->putByte(OP_ADD_EvGv);
emitModRm_rr(src, dst);
}
- void emitAddl_i8r(int imm, RegisterID dst)
+ void addl_i8r(int imm, RegisterID dst)
{
m_buffer->putByte(OP_GROUP1_EvIb);
emitModRm_opr(GROUP1_OP_ADD, dst);
m_buffer->putByte(imm);
}
- void emitAddl_i32r(int imm, RegisterID dst)
+ void addl_i32r(int imm, RegisterID dst)
{
m_buffer->putByte(OP_GROUP1_EvIz);
emitModRm_opr(GROUP1_OP_ADD, dst);
m_buffer->putInt(imm);
}
- void emitAddl_mr(int offset, RegisterID base, RegisterID dst)
+ void addl_mr(int offset, RegisterID base, RegisterID dst)
{
m_buffer->putByte(OP_ADD_GvEv);
emitModRm_rm(dst, base, offset);
}
- void emitAndl_rr(RegisterID src, RegisterID dst)
+ void andl_rr(RegisterID src, RegisterID dst)
{
m_buffer->putByte(OP_AND_EvGv);
emitModRm_rr(src, dst);
}
- void emitAndl_i32r(int imm, RegisterID dst)
+ void andl_i32r(int imm, RegisterID dst)
{
m_buffer->putByte(OP_GROUP1_EvIz);
emitModRm_opr(GROUP1_OP_AND, dst);
m_buffer->putInt(imm);
}
- void emitCmpl_i8r(int imm, RegisterID dst)
+ void cmpl_i8r(int imm, RegisterID dst)
{
m_buffer->putByte(OP_GROUP1_EvIb);
emitModRm_opr(GROUP1_OP_CMP, dst);
m_buffer->putByte(imm);
}
- void emitCmpl_rr(RegisterID src, RegisterID dst)
+ void cmpl_rr(RegisterID src, RegisterID dst)
{
m_buffer->putByte(OP_CMP_EvGv);
emitModRm_rr(src, dst);
}
- void emitCmpl_rm(RegisterID src, int offset, RegisterID base)
+ void cmpl_rm(RegisterID src, int offset, RegisterID base)
{
m_buffer->putByte(OP_CMP_EvGv);
emitModRm_rm(src, base, offset);
}
- void emitCmpl_i32r(int imm, RegisterID dst)
+ void cmpl_i32r(int imm, RegisterID dst)
{
m_buffer->putByte(OP_GROUP1_EvIz);
emitModRm_opr(GROUP1_OP_CMP, dst);
m_buffer->putInt(imm);
}
- void emitCmpl_i32m(int imm, RegisterID dst)
+ void cmpl_i32m(int imm, RegisterID dst)
{
m_buffer->putByte(OP_GROUP1_EvIz);
emitModRm_opm(GROUP1_OP_CMP, dst);
m_buffer->putInt(imm);
}
- void emitCmpl_i32m(int imm, int offset, RegisterID dst)
+ void cmpl_i32m(int imm, int offset, RegisterID dst)
{
m_buffer->putByte(OP_GROUP1_EvIz);
emitModRm_opm(GROUP1_OP_CMP, dst, offset);
m_buffer->putInt(imm);
}
- void emitCmpl_i32m(int imm, void* addr)
+ void cmpl_i32m(int imm, void* addr)
{
m_buffer->putByte(OP_GROUP1_EvIz);
emitModRm_opm(GROUP1_OP_CMP, addr);
m_buffer->putInt(imm);
}
- void emitCmpw_rm(RegisterID src, RegisterID base, RegisterID index, int scale)
+ void cmpw_rm(RegisterID src, RegisterID base, RegisterID index, int scale)
{
m_buffer->putByte(PRE_OPERAND_SIZE);
m_buffer->putByte(OP_CMP_EvGv);
emitModRm_rmsib(src, base, index, scale);
}
- void emitOrl_rr(RegisterID src, RegisterID dst)
+ void orl_rr(RegisterID src, RegisterID dst)
{
m_buffer->putByte(OP_OR_EvGv);
emitModRm_rr(src, dst);
}
- void emitOrl_i8r(int imm, RegisterID dst)
+ void orl_rr(int imm, RegisterID dst)
{
m_buffer->putByte(OP_GROUP1_EvIb);
emitModRm_opr(GROUP1_OP_OR, dst);
m_buffer->putByte(imm);
}
- void emitSubl_rr(RegisterID src, RegisterID dst)
+ void subl_rr(RegisterID src, RegisterID dst)
{
m_buffer->putByte(OP_SUB_EvGv);
emitModRm_rr(src, dst);
}
- void emitSubl_i8r(int imm, RegisterID dst)
+ void subl_i8r(int imm, RegisterID dst)
{
m_buffer->putByte(OP_GROUP1_EvIb);
emitModRm_opr(GROUP1_OP_SUB, dst);
m_buffer->putByte(imm);
}
- void emitSubl_i32r(int imm, RegisterID dst)
+ void subl_i32r(int imm, RegisterID dst)
{
m_buffer->putByte(OP_GROUP1_EvIz);
emitModRm_opr(GROUP1_OP_SUB, dst);
m_buffer->putInt(imm);
}
- void emitSubl_mr(int offset, RegisterID base, RegisterID dst)
+ void subl_mr(int offset, RegisterID base, RegisterID dst)
{
m_buffer->putByte(OP_SUB_GvEv);
emitModRm_rm(dst, base, offset);
}
- void emitTestl_i32r(int imm, RegisterID dst)
+ void testl_i32r(int imm, RegisterID dst)
{
m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
m_buffer->putByteUnchecked(OP_GROUP3_EvIz);
m_buffer->putIntUnchecked(imm);
}
- void emitTestl_rr(RegisterID src, RegisterID dst)
+ void testl_rr(RegisterID src, RegisterID dst)
{
m_buffer->putByte(OP_TEST_EvGv);
emitModRm_rr(src, dst);
}
- void emitXorl_i8r(int imm, RegisterID dst)
+ void xorl_i8r(int imm, RegisterID dst)
{
m_buffer->putByte(OP_GROUP1_EvIb);
emitModRm_opr(GROUP1_OP_XOR, dst);
m_buffer->putByte(imm);
}
- void emitXorl_rr(RegisterID src, RegisterID dst)
+ void xorl_rr(RegisterID src, RegisterID dst)
{
m_buffer->putByte(OP_XOR_EvGv);
emitModRm_rr(src, dst);
}
- void emitSarl_i8r(int imm, RegisterID dst)
+ void sarl_i8r(int imm, RegisterID dst)
{
if (imm == 1) {
m_buffer->putByte(OP_GROUP2_Ev1);
}
}
- void emitSarl_CLr(RegisterID dst)
+ void sarl_CLr(RegisterID dst)
{
m_buffer->putByte(OP_GROUP2_EvCL);
emitModRm_opr(GROUP2_OP_SAR, dst);
}
- void emitShl_i8r(int imm, RegisterID dst)
+ void shl_i8r(int imm, RegisterID dst)
{
if (imm == 1) {
m_buffer->putByte(OP_GROUP2_Ev1);
}
}
- void emitShll_CLr(RegisterID dst)
+ void shll_CLr(RegisterID dst)
{
m_buffer->putByte(OP_GROUP2_EvCL);
emitModRm_opr(GROUP2_OP_SHL, dst);
}
- void emitMull_rr(RegisterID src, RegisterID dst)
+ void imull_rr(RegisterID src, RegisterID dst)
{
m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_MUL_GvEv);
+ m_buffer->putByte(OP2_IMUL_GvEv);
+ emitModRm_rr(dst, src);
+ }
+
+ void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
+ {
+ m_buffer->putByte(OP_IMUL_GvEvIz);
emitModRm_rr(dst, src);
+ m_buffer->putInt(value);
}
- void emitIdivl_r(RegisterID dst)
+ void idivl_r(RegisterID dst)
{
m_buffer->putByte(OP_GROUP3_Ev);
emitModRm_opr(GROUP3_OP_IDIV, dst);
}
- void emitCdq()
+ void cdq()
{
m_buffer->putByte(OP_CDQ);
}
- void emitMovl_mr(RegisterID base, RegisterID dst)
+ void movl_mr(RegisterID base, RegisterID dst)
{
m_buffer->putByte(OP_MOV_GvEv);
emitModRm_rm(dst, base);
}
- void emitMovl_mr(int offset, RegisterID base, RegisterID dst)
+ void movl_mr(int offset, RegisterID base, RegisterID dst)
{
m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
m_buffer->putByteUnchecked(OP_MOV_GvEv);
emitModRm_rm_Unchecked(dst, base, offset);
}
- void emitMovl_mr(void* addr, RegisterID dst)
+ void movl_mr(void* addr, RegisterID dst)
{
m_buffer->putByte(OP_MOV_GvEv);
emitModRm_rm(dst, addr);
}
- void emitMovl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
+ void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
{
m_buffer->putByte(OP_MOV_GvEv);
emitModRm_rmsib(dst, base, index, scale, offset);
}
- void emitMovzwl_mr(int offset, RegisterID base, RegisterID dst)
+ void movzwl_mr(int offset, RegisterID base, RegisterID dst)
{
m_buffer->putByte(OP_2BYTE_ESCAPE);
m_buffer->putByte(OP2_MOVZX_GvEw);
emitModRm_rm(dst, base, offset);
}
- void emitMovzwl_mr(RegisterID base, RegisterID index, int scale, RegisterID dst)
+ void movzwl_mr(RegisterID base, RegisterID index, int scale, RegisterID dst)
{
m_buffer->putByte(OP_2BYTE_ESCAPE);
m_buffer->putByte(OP2_MOVZX_GvEw);
emitModRm_rmsib(dst, base, index, scale);
}
- void emitMovzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
+ void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
{
m_buffer->putByte(OP_2BYTE_ESCAPE);
m_buffer->putByte(OP2_MOVZX_GvEw);
emitModRm_rmsib(dst, base, index, scale, offset);
}
- void emitMovl_rm(RegisterID src, RegisterID base)
+ void movl_rm(RegisterID src, RegisterID base)
{
m_buffer->putByte(OP_MOV_EvGv);
emitModRm_rm(src, base);
}
- void emitMovl_rm(RegisterID src, int offset, RegisterID base)
+ void movl_rm(RegisterID src, int offset, RegisterID base)
{
m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
m_buffer->putByteUnchecked(OP_MOV_EvGv);
emitModRm_rm_Unchecked(src, base, offset);
}
- void emitMovl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
+ void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
{
m_buffer->putByte(OP_MOV_EvGv);
emitModRm_rmsib(src, base, index, scale, offset);
}
- void emitMovl_i32r(int imm, RegisterID dst)
+ void movl_i32r(int imm, RegisterID dst)
{
m_buffer->putByte(OP_GROUP11_EvIz);
emitModRm_opr(GROUP11_MOV, dst);
m_buffer->putInt(imm);
}
- void emitMovl_i32m(int imm, int offset, RegisterID base)
+ void movl_i32m(int imm, int offset, RegisterID base)
{
m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
m_buffer->putByteUnchecked(OP_GROUP11_EvIz);
m_buffer->putIntUnchecked(imm);
}
- void emitMovl_i32m(int imm, void* addr)
+ void movl_i32m(int imm, void* addr)
{
m_buffer->putByte(OP_GROUP11_EvIz);
emitModRm_opm(GROUP11_MOV, addr);
m_buffer->putInt(imm);
}
- void emitLeal_mr(int offset, RegisterID base, RegisterID dst)
+ void leal_mr(int offset, RegisterID base, RegisterID dst)
{
m_buffer->putByte(OP_LEA);
emitModRm_rm(dst, base, offset);
}
- void emitRet()
+ void ret()
{
m_buffer->putByte(OP_RET);
}
- void emitJmpN_r(RegisterID dst)
+ void jmp_r(RegisterID dst)
{
m_buffer->putByte(OP_GROUP5_Ev);
emitModRm_opr(GROUP5_OP_JMPN, dst);
}
- void emitJmpN_m(int offset, RegisterID base)
+ void jmp_m(int offset, RegisterID base)
{
m_buffer->putByte(OP_GROUP5_Ev);
emitModRm_opm(GROUP5_OP_JMPN, base, offset);
}
- void emitCallN_r(RegisterID dst)
+ void call_r(RegisterID dst)
{
m_buffer->putByte(OP_GROUP5_Ev);
emitModRm_opr(GROUP5_OP_CALLN, dst);
return m_buffer->copy();
}
+#if COMPILER(MSVC)
+ void emitConvertToFastCall()
+ {
+ movl_mr(4, X86::esp, X86::eax);
+ movl_mr(8, X86::esp, X86::edx);
+ movl_mr(12, X86::esp, X86::ecx);
+ }
+
+ void emitRestoreArgumentReference()
+ {
+ movl_rm(X86::esp, 0, X86::esp);
+ }
+#else
+ void emitConvertToFastCall() {};
+ void emitRestoreArgumentReference() {};
+#endif
+
private:
void emitModRm_rr(RegisterID reg, RegisterID rm)
{
void emitModRm_rm(RegisterID reg, void* addr)
{
- m_buffer->putByte(MODRM(0, reg, NO_BASE));
+ m_buffer->putByte(MODRM(0, reg, X86::noBase));
m_buffer->putInt((int)addr);
}
void emitModRm_rm(RegisterID reg, RegisterID base)
{
- if (base == esp) {
- m_buffer->putByte(MODRM(0, reg, HAS_SIB));
- m_buffer->putByte(SIB(0, NO_SCALE, esp));
+ if (base == X86::esp) {
+ m_buffer->putByte(MODRM(0, reg, X86::hasSib));
+ m_buffer->putByte(SIB(0, X86::noScale, X86::esp));
} else
m_buffer->putByte(MODRM(0, reg, base));
}
void emitModRm_rm_Unchecked(RegisterID reg, RegisterID base, int offset)
{
- if (base == esp) {
+ if (base == X86::esp) {
if (CAN_SIGN_EXTEND_8_32(offset)) {
- m_buffer->putByteUnchecked(MODRM(1, reg, HAS_SIB));
- m_buffer->putByteUnchecked(SIB(0, NO_SCALE, esp));
+ m_buffer->putByteUnchecked(MODRM(1, reg, X86::hasSib));
+ m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));
m_buffer->putByteUnchecked(offset);
} else {
- m_buffer->putByteUnchecked(MODRM(2, reg, HAS_SIB));
- m_buffer->putByteUnchecked(SIB(0, NO_SCALE, esp));
+ m_buffer->putByteUnchecked(MODRM(2, reg, X86::hasSib));
+ m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));
m_buffer->putIntUnchecked(offset);
}
} else {
while (scale >>= 1)
shift++;
- m_buffer->putByte(MODRM(0, reg, HAS_SIB));
+ m_buffer->putByte(MODRM(0, reg, X86::hasSib));
m_buffer->putByte(SIB(shift, index, base));
}
shift++;
if (CAN_SIGN_EXTEND_8_32(offset)) {
- m_buffer->putByte(MODRM(1, reg, HAS_SIB));
+ m_buffer->putByte(MODRM(1, reg, X86::hasSib));
m_buffer->putByte(SIB(shift, index, base));
m_buffer->putByte(offset);
} else {
- m_buffer->putByte(MODRM(2, reg, HAS_SIB));
+ m_buffer->putByte(MODRM(2, reg, X86::hasSib));
m_buffer->putByte(SIB(shift, index, base));
m_buffer->putInt(offset);
}
JITCodeBuffer* m_buffer;
};
-} // namespace KJS
+} // namespace JSC
#endif // ENABLE(MASM) && PLATFORM(X86)