pentium: This is the kind of problems you find when a bios uses xmm4 as call stack [O. Galibert]

This commit is contained in:
Olivier Galibert 2014-11-19 20:00:02 +01:00
parent 1da9e187ee
commit 01dc9b6434
5 changed files with 81 additions and 14 deletions

View file

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

View file

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

View file

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

View file

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

View file

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