Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #736 from FioraAeterna/fixdirt
JIT: Don't assume the reserved bits in GQRs are zero
  • Loading branch information
delroth committed Aug 5, 2014
2 parents b6dac8f + 133e045 commit b7d4481
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
10 changes: 8 additions & 2 deletions Source/Core/Core/PowerPC/Jit64/Jit_LoadStorePaired.cpp
Expand Up @@ -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!
Expand Down Expand Up @@ -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));
Expand Down
10 changes: 8 additions & 2 deletions Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp
Expand Up @@ -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));

Expand Down Expand Up @@ -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)));
Expand Down

0 comments on commit b7d4481

Please sign in to comment.