* Removed all Id tags.
[cacao.git] / src / vm / jit / i386 / codegen.h
index 78c003ffc8cf1ffdc5a2adb6872cb19d43f67aa3..aa635ed5673c119c6d1a72d908db4758e1e284d1 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/i386/codegen.h - code generation macros and definitions for i386
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-            Christian Thalinger
-
-   Changes:
-
-   $Id: codegen.h 4669 2006-03-21 14:07:34Z twisti $
-
 */
 
 
@@ -40,6 +31,8 @@
 #include "config.h"
 #include "vm/types.h"
 
+#include "vm/jit/i386/emit.h"
+
 #include "vm/jit/jit.h"
 
 
 # define LSRA_USES_REG_RES
 #endif
 
-/* some defines ***************************************************************/
-
-#define PATCHER_CALL_SIZE    5          /* size in bytes of a patcher call    */
-
 
 /* additional functions and macros to generate code ***************************/
 
     } while (0)
 
 
-/* gen_nullptr_check(objreg) */
-
-#define gen_nullptr_check(objreg) \
-    if (checknull) { \
-        M_TEST(objreg); \
-        M_BEQ(0); \
-           codegen_add_nullpointerexception_ref(cd, cd->mcodeptr); \
-    }
-
-#define gen_bound_check \
-    if (checkbounds) { \
-        M_CMP_MEMBASE(s1, OFFSET(java_arrayheader, size), s2); \
-        M_BAE(0); \
-        codegen_add_arrayindexoutofboundsexception_ref(cd, cd->mcodeptr, s2); \
-    }
-
-#define gen_div_check(v) \
-    if (checknull) { \
-        if ((v)->flags & INMEMORY) \
-            M_CMP_IMM_MEMBASE(0, REG_SP, src->regoff * 4); \
-        else \
-            M_TEST(src->regoff); \
-        M_BEQ(0); \
-        codegen_add_arithmeticexception_ref(cd, cd->mcodeptr); \
-    }
-
-
 /* MCODECHECK(icnt) */
 
 #define MCODECHECK(icnt) \
-       if ((cd->mcodeptr + (icnt)) > (u1 *) cd->mcodeend) \
-        cd->mcodeptr = (u1 *) codegen_increase(cd, cd->mcodeptr)
+    do { \
+        if ((cd->mcodeptr + (icnt)) > (u1 *) cd->mcodeend) \
+            codegen_increase(cd); \
+    } while (0)
 
 
 /* M_INTMOVE:
      if a and b are the same int-register, no code will be generated.
 */ 
 
-#define M_INTMOVE(reg,dreg) \
-    if ((reg) != (dreg)) { \
-        i386_mov_reg_reg(cd, (reg),(dreg)); \
-    }
+#define M_INTMOVE(a,b) \
+    do { \
+        if ((a) != (b)) \
+            M_MOV(a, b); \
+    } while (0)
+
+#define M_LNGMOVE(a,b) \
+    do { \
+        if (GET_HIGH_REG(a) == GET_LOW_REG(b)) { \
+            assert((GET_LOW_REG(a) != GET_HIGH_REG(b))); \
+            M_INTMOVE(GET_HIGH_REG(a), GET_HIGH_REG(b)); \
+            M_INTMOVE(GET_LOW_REG(a), GET_LOW_REG(b)); \
+        } else { \
+            M_INTMOVE(GET_LOW_REG(a), GET_LOW_REG(b)); \
+            M_INTMOVE(GET_HIGH_REG(a), GET_HIGH_REG(b)); \
+        } \
+    } while (0)
 
 
 /* M_FLTMOVE:
     if a and b are the same float-register, no code will be generated
 */
 
