Index: priv/guest-x86/toIR.c
===================================================================
--- priv/guest-x86/toIR.c	(revision 1574)
+++ priv/guest-x86/toIR.c	(working copy)
@@ -6434,6 +6434,85 @@
    jmp_treg(Ijk_Ret,t2);
 }
 
+static
+void dis_iret ( Int delta )
+{
+    IRTemp t1 = newTemp(Ity_I32), t2 = newTemp(Ity_I32), t3 = newTemp(Ity_I32);
+    assign(t2, getIReg(4, R_ESP));
+
+    /* FIXME: we don't handle CS from stack */
+    assign(t1, loadLE(Ity_I32, binop(Iop_Add32,mkexpr(t2),mkU32(8))));
+    assign(t3, loadLE(Ity_I32, mkexpr(t2)));
+    putIReg(4, R_ESP,binop(Iop_Add32, mkexpr(t2), mkU32(12)));
+
+    /* t1 is the flag word.  Mask out everything except OSZACP and 
+       set the flags thunk to X86G_CC_OP_COPY. */
+    stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(X86G_CC_OP_COPY) ));
+    stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
+    stmt( IRStmt_Put( OFFB_CC_DEP1, 
+                      binop(Iop_And32,
+                            mkexpr(t1), 
+                            mkU32( X86G_CC_MASK_C | X86G_CC_MASK_P 
+                                   | X86G_CC_MASK_A | X86G_CC_MASK_Z 
+                                   | X86G_CC_MASK_S| X86G_CC_MASK_O )
+                          )
+              )
+        );
+    /* Set NDEP even though it isn't used.  This makes redundant-PUT
+       elimination of previous stores to this field work better. */
+    stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
+
+    /* Also need to set the D flag, which is held in bit 10 of t1.
+       If zero, put 1 in OFFB_DFLAG, else -1 in OFFB_DFLAG. */
+    stmt( IRStmt_Put( 
+              OFFB_DFLAG,
+              IRExpr_Mux0X( 
+                  unop(Iop_32to8,
+                       binop(Iop_And32, 
+                             binop(Iop_Shr32, mkexpr(t1), mkU8(10)), 
+                             mkU32(1))),
+                  mkU32(1), 
+                  mkU32(0xFFFFFFFF))) 
+        );
+
+    /* Set the ID flag */
+    stmt( IRStmt_Put( 
+              OFFB_IDFLAG,
+              IRExpr_Mux0X( 
+                  unop(Iop_32to8,
+                       binop(Iop_And32, 
+                             binop(Iop_Shr32, mkexpr(t1), mkU8(21)), 
+                             mkU32(1))),
+                  mkU32(0), 
+                  mkU32(1))) 
+        );
+
+    /* And set the AC flag.  If setting it 1 to, emit an emulation
+       warning. */
+    stmt( IRStmt_Put( 
+              OFFB_ACFLAG,
+              IRExpr_Mux0X( 
+                  unop(Iop_32to8,
+                       binop(Iop_And32, 
+                             binop(Iop_Shr32, mkexpr(t1), mkU8(18)), 
+                             mkU32(1))),
+                  mkU32(0), 
+                  mkU32(1))) 
+        );
+
+    put_emwarn( mkU32(EmWarn_X86_acFlag) );
+    stmt( 
+        IRStmt_Exit(
+            binop( Iop_CmpNE32, 
+                   binop(Iop_And32, mkexpr(t1), mkU32(1<<18)), 
+                   mkU32(0) ),
+            Ijk_EmWarn,
+            IRConst_U32( ((Addr32)guest_EIP_bbstart)+delta)
+            )
+        );
+    jmp_treg(Ijk_Ret,t3);
+}
+
 /*------------------------------------------------------------*/
 /*--- SSE/SSE2/SSE3 helpers                                ---*/
 /*------------------------------------------------------------*/
@@ -10635,6 +10714,11 @@
       dres.whatNext = Dis_StopHere;
       DIP("ret\n");
       break;
+   case 0xCF: /* IRET */
+      dis_iret( delta );
+      dres.whatNext = Dis_StopHere;
+      DIP("iret\n");
+      break;
       
    case 0xE8: /* CALL J4 */
       d32 = getUDisp32(delta); delta += 4;
@@ -11468,12 +11552,12 @@
        break;
      }
 
-//--    case 0x1F: /* POP %DS */
-//--       dis_pop_segreg( cb, R_DS, sz ); break;
-//--    case 0x07: /* POP %ES */
-//--       dis_pop_segreg( cb, R_ES, sz ); break;
-//--    case 0x17: /* POP %SS */
-//--       dis_pop_segreg( cb, R_SS, sz ); break;
+   case 0x1F: /* POP %DS */
+      dis_pop_segreg( R_DS, sz ); break;
+   case 0x07: /* POP %ES */
+      dis_pop_segreg( R_ES, sz ); break;
+   case 0x17: /* POP %SS */
+      dis_pop_segreg( R_SS, sz ); break;
 
    /* ------------------------ PUSH ----------------------- */
 
@@ -11605,14 +11689,14 @@
       break;
 
 
-//--    case 0x0E: /* PUSH %CS */
-//--       dis_push_segreg( cb, R_CS, sz ); break;
-//--    case 0x1E: /* PUSH %DS */
-//--       dis_push_segreg( cb, R_DS, sz ); break;
-//--    case 0x06: /* PUSH %ES */
-//--       dis_push_segreg( cb, R_ES, sz ); break;
-//--    case 0x16: /* PUSH %SS */
-//--       dis_push_segreg( cb, R_SS, sz ); break;
+   case 0x0E: /* PUSH %CS */
+      dis_push_segreg( R_CS, sz ); break;
+   case 0x1E: /* PUSH %DS */
+      dis_push_segreg( R_DS, sz ); break;
+   case 0x06: /* PUSH %ES */
+      dis_push_segreg( R_ES, sz ); break;
+   case 0x16: /* PUSH %SS */
+      dis_push_segreg( R_SS, sz ); break;
 
    /* ------------------------ SCAS et al ----------------- */
 
