]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add the FPU control word to the x86 guest state. And fix some bugs
authorJulian Seward <jseward@acm.org>
Wed, 8 Sep 2004 19:06:34 +0000 (19:06 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 8 Sep 2004 19:06:34 +0000 (19:06 +0000)
copying stuff in and out of baseBlock.

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

VEX/hacked104/vg_include.h
VEX/hacked104/vg_main.c
VEX/hacked104/vg_scheduler.c
VEX/priv/guest-x86/gdefs.h
VEX/priv/guest-x86/ghelpers.c
VEX/priv/host-x86/hdefs.c

index 143b2b24172f91fcf05f021d9fdbc6c1ac7dbab7..123a44c1d21787c1739ce28dfb30bfd9fd88cac5 100644 (file)
@@ -741,6 +741,9 @@ typedef
 
       ULong m_f0, m_f1, m_f2, m_f3, m_f4, m_f5, m_f6, m_f7;
       UInt  m_ftop;
+      UInt  m_fpucw;
+      UInt  m_ftag74;
+      UInt  m_ftag30;
 
       UInt sh_eax;
       UInt sh_ebx;
@@ -1984,6 +1987,7 @@ extern Int VGOFF_(m_f5);
 extern Int VGOFF_(m_f6);
 extern Int VGOFF_(m_f7);
 extern Int VGOFF_(m_ftag0);
+extern Int VGOFF_(m_fpucw);
 
 /* Reg-alloc spill area (VG_MAX_SPILLSLOTS words long). */
 extern Int VGOFF_(spillslots);
index bc161d575902a1a32661995089c6b77f8482996d..e84db47bf0371ad922b4aab8116b05629c567cc9 100644 (file)
@@ -68,6 +68,7 @@ Int VGOFF_(m_f5) = INVALID_OFFSET;
 Int VGOFF_(m_f6) = INVALID_OFFSET;
 Int VGOFF_(m_f7) = INVALID_OFFSET;
 Int VGOFF_(m_ftag0) = INVALID_OFFSET;
+Int VGOFF_(m_fpucw) = INVALID_OFFSET;
 
 Int VGOFF_(spillslots) = INVALID_OFFSET;
 Int VGOFF_(sh_eax) = INVALID_OFFSET;
@@ -194,61 +195,62 @@ static void vg_init_baseBlock ( void )
    /* 26 */ VGOFF_(m_f6)    = alloc_BaB(2);
    /* 28 */ VGOFF_(m_f7)    = alloc_BaB(2);
    /* 30 */ VGOFF_(m_ftag0) = alloc_BaB(2);
-
-   /* 32  */ VGOFF_(sh_eax)    = alloc_BaB(1);
-   /* 33  */ VGOFF_(sh_ecx)    = alloc_BaB(1);
-   /* 34  */ VGOFF_(sh_edx)    = alloc_BaB(1);
-   /* 35  */ VGOFF_(sh_ebx)    = alloc_BaB(1);
-   /* 36  */ VGOFF_(sh_esp)    = alloc_BaB(1);
-   /* 37  */ VGOFF_(sh_ebp)    = alloc_BaB(1);
-   /* 38  */ VGOFF_(sh_esi)    = alloc_BaB(1);
-   /* 39  */ VGOFF_(sh_edi)    = alloc_BaB(1);
-   /* 40  */ VGOFF_(sh_eflags) = alloc_BaB(1);
+   /* 32 */ VGOFF_(m_fpucw) = alloc_BaB(1);
+
+   /* 33  */ VGOFF_(sh_eax)    = alloc_BaB(1);
+   /* 34  */ VGOFF_(sh_ecx)    = alloc_BaB(1);
+   /* 35  */ VGOFF_(sh_edx)    = alloc_BaB(1);
+   /* 36  */ VGOFF_(sh_ebx)    = alloc_BaB(1);
+   /* 37  */ VGOFF_(sh_esp)    = alloc_BaB(1);
+   /* 38  */ VGOFF_(sh_ebp)    = alloc_BaB(1);
+   /* 39  */ VGOFF_(sh_esi)    = alloc_BaB(1);
+   /* 40  */ VGOFF_(sh_edi)    = alloc_BaB(1);
+   /* 41  */ VGOFF_(sh_eflags) = alloc_BaB(1);
 
    /* stated offsets are wrong after here */
-   /* 41 */ 
+   /* 42 */ 
    VGOFF_(log_1I_0D_cache_access)  
       = alloc_BaB_1_set( (Addr) & VG_(log_1I_0D_cache_access) );
-   /* 42 */ 
+   /* 43 */ 
    VGOFF_(log_0I_1D_cache_access)  
       = alloc_BaB_1_set( (Addr) & VG_(log_0I_1D_cache_access) );
-   /* 43 */ 
+   /* 44 */ 
    VGOFF_(log_1I_1D_cache_access)  
       = alloc_BaB_1_set( (Addr) & VG_(log_1I_1D_cache_access) );
-   /* 44 */ 
+   /* 45 */ 
    VGOFF_(log_0I_2D_cache_access)  
       = alloc_BaB_1_set( (Addr) & VG_(log_0I_2D_cache_access) );
-   /* 45 */ 
+   /* 46 */ 
    VGOFF_(log_1I_2D_cache_access)  
       = alloc_BaB_1_set( (Addr) & VG_(log_1I_2D_cache_access) );
 
-   /* 46  */ 
+   /* 47  */ 
    VGOFF_(helper_value_check4_fail) 
       = alloc_BaB_1_set( (Addr) & VG_(helper_value_check4_fail) );
-   /* 47 */
+   /* 48 */
    VGOFF_(helper_value_check0_fail)
       = alloc_BaB_1_set( (Addr) & VG_(helper_value_check0_fail) );
 
-   /* 48  */
+   /* 49  */
    VGOFF_(helperc_STOREV4)
       = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV4) );
