From 397cc6b217babb7ed50b4567d28cf387bcb51cf8 Mon Sep 17 00:00:00 2001 From: cracyc Date: Sat, 11 Feb 2023 19:26:01 -0600 Subject: i386: add fxsave and fxstor --- src/devices/cpu/i386/pentops.hxx | 66 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/devices/cpu/i386/pentops.hxx b/src/devices/cpu/i386/pentops.hxx index a43ecf30161..4d5b4a88a7e 100644 --- a/src/devices/cpu/i386/pentops.hxx +++ b/src/devices/cpu/i386/pentops.hxx @@ -2801,12 +2801,76 @@ void i386_device::sse_group_0fae() // Opcode 0f ae uint32_t ea; 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 ea = GetEA(modm, 0); m_mxcsr = READ32(ea); break; case 3: // stmxcsr m32 - ea = GetEA(modm, 0); + ea = GetEA(modm, 1); WRITE32(ea, m_mxcsr); break; case 7: // clflush m8 -- cgit v1.2.3