]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Try to get x86 instruction representation to something sane, and fix
authorJulian Seward <jseward@acm.org>
Wed, 30 Jun 2004 16:37:16 +0000 (16:37 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 30 Jun 2004 16:37:16 +0000 (16:37 +0000)
up the selector accordingly.

git-svn-id: svn://svn.valgrind.org/vex/trunk@27

VEX/include/ir_defs.h
VEX/include/x86h_defs.h
VEX/isel_x86.c
VEX/x86h_defs.c

index e666146e201379b3e6320793192677f0b1ef083f..ae3082cd418393e15a6b2e2d8514b15807b1c960 100644 (file)
@@ -116,7 +116,7 @@ typedef
             struct _IRExpr* addr;
          } LDle;
          struct {
-            struct _IRConst* con;
+            IRConst* con;
          } Const;
       } Iex;
    }
@@ -187,19 +187,19 @@ typedef
    IRNextTag;
 
 typedef
-   struct _IRNext {
+   struct {
       IRNextTag tag;
       union {
          struct {
-            struct _IRConst* dst;
+            IRConst* dst;
          } UJump;
          struct {
-            struct _IRExpr*  cond;
-            struct _IRConst* dst0;
-            struct _IRConst* dst1;
+            IRExpr*  cond;
+            IRConst* dst0;
+            IRConst* dst1;
          } CJump01;
          struct {
-            struct _IRExpr* dst;
+            IRExpr* dst;
          } IJump;
       } Inx;
    }
index 30c118571949ced305763cc0676b4e06c4ae1ba8..e60a9e38a409ecfa1d61adfaac218ca6f75eba7c 100644 (file)
@@ -23,8 +23,8 @@ extern void ppHRegX86 ( FILE*, HReg );
 
 typedef
    enum {
-     Xam_IR,
-     Xam_IRRS
+     Xam_IR,        /* Immediate + Reg */
+     Xam_IRRS       /* Immediate + Reg1 + (Reg2 << Shift) */
    }
    X86AModeTag;
 
@@ -52,19 +52,19 @@ extern X86AMode* X86AMode_IRRS ( UInt, HReg, HReg, Int );
 extern void ppX86AMode ( FILE*, X86AMode* );
 
 
-/* --------- Operands.  Not all are valid for all insns. --------- */
+/* --------- Operand, which can be reg, immediate or memory. --------- */
 
 typedef 
    enum {
-      Xop_Imm,
-      Xop_Reg,
-      Xop_Mem
+      Xrmi_Imm,
+      Xrmi_Reg,
+      Xrmi_Mem
    }
-   X86OperandTag;
+   X86RMITag;
 
 typedef
    struct {
-      X86OperandTag tag;
+      X86RMITag tag;
       union {
          struct {
             UInt imm32;
@@ -76,33 +76,109 @@ typedef
             X86AMode* am;
          } Mem;
       }
-      Xop;
+      Xrmi;
    }
-   X86Operand;
+   X86RMI;
 
-extern X86Operand* X86Operand_Imm ( UInt );
-extern X86Operand* X86Operand_Reg ( HReg );
-extern X86Operand* X86Operand_Mem ( X86AMode* );
+extern X86RMI* X86RMI_Imm ( UInt );
+extern X86RMI* X86RMI_Reg ( HReg );
+extern X86RMI* X86RMI_Mem ( X86AMode* );
 
-extern void ppX86Operand ( FILE*, X86Operand* );
+extern void ppX86RMI ( FILE*, X86RMI* );
+
+
+/* --------- Operand, which can be reg or immediate only. --------- */
+
+typedef 
+   enum {
+      Xri_Imm,
+      Xri_Reg
+   }
+   X86RITag;
+
+typedef
+   struct {
+      X86RITag tag;
+      union {
+         struct {
+            UInt imm32;
+         } Imm;
+         struct {
+            HReg reg;
+         } Reg;
+      }
+      Xri;
+   }
+   X86RI;
+
+extern X86RI* X86RI_Imm ( UInt );
+extern X86RI* X86RI_Reg ( HReg );
+
+extern void ppX86RI ( FILE*, X86RI* );
+
+
+/* --------- Operand, which can be reg or memory only. --------- */
+
+typedef 
+   enum {
+      Xrm_Reg,
+      Xrm_Mem
+   }
+   X86RMTag;
+
+typedef
+   struct {
+      X86RMTag tag;
+      union {
+         struct {
+            HReg reg;
+         } Reg;
+         struct {
+            X86AMode* am;
+         } Mem;
+      }
+      Xrm;
+   }
+   X86RM;
+
+extern X86RM* X86RM_Reg ( HReg );
+extern X86RM* X86RM_Mem ( X86AMode* );
+
+extern void ppX86RM ( FILE*, X86RM* );
 
 
 /* --------- Instructions. --------- */
 
+/* --------- */
 typedef 
-   enum { Xalu_ADD, Xalu_SUB, Xalu_ADC, Xalu_SBB, Xalu_AND, Xalu_OR, Xalu_XOR }
+   enum { 
+      Xalu_MOV,
+      Xalu_ADD, Xalu_SUB, Xalu_ADC, Xalu_SBB, 
+      Xalu_AND, Xalu_OR, Xalu_XOR 
+   }
    X86AluOp;
 
 extern void ppX86AluOp ( FILE*, X86AluOp );
 
 
+/* --------- */
+typedef
+   enum {
+      Xsh_SHL, Xsh_SHR, Xsh_SAR, 
+      Xsh_ROL, Xsh_ROR
+   }
+   X86ShiftOp;
+
+extern void ppX86ShiftOp ( FILE*, X86ShiftOp );
+
+
+/* --------- */
 typedef
    enum {
-      Xin_LD32,     /* 32-bit integer load */
-      Xin_ST32,     /* 32-bit integer store */
-      Xin_Alu32,    /* 32-bit arith/logical, R-R, R-M, M-R */
-      Xin_Mov32,    /* 32-bit move R-R R-M M-R I-R I-M */
-      Xin_Alu16     /* 16-bit arith/logical, R-R, R-M, M-R */
+      Xin_Alu32R,    /* 32-bit mov/arith/logical, dst=REG */
+      Xin_Alu32M,    /* 32-bit mov/arith/logical, dst=MEM */
+      Xin_Sh32,      /* 32-bit shift/rotate, dst=REG or MEM */
+      Xin_RET
    }
    X86InstrTag;
 
@@ -112,37 +188,31 @@ typedef
    struct {
       X86InstrTag tag;
       union {
-        struct {
-           HReg src;
-           X86AMode* dst;
-        } ST32;
-        struct {
-           X86AMode* src;
-           HReg dst;
-        } LD32;
          struct {
-            X86AluOp    op;
-            X86Operand* src;
-            X86Operand* dst;
-         } Alu32;
+            X86AluOp op;
+            X86RMI*  src;
+            HReg     dst;
+         } Alu32R;
          struct {
-            X86Operand* src;
-            X86Operand* dst;
-         } Mov32;
+            X86AluOp  op;
+            X86RI*    src;
+            X86AMode* dst;
+         } Alu32M;
          struct {
-            X86AluOp    op;
-            X86Operand* src;
-            X86Operand* dst;
-         } Alu16;
+            X86ShiftOp op;
+            UInt       src;  /* shift amount, or 0 means %cl */
+            X86RM*     dst;
+         } Sh32;
+        struct {
+        } RET;
       } Xin;
    }
    X86Instr;
 
