]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Simulate bit 21 of eflags (ID), so that CPUID tests work properly.
authorJulian Seward <jseward@acm.org>
Tue, 26 Oct 2004 00:50:52 +0000 (00:50 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 26 Oct 2004 00:50:52 +0000 (00:50 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@430

VEX/priv/guest-x86/ghelpers.c
VEX/priv/guest-x86/toIR.c
VEX/pub/libvex_guest_x86.h

index 577241f394e1915b44c273e8a1f9a261c6701a4d..e61ba92347cba6cc74062270a3e7b5af7a22d94e 100644 (file)
@@ -1317,6 +1317,8 @@ void LibVEX_GuestX86_put_eflags ( UInt eflags_native,
 {
    vex_state->guest_DFLAG
       = (eflags_native & (1<<10)) ? 0xFFFFFFFF : 0x00000001;
+   vex_state->guest_IDFLAG
+      = (eflags_native & (1<<21)) ? 1 : 0;
 
    /* Mask out everything except O S Z A C P. */
    eflags_native
@@ -1341,6 +1343,8 @@ UInt LibVEX_GuestX86_get_eflags ( /*IN*/VexGuestX86State* vex_state )
    vassert(dflag == 1 || dflag == 0xFFFFFFFF);
    if (dflag == 0xFFFFFFFF)
       eflags |= (1<<10);
+   if (vex_state->guest_IDFLAG == 1)
+      eflags |= (1<<21);
                                             
    return eflags;
 }
@@ -1363,6 +1367,7 @@ void LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state )
    vex_state->guest_CC_SRC = 0;
    vex_state->guest_CC_DST = 0;
    vex_state->guest_DFLAG  = 1; /* forwards */
+   vex_state->guest_IDFLAG = 0;
 
    vex_state->guest_EIP = 0;
 
index 6da101ec2ff4b4b77cb50a56b02b5ed671b29f24..18623db6c34416077cb3dc58df0554b00454993a 100644 (file)
@@ -214,6 +214,7 @@ IRBB* bbToIR_X86Instr ( UChar* x86code,
 #define OFFB_CC_SRC  offsetof(VexGuestX86State,guest_CC_SRC)
 #define OFFB_CC_DST  offsetof(VexGuestX86State,guest_CC_DST)
 #define OFFB_DFLAG   offsetof(VexGuestX86State,guest_DFLAG)
+#define OFFB_IDFLAG  offsetof(VexGuestX86State,guest_IDFLAG)
 #define OFFB_FTOP    offsetof(VexGuestX86State,guest_FTOP)
 #define OFFB_FC3210  offsetof(VexGuestX86State,guest_FC3210)
 #define OFFB_FPUCW   offsetof(VexGuestX86State,guest_FPUCW)
@@ -8218,6 +8219,18 @@ static DisResult disInstr ( /*IN*/  Bool    resteerOK,
                   mkU32(0xFFFFFFFF))) 
           );
 
+      /* And 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))) 
+          );
+
       DIP("popf%c\n", nameISize(sz));
       break;
 
@@ -8348,7 +8361,7 @@ static DisResult disInstr ( /*IN*/  Bool    resteerOK,
       break;
 
    case 0x9C: /* PUSHF */ {
-      IRTemp t3;
+      IRTemp t3, t4;
       vassert(sz == 2 || sz == 4);
       vassert(sz == 4);  // wait for sz==2 test case
 
@@ -8368,11 +8381,22 @@ static DisResult disInstr ( /*IN*/  Bool    resteerOK,
                              unop(Iop_Not32, IRExpr_Get(OFFB_DFLAG,Ity_I32)),
                              mkU32(1<<10))) 
             );
+
+      /* And patch in the ID flag. */
+      t4 = newTemp(Ity_I32);
+      assign( t4, binop(Iop_Or32,
+                        mkexpr(t3),
+                        binop(Iop_And32,
+                             binop(Iop_Shl32, IRExpr_Get(OFFB_IDFLAG,Ity_I32), 
+                                               mkU8(21)),
+                             mkU32(1<<21)))
+            );
+
       /* if sz==2, the stored value needs to be narrowed. */
       if (sz == 2)
-       storeLE( mkexpr(t1), unop(Iop_32to16,mkexpr(t3)) );
+       storeLE( mkexpr(t1), unop(Iop_32to16,mkexpr(t4)) );
       else 
-       storeLE( mkexpr(t1), mkexpr(t3) );
+       storeLE( mkexpr(t1), mkexpr(t4) );
 
       DIP("pushf%c\n", nameISize(sz));
       break;
index 7b683bb0fa6cfa2bc82023e94e1e36f94937199f..ababaad35834fa93e9f88203299dc87568272270 100644 (file)
@@ -87,6 +87,8 @@ typedef
       UInt  guest_CC_DST;
       /* The D flag is stored here, as either -1 or +1 */
       UInt  guest_DFLAG;
+      /* Bit 21 (ID) of eflags stored here, as either 0 or 1. */
+      UInt  guest_IDFLAG;
       /* EIP */
       UInt  guest_EIP;
       /* FPU */
@@ -103,7 +105,7 @@ typedef
       UShort guest_GS;
       UShort guest_SS;
       /* Padding to make it have an 8-aligned size */
-      UInt   padding;
+      /* UInt   padding; */
    }
    VexGuestX86State;