-   /* 49  */
+   /* 50  */
    VGOFF_(helperc_STOREV1)
       = alloc_BaB_1_set( (Addr) & VG_(helperc_STOREV1) );
 
-   /* 50 */
+   /* 51 */
    VGOFF_(helperc_LOADV4)
       = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV4) );
-   /* 51 */
+   /* 52 */
    VGOFF_(helperc_LOADV1)
       = alloc_BaB_1_set( (Addr) & VG_(helperc_LOADV1) );
 
-   /* 52 */
+   /* 53 */
    VGOFF_(handle_esp_assignment)
       = alloc_BaB_1_set( (Addr) & VGM_(handle_esp_assignment) );
 
-   /* There are currently 24 spill slots */
-   /* 53 .. 49  This overlaps the magic boundary at >= 32 words, but
+   /* There are currently 100 spill slots */
+   /* 54 .. 154  This overlaps the magic boundary at >= 32 words, but
       most spills are to low numbered spill slots, so the ones above
       the boundary don't see much action. */
    VGOFF_(spillslots) = alloc_BaB(VG_MAX_SPILLSLOTS);
index 4a0b42271e4bf9d6f9aa2a9ebd955c2a5dd9c461..70647f0ae12178a9d4bd928e1159c3c0acb50052 100644 (file)
@@ -399,7 +399,10 @@ void VG_(load_thread_state) ( ThreadId tid )
    *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f5)]) = VG_(threads)[tid].m_f5;
    *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f6)]) = VG_(threads)[tid].m_f6;
    *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f7)]) = VG_(threads)[tid].m_f7;
-   VG_(baseBlock)[VGOFF_(m_ftop)] = VG_(threads)[tid].m_ftop;
+   VG_(baseBlock)[VGOFF_(m_ftop)]    = VG_(threads)[tid].m_ftop;
+   VG_(baseBlock)[VGOFF_(m_fpucw)]   = VG_(threads)[tid].m_fpucw;
+   VG_(baseBlock)[VGOFF_(m_ftag0)+0] = VG_(threads)[tid].m_ftag30;
+   VG_(baseBlock)[VGOFF_(m_ftag0)+1] = VG_(threads)[tid].m_ftag74;
 
    VG_(baseBlock)[VGOFF_(sh_eax)] = VG_(threads)[tid].sh_eax;
    VG_(baseBlock)[VGOFF_(sh_ebx)] = VG_(threads)[tid].sh_ebx;
@@ -450,10 +453,13 @@ void VG_(save_thread_state) ( ThreadId tid )
    VG_(threads)[tid].m_f2   = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f2)]);
    VG_(threads)[tid].m_f3   = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f3)]);
    VG_(threads)[tid].m_f4   = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f4)]);
-   VG_(threads)[tid].m_f5   = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f5)]);
-   VG_(threads)[tid].m_f6   = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f6)]);
-   VG_(threads)[tid].m_f7   = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f7)]);
-   VG_(threads)[tid].m_ftop = VG_(baseBlock)[VGOFF_(m_ftop)];
+   VG_(threads)[tid].m_f5     = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f5)]);
+   VG_(threads)[tid].m_f6     = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f6)]);
+   VG_(threads)[tid].m_f7     = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f7)]);
+   VG_(threads)[tid].m_ftop   = VG_(baseBlock)[VGOFF_(m_ftop)];
+   VG_(threads)[tid].m_fpucw  = VG_(baseBlock)[VGOFF_(m_fpucw)];
+   VG_(threads)[tid].m_ftag30 = VG_(baseBlock)[VGOFF_(m_ftag0)+0];
+   VG_(threads)[tid].m_ftag74 = VG_(baseBlock)[VGOFF_(m_ftag0)+1];
 
    VG_(threads)[tid].sh_eax = VG_(baseBlock)[VGOFF_(sh_eax)];
    VG_(threads)[tid].sh_ebx = VG_(baseBlock)[VGOFF_(sh_ebx)];
