From 299bec581a976174ac2768ac0f966b56c3d8b6c0 Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Sun, 9 Nov 2014 20:35:18 +0100 Subject: pentium: Some stuff to make lindbergh go further [O. Galibert] --- src/emu/cpu/i386/i386.c | 10 ++++---- src/emu/cpu/i386/i386.h | 3 +++ src/emu/cpu/i386/i386ops.inc | 2 ++ src/emu/cpu/i386/i386priv.h | 31 +++++++++++++++++++++++++ src/emu/cpu/i386/pentops.inc | 54 ++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 94 insertions(+), 6 deletions(-) diff --git a/src/emu/cpu/i386/i386.c b/src/emu/cpu/i386/i386.c index 32374631565..9e4494500bf 100644 --- a/src/emu/cpu/i386/i386.c +++ b/src/emu/cpu/i386/i386.c @@ -3148,7 +3148,7 @@ void i386_device::i386_common_init(int tlbsize) zero_state(); - save_item(NAME( m_reg.d)); + save_item(NAME(m_reg.d)); save_item(NAME(m_sreg[ES].selector)); save_item(NAME(m_sreg[ES].base)); save_item(NAME(m_sreg[ES].limit)); @@ -3190,9 +3190,9 @@ void i386_device::i386_common_init(int tlbsize) save_item(NAME(m_AF)); save_item(NAME(m_IF)); save_item(NAME(m_TF)); - save_item(NAME( m_cr)); - save_item(NAME( m_dr)); - save_item(NAME( m_tr)); + save_item(NAME(m_cr)); + save_item(NAME(m_dr)); + save_item(NAME(m_tr)); save_item(NAME(m_idtr.base)); save_item(NAME(m_idtr.limit)); save_item(NAME(m_gdtr.base)); @@ -3512,6 +3512,7 @@ void i386_device::zero_state() m_ext = 0; m_halted = 0; m_operand_size = 0; + m_xmm_operand_size = 0; m_address_size = 0; m_operand_prefix = 0; m_address_prefix = 0; @@ -3765,6 +3766,7 @@ void i386_device::execute_run() { i386_check_irq_line(); m_operand_size = m_sreg[CS].d; + m_xmm_operand_size = 0; m_address_size = m_sreg[CS].d; m_operand_prefix = 0; m_address_prefix = 0; diff --git a/src/emu/cpu/i386/i386.h b/src/emu/cpu/i386/i386.h index 235d6e898d5..d3c158d16d3 100644 --- a/src/emu/cpu/i386/i386.h +++ b/src/emu/cpu/i386/i386.h @@ -187,6 +187,7 @@ struct I386_CALL_GATE int m_halted; int m_operand_size; + int m_xmm_operand_size; int m_address_size; int m_operand_prefix; int m_address_prefix; @@ -331,6 +332,8 @@ struct I386_CALL_GATE void pentium_msr_write(UINT32 offset, UINT64 data, UINT8 *valid_msr); UINT64 p6_msr_read(UINT32 offset,UINT8 *valid_msr); void p6_msr_write(UINT32 offset, UINT64 data, UINT8 *valid_msr); + UINT64 piv_msr_read(UINT32 offset,UINT8 *valid_msr); + void piv_msr_write(UINT32 offset, UINT64 data, UINT8 *valid_msr); inline UINT64 MSR_READ(UINT32 offset,UINT8 *valid_msr); inline void MSR_WRITE(UINT32 offset, UINT64 data, UINT8 *valid_msr); UINT32 i386_load_protected_mode_segment(I386_SREG *seg, UINT64 *desc ); diff --git a/src/emu/cpu/i386/i386ops.inc b/src/emu/cpu/i386/i386ops.inc index 8d4cc59b5b5..e4c2e4634d0 100644 --- a/src/emu/cpu/i386/i386ops.inc +++ b/src/emu/cpu/i386/i386ops.inc @@ -1134,6 +1134,7 @@ void i386_device::i386_repeat(int invert_flag) break; case 0x66: m_operand_size ^= 1; + m_xmm_operand_size ^= 1; break; case 0x67: m_address_size ^= 1; @@ -2286,6 +2287,7 @@ void i386_device::i386_operand_size() // Opcode prefix 0x66 if(m_operand_prefix == 0) { m_operand_size ^= 1; + m_xmm_operand_size ^= 1; m_operand_prefix = 1; } m_opcode = FETCH(); diff --git a/src/emu/cpu/i386/i386priv.h b/src/emu/cpu/i386/i386priv.h index 5c24b86d3e4..d1fbb4372b6 100644 --- a/src/emu/cpu/i386/i386priv.h +++ b/src/emu/cpu/i386/i386priv.h @@ -1328,6 +1328,31 @@ void i386_device::p6_msr_write(UINT32 offset, UINT64 data, UINT8 *valid_msr) } } + +// PIV (Pentium 4+) +UINT64 i386_device::piv_msr_read(UINT32 offset,UINT8 *valid_msr) +{ + switch(offset) + { + default: + logerror("RDMSR: unimplemented register called %08x at %08x\n",offset,m_pc-2); + *valid_msr = 1; + return 0; + } + return -1; +} + +void i386_device::piv_msr_write(UINT32 offset, UINT64 data, UINT8 *valid_msr) +{ + switch(offset) + { + default: + logerror("WRMSR: unimplemented register called %08x (%08x%08x) at %08x\n",offset,(UINT32)(data >> 32),(UINT32)data,m_pc-2); + *valid_msr = 1; + break; + } +} + UINT64 i386_device::MSR_READ(UINT32 offset,UINT8 *valid_msr) { UINT64 res; @@ -1343,6 +1368,9 @@ UINT64 i386_device::MSR_READ(UINT32 offset,UINT8 *valid_msr) case 6: // Pentium Pro, Pentium II, Pentium III res = p6_msr_read(offset,valid_msr); break; + case 15: // Pentium 4+ + res = piv_msr_read(offset,valid_msr); + break; default: res = 0; break; @@ -1364,6 +1392,9 @@ void i386_device::MSR_WRITE(UINT32 offset, UINT64 data, UINT8 *valid_msr) case 6: // Pentium Pro, Pentium II, Pentium III p6_msr_write(offset,data,valid_msr); break; + case 15: // Pentium 4+ + piv_msr_write(offset,data,valid_msr); + break; } } diff --git a/src/emu/cpu/i386/pentops.inc b/src/emu/cpu/i386/pentops.inc index 101bad73c64..9545d20c285 100644 --- a/src/emu/cpu/i386/pentops.inc +++ b/src/emu/cpu/i386/pentops.inc @@ -1269,10 +1269,60 @@ void i386_device::mmx_group_0f73() // Opcode 0f 73 switch ( (modm & 0x38) >> 3 ) { case 2: // psrlq - MMX(modm & 7).q=MMX(modm & 7).q >> imm8; + if (m_xmm_operand_size) + { + XMM(modm & 7).q[0] = imm8 > 63 ? 0 : XMM(modm & 7).q[0] >> imm8; + XMM(modm & 7).q[1] = imm8 > 63 ? 0 : XMM(modm & 7).q[1] >> imm8; + } + else + MMX(modm & 7).q = imm8 > 63 ? 0 : MMX(modm & 7).q >> imm8; + break; + case 3: // psrldq + if (imm8 >= 16) + { + XMM(modm & 7).q[0] = 0; + XMM(modm & 7).q[1] = 0; + } + else if(imm8 >= 8) + { + imm8 = (imm8 & 7) << 3; + XMM(modm & 7).q[0] = XMM(modm & 7).q[1] >> imm8; + XMM(modm & 7).q[1] = 0; + } + 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; + } break; case 6: // psllq - MMX(modm & 7).q=MMX(modm & 7).q << imm8; + if (m_xmm_operand_size) + { + XMM(modm & 7).q[0] = imm8 > 63 ? 0 : XMM(modm & 7).q[0] << imm8; + XMM(modm & 7).q[1] = imm8 > 63 ? 0 : XMM(modm & 7).q[1] << imm8; + } + else + MMX(modm & 7).q = imm8 > 63 ? 0 : MMX(modm & 7).q << imm8; + break; + case 7: // pslldq + if (imm8 >= 16) + { + XMM(modm & 7).q[0] = 0; + XMM(modm & 7).q[1] = 0; + } + else if(imm8 >= 8) + { + imm8 = (imm8 & 7) << 3; + XMM(modm & 7).q[1] = XMM(modm & 7).q[0] << imm8; + XMM(modm & 7).q[0] = 0; + } + 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; + } break; default: report_invalid_modrm("mmx_group0f73", modm); -- cgit v1.2.3