-extern X86Instr* X86Instr_ST32  ( HReg, X86AMode* );
-extern X86Instr* X86Instr_LD32  ( X86AMode*, HReg );
-extern X86Instr* X86Instr_Alu32 ( X86AluOp, X86Operand*, X86Operand* );
-extern X86Instr* X86Instr_Mov32 ( X86Operand*, X86Operand* );
-extern X86Instr* X86Instr_Alu16 ( X86AluOp, X86Operand*, X86Operand* );
+extern X86Instr* X86Instr_Alu32R ( X86AluOp, X86RMI*, HReg );
+extern X86Instr* X86Instr_Alu32M ( X86AluOp, X86RI*,  X86AMode* );
+extern X86Instr* X86Instr_Sh32   ( X86ShiftOp, UInt, X86RM* );
+extern X86Instr* X86Instr_RET    ( void );
 
 extern void ppX86Instr ( FILE*, X86Instr* );
 
index 93ae6a33b6c998ad53cad6a7b4645e59756f43f3..340301e92a3b56d458c40ce97c0c99c5ae79f464 100644 (file)
@@ -90,6 +90,18 @@ static HReg newVRegI ( ISelEnv* env )
 /*--- ISEL: Integer expressions                         ---*/
 /*---------------------------------------------------------*/
 
