evex support - step2
This commit is contained in:
parent
5fe5bf1ed6
commit
5d61c19b0b
@ -269,6 +269,19 @@
|
||||
#define BX_CPU_ID (0)
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_EVEX
|
||||
|
||||
#define BX_READ_8BIT_OPMASK(index) (BX_CPU_THIS_PTR opmask[index].word.byte.rh)
|
||||
#define BX_READ_16BIT_OPMASK(index) (BX_CPU_THIS_PTR opmask[index].word.rx)
|
||||
#define BX_READ_32BIT_OPMASK(index) (BX_CPU_THIS_PTR opmask[index].dword.erx)
|
||||
#define BX_READ_OPMASK(index) (BX_CPU_THIS_PTR opmask[index].rrx)
|
||||
|
||||
#define BX_WRITE_OPMASK(index, val_64) { \
|
||||
BX_CPU_THIS_PTR opmask[index].rrx = val_64; \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // defined(NEED_CPU_REG_SHORTCUTS)
|
||||
|
||||
// <TAG-INSTRUMENTATION_COMMON-BEGIN>
|
||||
@ -1050,7 +1063,7 @@ public: // for now...
|
||||
Bit32u mxcsr_mask;
|
||||
|
||||
#if BX_SUPPORT_EVEX
|
||||
bx_gen_reg_t mask[8];
|
||||
bx_gen_reg_t opmask[8];
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -859,6 +859,10 @@ void BX_CPU_C::reset(unsigned source)
|
||||
BX_CPU_THIS_PTR avx_ok = 0;
|
||||
#endif
|
||||
|
||||
#if BX_SUUPORT_EVEX
|
||||
for (n=0; n<8; n++) BX_WRITE_OPMASK(index, 0);
|
||||
#endif
|
||||
|
||||
// Reset XMM state - unchanged on #INIT
|
||||
if (source == BX_RESET_HARDWARE) {
|
||||
for(n=0; n<BX_XMM_REGISTERS; n++) {
|
||||
|
@ -254,7 +254,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FXSAVE(bxInstruction_c *i)
|
||||
if(BX_CPU_THIS_PTR cr4.get_OSFXSR() && bx_cpuid_support_sse())
|
||||
{
|
||||
/* store XMM register file */
|
||||
for(index=0; index < BX_XMM_REGISTERS; index++)
|
||||
for(index=0; index < 16; index++)
|
||||
{
|
||||
// save XMM8-XMM15 only in 64-bit mode
|
||||
if (index < 8 || long64_mode()) {
|
||||
@ -374,7 +374,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FXRSTOR(bxInstruction_c *i)
|
||||
if(BX_CPU_THIS_PTR cr4.get_OSFXSR() && bx_cpuid_support_sse())
|
||||
{
|
||||
/* load XMM register file */
|
||||
for(index=0; index < BX_XMM_REGISTERS; index++)
|
||||
for(index=0; index < 16; index++)
|
||||
{
|
||||
// restore XMM8-XMM15 only in 64-bit mode
|
||||
if (index < 8 || long64_mode()) {
|
||||
|
@ -357,6 +357,14 @@ typedef union bx_zmm_reg_t {
|
||||
else if (vlen == BX_VL128) { BX_CLEAR_AVX_HIGH128(index); } \
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_EVEX
|
||||
|
||||
/* read upper 256-bit part of ZMM register */
|
||||
#define BX_READ_ZMM_REG_HI(index) \
|
||||
(BX_CPU_THIS_PTR vmm[index].vmm256(1))
|
||||
|
||||
#endif
|
||||
|
||||
/* MXCSR REGISTER */
|
||||
|
||||
/* 31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16
|
||||
|
@ -26,6 +26,12 @@
|
||||
#include "cpu.h"
|
||||
#define LOG_THIS BX_CPU_THIS_PTR
|
||||
|
||||
#define XSAVE_SSE_STATE_OFFSET 160
|
||||
#define XSAVE_YMM_STATE_OFFSET 576
|
||||
#define XSAVE_OPMASK_STATE_OFFSET 1088
|
||||
#define XSAVE_ZMM_HI256_STATE_OFFSET 1152
|
||||
#define XSAVE_HI_ZMM_STATE_OFFSET 1664
|
||||
|
||||
/* 0F AE /4 */
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::XSAVE(bxInstruction_c *i)
|
||||
{
|
||||
@ -138,12 +144,12 @@ 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 < BX_XMM_REGISTERS; index++)
|
||||
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+160) & asize_mask, (Bit8u *)(&BX_READ_XMM_REG(index)));
|
||||
(eaddr+index*16+XSAVE_SSE_STATE_OFFSET) & asize_mask, (Bit8u *)(&BX_READ_XMM_REG(index)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,12 +161,12 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::XSAVE(bxInstruction_c *i)
|
||||
if ((features_save_enable_mask & BX_XCR0_YMM_MASK) != 0)
|
||||
{
|
||||
/* store AVX state */
|
||||
for(index=0; index < BX_XMM_REGISTERS; index++)
|
||||
for(index=0; index < 16; index++)
|
||||
{
|
||||
// save YMM8-YMM15 only in 64-bit mode
|
||||
if (index < 8 || long64_mode()) {
|
||||
write_virtual_xmmword(i->seg(),
|
||||
(eaddr+index*16+576) & asize_mask, (Bit8u *)(&BX_READ_AVX_REG_LANE(index, 1)));
|
||||
(eaddr+index*16+XSAVE_YMM_STATE_OFFSET) & asize_mask, (Bit8u *)(&BX_READ_AVX_REG_LANE(index, 1)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,6 +174,43 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::XSAVE(bxInstruction_c *i)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_EVEX
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
if ((features_save_enable_mask & BX_XCR0_OPMASK_MASK) != 0)
|
||||
{
|
||||
// save OPMASK state to XSAVE area
|
||||
for(index=0; index < 8; index++) {
|
||||
write_virtual_qword(i->seg(), (eaddr+index*8+XSAVE_OPMASK_STATE_OFFSET) & asize_mask, BX_READ_OPMASK(index));
|
||||
}
|
||||
|
||||
header1 |= BX_XCR0_OPMASK_MASK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
if ((features_save_enable_mask & BX_XCR0_ZMM_HI256_MASK) != 0)
|
||||
{
|
||||
// save upper part of ZMM registrs to XSAVE area
|
||||
for(index=0; index < 16; index++) {
|
||||
write_virtual_ymmword(i->seg(), (eaddr+index*32+XSAVE_ZMM_HI256_STATE_OFFSET) & asize_mask,
|
||||
(Bit8u *)(&BX_READ_ZMM_REG_HI(index)));
|
||||
}
|
||||
|
||||
header1 |= BX_XCR0_ZMM_HI256_MASK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
if ((features_save_enable_mask & BX_XCR0_HI_ZMM_MASK) != 0)
|
||||
{
|
||||
// load ZMM state from XSAVE area
|
||||
for(index=0; index < 16; index++) {
|
||||
write_virtual_zmmword(i->seg(), (eaddr+index*64+XSAVE_HI_ZMM_STATE_OFFSET) & asize_mask,
|
||||
(Bit8u *)(&BX_READ_AVX_REG(index+16)));
|
||||
}
|
||||
|
||||
header1 |= BX_XCR0_HI_ZMM_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
// always update header to 'dirty' state
|
||||
write_virtual_qword(i->seg(), (eaddr + 512) & asize_mask, header1);
|
||||
#endif
|
||||
@ -317,18 +360,18 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::XRSTOR(bxInstruction_c *i)
|
||||
{
|
||||
if (header1 & BX_XCR0_SSE_MASK) {
|
||||
// load SSE state from XSAVE area
|
||||
for(index=0; index < BX_XMM_REGISTERS; index++)
|
||||
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+160) & asize_mask, (Bit8u *)(&BX_READ_XMM_REG(index)));
|
||||
(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 < BX_XMM_REGISTERS; index++) {
|
||||
for(index=0; index < 16; index++) {
|
||||
// set XMM8-XMM15 only in 64-bit mode
|
||||
if (index < 8 || long64_mode())
|
||||
BX_WRITE_XMM_REG(index, xmmnil);
|
||||
@ -342,24 +385,81 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::XRSTOR(bxInstruction_c *i)
|
||||
{
|
||||
if (header1 & BX_XCR0_YMM_MASK) {
|
||||
// load AVX state from XSAVE area
|
||||
for(index=0; index < BX_XMM_REGISTERS; index++)
|
||||
for(index=0; index < 16; index++)
|
||||
{
|
||||
// restore YMM8-YMM15 only in 64-bit mode
|
||||
if (index < 8 || long64_mode()) {
|
||||
read_virtual_xmmword(i->seg(),
|
||||
(eaddr+index*16+576) & asize_mask, (Bit8u *)(&BX_READ_AVX_REG_LANE(index, 1)));
|
||||
(eaddr+index*16+XSAVE_YMM_STATE_OFFSET) & asize_mask, (Bit8u *)(&BX_READ_AVX_REG_LANE(index, 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// initialize upper part of AVX registers with reset values
|
||||
for(index=0; index < BX_XMM_REGISTERS; index++) {
|
||||
for(index=0; index < 16; index++) {
|
||||
// set YMM8-YMM15 only in 64-bit mode
|
||||
if (index < 8 || long64_mode()) BX_CLEAR_AVX_HIGH128(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_EVEX
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
if ((features_load_enable_mask & BX_XCR0_OPMASK_MASK) != 0)
|
||||
{
|
||||
if (header1 & BX_XCR0_OPMASK_MASK) {
|
||||
// load opmask registers from XSAVE area
|
||||
for(index=0; index < 8; index++) {
|
||||
Bit64u opmask = read_virtual_qword(i->seg(), (eaddr+index*8+XSAVE_OPMASK_STATE_OFFSET) & asize_mask);
|
||||
BX_WRITE_OPMASK(index, opmask);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// initialize opmask registers with reset values
|
||||
for(index=0; index < 8; index++) {
|
||||
BX_WRITE_OPMASK(index, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
if ((features_load_enable_mask & BX_XCR0_ZMM_HI256_MASK) != 0)
|
||||
{
|
||||
if (header1 & BX_XCR0_ZMM_HI256_BIT) {
|
||||
// load upper part of ZMM registers from XSAVE area
|
||||
for(index=0; index < 16; index++) {
|
||||
read_virtual_ymmword(i->seg(), (eaddr+index*32+XSAVE_ZMM_HI256_STATE_OFFSET) & asize_mask,
|
||||
(Bit8u *)(&BX_READ_ZMM_REG_HI(index)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// initialize upper part of ZMM registers with reset values
|
||||
for(index=0; index < 16; index++) {
|
||||
BX_CLEAR_AVX_HIGH256(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
if ((features_load_enable_mask & BX_XCR0_HI_ZMM_MASK) != 0)
|
||||
{
|
||||
if (header1 & BX_XCR0_HI_ZMM_MASK) {
|
||||
// load ZMM state from XSAVE area
|
||||
for(index=0; index < 16; index++) {
|
||||
read_virtual_zmmword(i->seg(), (eaddr+index*64+XSAVE_HI_ZMM_STATE_OFFSET) & asize_mask,
|
||||
(Bit8u *)(&BX_READ_AVX_REG(index+16)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// initialize upper part of ZMM registers with reset values
|
||||
for(index=0; index < 16; index++) {
|
||||
BX_WRITE_XMM_REG_CLEAR_HIGH(index+16, xmmnil);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
BX_NEXT_INSTR(i);
|
||||
|
Loading…
x
Reference in New Issue
Block a user