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

@ -3512,6 +3512,7 @@ void i386_device::zero_state()
m_ext = 0; m_ext = 0;
m_halted = 0; m_halted = 0;
m_operand_size = 0; m_operand_size = 0;
m_xmm_operand_size = 0;
m_address_size = 0; m_address_size = 0;
m_operand_prefix = 0; m_operand_prefix = 0;
m_address_prefix = 0; m_address_prefix = 0;
@ -3765,6 +3766,7 @@ void i386_device::execute_run()
{ {
i386_check_irq_line(); i386_check_irq_line();
m_operand_size = m_sreg[CS].d; m_operand_size = m_sreg[CS].d;
m_xmm_operand_size = 0;
m_address_size = m_sreg[CS].d; m_address_size = m_sreg[CS].d;
m_operand_prefix = 0; m_operand_prefix = 0;
m_address_prefix = 0; m_address_prefix = 0;

View File

@ -187,6 +187,7 @@ struct I386_CALL_GATE
int m_halted; int m_halted;
int m_operand_size; int m_operand_size;
int m_xmm_operand_size;
int m_address_size; int m_address_size;
int m_operand_prefix; int m_operand_prefix;
int m_address_prefix; int m_address_prefix;
@ -331,6 +332,8 @@ struct I386_CALL_GATE
void pentium_msr_write(UINT32 offset, UINT64 data, UINT8 *valid_msr); void pentium_msr_write(UINT32 offset, UINT64 data, UINT8 *valid_msr);
UINT64 p6_msr_read(UINT32 offset,UINT8 *valid_msr); UINT64 p6_msr_read(UINT32 offset,UINT8 *valid_msr);
void p6_msr_write(UINT32 offset, UINT64 data, 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 UINT64 MSR_READ(UINT32 offset,UINT8 *valid_msr);
inline void MSR_WRITE(UINT32 offset, UINT64 data, 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 ); 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; break;
case 0x66: case 0x66:
m_operand_size ^= 1; m_operand_size ^= 1;
m_xmm_operand_size ^= 1;
break; break;
case 0x67: case 0x67:
m_address_size ^= 1; m_address_size ^= 1;
@ -2286,6 +2287,7 @@ void i386_device::i386_operand_size() // Opcode prefix 0x66
if(m_operand_prefix == 0) if(m_operand_prefix == 0)
{ {
m_operand_size ^= 1; m_operand_size ^= 1;
m_xmm_operand_size ^= 1;
m_operand_prefix = 1; m_operand_prefix = 1;
} }
m_opcode = FETCH(); 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 i386_device::MSR_READ(UINT32 offset,UINT8 *valid_msr)
{ {
UINT64 res; UINT64 res;
@ -1343,6 +1368,9 @@ UINT64 i386_device::MSR_READ(UINT32 offset,UINT8 *valid_msr)
case 6: // Pentium Pro, Pentium II, Pentium III case 6: // Pentium Pro, Pentium II, Pentium III
res = p6_msr_read(offset,valid_msr); res = p6_msr_read(offset,valid_msr);
break; break;
case 15: // Pentium 4+
res = piv_msr_read(offset,valid_msr);
break;
default: default:
res = 0; res = 0;
break; 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 case 6: // Pentium Pro, Pentium II, Pentium III
p6_msr_write(offset,data,valid_msr); p6_msr_write(offset,data,valid_msr);
break; 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 ) switch ( (modm & 0x38) >> 3 )
{ {
case 2: // psrlq 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; break;
case 6: // psllq 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; break;
default: default:
report_invalid_modrm("mmx_group0f73", modm); report_invalid_modrm("mmx_group0f73", modm);