xsave sse state using same interface as all other advanced states

This commit is contained in:
Stanislav Shwartsman 2014-03-04 21:06:29 +00:00
parent 0c4e5eb6c5
commit bfe6ecabb8
2 changed files with 52 additions and 30 deletions

View File

@ -4914,6 +4914,8 @@ public: // for now...
BX_SMF void print_state_AVX(void);
#endif
#if BX_CPU_LEVEL >= 6
BX_SMF void xsave_sse_state(bxInstruction_c *i, bx_address offset);
#if BX_SUPPORT_AVX
BX_SMF void xsave_ymm_state(bxInstruction_c *i, bx_address offset);
#if BX_SUPPORT_EVEX
@ -4923,6 +4925,7 @@ public: // for now...
#endif
#endif
BX_SMF void xrstor_sse_state(bxInstruction_c *i, bx_address offset);
#if BX_SUPPORT_AVX
BX_SMF void xrstor_ymm_state(bxInstruction_c *i, bx_address offset);
#if BX_SUPPORT_EVEX
@ -4932,6 +4935,7 @@ public: // for now...
#endif
#endif
BX_SMF void xrstor_init_sse_state(void);
#if BX_SUPPORT_AVX
BX_SMF void xrstor_init_ymm_state(void);
#if BX_SUPPORT_EVEX
@ -4940,6 +4944,7 @@ public: // for now...
BX_SMF void xrstor_init_hi_zmm_state(void);
#endif
#endif
#endif
#if BX_SUPPORT_MONITOR_MWAIT
BX_SMF bx_bool is_monitor(bx_phy_address addr, unsigned len);

View File

@ -146,16 +146,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::XSAVE(bxInstruction_c *i)
/////////////////////////////////////////////////////////////////////////////
if ((features_save_enable_mask & BX_XCR0_SSE_MASK) != 0)
{
/* store XMM register file */
for(index=0; index < 16; index++)
{
// save XMM8-XMM15 only in 64-bit mode
if (index < 8 || long64_mode()) {
write_virtual_xmmword(i->seg(),
(eaddr+index*16+XSAVE_SSE_STATE_OFFSET) & asize_mask, (Bit8u *)(&BX_READ_XMM_REG(index)));
}
}
xsave_sse_state(i, eaddr+XSAVE_SSE_STATE_OFFSET);
header1 |= BX_XCR0_SSE_MASK;
}
@ -341,25 +332,10 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::XRSTOR(bxInstruction_c *i)
/////////////////////////////////////////////////////////////////////////////
if ((features_load_enable_mask & BX_XCR0_SSE_MASK) != 0)
{
if (header1 & BX_XCR0_SSE_MASK) {
// load SSE state from XSAVE area
for(index=0; index < 16; index++)
{
// restore XMM8-XMM15 only in 64-bit mode
if (index < 8 || long64_mode()) {
read_virtual_xmmword(i->seg(),
(eaddr+index*16+XSAVE_SSE_STATE_OFFSET) & asize_mask, (Bit8u *)(&BX_READ_XMM_REG(index)));
}
}
}
else {
// initialize SSE with reset values
for(index=0; index < 16; index++) {
// set XMM8-XMM15 only in 64-bit mode
if (index < 8 || long64_mode())
BX_CLEAR_XMM_REG(index);
}
}
if (header1 & BX_XCR0_SSE_MASK)
xrstor_sse_state(i, eaddr+XSAVE_SSE_STATE_OFFSET);
else
xrstor_init_sse_state();
}
#if BX_SUPPORT_AVX
@ -407,6 +383,45 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::XRSTOR(bxInstruction_c *i)
BX_NEXT_INSTR(i);
}
// SSE state management //
#if BX_CPU_LEVEL >= 6
void BX_CPU_C::xsave_sse_state(bxInstruction_c *i, bx_address offset)
{
bx_address asize_mask = i->asize_mask();
/* store XMM register file */
for(unsigned index=0; index < 16; index++) {
// save XMM8-XMM15 only in 64-bit mode
if (index < 8 || long64_mode()) {
write_virtual_xmmword(i->seg(), (offset + index*16) & asize_mask, (Bit8u *)(&BX_READ_XMM_REG(index)));
}
}
}
void BX_CPU_C::xrstor_sse_state(bxInstruction_c *i, bx_address offset)
{
bx_address asize_mask = i->asize_mask();
// load SSE state from XSAVE area
for(unsigned index=0; index < 16; index++) {
// restore XMM8-XMM15 only in 64-bit mode
if (index < 8 || long64_mode()) {
read_virtual_xmmword(i->seg(), (offset+index*16) & asize_mask, (Bit8u *)(&BX_READ_XMM_REG(index)));
}
}
}
void BX_CPU_C::xrstor_init_sse_state(void)
{
// initialize SSE with reset values
for(unsigned index=0; index < 16; index++) {
// set XMM8-XMM15 only in 64-bit mode
if (index < 8 || long64_mode()) BX_CLEAR_XMM_REG(index);
}
}
#if BX_SUPPORT_AVX
// YMM state management //
@ -540,7 +555,9 @@ void BX_CPU_C::xrstor_init_hi_zmm_state(void)
}
#endif // BX_SUPPORT_EVEX
#endif
#endif // BX_SUPPORT_AVX
#endif // BX_CPU_LEVEL >= 6
/* 0F 01 D0 */
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::XGETBV(bxInstruction_c *i)