-#define M_FLTMOVE(reg,dreg) \
-    do { \
-        log_text("M_FLTMOVE"); \
-        assert(0); \
+#define M_FLTMOVE(reg,dreg)                                          \
+    do {                                                             \
+        if ((reg) != (dreg)) {                                       \
+            log_text("M_FLTMOVE");                                   \
+            assert(0);                                               \
+        }                                                            \
     } while (0)
 
 
-#define M_LNGMEMMOVE(reg,dreg) \
+#define ICONST(d,c) \
     do { \
-        i386_mov_membase_reg(cd, REG_SP, (reg) * 4, REG_ITMP1); \
-        i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, (dreg) * 4); \
-        i386_mov_membase_reg(cd, REG_SP, (reg) * 4 + 4, REG_ITMP1); \
-        i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, (dreg) * 4 + 4); \
+        if ((c) == 0) \
+            M_CLR(d); \
+        else \
+            M_MOV_IMM((c), d); \
     } while (0)
 
 
-/* var_to_reg_xxx:
-    this function generates code to fetch data from a pseudo-register
-    into a real register. 
-    If the pseudo-register has actually been assigned to a real 
-    register, no code will be emitted, since following operations
-    can use this register directly.
-    
-    v: pseudoregister to be fetched from
-    tempregnum: temporary register to be used if v is actually spilled to ram
-
-    return: the register number, where the operand can be found after 
-            fetching (this wil be either tempregnum or the register
-            number allready given to v)
-*/
-
-#define var_to_reg_int(regnr,v,tempnr) \
+#define LCONST(d,c) \
     do { \
-        if ((v)->flags & INMEMORY) { \
-            COUNT_SPILLS; \
-            M_ILD(tempnr, REG_SP, (v)->regoff * 4); \
-            regnr = tempnr; \
+        if ((c) == 0) { \
+            M_CLR(GET_LOW_REG(d)); \
+            M_CLR(GET_HIGH_REG(d)); \
         } else { \
-            regnr = (v)->regoff; \
+            M_MOV_IMM((c), GET_LOW_REG(d)); \
+            M_MOV_IMM((c) >> 32, GET_HIGH_REG(d)); \
         } \
     } while (0)
 
-#define var_to_reg_lng(regnr,v,tempnr) \
-    do { \
-        if ((v)->flags & INMEMORY) { \
-            COUNT_SPILLS; \
-            M_LLD(tempnr, REG_SP, (v)->regoff * 4); \
-            regnr = tempnr; \
-        } else { \
-            regnr = (v)->regoff; \
-        } \
-    } while (0)
 
-#define var_to_reg_flt(regnr,v,tempnr) \
-    if ((v)->type == TYPE_FLT) { \
-        if ((v)->flags & INMEMORY) { \
-            COUNT_SPILLS; \
-            i386_flds_membase(cd, REG_SP, (v)->regoff * 4); \
-            fpu_st_offset++; \
-            regnr = tempnr; \
-        } else { \
-            i386_fld_reg(cd, (v)->regoff + fpu_st_offset); \
-            fpu_st_offset++; \
-            regnr = (v)->regoff; \
-        } \
-    } else { \
-        if ((v)->flags & INMEMORY) { \
-            COUNT_SPILLS; \
-            i386_fldl_membase(cd, REG_SP, (v)->regoff * 4); \
-            fpu_st_offset++; \
-            regnr = tempnr; \
-        } else { \
-            i386_fld_reg(cd, (v)->regoff + fpu_st_offset); \
-            fpu_st_offset++; \
-            regnr = (v)->regoff; \
-        } \
-    }
-
-#define NEW_var_to_reg_flt(regnr,v,tempnr) \
-    if ((v)->type == TYPE_FLT) { \
-       if ((v)->flags & INMEMORY) { \
-            COUNT_SPILLS; \
-            i386_flds_membase(cd, REG_SP, (v)->regoff * 4); \
-            fpu_st_offset++; \
-            regnr = tempnr; \
-        } else { \
-            regnr = (v)->regoff; \
-        } \
-    } else { \
-        if ((v)->flags & INMEMORY) { \
-            COUNT_SPILLS; \
-            i386_fldl_membase(cd, REG_SP, (v)->regoff * 4); \
-            fpu_st_offset++; \
-            regnr = tempnr; \
-        } else { \
-            regnr = (v)->regoff; \
-        } \
-    }
-
-
-/* store_reg_to_var_xxx:
-    This function generates the code to store the result of an operation
-    back into a spilled pseudo-variable.
-    If the pseudo-variable has not been spilled in the first place, this 
-    function will generate nothing.
-    
-    v ............ Pseudovariable
-    tempregnum ... Number of the temporary registers as returned by
-                   reg_of_var.
-*/     
-
-#define store_reg_to_var_int(sptr, tempregnum) \
-    if ((sptr)->flags & INMEMORY) { \
-        COUNT_SPILLS; \
-        M_IST(tempregnum, REG_SP, (sptr)->regoff * 4); \
-    }
-
-
-#define store_reg_to_var_lng(sptr, tempregnum) \
-    if ((sptr)->flags & INMEMORY) { \
-        COUNT_SPILLS; \
-        M_LST(tempregnum, REG_SP, (sptr)->regoff * 4); \
-    }
-
-
-#define store_reg_to_var_flt(sptr, tempregnum) \
-    if ((sptr)->type == TYPE_FLT) { \
-        if ((sptr)->flags & INMEMORY) { \
-             COUNT_SPILLS; \
-             i386_fstps_membase(cd, REG_SP, (sptr)->regoff * 4); \
-             fpu_st_offset--; \
-        } else { \
-/*                  i386_fxch_reg((sptr)->regoff);*/ \
-             i386_fstp_reg(cd, (sptr)->regoff + fpu_st_offset); \
-             fpu_st_offset--; \
-        } \
-    } else { \
-        if ((sptr)->flags & INMEMORY) { \
-            COUNT_SPILLS; \
-            i386_fstpl_membase(cd, REG_SP, (sptr)->regoff * 4); \
-            fpu_st_offset--; \
-        } else { \
-/*                  i386_fxch_reg((sptr)->regoff);*/ \
-            i386_fstp_reg(cd, (sptr)->regoff + fpu_st_offset); \
-            fpu_st_offset--; \
-        } \
-    }
-
-
-#define M_COPY(from,to) \
-    d = reg_of_var(rd, to, REG_ITMP1); \
-       if ((from->regoff != to->regoff) || \
-           ((from->flags ^ to->flags) & INMEMORY)) { \
-               if (IS_FLT_DBL_TYPE(from->type)) { \
-                       var_to_reg_flt(s1, from, d); \
-                       /*M_FLTMOVE(s1, d);*/ \
-                       store_reg_to_var_flt(to, d); \
-               } else { \
-            if (!IS_2_WORD_TYPE(from->type)) { \
-                if (to->flags & INMEMORY) { \
-                     if (from->flags & INMEMORY) { \
-                         i386_mov_membase_reg(cd, REG_SP, from->regoff * 4, REG_ITMP1); \
-                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, to->regoff * 4); \
-                     } else { \
-                         i386_mov_reg_membase(cd, from->regoff, REG_SP, to->regoff * 4); \
-                     } \
-                } else { \
-                     if (from->flags & INMEMORY) { \
-                         i386_mov_membase_reg(cd, REG_SP, from->regoff * 4, to->regoff); \
-                     } else { \
-                         i386_mov_reg_reg(cd, from->regoff, to->regoff); \
-                     } \
-                } \
-            } else { \
-                M_LNGMEMMOVE(from->regoff, to->regoff); \
-            } \
-               } \
-       }
-
-/* macros to create code ******************************************************/
-
-typedef enum {
-    REG_AL = 0,
-    REG_CL = 1,
-    REG_DL = 2,
-    REG_BL = 3,
-    REG_AH = 4,
-    REG_CH = 5,
-    REG_DH = 6,
-    REG_BH = 7,
-    REG_NREGB
-} I386_RegB_No;
-
-
-/* opcodes for alu instructions */
-
-typedef enum {
-    ALU_ADD = 0,
-    ALU_OR  = 1,
-    ALU_ADC = 2,
-    ALU_SBB = 3,
-    ALU_AND = 4,
-    ALU_SUB = 5,
-    ALU_XOR = 6,
-    ALU_CMP = 7,
-    ALU_NALU
-} I386_ALU_Opcode;
-
-typedef enum {
-    I386_ROL = 0,
-    I386_ROR = 1,
-    I386_RCL = 2,
-    I386_RCR = 3,
-    I386_SHL = 4,
-    I386_SHR = 5,
-    I386_SAR = 7,
-    I386_NSHIFT = 8
-} I386_Shift_Opcode;
-
-typedef enum {
-    I386_CC_O = 0,
-    I386_CC_NO = 1,
-    I386_CC_B = 2, I386_CC_C = 2, I386_CC_NAE = 2,
-    I386_CC_BE = 6, I386_CC_NA = 6,
-    I386_CC_AE = 3, I386_CC_NB = 3, I386_CC_NC = 3,
-    I386_CC_E = 4, I386_CC_Z = 4,
-    I386_CC_NE = 5, I386_CC_NZ = 5,
-    I386_CC_A = 7, I386_CC_NBE = 7,
-    I386_CC_S = 8, I386_CC_LZ = 8,
-    I386_CC_NS = 9, I386_CC_GEZ = 9,
-    I386_CC_P = 0x0a, I386_CC_PE = 0x0a,
-    I386_CC_NP = 0x0b, I386_CC_PO = 0x0b,
-    I386_CC_L = 0x0c, I386_CC_NGE = 0x0c,
-    I386_CC_GE = 0x0d, I386_CC_NL = 0x0d,
-    I386_CC_LE = 0x0e, I386_CC_NG = 0x0e,
-    I386_CC_G = 0x0f, I386_CC_NLE = 0x0f,
-    I386_NCC
-} I386_CC;
-
-
-/* modrm and stuff */
-
-#define i386_address_byte(mod,reg,rm) \
-    *(cd->mcodeptr++) = ((((mod) & 0x03) << 6) | (((reg) & 0x07) << 3) | (((rm) & 0x07)));
-
-
-#define i386_emit_reg(reg,rm) \
-    i386_address_byte(3,(reg),(rm));
-
-
-#define i386_is_imm8(imm) \
-    (((int)(imm) >= -128 && (int)(imm) <= 127))
-
-
-#define i386_emit_imm8(imm) \
-    *(cd->mcodeptr++) = (u1) ((imm) & 0xff);
-
-
-#define i386_emit_imm16(imm) \
-    do { \
-        imm_union imb; \
-        imb.i = (int) (imm); \
-        *(cd->mcodeptr++) = imb.b[0]; \
-        *(cd->mcodeptr++) = imb.b[1]; \
-    } while (0)
+/* branch defines *************************************************************/
 