@@ -488,7 +494,10 @@ void VG_(save_thread_state) ( ThreadId tid )
    *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f5)]) = junk64;
    *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f6)]) = junk64;
    *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f7)]) = junk64;
-   VG_(baseBlock)[VGOFF_(m_ftop)] = junk;
+   VG_(baseBlock)[VGOFF_(m_ftop)]    = junk;
+   VG_(baseBlock)[VGOFF_(m_fpucw)]   = junk;
+   VG_(baseBlock)[VGOFF_(m_ftag0)+0] = junk;
+   VG_(baseBlock)[VGOFF_(m_ftag0)+1] = junk;
 
    vg_tid_currently_in_baseBlock = VG_INVALID_THREADID;
 }
index 6ece7e9caa73fa308d4c113bb4c978c98084415d..cdb584425d619d48b46f9f926917194e8ee4bbe2 100644 (file)
@@ -204,6 +204,8 @@ typedef
    * fst from st(0) to st(i) does not take an overflow fault even if the
      destination is already full.
 
+   FPUCW[15:0] is the FPU's control word.  FPUCW[31:16] is unused.
+
 */
 #define OFFB_FTOP    (13*4)
 #define OFFB_F0      (14*4)
@@ -215,9 +217,10 @@ typedef
 #define OFFB_F6      (26*4)
 #define OFFB_F7      (28*4)
 #define OFFB_FTAG0   (30*4) // up to 30*4 + 7
+#define OFFB_FPUCW   (32*4)
 
 /* Don't forget to keep this up to date. */
-#define SIZEOF_X86H_STATE  (OFFB_FTAG0 + 8)
+#define SIZEOF_X86H_STATE  (OFFB_FPUCW + 4)
 
 
 
index 9e4c7a0c2a2d5898024828a24ce88ca725a144a5..4b63149af3a49e859dc8a5074f18e0550650d869 100644 (file)
@@ -1113,6 +1113,7 @@ void x87_to_vex ( /*IN*/UChar* x87_state, /*OUT*/UChar* vex_state )
    Fpu_State* x87     = (Fpu_State*)x87_state;
    UInt       ftop    = (x87->env[FP_ENV_STAT] >> 11) & 7;
    UInt       tagw    = x87->env[FP_ENV_TAG];
+   UInt       fpucw   = x87->env[FP_ENV_CTRL];
 
    /* Copy registers and tags */
    for (r = 0; r < 8; r++) {
@@ -1131,12 +1132,11 @@ void x87_to_vex ( /*IN*/UChar* x87_state, /*OUT*/UChar* vex_state )
    /* stack pointer */
    *(UInt*)(vex_state + OFFB_FTOP) = ftop;
 
-   /* TODO: Check the CW is 037F.  Or at least, bottom 6 bits are 1
-      (all exceptions masked), and 11:10, which is rounding control,
-      is set to ..?
-   */
+   /* control word */
+   *(UInt*)(vex_state + OFFB_FPUCW) = fpucw;
 }
 
+
 /* VISIBLE TO LIBVEX CLIENT */
 void vex_to_x87 ( /*IN*/UChar* vex_state, /*OUT*/UChar* x87_state )
 {
@@ -1151,7 +1151,7 @@ void vex_to_x87 ( /*IN*/UChar* vex_state, /*OUT*/UChar* x87_state )
       x87->env[i] = 0;
 
    x87->env[1] = x87->env[3] = x87->env[5] = x87->env[13] = 0xFFFF;
-   x87->env[FP_ENV_CTRL] = 0x037F;
+   x87->env[FP_ENV_CTRL] = (UShort)( *(UInt*)(vex_state + OFFB_FPUCW) );
    x87->env[FP_ENV_STAT] = (ftop & 7) << 11;
 
    tagw = 0;
index bf7810b140342ae16539706c89139c926a0da824..e25cad21eee5cbc1866a44532fa1f805aba5a35a 100644 (file)
@@ -998,12 +998,12 @@ Bool isMove_X86Instr ( X86Instr* i, HReg* src, HReg* dst )
 
 
 /* x86 spill/reload using the hacked104 testbed.  Spill slots
-   start at word 53, and there are 100 in total. 
+   start at word 54, and there are 100 in total. 
 */
 
 X86Instr* genSpill_X86 ( HReg rreg, Int offset )
 {
-   Int base = 4 * 53;
+   Int base = 4 * 54;
    vassert(offset >= 0);
    vassert(offset <= 4*(100-1));
    vassert(!hregIsVirtual(rreg));
@@ -1021,7 +1021,7 @@ X86Instr* genSpill_X86 ( HReg rreg, Int offset )
 
 X86Instr* genReload_X86 ( HReg rreg, Int offset )
 {
-   Int base = 4 * 53;
+   Int base = 4 * 54;
    vassert(offset >= 0);
    vassert(offset <= 4*(100-1));
    vassert(!hregIsVirtual(rreg));