+/* forwards ... */
+static X86RMI* iselIntExpr_RMI ( ISelEnv* env, IRExpr* e );
+
+
+static X86Instr* mk_MOV_RR ( HReg src, HReg dst )
+{
+   assert(hregClass(src) == HRcInt);
+   assert(hregClass(dst) == HRcInt);
+   return X86Instr_Alu32R(Xalu_MOV, X86RMI_Reg(src), dst);
+}
+
+
 /* Select insns for an integer-typed expression, and add them to the
    code list.  Return a vreg holding the result.  The vreg MUST NOT BE
    MODIFIED.  If you want to modify it, ask for a new vreg, copy it in
@@ -97,7 +109,7 @@ static HReg newVRegI ( ISelEnv* env )
    best to map both vregs to the same real register, so the copies
    will often disappear later in the game.
 */
-HReg iselExprI ( ISelEnv* env, IRExpr* e )
+static HReg iselIntExpr_R ( ISelEnv* env, IRExpr* e )
 {
    assert(e);
    assert(typeOfIRExpr(env->type_env,e) == Ity_I32);
@@ -108,20 +120,18 @@ HReg iselExprI ( ISelEnv* env, IRExpr* e )
    return lookupIRTemp(env, e->Iex.Tmp.tmp);
 
    case Iex_Binop:
-      /* Add32(x,y) */
+      /* Add32(x,y).  For commutative ops we assume any literal
+         values are on the second operand. */
       if (e->Iex.Binop.op == Iop_Add32) {
-         HReg res = newVRegI(env);
-         HReg src = iselExprI(env, e->Iex.Binop.arg1);
-         HReg dst = iselExprI(env, e->Iex.Binop.arg2);
-         addInstr(env, X86Instr_Mov32(
-                          X86Operand_Reg(dst),
-                          X86Operand_Reg(res)));
-         addInstr(env, X86Instr_Alu32(
-                          Xalu_ADD, X86Operand_Reg(src),
-                                    X86Operand_Reg(res)) );
-         return res;
+         HReg dst    = newVRegI(env);
+         HReg reg    = iselIntExpr_R(env, e->Iex.Binop.arg1);
+         X86RMI* rmi = iselIntExpr_RMI(env, e->Iex.Binop.arg2);
+         addInstr(env, mk_MOV_RR(reg,dst));
+         addInstr(env, X86Instr_Alu32R(Xalu_ADD, rmi, dst));
+         return dst;
       }
 
+#if 0
    /* 32-bit literals */
    case Iex_Const: {
       switch (e->Iex.Const.con->tag) {
@@ -135,6 +145,7 @@ HReg iselExprI ( ISelEnv* env, IRExpr* e )
          default: break;
       }
    }
+#endif
 
    default: 
    break;
@@ -146,11 +157,15 @@ HReg iselExprI ( ISelEnv* env, IRExpr* e )
 }
 
 
-/* Similarly, return an AMode which computes the value of the
-   specified expression, possibly also adding insns to the code list
-   as a result.  
+/*---------------------------------------------------------*/
+/*--- ISEL: Integer expression auxiliaries              ---*/
+/*---------------------------------------------------------*/
+
+/* Return an AMode which computes the value of the specified
+   expression, possibly also adding insns to the code list as a
+   result.  
 */
