diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h index 732978bd93..fe480297d2 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h @@ -171,6 +171,7 @@ public: void mftb(UGeckoInstruction inst); void mtcrf(UGeckoInstruction inst); void mfcr(UGeckoInstruction inst); + void crXX(UGeckoInstruction inst); void reg_imm(UGeckoInstruction inst); @@ -205,6 +206,7 @@ public: void fsign(UGeckoInstruction inst); void stX(UGeckoInstruction inst); //stw sth stb void lXz(UGeckoInstruction inst); + void lbzu(UGeckoInstruction inst); void lha(UGeckoInstruction inst); void rlwinmx(UGeckoInstruction inst); void rlwimix(UGeckoInstruction inst); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStore.cpp index 890c3241c7..1cae5eaeef 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStore.cpp @@ -67,6 +67,16 @@ void JitIL::lXz(UGeckoInstruction inst) ibuild.EmitStoreGReg(val, inst.RD); } +void JitIL::lbzu(UGeckoInstruction inst) { + INSTRUCTION_START + JITDISABLE(LoadStore) + // TODO: Check whether lbzu crashes GFZP01(F-Zero GX) @ 0x8008575C or not + const IREmitter::InstLoc uAddress = ibuild.EmitAdd(ibuild.EmitLoadGReg(inst.RA), ibuild.EmitIntConst((int)inst.SIMM_16)); + const IREmitter::InstLoc temp = ibuild.EmitLoad8(uAddress); + ibuild.EmitStoreGReg(temp, inst.RD); + ibuild.EmitStoreGReg(uAddress, inst.RA); +} + void JitIL::lha(UGeckoInstruction inst) { INSTRUCTION_START diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_SystemRegisters.cpp index eb932b16b0..9356729d69 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_SystemRegisters.cpp @@ -186,3 +186,76 @@ void JitIL::mtcrf(UGeckoInstruction inst) } #endif } + +void JitIL::crXX(UGeckoInstruction inst) +{ + // Ported from Jit_SystemRegister.cpp + + // Get bit CRBA in EAX aligned with bit CRBD + const int shiftA = (inst.CRBD & 3) - (inst.CRBA & 3); + IREmitter::InstLoc eax = ibuild.EmitLoadCR(inst.CRBA >> 2); + if (shiftA < 0) + eax = ibuild.EmitShl(eax, ibuild.EmitIntConst(-shiftA)); + else if (shiftA > 0) + eax = ibuild.EmitShrl(eax, ibuild.EmitIntConst(shiftA)); + + // Get bit CRBB in ECX aligned with bit CRBD + const int shiftB = (inst.CRBD & 3) - (inst.CRBB & 3); + IREmitter::InstLoc ecx = ibuild.EmitLoadCR(inst.CRBB >> 2); + if (shiftB < 0) + ecx = ibuild.EmitShl(ecx, ibuild.EmitIntConst(-shiftB)); + else if (shiftB > 0) + ecx = ibuild.EmitShrl(ecx, ibuild.EmitIntConst(shiftB)); + + // Compute combined bit + const unsigned subop = inst.SUBOP10; + switch (subop) { + case 257: + // crand + eax = ibuild.EmitAnd(eax, ecx); + break; + case 129: + // crandc + ecx = ibuild.EmitXor(ecx, ibuild.EmitIntConst(-1U)); + eax = ibuild.EmitAnd(eax, ecx); + break; + case 289: + // creqv + eax = ibuild.EmitXor(eax, ecx); + eax = ibuild.EmitXor(eax, ibuild.EmitIntConst(-1U)); + break; + case 225: + // crnand + eax = ibuild.EmitAnd(eax, ecx); + eax = ibuild.EmitXor(eax, ibuild.EmitIntConst(-1U)); + break; + case 33: + // crnor + eax = ibuild.EmitOr(eax, ecx); + eax = ibuild.EmitXor(eax, ibuild.EmitIntConst(-1U)); + break; + case 449: + // cror + eax = ibuild.EmitOr(eax, ecx); + break; + case 417: + // crorc + ecx = ibuild.EmitXor(ecx, ibuild.EmitIntConst(-1U)); + eax = ibuild.EmitOr(eax, ecx); + break; + case 193: + // crxor + eax = ibuild.EmitXor(eax, ecx); + break; + default: + PanicAlert("crXX: invalid instruction"); + break; + } + + // Store result bit in CRBD + eax = ibuild.EmitAnd(eax, ibuild.EmitIntConst(0x8 >> (inst.CRBD & 3))); + IREmitter::InstLoc bd = ibuild.EmitLoadCR(inst.CRBD >> 2); + bd = ibuild.EmitAnd(bd, ibuild.EmitIntConst(~(0x8 >> (inst.CRBD & 3)))); + bd = ibuild.EmitOr(bd, eax); + ibuild.EmitStoreCR(bd, inst.CRBD >> 2); +} diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp index f3328fcfa3..a51a865d1f 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp @@ -82,7 +82,7 @@ static GekkoOPTemplate primarytable[] = {32, &JitIL::lXz}, //"lwz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, {33, &JitIL::lXz}, //"lwzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, {34, &JitIL::lXz}, //"lbz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, - {35, &JitIL::Default}, //"lbzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, + {35, &JitIL::lbzu}, //"lbzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, {40, &JitIL::lXz}, //"lhz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, {41, &JitIL::lXz}, //"lhzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, {42, &JitIL::lha}, //"lha", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, @@ -176,14 +176,14 @@ static GekkoOPTemplate table19[] = { {528, &JitIL::bcctrx}, //"bcctrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, {16, &JitIL::bclrx}, //"bclrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, - {257, &JitIL::Default}, //"crand", OPTYPE_CR, FL_EVIL}}, - {129, &JitIL::Default}, //"crandc", OPTYPE_CR, FL_EVIL}}, - {289, &JitIL::Default}, //"creqv", OPTYPE_CR, FL_EVIL}}, - {225, &JitIL::Default}, //"crnand", OPTYPE_CR, FL_EVIL}}, - {33, &JitIL::Default}, //"crnor", OPTYPE_CR, FL_EVIL}}, - {449, &JitIL::Default}, //"cror", OPTYPE_CR, FL_EVIL}}, - {417, &JitIL::Default}, //"crorc", OPTYPE_CR, FL_EVIL}}, - {193, &JitIL::Default}, //"crxor", OPTYPE_CR, FL_EVIL}}, + {257, &JitIL::crXX}, //"crand", OPTYPE_CR, FL_EVIL}}, + {129, &JitIL::crXX}, //"crandc", OPTYPE_CR, FL_EVIL}}, + {289, &JitIL::crXX}, //"creqv", OPTYPE_CR, FL_EVIL}}, + {225, &JitIL::crXX}, //"crnand", OPTYPE_CR, FL_EVIL}}, + {33, &JitIL::crXX}, //"crnor", OPTYPE_CR, FL_EVIL}}, + {449, &JitIL::crXX}, //"cror", OPTYPE_CR, FL_EVIL}}, + {417, &JitIL::crXX}, //"crorc", OPTYPE_CR, FL_EVIL}}, + {193, &JitIL::crXX}, //"crxor", OPTYPE_CR, FL_EVIL}}, {150, &JitIL::DoNothing}, //"isync", OPTYPE_ICACHE, FL_EVIL}}, {0, &JitIL::Default}, //"mcrf", OPTYPE_SYSTEM, FL_EVIL}},