Merge pull request #736 from FioraAeterna/fixdirt

JIT: Don't assume the reserved bits in GQRs are zero
This commit is contained in:
Pierre Bourdon 2014-08-04 20:32:08 -07:00
commit b7d4481081
2 changed files with 16 additions and 4 deletions

View File

@ -38,7 +38,12 @@ void Jit64::psq_st(UGeckoInstruction inst)
ADD(32, R(ECX), Imm32((u32)offset));
if (update && offset)
MOV(32, gpr.R(a), R(ECX));
MOVZX(32, 16, EAX, M(&PowerPC::ppcState.spr[SPR_GQR0 + inst.I]));
// Some games (e.g. Dirt 2) incorrectly set the unused bits which breaks the lookup table code.
// Hence, we need to mask out the unused bits. The layout of the GQR register is
// UU[SCALE]UUUUU[TYPE] where SCALE is 6 bits and TYPE is 3 bits, so we have to AND with
// 0b0011111100000111, or 0x3F07.
MOV(32, R(EAX), Imm32(0x3F07));
AND(32, R(EAX), M(&PowerPC::ppcState.spr[SPR_GQR0 + inst.I]));
MOVZX(32, 8, EDX, R(AL));
// FIXME: Fix ModR/M encoding to allow [EDX*4+disp32] without a base register!
@ -75,7 +80,8 @@ void Jit64::psq_l(UGeckoInstruction inst)
MOV(32, R(ECX), gpr.R(inst.RA));
if (update && offset)
MOV(32, gpr.R(inst.RA), R(ECX));
MOVZX(32, 16, EAX, M(((char *)&GQR(inst.I)) + 2));
MOV(32, R(EAX), Imm32(0x3F07));
AND(32, R(EAX), M(((char *)&GQR(inst.I)) + 2));
MOVZX(32, 8, EDX, R(AL));
if (inst.W)
OR(32, R(EDX), Imm8(8));

View File

@ -1270,7 +1270,12 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) {
// The lower 3 bits is for GQR index. The next 1 bit is for inst.W
unsigned int quantreg = (*I >> 16) & 0x7;
unsigned int w = *I >> 19;
Jit->MOVZX(32, 16, EAX, M(((char *)&GQR(quantreg)) + 2));
// Some games (e.g. Dirt 2) incorrectly set the unused bits which breaks the lookup table code.
// Hence, we need to mask out the unused bits. The layout of the GQR register is
// UU[SCALE]UUUUU[TYPE] where SCALE is 6 bits and TYPE is 3 bits, so we have to AND with
// 0b0011111100000111, or 0x3F07.
Jit->MOV(32, R(EAX), Imm32(0x3F07));
Jit->AND(32, R(EAX), M(((char *)&GQR(quantreg)) + 2));
Jit->MOVZX(32, 8, EDX, R(AL));
Jit->OR(32, R(EDX), Imm8(w << 3));
@ -1317,7 +1322,8 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) {
regSpill(RI, EAX);
regSpill(RI, EDX);
u32 quantreg = *I >> 24;
Jit->MOVZX(32, 16, EAX, M(&PowerPC::ppcState.spr[SPR_GQR0 + quantreg]));
Jit->MOV(32, R(EAX), Imm32(0x3F07));
Jit->AND(32, R(EAX), M(&PowerPC::ppcState.spr[SPR_GQR0 + quantreg]));
Jit->MOVZX(32, 8, EDX, R(AL));
Jit->MOV(32, R(ECX), regLocForInst(RI, getOp2(I)));