-X86AMode* iselAMode ( ISelEnv* env, IRExpr* e )
+static X86AMode* iselIntExpr_AMode ( ISelEnv* env, IRExpr* e )
 {
    assert(e);
    assert(typeOfIRExpr(env->type_env,e) == Ity_I32);
@@ -164,8 +179,8 @@ X86AMode* iselAMode ( ISelEnv* env, IRExpr* e )
        && e->Iex.Binop.arg2->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U32) {
       UInt shift = e->Iex.Binop.arg2->Iex.Binop.arg2->Iex.Const.con->Ico.U32;
       if (shift == 2 || shift == 4 || shift == 8) {
-         HReg r1 = iselExprI(env, e->Iex.Binop.arg1);
-         HReg r2 = iselExprI(env, e->Iex.Binop.arg2->Iex.Binop.arg1 );
+         HReg r1 = iselIntExpr_R(env, e->Iex.Binop.arg1);
+         HReg r2 = iselIntExpr_R(env, e->Iex.Binop.arg2->Iex.Binop.arg1 );
          return X86AMode_IRRS(0, r1, r2, shift);
       }
    }
@@ -175,36 +190,87 @@ X86AMode* iselAMode ( ISelEnv* env, IRExpr* e )
        && e->Iex.Binop.op == Iop_Add32
        && e->Iex.Binop.arg2->tag == Iex_Const
        && e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U32) {
-      HReg r1 = iselExprI(env,  e->Iex.Binop.arg1);
+      HReg r1 = iselIntExpr_R(env,  e->Iex.Binop.arg1);
       return X86AMode_IR(r1, e->Iex.Binop.arg2->Iex.Const.con->Ico.U32);
    }
 
    /* Doesn't match anything in particular.  Generate it into
       a register and use that. */
    {
-      HReg r1 = iselExprI(env, e);
+      HReg r1 = iselIntExpr_R(env, e);
       return X86AMode_IR(r1, 0);
    }
 }
 
 
+/* Similarly, calculate an expression into an X86RMI operand. */
+
+static X86RMI* iselIntExpr_RMI ( ISelEnv* env, IRExpr* e )
+{
+   assert(e);
+   assert(typeOfIRExpr(env->type_env,e) == Ity_I32);
+
+   /* special case: immediate */
+   if (e->tag == Iex_Const 
+       && e->Iex.Const.con->tag == Ico_U32) {
+      return X86RMI_Imm(e->Iex.Const.con->Ico.U32);
+   }
+
+   /* special case: load from memory */
+
+   /* default case: calculate into a register and return that */
+   {
+      HReg r = iselIntExpr_R ( env, e );
+      return X86RMI_Reg(r);
+   }
+}
+
+
+/* Calculate an expression into an X86RI operand. */
+
+static X86RI* iselIntExpr_RI ( ISelEnv* env, IRExpr* e )
+{
+   assert(e);
+   assert(typeOfIRExpr(env->type_env,e) == Ity_I32);
+
+   /* special case: immediate */
+   if (e->tag == Iex_Const 
+       && e->Iex.Const.con->tag == Ico_U32) {
+      return X86RI_Imm(e->Iex.Const.con->Ico.U32);
+   }
+
+   /* default case: calculate into a register and return that */
+   {
+      HReg r = iselIntExpr_R ( env, e );
+      return X86RI_Reg(r);
+   }
+}
+
+
 /*---------------------------------------------------------*/
 /*--- ISEL: Statements                                  ---*/
 /*---------------------------------------------------------*/
 
 void iselStmt ( ISelEnv* env, IRStmt* stmt )
 {
+   fprintf(stdout, "-- ");
+   ppIRStmt(stdout, stmt);
+   fprintf(stdout, "\n");
+
    switch (stmt->tag) {
 
    case Ist_Put:
      if (stmt->Ist.Put.size == 4) {
-       HReg ebp = mkHReg(5, HRcInt, False);
-       HReg reg = iselExprI(env, stmt->Ist.Put.expr);
+       /* We're going to write to memory, so compute the
+         RHS into an X86RI. */
+       HReg   ebp = mkHReg(5, HRcInt, False);
+       X86RI* ri  = iselIntExpr_RI(env, stmt->Ist.Put.expr);
        addInstr(env,
-               X86Instr_ST32(reg,
-                             X86AMode_IR(stmt->Ist.Put.offset,
-                                         ebp)
-                             ));
+               X86Instr_Alu32M(
+                   Xalu_MOV,
+                   ri,
+                  X86AMode_IR(stmt->Ist.Put.offset,ebp)
+              ));
        return;
      }
 
@@ -221,8 +287,22 @@ void iselStmt ( ISelEnv* env, IRStmt* stmt )
 
 void iselNext ( ISelEnv* env, IRNext* next )
 {
+   fprintf(stdout, "-- ");
+   ppIRNext(stdout, next);
+   fprintf(stdout, "\n");
+
    switch (next->tag) {
-   default: 
+   case Inx_UJump: {
+      HReg eax = mkHReg(0, HRcInt, False);
+      assert(next->Inx.UJump.dst->tag == Ico_U32);
+      addInstr(env, X86Instr_Alu32R(
+                       Xalu_MOV, 
+                       X86RMI_Imm(next->Inx.UJump.dst->Ico.U32),
+                       eax));
+      addInstr(env, X86Instr_RET());
+      return;
+   }
+   default:
       ppIRNext(stderr, next);
       panic("iselNext");
    }
@@ -267,6 +347,7 @@ void /* not really, but for the time being ... */
       }
       env->vregmap[i].vreg = hreg;
    }
