]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
The party never stops in x86-land: implement 'fstsw' as cachegrind's
authorJulian Seward <jseward@acm.org>
Sun, 20 Mar 2005 12:51:39 +0000 (12:51 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 20 Mar 2005 12:51:39 +0000 (12:51 +0000)
regression tests require it.

Also tighten up assertion checking in putIReg, and update some
copyright notices.

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

VEX/priv/guest-x86/gdefs.h
VEX/priv/guest-x86/ghelpers.c
VEX/priv/guest-x86/toIR.c

index cb320ccc2bf03f59f171be40088d3e9b7968e747..5ae6ee498c6c1b8775dcd12b62c944c2b7ea8a70 100644 (file)
@@ -128,20 +128,18 @@ extern void  x86g_dirtyhelper_CPUID_sse0 ( VexGuestX86State* );
 extern void  x86g_dirtyhelper_CPUID_sse1 ( VexGuestX86State* );
 extern void  x86g_dirtyhelper_CPUID_sse2 ( VexGuestX86State* );
 
-extern void  x86g_dirtyhelper_FSAVE ( VexGuestX86State*, HWord );
-
 extern void  x86g_dirtyhelper_FINIT ( VexGuestX86State* );
 
+extern void  x86g_dirtyhelper_FXSAVE ( VexGuestX86State*, HWord );
+extern void  x86g_dirtyhelper_FSAVE  ( VexGuestX86State*, HWord );
+extern void  x86g_dirtyhelper_FSTENV ( VexGuestX86State*, HWord );
+
 extern VexEmWarn
             x86g_dirtyhelper_FRSTOR ( VexGuestX86State*, HWord );
 
-extern void x86g_dirtyhelper_FSTENV ( VexGuestX86State*, HWord );
-
 extern VexEmWarn 
             x86g_dirtyhelper_FLDENV ( VexGuestX86State*, HWord );
 
-extern void  x86g_dirtyhelper_FXSAVE ( VexGuestX86State*, HWord );
-
 
 /*---------------------------------------------------------*/
 /*--- Condition code stuff                              ---*/
index 4bf846494487ff79587a48754053afb4697d7211..fcccc2216ac0ff226962d696aba0d2102bd7e734 100644 (file)
@@ -2,7 +2,7 @@
 /*---------------------------------------------------------------*/
 /*---                                                         ---*/
 /*--- This file (guest-x86/ghelpers.c) is                     ---*/
-/*--- Copyright (c) 2004 OpenWorks LLP.  All rights reserved. ---*/
+/*--- Copyright (c) OpenWorks LLP.  All rights reserved.      ---*/
 /*---                                                         ---*/
 /*---------------------------------------------------------------*/
 
@@ -10,7 +10,7 @@
    This file is part of LibVEX, a library for dynamic binary
    instrumentation and translation.
 
-   Copyright (C) 2004 OpenWorks, LLP.
+   Copyright (C) 2004-2005 OpenWorks, LLP.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
index bc9c14fd7ba70bf2cd30b44c9036010049dbec6e..937578a5a419f76c9b12beb678c5463dbf8c6555 100644 (file)
@@ -2,7 +2,7 @@
 /*--------------------------------------------------------------------*/
 /*---                                                              ---*/
 /*--- This file (guest-x86/toIR.c) is                              ---*/
-/*--- Copyright (c) 2004 OpenWorks LLP.  All rights reserved.      ---*/
+/*--- Copyright (c) OpenWorks LLP.  All rights reserved.           ---*/
 /*---                                                              ---*/
 /*--------------------------------------------------------------------*/
 
@@ -10,7 +10,7 @@
    This file is part of LibVEX, a library for dynamic binary
    instrumentation and translation.
 
-   Copyright (C) 2004 OpenWorks, LLP.
+   Copyright (C) 2004-2005 OpenWorks, LLP.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -673,9 +673,13 @@ static IRExpr* getIReg ( Int sz, UInt archreg )
 static void putIReg ( Int sz, UInt archreg, IRExpr* e )
 {
    IRType ty = typeOfIRExpr(irbb->tyenv, e);
-   vassert(sz == 1 || sz == 2 || sz == 4);
+   switch (sz) {
+      case 1: vassert(ty == Ity_I8); break;
+      case 2: vassert(ty == Ity_I16); break;
+      case 4: vassert(ty == Ity_I32); break;
+      default: vpanic("putIReg(x86)");
+   }
    vassert(archreg < 8);
-   vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);
    stmt( IRStmt_Put(integerGuestRegOffset(sz,archreg), e) );
 }
 
@@ -3436,6 +3440,21 @@ static void clear_C2 ( void )
    put_C3210( binop(Iop_And32, get_C3210(), mkU32(~X86G_FC_MASK_C2)) );
 }
 
+/* Invent a plausible-looking FPU status word value:
+      ((ftop & 7) << 11) | (c3210 & 0x4700)
+ */
+static IRExpr* get_FPU_sw ( void )
+{
+   return
+      unop(Iop_32to16,
+           binop(Iop_Or32,
+                 binop(Iop_Shl32, 
+                       binop(Iop_And32, get_ftop(), mkU32(7)), 
+                             mkU8(11)),
+                       binop(Iop_And32, get_C3210(), mkU32(0x4700))
+      ));
+}
+
 
 /* ------------------------------------------------------- */
 /* Given all that stack-mangling junk, we can now go ahead
@@ -3726,7 +3745,7 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
                fp_pop();
                break;
 
-            case 4: { /* FLDENV m108 */
+            case 4: { /* FLDENV m28 */
                /* Uses dirty helper: 
                      VexEmWarn x86g_do_FLDENV ( VexGuestX86State*, Addr32 ) */
                IRTemp   ew = newTemp(Ity_I32);
@@ -4666,6 +4685,14 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
                break;
             }
 
+            case 7: { /* FNSTSW m16 */
+               IRExpr* sw = get_FPU_sw();
+               vassert(typeOfIRExpr(irbb->tyenv, sw) == Ity_I16);
+               storeLE( mkexpr(addr), sw );
+               DIP("fnstsw %s\n", dis_buf);
+               break;
+            }
+
             default:
                vex_printf("unhandled opc_aux = 0x%2x\n", gregOfRM(modrm));
                vex_printf("first_opcode == 0xDD\n");
@@ -4907,18 +4934,8 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
 
             case 0xE0: /* FNSTSW %ax */
                DIP("fnstsw %%ax\n");
-               /* Invent a plausible-looking FPU status word value and
-                  dump it in %AX:
-                     ((ftop & 7) << 11) | (c3210 & 0x4700)
-               */
-               putIReg(2, R_EAX,
-                  unop(Iop_32to16,
-                       binop(Iop_Or32,
-                             binop(Iop_Shl32, 
-                                   binop(Iop_And32, get_ftop(), mkU32(7)), 
-                                   mkU8(11)),
-                             binop(Iop_And32, get_C3210(), mkU32(0x4700))
-               )));
+               /* Get the FPU status word value and dump it in %AX. */
+               putIReg(2, R_EAX, get_FPU_sw());
                break;
 
             case 0xE8 ... 0xEF: /* FUCOMIP %st(0),%st(?) */