i386: add fxsave and fxstor

This commit is contained in:
cracyc 2023-02-11 19:26:01 -06:00
parent 0ad3bf7c04
commit 397cc6b217

View File

@ -2801,12 +2801,76 @@ void i386_device::sse_group_0fae() // Opcode 0f ae
uint32_t ea; uint32_t ea;
switch ( (modm & 0x38) >> 3 ) switch ( (modm & 0x38) >> 3 )
{ {
case 0: // fxsave
{
u8 atag = 0;
ea = GetEA(modm, 1);
WRITE16(ea + 0, m_x87_cw);
WRITE16(ea + 2, m_x87_sw);
for(int i = 0; i < 8; i++)
if((m_x87_tw & (3 << i)) != 3) atag |= 1 << i;
WRITE16(ea + 4, atag);
WRITE16(ea + 6, m_x87_opcode);
WRITE32(ea + 8, m_x87_inst_ptr);
WRITE32(ea + 12, m_x87_cs);
WRITE32(ea + 16, m_x87_data_ptr);
WRITE32(ea + 20, m_x87_ds);
WRITE32(ea + 24, m_mxcsr);
WRITE32(ea + 28, 0); // mxcsr_mask
for(int i = 0; i < 8; i++)
{
WRITE64(ea + i*16 + 32, m_x87_reg[i].low);
WRITE64(ea + i*16 + 40, m_x87_reg[i].high);
}
for(int i = 0; i < 8; i++)
{
WRITE64(ea + i*16 + 160, m_sse_reg[i].q[0]);
WRITE64(ea + i*16 + 168, m_sse_reg[i].q[1]);
}
break;
}
case 1:
{
u8 atag;
ea = GetEA(modm, 0);
x87_write_cw(READ16(ea));
m_x87_sw = READ16(ea + 2);
atag = READ8(ea + 4);
m_x87_opcode = READ16(ea + 6);
m_x87_inst_ptr = READ32(ea + 8);
m_x87_cs = READ16(ea + 12);
m_x87_data_ptr = READ32(ea + 16);
m_x87_ds = READ16(ea + 20);
m_mxcsr = READ32(ea + 24);
// mxcsr_mask
for(int i = 0; i < 8; i++)
{
int tag;
m_x87_reg[i].low = READ64(ea + i*16 + 32);
m_x87_reg[i].high = READ16(ea + i*16 + 40);
if(!(atag & (1 << i)))
tag = X87_TW_EMPTY;
if(floatx80_is_zero(m_x87_reg[i]))
tag = X87_TW_ZERO;
else if(floatx80_is_inf(m_x87_reg[i]) || floatx80_is_nan(m_x87_reg[i]))
tag = X87_TW_SPECIAL;
else
tag = X87_TW_VALID;
x87_set_tag(i, tag);
}
for(int i = 0; i < 8; i++)
{
m_sse_reg[i].q[0] = READ64(ea + i*16 + 160);
m_sse_reg[i].q[1] = READ64(ea + i*16 + 168);
}
break;
}
case 2: // ldmxcsr m32 case 2: // ldmxcsr m32
ea = GetEA(modm, 0); ea = GetEA(modm, 0);
m_mxcsr = READ32(ea); m_mxcsr = READ32(ea);
break; break;
case 3: // stmxcsr m32 case 3: // stmxcsr m32
ea = GetEA(modm, 0); ea = GetEA(modm, 1);
WRITE32(ea, m_mxcsr); WRITE32(ea, m_mxcsr);
break; break;
case 7: // clflush m8 case 7: // clflush m8