+#define BRANCH_UNCONDITIONAL_SIZE    5  /* size in bytes of a branch          */
+#define BRANCH_CONDITIONAL_SIZE      6  /* size in bytes of a branch          */
 
-#define i386_emit_imm32(imm) \
+#define BRANCH_NOPS \
     do { \
-        imm_union imb; \
-        imb.i = (int) (imm); \
-        *(cd->mcodeptr++) = imb.b[0]; \
-        *(cd->mcodeptr++) = imb.b[1]; \
-        *(cd->mcodeptr++) = imb.b[2]; \
-        *(cd->mcodeptr++) = imb.b[3]; \
+        M_NOP; \
+        M_NOP; \
+        M_NOP; \
+        M_NOP; \
+        M_NOP; \
+        M_NOP; \
     } while (0)
 
 
-#define i386_emit_mem(r,mem) \
-    do { \
-        i386_address_byte(0,(r),5); \
-        i386_emit_imm32((mem)); \
-    } while (0)
+/* patcher defines ************************************************************/
 
+#define PATCHER_CALL_SIZE    5          /* size in bytes of a patcher call    */
 
-#define i386_emit_membase(basereg,disp,dreg) \
+#define PATCHER_NOPS \
     do { \
-        if ((basereg) == ESP) { \
-            if ((disp) == 0) { \
-                i386_address_byte(0, (dreg), ESP); \
-                i386_address_byte(0, ESP, ESP); \
-            } else if (i386_is_imm8((disp))) { \
-                i386_address_byte(1, (dreg), ESP); \
-                i386_address_byte(0, ESP, ESP); \
-                i386_emit_imm8((disp)); \
-            } else { \
-                i386_address_byte(2, (dreg), ESP); \
-                i386_address_byte(0, ESP, ESP); \
-                i386_emit_imm32((disp)); \
-            } \
-            break; \
-        } \
-        \
-        if ((disp) == 0 && (basereg) != EBP) { \
-            i386_address_byte(0, (dreg), (basereg)); \
-            break; \
-        } \
-        \
-        if (i386_is_imm8((disp))) { \
-            i386_address_byte(1, (dreg), (basereg)); \
-            i386_emit_imm8((disp)); \
-        } else { \
-            i386_address_byte(2, (dreg), (basereg)); \
-            i386_emit_imm32((disp)); \
-        } \
+        M_NOP; \
+        M_NOP; \
+        M_NOP; \
+        M_NOP; \
+        M_NOP; \
     } while (0)
 
 
