diff --git a/src/emu/cpu/i386/i386.c b/src/emu/cpu/i386/i386.c index 9e4494500bf..3143b211ea6 100644 --- a/src/emu/cpu/i386/i386.c +++ b/src/emu/cpu/i386/i386.c @@ -3338,6 +3338,21 @@ void i386_device::register_state_i386_x87() state_add( X87_ST7, "ST7", m_debugger_temp ).formatstr("%15s"); } +void i386_device::register_state_i386_x87_xmm() +{ + register_state_i386_x87(); + + state_add( SSE_XMM0, "XMM0", m_debugger_temp ).formatstr("%32s"); + state_add( SSE_XMM1, "XMM1", m_debugger_temp ).formatstr("%32s"); + state_add( SSE_XMM2, "XMM2", m_debugger_temp ).formatstr("%32s"); + state_add( SSE_XMM3, "XMM3", m_debugger_temp ).formatstr("%32s"); + state_add( SSE_XMM4, "XMM4", m_debugger_temp ).formatstr("%32s"); + state_add( SSE_XMM5, "XMM5", m_debugger_temp ).formatstr("%32s"); + state_add( SSE_XMM6, "XMM6", m_debugger_temp ).formatstr("%32s"); + state_add( SSE_XMM7, "XMM7", m_debugger_temp ).formatstr("%32s"); + +} + void i386_device::state_import(const device_state_entry &entry) { switch (entry.index()) @@ -3411,6 +3426,30 @@ void i386_device::state_string_export(const device_state_entry &entry, astring & case X87_ST7: string.printf("%f", fx80_to_double(ST(7))); break; + case SSE_XMM0: + string.printf("%08x%08x%08x%08x", XMM(0).d[3], XMM(0).d[2], XMM(0).d[1], XMM(0).d[0]); + break; + case SSE_XMM1: + string.printf("%08x%08x%08x%08x", XMM(1).d[3], XMM(1).d[2], XMM(1).d[1], XMM(1).d[0]); + break; + case SSE_XMM2: + string.printf("%08x%08x%08x%08x", XMM(2).d[3], XMM(2).d[2], XMM(2).d[1], XMM(2).d[0]); + break; + case SSE_XMM3: + string.printf("%08x%08x%08x%08x", XMM(3).d[3], XMM(3).d[2], XMM(3).d[1], XMM(3).d[0]); + break; + case SSE_XMM4: + string.printf("%08x%08x%08x%08x", XMM(4).d[3], XMM(4).d[2], XMM(4).d[1], XMM(4).d[0]); + break; + case SSE_XMM5: + string.printf("%08x%08x%08x%08x", XMM(5).d[3], XMM(5).d[2], XMM(5).d[1], XMM(5).d[0]); + break; + case SSE_XMM6: + string.printf("%08x%08x%08x%08x", XMM(6).d[3], XMM(6).d[2], XMM(6).d[1], XMM(6).d[0]); + break; + case SSE_XMM7: + string.printf("%08x%08x%08x%08x", XMM(7).d[3], XMM(7).d[2], XMM(7).d[1], XMM(7).d[0]); + break; } } @@ -4245,7 +4284,7 @@ void pentium3_device::device_start() { // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large i386_common_init(96); - register_state_i386_x87(); + register_state_i386_x87_xmm(); build_x87_opcode_table(); build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO | OP_MMX | OP_SSE); @@ -4314,7 +4353,7 @@ void pentium4_device::device_start() { // 128 dtlb, 64 itlb i386_common_init(196); - register_state_i386_x87(); + register_state_i386_x87_xmm(); build_x87_opcode_table(); build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO | OP_MMX | OP_SSE | OP_SSE2); diff --git a/src/emu/cpu/i386/i386.h b/src/emu/cpu/i386/i386.h index d3c158d16d3..8fe66f8bc5c 100644 --- a/src/emu/cpu/i386/i386.h +++ b/src/emu/cpu/i386/i386.h @@ -271,6 +271,7 @@ struct I386_CALL_GATE void register_state_i386(); void register_state_i386_x87(); + void register_state_i386_x87_xmm(); inline UINT32 i386_translate(int segment, UINT32 ip, int rwn); inline vtlb_entry get_permissions(UINT32 pte, int wp); bool i386_translate_address(int intention, offs_t *address, vtlb_entry *entry); diff --git a/src/emu/cpu/i386/i386dasm.c b/src/emu/cpu/i386/i386dasm.c index 302685097c5..57737434e1e 100644 --- a/src/emu/cpu/i386/i386dasm.c +++ b/src/emu/cpu/i386/i386dasm.c @@ -741,7 +741,7 @@ static const I386_OPCODE i386_opcode_table2[256] = "cmpss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, {"movnti", MODRM, PARAM_RM, PARAM_REG, 0 }, {"pinsrw", MODRM, PARAM_MMX, PARAM_RM, PARAM_UI8 }, - {"pextrw", MODRM, PARAM_MMX, PARAM_MMXM, PARAM_UI8 }, + {"pextrw", MODRM, PARAM_MMX, PARAM_RM, PARAM_UI8 }, {"shufps\0" "shufpd\0" "???\0" diff --git a/src/emu/cpu/i386/i386priv.h b/src/emu/cpu/i386/i386priv.h index d1fbb4372b6..d027117d211 100644 --- a/src/emu/cpu/i386/i386priv.h +++ b/src/emu/cpu/i386/i386priv.h @@ -153,7 +153,16 @@ enum X87_ST4, X87_ST5, X87_ST6, - X87_ST7 + X87_ST7, + + SSE_XMM0, + SSE_XMM1, + SSE_XMM2, + SSE_XMM3, + SSE_XMM4, + SSE_XMM5, + SSE_XMM6, + SSE_XMM7 }; enum diff --git a/src/emu/cpu/i386/pentops.inc b/src/emu/cpu/i386/pentops.inc index 9545d20c285..390f96618f8 100644 --- a/src/emu/cpu/i386/pentops.inc +++ b/src/emu/cpu/i386/pentops.inc @@ -1292,8 +1292,8 @@ void i386_device::mmx_group_0f73() // Opcode 0f 73 else if(imm8) { imm8 = imm8 << 3; - XMM(modm & 7).q[1] = (XMM(modm & 7).q[0] << (64 - imm8)) | (XMM(modm & 7).q[1] >> imm8); - XMM(modm & 7).q[0] = XMM(modm & 7).q[0] >> imm8; + XMM(modm & 7).q[0] = (XMM(modm & 7).q[1] << (64 - imm8)) | (XMM(modm & 7).q[0] >> imm8); + XMM(modm & 7).q[1] = XMM(modm & 7).q[0] >> imm8; } break; case 6: // psllq @@ -1320,8 +1320,8 @@ void i386_device::mmx_group_0f73() // Opcode 0f 73 else if(imm8) { imm8 = imm8 << 3; - XMM(modm & 7).q[0] = (XMM(modm & 7).q[1] << (64 - imm8)) | (XMM(modm & 7).q[0] >> imm8); - XMM(modm & 7).q[1] = XMM(modm & 7).q[1] << imm8; + XMM(modm & 7).q[1] = (XMM(modm & 7).q[0] >> (64 - imm8)) | (XMM(modm & 7).q[1] << imm8); + XMM(modm & 7).q[0] = XMM(modm & 7).q[0] << imm8; } break; default: @@ -3570,12 +3570,18 @@ void i386_device::sse_pinsrw_r64_r16m16_i8() // Opcode 0f c4 if( modrm >= 0xc0 ) { UINT8 imm8 = FETCH(); UINT16 v = LOAD_RM16(modrm); - MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v; + if (m_xmm_operand_size) + XMM((modrm >> 3) & 0x7).w[imm8 & 7] = v; + else + MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v; } else { UINT32 ea = GetEA(modrm, 0); UINT8 imm8 = FETCH(); UINT16 v = READ16(ea); - MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v; + if (m_xmm_operand_size) + XMM((modrm >> 3) & 0x7).w[imm8 & 7] = v; + else + MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v; } CYCLES(1); // TODO: correct cycle count } @@ -3587,12 +3593,18 @@ void i386_device::sse_pinsrw_r64_r32m16_i8() // Opcode 0f c4 if( modrm >= 0xc0 ) { UINT8 imm8 = FETCH(); UINT16 v = (UINT16)LOAD_RM32(modrm); - MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v; + if (m_xmm_operand_size) + XMM((modrm >> 3) & 0x7).w[imm8 & 7] = v; + else + MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v; } else { UINT32 ea = GetEA(modrm, 0); UINT8 imm8 = FETCH(); UINT16 v = READ16(ea); - MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v; + if (m_xmm_operand_size) + XMM((modrm >> 3) & 0x7).w[imm8 & 7] = v; + else + MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v; } CYCLES(1); // TODO: correct cycle count } @@ -3603,7 +3615,10 @@ void i386_device::sse_pextrw_r16_r64_i8() // Opcode 0f c5 UINT8 modrm = FETCH(); if( modrm >= 0xc0 ) { UINT8 imm8 = FETCH(); - STORE_REG16(modrm, MMX(modrm & 0x7).w[imm8 & 3]); + if (m_xmm_operand_size) + STORE_REG16(modrm, XMM(modrm & 0x7).w[imm8 & 7]); + else + STORE_REG16(modrm, MMX(modrm & 0x7).w[imm8 & 3]); } else { //UINT8 imm8 = FETCH(); report_invalid_modrm("pextrw_r16_r64_i8", modrm); @@ -3617,7 +3632,10 @@ void i386_device::sse_pextrw_r32_r64_i8() // Opcode 0f c5 UINT8 modrm = FETCH(); if( modrm >= 0xc0 ) { UINT8 imm8 = FETCH(); - STORE_REG32(modrm, MMX(modrm & 0x7).w[imm8 & 3]); + if (m_xmm_operand_size) + STORE_REG32(modrm, XMM(modrm & 0x7).w[imm8 & 7]); + else + STORE_REG32(modrm, MMX(modrm & 0x7).w[imm8 & 3]); } else { //UINT8 imm8 = FETCH(); report_invalid_modrm("pextrw_r32_r64_i8", modrm);