pentium: Some stuff to make lindbergh go further [O. Galibert]

This commit is contained in:
Olivier Galibert 2014-11-09 20:35:18 +01:00
parent 822fe9bfa0
commit 299bec581a
5 changed files with 94 additions and 6 deletions

View File

@ -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;

View File

@ -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 );

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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);