-#define i386_emit_membase32(basereg,disp,dreg) \
-    do { \
-        if ((basereg) == ESP) { \
-            i386_address_byte(2, (dreg), ESP); \
-            i386_address_byte(0, ESP, ESP); \
-            i386_emit_imm32((disp)); \
-        } else { \
-            i386_address_byte(2, (dreg), (basereg)); \
-            i386_emit_imm32((disp)); \
-        } \
-    } while (0)
-
+/* stub defines ***************************************************************/
 
-#define i386_emit_memindex(reg,disp,basereg,indexreg,scale) \
-    do { \
-        if ((basereg) == -1) { \
-            i386_address_byte(0, (reg), 4); \
-            i386_address_byte((scale), (indexreg), 5); \
-            i386_emit_imm32((disp)); \
-        \
-        } else if ((disp) == 0 && (basereg) != EBP) { \
-            i386_address_byte(0, (reg), 4); \
-            i386_address_byte((scale), (indexreg), (basereg)); \
-        \
-        } else if (i386_is_imm8((disp))) { \
-            i386_address_byte(1, (reg), 4); \
-            i386_address_byte((scale), (indexreg), (basereg)); \
-            i386_emit_imm8 ((disp)); \
-        \
-        } else { \
-            i386_address_byte(2, (reg), 4); \
-            i386_address_byte((scale), (indexreg), (basereg)); \
-            i386_emit_imm32((disp)); \
-        }    \
-     } while (0)
+#define COMPILERSTUB_CODESIZE    12
 
 
 /* macros to create code ******************************************************/
 