+   env->ctr = 100;  //env->n_vregmap;
 
    /* Ok, finally we can iterate over the statements. */
    for (stmt = bb->stmts; stmt; stmt=stmt->link)
index 0f3549a84a6a55b1c2a985ab11f79d99dbc9d2b9..bad05b88b3ddcb9ae60533935c47786673efd05d 100644 (file)
@@ -87,42 +87,102 @@ void ppX86AMode ( FILE* f, X86AMode* am ) {
 }
 
 
-/* --------- X86Operand.  Not all are valid for all insns. --------- */
+/* --------- Operand, which can be reg, immediate or memory. --------- */
 
-X86Operand* X86Operand_Imm ( UInt imm32 ) {
-   X86Operand* op    = malloc(sizeof(X86Operand));
-   op->tag           = Xop_Imm;
-   op->Xop.Imm.imm32 = imm32;
+X86RMI* X86RMI_Imm ( UInt imm32 ) {
+   X86RMI* op         = malloc(sizeof(X86RMI));
+   op->tag            = Xrmi_Imm;
+   op->Xrmi.Imm.imm32 = imm32;
    return op;
 }
 
-X86Operand* X86Operand_Reg ( HReg reg ) {
-   X86Operand* op  = malloc(sizeof(X86Operand));
-   op->tag         = Xop_Reg;
-   op->Xop.Reg.reg = reg;
+X86RMI* X86RMI_Reg ( HReg reg ) {
+   X86RMI* op       = malloc(sizeof(X86RMI));
+   op->tag          = Xrmi_Reg;
+   op->Xrmi.Reg.reg = reg;
    return op;
 }
 
-X86Operand* X86Operand_Mem ( X86AMode* am ) {
-   X86Operand* op = malloc(sizeof(X86Operand));
-   op->tag        = Xop_Mem;
-   op->Xop.Mem.am = am;
+X86RMI* X86RMI_Mem ( X86AMode* am ) {
+   X86RMI* op      = malloc(sizeof(X86RMI));
+   op->tag         = Xrmi_Mem;
+   op->Xrmi.Mem.am = am;
    return op;
 }
 
-void ppX86Operand ( FILE* f, X86Operand* op ) {
+void ppX86RMI ( FILE* f, X86RMI* op ) {
    switch (op->tag) {
-      case Xop_Imm: 
-         fprintf(f, "$0x%x", op->Xop.Imm.imm32);
+      case Xrmi_Imm: 
+         fprintf(f, "$0x%x", op->Xrmi.Imm.imm32);
          return;
-      case Xop_Reg: 
-         ppHRegX86(f, op->Xop.Reg.reg);
+      case Xrmi_Reg: 
+         ppHRegX86(f, op->Xrmi.Reg.reg);
          return;
-      case Xop_Mem: 
-         ppX86AMode(f, op->Xop.Mem.am);
+      case Xrmi_Mem: 
+         ppX86AMode(f, op->Xrmi.Mem.am);
          return;
      default: 
-         panic("ppX86Operand");
+         panic("ppX86RMI");
+   }
+}
+
+
+/* --------- Operand, which can be reg or immediate only. --------- */
+
+X86RI* X86RI_Imm ( UInt imm32 ) {
+   X86RI* op         = malloc(sizeof(X86RI));
+   op->tag           = Xri_Imm;
+   op->Xri.Imm.imm32 = imm32;
+   return op;
+}
+
+X86RI* X86RI_Reg ( HReg reg ) {
+   X86RI* op       = malloc(sizeof(X86RI));
+   op->tag         = Xri_Reg;
+   op->Xri.Reg.reg = reg;
+   return op;
+}
+
+void ppX86RI ( FILE* f, X86RI* op ) {
+   switch (op->tag) {
+      case Xri_Imm: 
+         fprintf(f, "$0x%x", op->Xri.Imm.imm32);
+         return;
+      case Xri_Reg: 
+         ppHRegX86(f, op->Xri.Reg.reg);
+         return;
+     default: 
+         panic("ppX86RI");
+   }
+}
+
+
+/* --------- Operand, which can be reg or memory only. --------- */
+
+X86RM* X86RM_Reg ( HReg reg ) {
+   X86RM* op       = malloc(sizeof(X86RM));
+   op->tag         = Xrm_Reg;
+   op->Xrm.Reg.reg = reg;
+   return op;
+}
+
+X86RM* X86RM_Mem ( X86AMode* am ) {
+   X86RM* op      = malloc(sizeof(X86RM));
+   op->tag        = Xrm_Mem;
+   op->Xrm.Mem.am = am;
+   return op;
+}
+
+void ppX86RM ( FILE* f, X86RM* op ) {
+   switch (op->tag) {
+      case Xrm_Mem: 
+         ppX86AMode(f, op->Xrm.Mem.am);
+         return;
+      case Xrm_Reg: 
+         ppHRegX86(f, op->Xrm.Reg.reg);
+         return;
+     default: 
+         panic("ppX86RM");
    }
 }
 
@@ -132,6 +192,7 @@ void ppX86Operand ( FILE* f, X86Operand* op ) {
 void ppX86AluOp ( FILE* f, X86AluOp op ) {
    Char* name;
    switch (op) {
+      case Xalu_MOV: name = "mov"; break;
       case Xalu_ADD: name = "add"; break;
       case Xalu_SUB: name = "sub"; break;
       case Xalu_ADC: name = "adc"; break;
@@ -144,81 +205,80 @@ void ppX86AluOp ( FILE* f, X86AluOp op ) {
    fprintf(f, "%s", name);
 }
 
-X86Instr* X86Instr_ST32 ( HReg src, X86AMode* dst ) {
-   X86Instr* i     = malloc(sizeof(X86Instr));
-   i->tag          = Xin_ST32;
-   i->Xin.ST32.src = src;
-   i->Xin.ST32.dst = dst;
-   return i;
+void ppX86ShiftOp ( FILE* f, X86ShiftOp op ) {
+   Char* name;
+   switch (op) {
+      case Xsh_SHL: name = "shl"; break;
+      case Xsh_SHR: name = "shr"; break;
+      case Xsh_SAR: name = "sar"; break;
+      case Xsh_ROL: name = "rol"; break;
+      case Xsh_ROR: name = "ror"; break;
+      default: panic("ppX86ShiftOp");
+   }
+   fprintf(f, "%s", name);
 }
 
-X86Instr* X86Instr_LD32 ( X86AMode* src, HReg dst ) {
-   X86Instr* i     = malloc(sizeof(X86Instr));
-   i->tag          = Xin_LD32;
-   i->Xin.LD32.src = src;
-   i->Xin.LD32.dst = dst;
+X86Instr* X86Instr_Alu32R ( X86AluOp op, X86RMI* src, HReg dst ) {
+   X86Instr* i       = malloc(sizeof(X86Instr));
+   i->tag            = Xin_Alu32R;
+   i->Xin.Alu32R.op  = op;
+   i->Xin.Alu32R.src = src;
+   i->Xin.Alu32R.dst = dst;
    return i;
 }
 
-X86Instr* X86Instr_Alu32 ( X86AluOp op, X86Operand* src, X86Operand* dst ) {
-   X86Instr* i      = malloc(sizeof(X86Instr));
-   i->tag           = Xin_Alu32;
-   i->Xin.Alu32.op  = op;
-   i->Xin.Alu32.src = src;
-   i->Xin.Alu32.dst = dst;
+X86Instr* X86Instr_Alu32M ( X86AluOp op, X86RI* src, X86AMode* dst ) {
+   X86Instr* i       = malloc(sizeof(X86Instr));
+   i->tag            = Xin_Alu32M;
+   i->Xin.Alu32M.op  = op;
+   i->Xin.Alu32M.src = src;
+   i->Xin.Alu32M.dst = dst;
    return i;
 }
 
-X86Instr* X86Instr_Mov32 ( X86Operand* src, X86Operand* dst ) {
-   X86Instr* i      = malloc(sizeof(X86Instr));
-   i->tag           = Xin_Mov32;
-   i->Xin.Mov32.src = src;
-   i->Xin.Mov32.dst = dst;
+X86Instr* X86Instr_Sh32 ( X86ShiftOp op, UInt src, X86RM* dst ) {
+   X86Instr* i     = malloc(sizeof(X86Instr));
+   i->tag          = Xin_Sh32;
+   i->Xin.Sh32.op  = op;
+   i->Xin.Sh32.src = src;
+   i->Xin.Sh32.dst = dst;
    return i;
 }
 
-X86Instr* X86Instr_Alu16 ( X86AluOp op, X86Operand* src, X86Operand* dst ) {
-   X86Instr* i      = malloc(sizeof(X86Instr));
-   i->tag           = Xin_Alu16;
-   i->Xin.Alu16.op  = op;
-   i->Xin.Alu16.src = src;
-   i->Xin.Alu16.dst = dst;
+X86Instr* X86Instr_RET ( void ) {
+   X86Instr* i     = malloc(sizeof(X86Instr));
+   i->tag          = Xin_RET;
    return i;
 }
 
+
 void ppX86Instr ( FILE* f, X86Instr* i ) {
    switch (i->tag) {
-      case Xin_ST32:
-         fprintf(f, "movl ");
-         ppHRegX86(f, i->Xin.ST32.src);
-         fprintf(f, ",");
-         ppX86AMode(f, i->Xin.ST32.dst);
-         return;
-      case Xin_LD32:
-         fprintf(f, "movl ");
-         ppX86AMode(f, i->Xin.LD32.src);
+      case Xin_Alu32R:
+         ppX86AluOp(f, i->Xin.Alu32R.op);
+         fprintf(f, "l ");
+         ppX86RMI(f, i->Xin.Alu32R.src);
          fprintf(f, ",");
-         ppHRegX86(f, i->Xin.LD32.dst);
+         ppHRegX86(f, i->Xin.Alu32R.dst);
          return;
-      case Xin_Alu32:
-         ppX86AluOp(f, i->Xin.Alu32.op);
+      case Xin_Alu32M:
+         ppX86AluOp(f, i->Xin.Alu32M.op);
          fprintf(f, "l ");
-         ppX86Operand(f, i->Xin.Alu32.src);
+         ppX86RI(f, i->Xin.Alu32M.src);
          fprintf(f, ",");
-         ppX86Operand(f, i->Xin.Alu32.dst);
+         ppX86AMode(f, i->Xin.Alu32M.dst);
          return;
-      case Xin_Mov32:
-         fprintf(f, "movl ");
-         ppX86Operand(f, i->Xin.Mov32.src);
-         fprintf(f, ",");
-         ppX86Operand(f, i->Xin.Mov32.dst);
+      case Xin_Sh32:
+         ppX86ShiftOp(f, i->Xin.Sh32.op);
+         fprintf(f, "l ");
+         if (i->Xin.Sh32.src == 0)
+          fprintf(f, " %%cl,"); 
+         else 
+            fprintf(f, " $%d,", i->Xin.Sh32.src);
+         ppX86RM(f, i->Xin.Sh32.dst);
          return;
-      case Xin_Alu16:
-         ppX86AluOp(f, i->Xin.Alu16.op);
-         fprintf(f, "w ");
-         ppX86Operand(f, i->Xin.Alu16.src);
-         fprintf(f, ",");
-         ppX86Operand(f, i->Xin.Alu16.dst);
+      case Xin_RET:
+         fprintf(f, "ret");
          return;
       default:
          panic("ppX86Instr");