From: Julian Seward Date: Wed, 8 Sep 2004 19:06:34 +0000 (+0000) Subject: Add the FPU control word to the x86 guest state. And fix some bugs X-Git-Tag: svn/VALGRIND_3_0_1^2~1095 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bcb5c9eabea0be35efcd43923c703488719dc761;p=thirdparty%2Fvalgrind.git Add the FPU control word to the x86 guest state. And fix some bugs copying stuff in and out of baseBlock. git-svn-id: svn://svn.valgrind.org/vex/trunk@239 --- diff --git a/VEX/hacked104/vg_include.h b/VEX/hacked104/vg_include.h index 143b2b2417..123a44c1d2 100644 --- a/VEX/hacked104/vg_include.h +++ b/VEX/hacked104/vg_include.h @@ -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); diff --git a/VEX/hacked104/vg_main.c b/VEX/hacked104/vg_main.c index bc161d5759..e84db47bf0 100644 --- a/VEX/hacked104/vg_main.c +++ b/VEX/hacked104/vg_main.c @@ -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); diff --git a/VEX/hacked104/vg_scheduler.c b/VEX/hacked104/vg_scheduler.c index 4a0b42271e..70647f0ae1 100644 --- a/VEX/hacked104/vg_scheduler.c +++ b/VEX/hacked104/vg_scheduler.c @@ -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; } diff --git a/VEX/priv/guest-x86/gdefs.h b/VEX/priv/guest-x86/gdefs.h index 6ece7e9caa..cdb584425d 100644 --- a/VEX/priv/guest-x86/gdefs.h +++ b/VEX/priv/guest-x86/gdefs.h @@ -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) diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index 9e4c7a0c2a..4b63149af3 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -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; diff --git a/VEX/priv/host-x86/hdefs.c b/VEX/priv/host-x86/hdefs.c index bf7810b140..e25cad21ee 100644 --- a/VEX/priv/host-x86/hdefs.c +++ b/VEX/priv/host-x86/hdefs.c @@ -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));