This fixes 4627 vertices sample when executing 3 instructions in a batch.
We're on the right lines here, however, WWE Raw and all XDK samples regressed further, despite the above improvement. Stack corruption now happens for most software with while(true). Perhaps there's an extra condition on sign-extension that we're not checking for?
This commit is contained in:
parent
ae572166f1
commit
cd22ba6145
|
@ -725,6 +725,30 @@ inline bool EmuX86_HasFlag_ZF(LPEXCEPTION_POINTERS e)
|
|||
|
||||
// See http://x86.renejeschke.de/ for affected CPU flags per instruction
|
||||
|
||||
void SignExtend32(uint32_t& dest, size_t from)
|
||||
{
|
||||
int32_t signExtended = 0;
|
||||
switch (from) {
|
||||
case 8:
|
||||
signExtended = (int8_t)dest;
|
||||
break;
|
||||
case 16:
|
||||
signExtended = (int16_t)dest;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ((uint32_t)signExtended != dest) {
|
||||
DebugBreak();
|
||||
}
|
||||
#endif
|
||||
|
||||
dest = (uint32_t)signExtended;
|
||||
}
|
||||
|
||||
// Keep opcode emulations alphabetically ordered :
|
||||
|
||||
bool EmuX86_Opcode_ADD(LPEXCEPTION_POINTERS e, _DInst& info)
|
||||
|
@ -739,7 +763,10 @@ bool EmuX86_Opcode_ADD(LPEXCEPTION_POINTERS e, _DInst& info)
|
|||
if (!EmuX86_Operand_Addr_ForReadWrite(e, info, 0, OUT opAddr))
|
||||
return false;
|
||||
|
||||
const uint32_t dest = EmuX86_Addr_Read(opAddr);
|
||||
uint32_t dest = EmuX86_Addr_Read(opAddr);
|
||||
if (info.ops[0].size > info.ops[1].size) {
|
||||
SignExtend32(dest, info.ops[1].size);
|
||||
}
|
||||
|
||||
uint32_t result = 0;
|
||||
uint32_t eflags = e->ContextRecord->EFlags;
|
||||
|
@ -776,6 +803,10 @@ bool EmuX86_Opcode_AND(LPEXCEPTION_POINTERS e, _DInst& info)
|
|||
|
||||
uint32_t dest = EmuX86_Addr_Read(opAddr);
|
||||
|
||||
if (info.ops[0].size > info.ops[1].size) {
|
||||
SignExtend32(src, info.ops[1].size);
|
||||
}
|
||||
|
||||
uint32_t result = 0;
|
||||
uint32_t eflags = e->ContextRecord->EFlags;
|
||||
__asm {
|
||||
|
@ -817,6 +848,10 @@ bool EmuX86_Opcode_CMP(LPEXCEPTION_POINTERS e, _DInst& info)
|
|||
uint32_t dest = 0;
|
||||
if (!EmuX86_Operand_Read(e, info, 0, &dest))
|
||||
return false;
|
||||
|
||||
if (info.ops[0].size > info.ops[1].size) {
|
||||
SignExtend32(src, info.ops[1].size);
|
||||
}
|
||||
|
||||
uint32_t eflags = e->ContextRecord->EFlags;
|
||||
__asm {
|
||||
|
@ -845,7 +880,6 @@ bool EmuX86_Opcode_CMPXCHG(LPEXCEPTION_POINTERS e, _DInst& info)
|
|||
if (!EmuX86_Operand_Read(e, info, 0, &dest))
|
||||
return false;
|
||||
|
||||
|
||||
uint32_t mask;
|
||||
switch (info.ops[0].size) {
|
||||
case 8: mask = 0xFF; break; // TODO : Needs test-case
|
||||
|
@ -1143,7 +1177,7 @@ bool EmuX86_Opcode_NOT(LPEXCEPTION_POINTERS e, _DInst& info)
|
|||
OperandAddress opAddr;
|
||||
if (!EmuX86_Operand_Addr_ForReadWrite(e, info, 0, OUT opAddr))
|
||||
return false;
|
||||
|
||||
|
||||
uint32_t dest = EmuX86_Addr_Read(opAddr);
|
||||
uint32_t result = 0;
|
||||
uint32_t eflags = e->ContextRecord->EFlags;
|
||||
|
@ -1180,7 +1214,10 @@ bool EmuX86_Opcode_OR(LPEXCEPTION_POINTERS e, _DInst& info)
|
|||
if (!EmuX86_Operand_Addr_ForReadWrite(e, info, 0, OUT opAddr))
|
||||
return false;
|
||||
|
||||
uint32_t dest = EmuX86_Addr_Read(opAddr);
|
||||
uint32_t dest = EmuX86_Addr_Read(opAddr);
|
||||
if (info.ops[0].size > info.ops[1].size) {
|
||||
SignExtend32(src, info.ops[1].size);
|
||||
}
|
||||
|
||||
uint32_t result = 0;
|
||||
uint32_t eflags = e->ContextRecord->EFlags;
|
||||
|
@ -1279,7 +1316,7 @@ bool EmuX86_Opcode_SAR(LPEXCEPTION_POINTERS e, _DInst& info)
|
|||
return false;
|
||||
|
||||
uint32_t dest = EmuX86_Addr_Read(opAddr);
|
||||
|
||||
|
||||
uint32_t result = 0;
|
||||
uint32_t eflags = e->ContextRecord->EFlags;
|
||||
uint8_t byteSrc = src;
|
||||
|
@ -1318,6 +1355,10 @@ bool EmuX86_Opcode_SBB(LPEXCEPTION_POINTERS e, _DInst& info)
|
|||
|
||||
uint32_t dest = EmuX86_Addr_Read(opAddr);
|
||||
|
||||
if (info.ops[0].size > info.ops[1].size) {
|
||||
SignExtend32(src, info.ops[1].size);
|
||||
}
|
||||
|
||||
uint32_t result = 0;
|
||||
uint32_t eflags = e->ContextRecord->EFlags;
|
||||
__asm {
|
||||
|
@ -1399,8 +1440,9 @@ bool EmuX86_Opcode_SHR(LPEXCEPTION_POINTERS e, _DInst& info)
|
|||
if (!EmuX86_Operand_Addr_ForReadWrite(e, info, 0, OUT opAddr))
|
||||
return false;
|
||||
|
||||
uint32_t dest = EmuX86_Addr_Read(opAddr);
|
||||
|
||||
uint32_t dest = EmuX86_Addr_Read(opAddr);
|
||||
|
||||
uint32_t result = 0;
|
||||
uint32_t eflags = e->ContextRecord->EFlags;
|
||||
uint8_t byteSrc = src;
|
||||
|
@ -1444,6 +1486,10 @@ bool EmuX86_Opcode_SUB(LPEXCEPTION_POINTERS e, _DInst& info)
|
|||
return false;
|
||||
|
||||
uint32_t dest = EmuX86_Addr_Read(opAddr);
|
||||
|
||||
if (info.ops[0].size > info.ops[1].size) {
|
||||
SignExtend32(src, info.ops[1].size);
|
||||
}
|
||||
|
||||
uint32_t result = 0;
|
||||
uint32_t eflags = e->ContextRecord->EFlags;
|
||||
|
@ -1509,6 +1555,10 @@ bool EmuX86_Opcode_XOR(LPEXCEPTION_POINTERS e, _DInst& info)
|
|||
|
||||
uint32_t dest = EmuX86_Addr_Read(opAddr);
|
||||
|
||||
if (info.ops[0].size > info.ops[1].size) {
|
||||
SignExtend32(src, info.ops[1].size);
|
||||
}
|
||||
|
||||
uint32_t result = 0;
|
||||
uint32_t eflags = e->ContextRecord->EFlags;
|
||||
__asm {
|
||||
|
@ -2861,7 +2911,7 @@ bool EmuX86_DecodeException(LPEXCEPTION_POINTERS e)
|
|||
|
||||
// Execute op-codes until we hit an unhandled instruction, or an error occurs
|
||||
while (true)
|
||||
//for (int x=0;x<1;x++)
|
||||
//for (int x=0;x<3;x++)
|
||||
{
|
||||
if (!EmuX86_DecodeOpcode((uint8_t*)e->ContextRecord->Eip, info)) {
|
||||
EmuLog(LOG_PREFIX, LOG_LEVEL::WARNING, "Error decoding opcode at 0x%08X", e->ContextRecord->Eip);
|
||||
|
|
Loading…
Reference in New Issue