diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index 81d6b9f26e..74ba93f873 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -209,14 +209,7 @@ public: void mcrf(UGeckoInstruction inst); void mcrxr(UGeckoInstruction inst); - void crand(UGeckoInstruction inst); - void crandc(UGeckoInstruction inst); - void creqv(UGeckoInstruction inst); - void crnand(UGeckoInstruction inst); - void crnor(UGeckoInstruction inst); - void cror(UGeckoInstruction inst); - void crorc(UGeckoInstruction inst); - void crxor(UGeckoInstruction inst); + void crXXX(UGeckoInstruction inst); void reg_imm(UGeckoInstruction inst); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp index 9d7ce9eac1..71fbd7e200 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp @@ -174,14 +174,14 @@ static GekkoOPTemplate table19[] = { {528, &Jit64::bcctrx}, //"bcctrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, {16, &Jit64::bclrx}, //"bclrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, - {257, &Jit64::crand}, //"crand", OPTYPE_CR, FL_EVIL}}, - {129, &Jit64::crandc}, //"crandc", OPTYPE_CR, FL_EVIL}}, - {289, &Jit64::creqv}, //"creqv", OPTYPE_CR, FL_EVIL}}, - {225, &Jit64::crnand}, //"crnand", OPTYPE_CR, FL_EVIL}}, - {33, &Jit64::crnor}, //"crnor", OPTYPE_CR, FL_EVIL}}, - {449, &Jit64::cror}, //"cror", OPTYPE_CR, FL_EVIL}}, - {417, &Jit64::crorc}, //"crorc", OPTYPE_CR, FL_EVIL}}, - {193, &Jit64::crxor}, //"crxor", OPTYPE_CR, FL_EVIL}}, + {257, &Jit64::crXXX}, //"crand", OPTYPE_CR, FL_EVIL}}, + {129, &Jit64::crXXX}, //"crandc", OPTYPE_CR, FL_EVIL}}, + {289, &Jit64::crXXX}, //"creqv", OPTYPE_CR, FL_EVIL}}, + {225, &Jit64::crXXX}, //"crnand", OPTYPE_CR, FL_EVIL}}, + {33, &Jit64::crXXX}, //"crnor", OPTYPE_CR, FL_EVIL}}, + {449, &Jit64::crXXX}, //"cror", OPTYPE_CR, FL_EVIL}}, + {417, &Jit64::crXXX}, //"crorc", OPTYPE_CR, FL_EVIL}}, + {193, &Jit64::crXXX}, //"crxor", OPTYPE_CR, FL_EVIL}}, {150, &Jit64::DoNothing}, //"isync", OPTYPE_ICACHE, FL_EVIL}}, {0, &Jit64::mcrf}, //"mcrf", OPTYPE_SYSTEM, FL_EVIL}}, diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp index 5d3eebbd36..bbfddd4f0b 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp @@ -219,10 +219,11 @@ void Jit64::mcrxr(UGeckoInstruction inst) AND(32, M(&PowerPC::ppcState.spr[SPR_XER]), Imm32(0x0FFFFFFF)); } -void Jit64::crand(UGeckoInstruction inst) +void Jit64::crXXX(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(SystemRegisters) + _dbg_assert_msg_(DYNA_REC, inst.OPCD == 19, "Invalid crXXX"); // USES_CR @@ -244,257 +245,45 @@ void Jit64::crand(UGeckoInstruction inst) SHR(8, R(ECX), Imm8(shiftB)); // Compute combined bit - AND(8, R(EAX), R(ECX)); - - // Store result bit in CRBD - AND(8, R(EAX), Imm8(0x8 >> (inst.CRBD & 3))); - AND(8, M(&PowerPC::ppcState.cr_fast[inst.CRBD >> 2]), Imm8(~(0x8 >> (inst.CRBD & 3)))); - OR(8, M(&PowerPC::ppcState.cr_fast[inst.CRBD >> 2]), R(EAX)); - - gpr.UnlockAllX(); -} - -void Jit64::crandc(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(SystemRegisters) - - // USES_CR - - // Get bit CRBA in EAX aligned with bit CRBD - int shiftA = (inst.CRBD & 3) - (inst.CRBA & 3); - MOV(8, R(EAX), M(&PowerPC::ppcState.cr_fast[inst.CRBA >> 2])); - if (shiftA < 0) - SHL(8, R(EAX), Imm8(-shiftA)); - else if (shiftA > 0) - SHR(8, R(EAX), Imm8(shiftA)); - - // Get bit CRBB in ECX aligned with bit CRBD - gpr.FlushLockX(ECX); - int shiftB = (inst.CRBD & 3) - (inst.CRBB & 3); - MOV(8, R(ECX), M(&PowerPC::ppcState.cr_fast[inst.CRBB >> 2])); - if (shiftB < 0) - SHL(8, R(ECX), Imm8(-shiftB)); - else if (shiftB > 0) - SHR(8, R(ECX), Imm8(shiftB)); - - // Compute combined bit - NOT(8, R(ECX)); - AND(8, R(EAX), R(ECX)); - - // Store result bit in CRBD - AND(8, R(EAX), Imm8(0x8 >> (inst.CRBD & 3))); - AND(8, M(&PowerPC::ppcState.cr_fast[inst.CRBD >> 2]), Imm8(~(0x8 >> (inst.CRBD & 3)))); - OR(8, M(&PowerPC::ppcState.cr_fast[inst.CRBD >> 2]), R(EAX)); - - gpr.UnlockAllX(); -} - -void Jit64::creqv(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(SystemRegisters) - - // USES_CR - - // Get bit CRBA in EAX aligned with bit CRBD - int shiftA = (inst.CRBD & 3) - (inst.CRBA & 3); - MOV(8, R(EAX), M(&PowerPC::ppcState.cr_fast[inst.CRBA >> 2])); - if (shiftA < 0) - SHL(8, R(EAX), Imm8(-shiftA)); - else if (shiftA > 0) - SHR(8, R(EAX), Imm8(shiftA)); - - // Get bit CRBB in ECX aligned with bit CRBD - gpr.FlushLockX(ECX); - int shiftB = (inst.CRBD & 3) - (inst.CRBB & 3); - MOV(8, R(ECX), M(&PowerPC::ppcState.cr_fast[inst.CRBB >> 2])); - if (shiftB < 0) - SHL(8, R(ECX), Imm8(-shiftB)); - else if (shiftB > 0) - SHR(8, R(ECX), Imm8(shiftB)); - - // Compute combined bit - XOR(8, R(EAX), R(ECX)); - NOT(8, R(EAX)); - - // Store result bit in CRBD - AND(8, R(EAX), Imm8(0x8 >> (inst.CRBD & 3))); - AND(8, M(&PowerPC::ppcState.cr_fast[inst.CRBD >> 2]), Imm8(~(0x8 >> (inst.CRBD & 3)))); - OR(8, M(&PowerPC::ppcState.cr_fast[inst.CRBD >> 2]), R(EAX)); - - gpr.UnlockAllX(); -} - -void Jit64::crnand(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(SystemRegisters) - - // USES_CR - - // Get bit CRBA in EAX aligned with bit CRBD - int shiftA = (inst.CRBD & 3) - (inst.CRBA & 3); - MOV(8, R(EAX), M(&PowerPC::ppcState.cr_fast[inst.CRBA >> 2])); - if (shiftA < 0) - SHL(8, R(EAX), Imm8(-shiftA)); - else if (shiftA > 0) - SHR(8, R(EAX), Imm8(shiftA)); - - // Get bit CRBB in ECX aligned with bit CRBD - gpr.FlushLockX(ECX); - int shiftB = (inst.CRBD & 3) - (inst.CRBB & 3); - MOV(8, R(ECX), M(&PowerPC::ppcState.cr_fast[inst.CRBB >> 2])); - if (shiftB < 0) - SHL(8, R(ECX), Imm8(-shiftB)); - else if (shiftB > 0) - SHR(8, R(ECX), Imm8(shiftB)); - - // Compute combined bit - AND(8, R(EAX), R(ECX)); - NOT(8, R(EAX)); - - // Store result bit in CRBD - AND(8, R(EAX), Imm8(0x8 >> (inst.CRBD & 3))); - AND(8, M(&PowerPC::ppcState.cr_fast[inst.CRBD >> 2]), Imm8(~(0x8 >> (inst.CRBD & 3)))); - OR(8, M(&PowerPC::ppcState.cr_fast[inst.CRBD >> 2]), R(EAX)); - - gpr.UnlockAllX(); -} - -void Jit64::crnor(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(SystemRegisters) - - // USES_CR - - // Get bit CRBA in EAX aligned with bit CRBD - int shiftA = (inst.CRBD & 3) - (inst.CRBA & 3); - MOV(8, R(EAX), M(&PowerPC::ppcState.cr_fast[inst.CRBA >> 2])); - if (shiftA < 0) - SHL(8, R(EAX), Imm8(-shiftA)); - else if (shiftA > 0) - SHR(8, R(EAX), Imm8(shiftA)); - - // Get bit CRBB in ECX aligned with bit CRBD - gpr.FlushLockX(ECX); - int shiftB = (inst.CRBD & 3) - (inst.CRBB & 3); - MOV(8, R(ECX), M(&PowerPC::ppcState.cr_fast[inst.CRBB >> 2])); - if (shiftB < 0) - SHL(8, R(ECX), Imm8(-shiftB)); - else if (shiftB > 0) - SHR(8, R(ECX), Imm8(shiftB)); - - // Compute combined bit - OR(8, R(EAX), R(ECX)); - NOT(8, R(EAX)); - - // Store result bit in CRBD - AND(8, R(EAX), Imm8(0x8 >> (inst.CRBD & 3))); - AND(8, M(&PowerPC::ppcState.cr_fast[inst.CRBD >> 2]), Imm8(~(0x8 >> (inst.CRBD & 3)))); - OR(8, M(&PowerPC::ppcState.cr_fast[inst.CRBD >> 2]), R(EAX)); - - gpr.UnlockAllX(); -} - -void Jit64::cror(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(SystemRegisters) - - // USES_CR - - // Get bit CRBA in EAX aligned with bit CRBD - int shiftA = (inst.CRBD & 3) - (inst.CRBA & 3); - MOV(8, R(EAX), M(&PowerPC::ppcState.cr_fast[inst.CRBA >> 2])); - if (shiftA < 0) - SHL(8, R(EAX), Imm8(-shiftA)); - else if (shiftA > 0) - SHR(8, R(EAX), Imm8(shiftA)); - - // Get bit CRBB in ECX aligned with bit CRBD - gpr.FlushLockX(ECX); - int shiftB = (inst.CRBD & 3) - (inst.CRBB & 3); - MOV(8, R(ECX), M(&PowerPC::ppcState.cr_fast[inst.CRBB >> 2])); - if (shiftB < 0) - SHL(8, R(ECX), Imm8(-shiftB)); - else if (shiftB > 0) - SHR(8, R(ECX), Imm8(shiftB)); - - // Compute combined bit - OR(8, R(EAX), R(ECX)); - - // Store result bit in CRBD - AND(8, R(EAX), Imm8(0x8 >> (inst.CRBD & 3))); - AND(8, M(&PowerPC::ppcState.cr_fast[inst.CRBD >> 2]), Imm8(~(0x8 >> (inst.CRBD & 3)))); - OR(8, M(&PowerPC::ppcState.cr_fast[inst.CRBD >> 2]), R(EAX)); - - gpr.UnlockAllX(); -} - -void Jit64::crorc(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(SystemRegisters) - - // USES_CR - - // Get bit CRBA in EAX aligned with bit CRBD - int shiftA = (inst.CRBD & 3) - (inst.CRBA & 3); - MOV(8, R(EAX), M(&PowerPC::ppcState.cr_fast[inst.CRBA >> 2])); - if (shiftA < 0) - SHL(8, R(EAX), Imm8(-shiftA)); - else if (shiftA > 0) - SHR(8, R(EAX), Imm8(shiftA)); - - // Get bit CRBB in ECX aligned with bit CRBD - gpr.FlushLockX(ECX); - int shiftB = (inst.CRBD & 3) - (inst.CRBB & 3); - MOV(8, R(ECX), M(&PowerPC::ppcState.cr_fast[inst.CRBB >> 2])); - if (shiftB < 0) - SHL(8, R(ECX), Imm8(-shiftB)); - else if (shiftB > 0) - SHR(8, R(ECX), Imm8(shiftB)); - - // Compute combined bit - NOT(8, R(ECX)); - OR(8, R(EAX), R(ECX)); - - // Store result bit in CRBD - AND(8, R(EAX), Imm8(0x8 >> (inst.CRBD & 3))); - AND(8, M(&PowerPC::ppcState.cr_fast[inst.CRBD >> 2]), Imm8(~(0x8 >> (inst.CRBD & 3)))); - OR(8, M(&PowerPC::ppcState.cr_fast[inst.CRBD >> 2]), R(EAX)); - - gpr.UnlockAllX(); -} - -void Jit64::crxor(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(SystemRegisters) - - // USES_CR - - // Get bit CRBA in EAX aligned with bit CRBD - int shiftA = (inst.CRBD & 3) - (inst.CRBA & 3); - MOV(8, R(EAX), M(&PowerPC::ppcState.cr_fast[inst.CRBA >> 2])); - if (shiftA < 0) - SHL(8, R(EAX), Imm8(-shiftA)); - else if (shiftA > 0) - SHR(8, R(EAX), Imm8(shiftA)); - - // Get bit CRBB in ECX aligned with bit CRBD - gpr.FlushLockX(ECX); - int shiftB = (inst.CRBD & 3) - (inst.CRBB & 3); - MOV(8, R(ECX), M(&PowerPC::ppcState.cr_fast[inst.CRBB >> 2])); - if (shiftB < 0) - SHL(8, R(ECX), Imm8(-shiftB)); - else if (shiftB > 0) - SHR(8, R(ECX), Imm8(shiftB)); - - // Compute combined bit - XOR(8, R(EAX), R(ECX)); + switch(inst.SUBOP10) + { + case 33: // crnor + OR(8, R(EAX), R(ECX)); + NOT(8, R(EAX)); + break; + + case 129: // crandc + NOT(8, R(ECX)); + AND(8, R(EAX), R(ECX)); + break; + + case 193: // crxor + XOR(8, R(EAX), R(ECX)); + break; + + case 225: // crnand + AND(8, R(EAX), R(ECX)); + NOT(8, R(EAX)); + break; + + case 257: // crand + AND(8, R(EAX), R(ECX)); + break; + + case 289: // creqv + XOR(8, R(EAX), R(ECX)); + NOT(8, R(EAX)); + break; + + case 417: // crorc + NOT(8, R(ECX)); + OR(8, R(EAX), R(ECX)); + break; + + case 449: // cror + OR(8, R(EAX), R(ECX)); + break; + } // Store result bit in CRBD AND(8, R(EAX), Imm8(0x8 >> (inst.CRBD & 3)));