Compress FPU tag word

This commit is contained in:
Stanislav Shwartsman 2008-05-10 13:34:47 +00:00
parent 307d75f632
commit 3634c6f892
5 changed files with 48 additions and 39 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.472 2008-05-09 18:09:03 sshwarts Exp $
// $Id: cpu.h,v 1.473 2008-05-10 13:34:47 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -3132,6 +3132,7 @@ public: // for now...
BX_SMF bx_bool FPU_exception(int exception);
BX_SMF int fpu_save_environment(bxInstruction_c *);
BX_SMF int fpu_load_environment(bxInstruction_c *);
BX_SMF Bit8u pack_FPU_TW(Bit16u tag_word);
BX_SMF Bit16u unpack_FPU_TW(Bit16u tag_byte);
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: i387.h,v 1.36 2008-04-27 19:48:58 sshwarts Exp $
// $Id: i387.h,v 1.37 2008-05-10 13:34:47 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Stanislav Shwartsman
@ -66,11 +66,12 @@ public:
void FPU_push();
void FPU_settagi(int tag, int stnr);
void FPU_settagi_valid(int stnr);
int FPU_gettagi(int stnr);
floatx80 FPU_read_regi(int stnr) { return st_space[(tos+stnr) & 7]; }
void FPU_save_regi(floatx80 reg, int stnr);
void FPU_save_regi(floatx80 reg, int tag, int stnr);
void FPU_save_regi(floatx80 reg, int stnr) { FPU_save_regi(reg, FPU_tagof(reg), stnr); }
public:
Bit16u cwd; // control word
@ -97,17 +98,23 @@ public:
#define BX_READ_FPU_REG(i) \
(BX_CPU_THIS_PTR the_i387.FPU_read_regi(i))
#define BX_WRITE_FPU_REGISTER_AND_TAG(value, tag, i) \
BX_CPU_THIS_PTR the_i387.FPU_save_regi((value), (tag), (i));
#define BX_WRITE_FPU_REG(value, i) \
BX_CPU_THIS_PTR the_i387.FPU_save_regi((value), (i));
#define BX_WRITE_FPU_REGISTER_AND_TAG(value, tag, i) \
BX_CPU_THIS_PTR the_i387.FPU_save_regi((value), (tag), (i));
BX_CPP_INLINE int i387_t::FPU_gettagi(int stnr)
{
return (twd >> (((stnr+tos) & 7)*2)) & 3;
}
BX_CPP_INLINE void i387_t::FPU_settagi_valid(int stnr)
{
int regnr = (stnr + tos) & 7;
twd &= ~(3 << (regnr*2)); // FPU_Tag_Valid == '00
}
BX_CPP_INLINE void i387_t::FPU_settagi(int tag, int stnr)
{
int regnr = (stnr + tos) & 7;
@ -126,10 +133,19 @@ BX_CPP_INLINE void i387_t::FPU_pop(void)
tos = (tos + 1) & 7;
}
// it is only possisble to read FPU tag word through certain
// instructions like FNSAVE, and they update tag word to its
// real value anyway
BX_CPP_INLINE void i387_t::FPU_save_regi(floatx80 reg, int stnr)
{
st_space[(stnr+tos) & 7] = reg;
FPU_settagi_valid(stnr);
}
BX_CPP_INLINE void i387_t::FPU_save_regi(floatx80 reg, int tag, int stnr)
{
st_space[(stnr+tos) & 7] = reg;
FPU_settagi(tag, stnr);
FPU_settagi(tag, stnr);
}
#include <string.h>

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.227 2008-05-09 22:33:36 sshwarts Exp $
// $Id: proc_ctrl.cc,v 1.228 2008-05-10 13:34:47 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -2573,7 +2573,7 @@ Bit32u BX_CPU_C::hwdebug_compare(bx_address laddr_0, unsigned size,
bx_address laddr_n = laddr_0 + (size - 1);
static bx_address alignment_mask[4] =
// 00b=1 01b=2 10b=undef 11b=4
{ 0x0, 0x1, 0x0, 0x3 };
{ 0x0, 0x1, 0x7, 0x3 };
Bit32u len0 = (dr7>>18) & 3;
Bit32u len1 = (dr7>>22) & 3;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: sse_move.cc,v 1.88 2008-04-16 05:41:43 sshwarts Exp $
// $Id: sse_move.cc,v 1.89 2008-05-10 13:34:47 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2003 Stanislav Shwartsman
@ -41,6 +41,22 @@ void BX_CPU_C::print_state_SSE(void)
#endif
#if BX_SUPPORT_FPU
Bit8u BX_CPU_C::pack_FPU_TW(Bit16u twd)
{
Bit8u tag_byte = 0;
if((twd & 0x0003) != 0x0003) tag_byte |= 0x01;
if((twd & 0x000c) != 0x000c) tag_byte |= 0x02;
if((twd & 0x0030) != 0x0030) tag_byte |= 0x04;
if((twd & 0x00c0) != 0x00c0) tag_byte |= 0x08;
if((twd & 0x0300) != 0x0300) tag_byte |= 0x10;
if((twd & 0x0c00) != 0x0c00) tag_byte |= 0x20;
if((twd & 0x3000) != 0x3000) tag_byte |= 0x40;
if((twd & 0xc000) != 0xc000) tag_byte |= 0x80;
return tag_byte;
}
Bit16u BX_CPU_C::unpack_FPU_TW(Bit16u tag_byte)
{
Bit32u twd = 0;
@ -158,20 +174,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FXSAVE(bxInstruction_c *i)
#endif
xmm.xmm16u(0) = BX_CPU_THIS_PTR the_i387.get_control_word();
xmm.xmm16u(1) = BX_CPU_THIS_PTR the_i387.get_status_word ();
Bit16u twd = BX_CPU_THIS_PTR the_i387.get_tag_word(), tag_byte = 0;
if((twd & 0x0003) != 0x0003) tag_byte |= 0x01;
if((twd & 0x000c) != 0x000c) tag_byte |= 0x02;
if((twd & 0x0030) != 0x0030) tag_byte |= 0x04;
if((twd & 0x00c0) != 0x00c0) tag_byte |= 0x08;
if((twd & 0x0300) != 0x0300) tag_byte |= 0x10;
if((twd & 0x0c00) != 0x0c00) tag_byte |= 0x20;
if((twd & 0x3000) != 0x3000) tag_byte |= 0x40;
if((twd & 0xc000) != 0xc000) tag_byte |= 0x80;
xmm.xmm16u(2) = tag_byte;
xmm.xmm16u(1) = BX_CPU_THIS_PTR the_i387.get_status_word();
xmm.xmm16u(2) = pack_FPU_TW(BX_CPU_THIS_PTR the_i387.get_tag_word());
/* x87 FPU Opcode (16 bits) */
/* The lower 11 bits contain the FPU opcode, upper 5 bits are reserved */

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: xsave.cc,v 1.9 2008-04-21 19:55:04 sshwarts Exp $
// $Id: xsave.cc,v 1.10 2008-05-10 13:34:47 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008 Stanislav Shwartsman
@ -60,20 +60,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::XSAVE(bxInstruction_c *i)
if (BX_CPU_THIS_PTR xcr0.get_FPU() && (EAX & BX_XCR0_FPU_MASK) != 0)
{
xmm.xmm16u(0) = BX_CPU_THIS_PTR the_i387.get_control_word();
xmm.xmm16u(1) = BX_CPU_THIS_PTR the_i387.get_status_word ();
Bit16u twd = BX_CPU_THIS_PTR the_i387.get_tag_word(), tag_byte = 0;
if((twd & 0x0003) != 0x0003) tag_byte |= 0x01;
if((twd & 0x000c) != 0x000c) tag_byte |= 0x02;
if((twd & 0x0030) != 0x0030) tag_byte |= 0x04;
if((twd & 0x00c0) != 0x00c0) tag_byte |= 0x08;
if((twd & 0x0300) != 0x0300) tag_byte |= 0x10;
if((twd & 0x0c00) != 0x0c00) tag_byte |= 0x20;
if((twd & 0x3000) != 0x3000) tag_byte |= 0x40;
if((twd & 0xc000) != 0xc000) tag_byte |= 0x80;
xmm.xmm16u(2) = tag_byte;
xmm.xmm16u(1) = BX_CPU_THIS_PTR the_i387.get_status_word();
xmm.xmm16u(2) = pack_FPU_TW(BX_CPU_THIS_PTR the_i387.get_tag_word());
/* x87 FPU Opcode (16 bits) */
/* The lower 11 bits contain the FPU opcode, upper 5 bits are reserved */