-#define M_ILD(a,b,disp)         i386_mov_membase_reg(cd, (b), (disp), (a))
+#define M_ILD(a,b,disp)         emit_mov_membase_reg(cd, (b), (disp), (a))
+#define M_ILD32(a,b,disp)       emit_mov_membase32_reg(cd, (b), (disp), (a))
+
 #define M_ALD(a,b,disp)         M_ILD(a,b,disp)
+#define M_ALD32(a,b,disp)       M_ILD32(a,b,disp)
 
-#define M_ILD32(a,b,disp)       i386_mov_membase32_reg(cd, (b), (disp), (a))
+#define M_ALD_MEM(a,disp)       emit_mov_mem_reg(cd, (disp), (a))
+
+#define M_ALD_MEM_GET_OPC(p)    (*(p))
+#define M_ALD_MEM_GET_MOD(p)    (((*(p + 1)) >> 6) & 0x03)
+#define M_ALD_MEM_GET_REG(p)    (((*(p + 1)) >> 3) & 0x07)
+#define M_ALD_MEM_GET_RM(p)     (((*(p + 1))     ) & 0x07)
+#define M_ALD_MEM_GET_DISP(p)   (*((u4 *) (p + 2)))
 
 #define M_LLD(a,b,disp) \
     do { \
@@ -497,13 +193,13 @@ typedef enum {
         M_ILD32(GET_HIGH_REG(a),b,disp + 4); \
     } while (0)
 
-#define M_IST(a,b,disp)         i386_mov_reg_membase(cd, (a), (b), (disp))
-#define M_IST_IMM(a,b,disp)     i386_mov_imm_membase(cd, (u4) (a), (b), (disp))
+#define M_IST(a,b,disp)         emit_mov_reg_membase(cd, (a), (b), (disp))
+#define M_IST_IMM(a,b,disp)     emit_mov_imm_membase(cd, (u4) (a), (b), (disp))
 #define M_AST(a,b,disp)         M_IST(a,b,disp)
 #define M_AST_IMM(a,b,disp)     M_IST_IMM(a,b,disp)
 
-#define M_IST32(a,b,disp)       i386_mov_reg_membase32(cd, (a), (b), (disp))
-#define M_IST32_IMM(a,b,disp)   i386_mov_imm_membase32(cd, (u4) (a), (b), (disp))
+#define M_IST32(a,b,disp)       emit_mov_reg_membase32(cd, (a), (b), (disp))
+#define M_IST32_IMM(a,b,disp)   emit_mov_imm_membase32(cd, (u4) (a), (b), (disp))
 
 #define M_LST(a,b,disp) \
     do { \
@@ -529,67 +225,122 @@ typedef enum {
         M_IST32_IMM(a >> 32,b,disp + 4); \
     } while (0)
 
-#define M_IADD_IMM(a,b)         i386_alu_imm_reg(cd, ALU_ADD, (a), (b))
-#define M_IADD_IMM32(a,b)       i386_alu_imm32_reg(cd, ALU_ADD, (a), (b))
-#define M_ISUB_IMM(a,b)         i386_alu_imm_reg(cd, ALU_SUB, (a), (b))
+#define M_IADD(a,b)             emit_alu_reg_reg(cd, ALU_ADD, (a), (b))
+#define M_ISUB(a,b)             emit_alu_reg_reg(cd, ALU_SUB, (a), (b))
+#define M_IMUL(a,b)             emit_imul_reg_reg(cd, (a), (b))
+#define M_IDIV(a)               emit_idiv_reg(cd, (a))
+
+#define M_MUL(a)                emit_mul_reg(cd, (a))
+
+#define M_IADD_IMM(a,b)         emit_alu_imm_reg(cd, ALU_ADD, (a), (b))
+#define M_ISUB_IMM(a,b)         emit_alu_imm_reg(cd, ALU_SUB, (a), (b))
+#define M_IMUL_IMM(a,b,c)       emit_imul_imm_reg_reg(cd, (b), (a), (c))
+
+#define M_IADD_IMM32(a,b)       emit_alu_imm32_reg(cd, ALU_ADD, (a), (b))
+#define M_ISUB_IMM32(a,b)       emit_alu_imm32_reg(cd, ALU_SUB, (a), (b))
+
+#define M_IADD_IMM_MEMBASE(a,b,c) emit_alu_imm_membase(cd, ALU_ADD, (a), (b), (c))
+
+#define M_ISUB_IMM_MEMABS(a,b)  emit_alu_imm_memabs(cd, ALU_SUB, (a), (b))
+
+#define M_IADDC(a,b)            emit_alu_reg_reg(cd, ALU_ADC, (a), (b))
+#define M_ISUBB(a,b)            emit_alu_reg_reg(cd, ALU_SBB, (a), (b))
 
-#define M_IADD_IMM_MEMBASE(a,b,c) i386_alu_imm_membase(cd, ALU_ADD, (a), (b), (c))
+#define M_IADDC_IMM(a,b)        emit_alu_imm_reg(cd, ALU_ADC, (a), (b))
+#define M_ISUBB_IMM(a,b)        emit_alu_imm_reg(cd, ALU_SBB, (a), (b))
 
 #define M_AADD_IMM(a,b)         M_IADD_IMM(a,b)
 #define M_AADD_IMM32(a,b)       M_IADD_IMM32(a,b)
 #define M_ASUB_IMM(a,b)         M_ISUB_IMM(a,b)
 
-#define M_OR_MEMBASE(a,b,c)     i386_alu_membase_reg(cd, ALU_OR, (a), (b), (c))
-#define M_XOR(a,b)              i386_alu_reg_reg(cd, ALU_XOR, (a), (b))
+#define M_NEG(a)                emit_neg_reg(cd, (a))
+
+#define M_AND(a,b)              emit_alu_reg_reg(cd, ALU_AND, (a), (b))
+#define M_OR(a,b)               emit_alu_reg_reg(cd, ALU_OR, (a), (b))
+#define M_XOR(a,b)              emit_alu_reg_reg(cd, ALU_XOR, (a), (b))
+
+#define M_AND_IMM(a,b)          emit_alu_imm_reg(cd, ALU_AND, (a), (b))
+#define M_OR_IMM(a,b)           emit_alu_imm_reg(cd, ALU_OR, (a), (b))
+#define M_XOR_IMM(a,b)          emit_alu_imm_reg(cd, ALU_XOR, (a), (b))
+
+#define M_AND_IMM32(a,b)        emit_alu_imm32_reg(cd, ALU_AND, (a), (b))
+
 #define M_CLR(a)                M_XOR(a,a)
 
-#define M_PUSH(a)               i386_push_reg(cd, (a))
-#define M_PUSH_IMM(a)           i386_push_imm(cd, (s4) (a))
-#define M_POP(a)                i386_pop_reg(cd, (a))
+#define M_PUSH(a)               emit_push_reg(cd, (a))
+#define M_PUSH_IMM(a)           emit_push_imm(cd, (s4) (a))
+#define M_POP(a)                emit_pop_reg(cd, (a))
+
+#define M_MOV(a,b)              emit_mov_reg_reg(cd, (a), (b))
+#define M_MOV_IMM(a,b)          emit_mov_imm_reg(cd, (u4) (a), (b))
+
+#define M_TEST(a)               emit_test_reg_reg(cd, (a), (a))
+#define M_TEST_IMM(a,b)         emit_test_imm_reg(cd, (a), (b))
+
+#define M_CMP(a,b)              emit_alu_reg_reg(cd, ALU_CMP, (a), (b))
+#define M_CMP_MEMBASE(a,b,c)    emit_alu_membase_reg(cd, ALU_CMP, (a), (b), (c))
+
+#define M_CMP_IMM(a,b)          emit_alu_imm_reg(cd, ALU_CMP, (a), (b))
+#define M_CMP_IMM_MEMBASE(a,b,c) emit_alu_imm_membase(cd, ALU_CMP, (a), (b), (c))
+
+#define M_CMP_IMM32(a,b)        emit_alu_imm32_reg(cd, ALU_CMP, (a), (b))
+
+#define M_BSEXT(a,b)            /* XXX does not work, because of nibbles */
+#define M_SSEXT(a,b)            emit_movswl_reg_reg(cd, (a), (b))
 
-#define M_MOV(a,b)              i386_mov_reg_reg(cd, (a), (b))
-#define M_MOV_IMM(a,b)          i386_mov_imm_reg(cd, (u4) (a), (b))
+#define M_CZEXT(a,b)            emit_movzwl_reg_reg(cd, (a), (b))
 
-#define M_TEST(a)               i386_test_reg_reg(cd, (a), (a))
+#define M_CLTD                  emit_cltd(cd)
 
-#define M_CMP(a,b)              i386_alu_reg_reg(cd, ALU_CMP, (a), (b))
-#define M_CMP_MEMBASE(a,b,c)    i386_alu_membase_reg(cd, ALU_CMP, (a), (b), (c))
+#define M_SLL(a)                emit_shift_reg(cd, SHIFT_SHL, (a))
+#define M_SRA(a)                emit_shift_reg(cd, SHIFT_SAR, (a))
+#define M_SRL(a)                emit_shift_reg(cd, SHIFT_SHR, (a))
 
-#define M_CMP_IMM_MEMBASE(a,b,c) i386_alu_imm_membase(cd, ALU_CMP, (a), (b), (c))
+#define M_SLL_IMM(a,b)          emit_shift_imm_reg(cd, SHIFT_SHL, (a), (b))
+#define M_SRA_IMM(a,b)          emit_shift_imm_reg(cd, SHIFT_SAR, (a), (b))
+#define M_SRL_IMM(a,b)          emit_shift_imm_reg(cd, SHIFT_SHR, (a), (b))
 
-#define M_CALL(a)               i386_call_reg(cd, (a))
-#define M_CALL_IMM(a)           i386_call_imm(cd, (a))
-#define M_RET                   i386_ret(cd)
+#define M_SLLD(a,b)             emit_shld_reg_reg(cd, (a), (b))
+#define M_SRLD(a,b)             emit_shrd_reg_reg(cd, (a), (b))
 
-#define M_BEQ(a)                i386_jcc(cd, I386_CC_E, (a))
-#define M_BNE(a)                i386_jcc(cd, I386_CC_NE, (a))
-#define M_BLT(a)                i386_jcc(cd, I386_CC_L, (a))
-#define M_BLE(a)                i386_jcc(cd, I386_CC_LE, (a))
-#define M_BGE(a)                i386_jcc(cd, I386_CC_GE, (a))
-#define M_BGT(a)                i386_jcc(cd, I386_CC_G, (a))
+#define M_SLLD_IMM(a,b,c)       emit_shld_imm_reg_reg(cd, (a), (b), (c))
+#define M_SRLD_IMM(a,b,c)       emit_shrd_imm_reg_reg(cd, (a), (b), (c))
 
-#define M_BBE(a)                i386_jcc(cd, I386_CC_BE, (a))
-#define M_BAE(a)                i386_jcc(cd, I386_CC_AE, (a))
+#define M_CALL(a)               emit_call_reg(cd, (a))
+#define M_CALL_IMM(a)           emit_call_imm(cd, (a))
+#define M_RET                   emit_ret(cd)
 
-#define M_JMP(a)                i386_jmp_reg(cd, (a))
-#define M_JMP_IMM(a)            i386_jmp_imm(cd, (a))
+#define M_BEQ(a)                emit_jcc(cd, CC_E, (a))
+#define M_BNE(a)                emit_jcc(cd, CC_NE, (a))
+#define M_BLT(a)                emit_jcc(cd, CC_L, (a))
+#define M_BLE(a)                emit_jcc(cd, CC_LE, (a))
+#define M_BGE(a)                emit_jcc(cd, CC_GE, (a))
+#define M_BGT(a)                emit_jcc(cd, CC_G, (a))
 
-#define M_NOP                   i386_nop(cd)
+#define M_BB(a)                 emit_jcc(cd, CC_B, (a))
+#define M_BBE(a)                emit_jcc(cd, CC_BE, (a))
+#define M_BAE(a)                emit_jcc(cd, CC_AE, (a))
+#define M_BA(a)                 emit_jcc(cd, CC_A, (a))
+#define M_BNS(a)                emit_jcc(cd, CC_NS, (a))
+#define M_BS(a)                 emit_jcc(cd, CC_S, (a))
 
+#define M_JMP(a)                emit_jmp_reg(cd, (a))
+#define M_JMP_IMM(a)            emit_jmp_imm(cd, (a))
 
-/* function gen_resolvebranch **************************************************
+#define M_NOP                   emit_nop(cd)
 
-    backpatches a branch instruction
 
-    parameters: ip ... pointer to instruction after branch (void*)
-                so ... offset of instruction after branch  (s4)
-                to ... offset of branch target             (s4)
+#define M_FLD(a,b,disp)         emit_flds_membase(cd, (b), (disp))
+#define M_DLD(a,b,disp)         emit_fldl_membase(cd, (b), (disp))
 
-*******************************************************************************/
+#define M_FLD32(a,b,disp)       emit_flds_membase32(cd, (b), (disp))
+#define M_DLD32(a,b,disp)       emit_fldl_membase32(cd, (b), (disp))
 
-#define gen_resolvebranch(ip,so,to) \
-    *((void **) ((ip) - 4)) = (void **) ((to) - (so));
+#define M_FST(a,b,disp)         emit_fstps_membase(cd, (b), (disp))
+#define M_DST(a,b,disp)         emit_fstpl_membase(cd, (b), (disp))
 
+#define M_FSTNP(a,b,disp)       emit_fsts_membase(cd, (b), (disp))
+#define M_DSTNP(a,b,disp)       emit_fstl_membase(cd, (b), (disp))
 
 #endif /* _CODEGEN_H */