copying stuff in and out of baseBlock.
git-svn-id: svn://svn.valgrind.org/vex/trunk@239
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;
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);
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;
/* 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);
*(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;
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)];
*(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;
}
* 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)
#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)
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++) {
/* 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 )
{
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;
/* 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));
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));