Inline immediate number version of op_mul.
[WebKit-https.git] / JavaScriptCore / masm / X86Assembler.h
index f98600a..0255dcb 100644 (file)
@@ -147,8 +147,7 @@ private:
 #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,
@@ -159,10 +158,15 @@ public:
         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,
@@ -178,6 +182,7 @@ public:
         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,
@@ -207,7 +212,7 @@ public:
         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,
@@ -245,167 +250,167 @@ public:
         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);
@@ -413,26 +418,26 @@ public:
         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);
@@ -444,13 +449,13 @@ public:
         }
     }
 
-    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);
@@ -462,103 +467,110 @@ public:
         }
     }
 
-    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);
@@ -566,37 +578,37 @@ public:
         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);
@@ -774,6 +786,23 @@ public:
         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)
     {
@@ -788,29 +817,29 @@ private:
 
     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 {
@@ -836,7 +865,7 @@ private:
         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));
     }
 
@@ -847,11 +876,11 @@ private:
             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);
         }