From ee2bf31e565114d7a21d00cfbc2abbbfa7fec8b2 Mon Sep 17 00:00:00 2001 From: magumagu9 Date: Sat, 17 Jan 2009 22:22:54 +0000 Subject: [PATCH] Misc accumulated Jit64IL work; I don't recall whether any of these changes individually led to perf improvements, although overall it's spending a lot less time in interpreter fallbacks. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1904 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/PowerPC/Jit64/Jit.h | 2 +- Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp | 77 +++++++++++++------ Source/Core/Core/Src/PowerPC/Jit64IL/IR.h | 30 +++++++- Source/Core/Core/Src/PowerPC/Jit64IL/Jit.h | 5 +- .../Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp | 8 +- .../Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp | 31 +++++--- .../Core/Src/PowerPC/Jit64IL/Jit_Integer.cpp | 28 +++---- .../Src/PowerPC/Jit64IL/Jit_LoadStore.cpp | 55 +++++++------ Source/Core/Core/Src/PowerPC/PPCTables.cpp | 31 +++++++- 9 files changed, 184 insertions(+), 83 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index 5e1af53334..909aa8617b 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -38,7 +38,7 @@ ////////////////////////////////////////////////////////////////////////////////////////// // Include // ŻŻŻŻŻŻŻŻŻŻ -#ifdef JITTEST +#if JITTEST #include "../Jit64IL/Jit.h" #else diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp index 007079338e..a73a02d172 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp @@ -1197,11 +1197,9 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { case RFIExit: case InterpreterBranch: case IdleLoop: - // No liveness effects - break; + case ShortIdleLoop: case Tramp: - if (thisUsed) - regMarkUse(RI, I, I - 1 - (*I >> 8), 1); + // No liveness effects break; case SExt8: case SExt16: @@ -1232,6 +1230,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { break; case StoreCR: case StoreCarry: + case StoreFPRF: regMarkUse(RI, I, getOp1(I), 1); break; case StoreGReg: @@ -1277,6 +1276,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { case FPMerge01: case FPMerge10: case FPMerge11: + case FDCmpCR: case InsertDoubleInMReg: if (thisUsed) { regMarkUse(RI, I, getOp1(I), 1); @@ -1411,6 +1411,15 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { regNormalRegClear(RI, I); break; } + case StoreFPRF: { + Jit->MOV(32, R(ECX), regLocForInst(RI, getOp1(I))); + Jit->AND(32, R(ECX), Imm8(0x1F)); + Jit->SHL(32, R(ECX), Imm8(12)); + Jit->AND(32, M(&FPSCR), Imm32(~(0x1F << 12))); + Jit->OR(32, M(&FPSCR), R(ECX)); + regNormalRegClear(RI, I); + break; + } case Load8: { regEmitMemLoad(RI, I, 8); break; @@ -1851,6 +1860,35 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { fregEmitBinInst(RI, I, &Jit64::SUBSD); break; } + case FDCmpCR: { + X64Reg destreg = regFindFreeReg(RI); + // TODO: Add case for NaN (CC_P) + Jit->MOVSD(XMM0, fregLocForInst(RI, getOp1(I))); + Jit->UCOMISD(XMM0, fregLocForInst(RI, getOp2(I))); + FixupBranch pNan = Jit->J_CC(CC_P); + FixupBranch pEqual = Jit->J_CC(CC_Z); + FixupBranch pLesser = Jit->J_CC(CC_C); + // Greater + Jit->MOV(32, R(destreg), Imm32(0x4)); + FixupBranch continue1 = Jit->J(); + // NaN + Jit->SetJumpTarget(pNan); + Jit->MOV(32, R(destreg), Imm32(0x1)); + FixupBranch continue2 = Jit->J(); + // Equal + Jit->SetJumpTarget(pEqual); + Jit->MOV(32, R(destreg), Imm32(0x2)); + FixupBranch continue3 = Jit->J(); + // Less + Jit->SetJumpTarget(pLesser); + Jit->MOV(32, R(destreg), Imm32(0x8)); + Jit->SetJumpTarget(continue1); + Jit->SetJumpTarget(continue2); + Jit->SetJumpTarget(continue3); + RI.regs[destreg] = I; + fregNormalRegClear(RI, I); + break; + } case FPAdd: { if (!thisUsed) break; fregEmitBinInst(RI, I, &Jit64::ADDPS); @@ -1962,7 +2000,14 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { unsigned IdleParam = ibuild->GetImmValue(getOp1(I)); unsigned InstLoc = ibuild->GetImmValue(getOp2(I)); Jit->ABI_CallFunctionC((void *)&PowerPC::OnIdle, IdleParam); - Jit->MOV(32, M(&PowerPC::ppcState.pc), Imm32(InstLoc + 12)); + Jit->MOV(32, M(&PC), Imm32(InstLoc + 12)); + Jit->JMP(asm_routines.testExceptions, true); + break; + } + case ShortIdleLoop: { + unsigned InstLoc = ibuild->GetImmValue(getOp1(I)); + Jit->ABI_CallFunction((void *)&CoreTiming::Idle); + Jit->MOV(32, M(&PC), Imm32(InstLoc)); Jit->JMP(asm_routines.testExceptions, true); break; } @@ -1998,25 +2043,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { Jit->WriteRfiExitDestInEAX(); break; } - case Tramp: { - if (!thisUsed) break; - // FIXME: Optimize! - InstLoc Op = I - 1 - (*I >> 8); - if (isFResult(*Op)) { - X64Reg reg = fregFindFreeReg(RI); - Jit->MOVAPD(reg, fregLocForInst(RI, Op)); - RI.fregs[reg] = I; - if (RI.IInfo[I - RI.FirstI] & 4) - fregClearInst(RI, Op); - } else { - X64Reg reg = regFindFreeReg(RI); - Jit->MOV(32, R(reg), regLocForInst(RI, Op)); - RI.regs[reg] = I; - if (RI.IInfo[I - RI.FirstI] & 4) - regClearInst(RI, Op); - } - break; - } + case Tramp: break; case Nop: break; default: PanicAlert("Unknown JIT instruction; aborting!"); @@ -2034,7 +2061,7 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { } } - if (UseProfile && RI.numSpills) + if (!RI.MakeProfile && RI.numSpills) printf("Block: %x, numspills %d\n", Jit->js.blockStart, RI.numSpills); Jit->UD2(); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h index 27edb78c5c..1762459286 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h @@ -54,6 +54,7 @@ namespace IREmitter { StoreCarry, StoreCTR, StoreMSR, + StoreFPRF, // Arbitrary interpreter instruction InterpreterFallback, @@ -184,6 +185,7 @@ namespace IREmitter { StoreSingle, StoreDouble, StoreFReg, + FDCmpCR, // "Trinary" operators // FIXME: Need to change representation! @@ -197,7 +199,9 @@ namespace IREmitter { SystemCall, RFIExit, InterpreterBranch, - IdleLoop, + IdleLoop, // The "usual" idle loop, load+compare+branch + ShortIdleLoop, // Idle loop seen in homebrew like wii mahjong, + // just a branch // "Opcode" representing a register too far away to // reference directly; this is a size optimization @@ -227,11 +231,19 @@ namespace IREmitter { } InstLoc inline getOp1(InstLoc i) { - return i - 1 - ((*i >> 8) & 255); + i = i - 1 - ((*i >> 8) & 255); + if (getOpcode(*i) == Tramp) { + i = i - 1 - (*i >> 8); + } + return i; } InstLoc inline getOp2(InstLoc i) { - return i - 1 - ((*i >> 16) & 255); + i = i - 1 - ((*i >> 16) & 255); + if (getOpcode(*i) == Tramp) { + i = i - 1 - (*i >> 8); + } + return i; } class IRBuilder { @@ -288,6 +300,9 @@ namespace IREmitter { InstLoc EmitStoreMSR(InstLoc val) { return FoldUOp(StoreMSR, val); } + InstLoc EmitStoreFPRF(InstLoc value) { + return FoldUOp(StoreFPRF, value); + } InstLoc EmitLoadGReg(unsigned reg) { return FoldZeroOp(LoadGReg, reg); } @@ -390,6 +405,9 @@ namespace IREmitter { InstLoc EmitInterpreterBranch() { return FoldZeroOp(InterpreterBranch, 0); } + InstLoc EmitLoadCarry() { + return FoldZeroOp(LoadCarry, 0); + } InstLoc EmitStoreCarry(InstLoc op1) { return FoldUOp(StoreCarry, op1); } @@ -402,6 +420,9 @@ namespace IREmitter { InstLoc EmitIdleLoop(InstLoc idleParam, InstLoc pc) { return FoldBiOp(IdleLoop, idleParam, pc); } + InstLoc EmitShortIdleLoop(InstLoc pc) { + return FoldUOp(ShortIdleLoop, pc); + } InstLoc EmitLoadSingle(InstLoc addr) { return FoldUOp(LoadSingle, addr); } @@ -498,6 +519,9 @@ namespace IREmitter { InstLoc EmitDoubleToSingle(InstLoc op1) { return FoldUOp(DoubleToSingle, op1); } + InstLoc EmitFDCmpCR(InstLoc op1, InstLoc op2) { + return FoldBiOp(FDCmpCR, op1, op2); + } void StartBackPass() { curReadPtr = &InstList[InstList.size()]; } void StartForwardPass() { curReadPtr = &InstList[0]; } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.h index 4204e512f8..7672d1676c 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.h @@ -280,11 +280,8 @@ public: void subfx(UGeckoInstruction inst); void subfex(UGeckoInstruction inst); - void lbzx(UGeckoInstruction inst); - void lwzx(UGeckoInstruction inst); + void lXzx(UGeckoInstruction inst); void lhax(UGeckoInstruction inst); - - void lwzux(UGeckoInstruction inst); void stXx(UGeckoInstruction inst); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp index 75ce9309de..fa5e885507 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Branch.cpp @@ -68,6 +68,11 @@ using namespace Gen; else destination = js.compilerPC + SignExt26(inst.LI << 2); + if (destination == js.compilerPC) { + ibuild.EmitShortIdleLoop(ibuild.EmitIntConst(js.compilerPC)); + return; + } + ibuild.EmitBranchUncond(ibuild.EmitIntConst(destination)); } @@ -109,7 +114,8 @@ using namespace Gen; } if (!Test) { - PanicAlert("Unconditional conditional branch?!"); + Test = ibuild.EmitIntConst(1); + //PanicAlert("Unconditional conditional branch?!"); } u32 destination; diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp index 8837cc86ff..dd1acb9989 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp @@ -28,7 +28,7 @@ void Jit64::fp_arith_s(UGeckoInstruction inst) { - if (inst.Rc || inst.OPCD != 59 || (inst.SUBOP5 != 25 && inst.SUBOP5 != 20 && inst.SUBOP5 != 21)) { + if (inst.Rc || (inst.SUBOP5 != 25 && inst.SUBOP5 != 20 && inst.SUBOP5 != 21)) { Default(inst); return; } IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA); @@ -61,22 +61,24 @@ void Jit64::fmaddXX(UGeckoInstruction inst) { - if (inst.Rc || inst.OPCD != 59) { + if (inst.Rc) { Default(inst); return; } - bool single_precision = inst.OPCD == 59; - IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA); - val = ibuild.EmitDoubleToSingle(val); - val = ibuild.EmitFSMul(val, ibuild.EmitDoubleToSingle(ibuild.EmitLoadFReg(inst.FC))); + val = ibuild.EmitFDMul(val, ibuild.EmitLoadFReg(inst.FC)); if (inst.SUBOP5 & 1) - val = ibuild.EmitFSAdd(val, ibuild.EmitDoubleToSingle(ibuild.EmitLoadFReg(inst.FB))); + val = ibuild.EmitFDAdd(val, ibuild.EmitLoadFReg(inst.FB)); else - val = ibuild.EmitFSSub(val, ibuild.EmitDoubleToSingle(ibuild.EmitLoadFReg(inst.FB))); + val = ibuild.EmitFDSub(val, ibuild.EmitLoadFReg(inst.FB)); if (inst.SUBOP5 & 2) - val = ibuild.EmitFSNeg(val); - val = ibuild.EmitDupSingleToMReg(val); + val = ibuild.EmitFDNeg(val); + if (inst.OPCD == 59) { + val = ibuild.EmitDoubleToSingle(val); + val = ibuild.EmitDupSingleToMReg(val); + } else { + val = ibuild.EmitInsertDoubleInMReg(val, ibuild.EmitLoadFReg(inst.FD)); + } ibuild.EmitStoreFReg(val, inst.FD); } @@ -92,6 +94,11 @@ void Jit64::fcmpx(UGeckoInstruction inst) { - Default(inst); - return; + printf("fcmpx at %x\n", js.compilerPC); + IREmitter::InstLoc lhs, rhs, res; + lhs = ibuild.EmitLoadFReg(inst.FA); + rhs = ibuild.EmitLoadFReg(inst.FB); + res = ibuild.EmitFDCmpCR(lhs, rhs); + ibuild.EmitStoreFPRF(res); + ibuild.EmitStoreCR(res, inst.CRFD); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Integer.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Integer.cpp index e8344ef92e..a6031d870b 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_Integer.cpp @@ -211,19 +211,21 @@ void Jit64::subfex(UGeckoInstruction inst) { - INSTRUCTION_START; - Default(inst); - return; - /* - u32 a = m_GPR[_inst.RA]; - u32 b = m_GPR[_inst.RB]; - int carry = GetCarry(); - m_GPR[_inst.RD] = (~a) + b + carry; - SetCarry(Helper_Carry(~a, b) || Helper_Carry((~a) + b, carry)); - - if (_inst.OE) PanicAlert("OE: subfcx"); - if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); - */ + if (inst.OE) PanicAlert("OE: subfex"); + IREmitter::InstLoc val, test, lhs, rhs, carry; + rhs = ibuild.EmitLoadGReg(inst.RA); + carry = ibuild.EmitLoadCarry(); + rhs = ibuild.EmitXor(rhs, ibuild.EmitIntConst(-1)); + rhs = ibuild.EmitAdd(rhs, carry); + test = ibuild.EmitICmpEq(rhs, ibuild.EmitIntConst(0)); + test = ibuild.EmitAnd(test, carry); + lhs = ibuild.EmitLoadGReg(inst.RB); + val = ibuild.EmitAdd(lhs, rhs); + ibuild.EmitStoreGReg(val, inst.RD); + test = ibuild.EmitOr(test, ibuild.EmitICmpUgt(lhs, val)); + ibuild.EmitStoreCarry(test); + if (inst.Rc) + ComputeRC(ibuild, val); } void Jit64::subfx(UGeckoInstruction inst) diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp index fcd512f232..e6f6ebc992 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_LoadStore.cpp @@ -39,24 +39,6 @@ //#define INSTRUCTION_START Default(inst); return; #define INSTRUCTION_START -void Jit64::lbzx(UGeckoInstruction inst) -{ - INSTRUCTION_START - IREmitter::InstLoc addr = ibuild.EmitLoadGReg(inst.RB); - if (inst.RA) - addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA)); - ibuild.EmitStoreGReg(ibuild.EmitLoad8(addr), inst.RD); -} - -void Jit64::lwzx(UGeckoInstruction inst) -{ - INSTRUCTION_START - IREmitter::InstLoc addr = ibuild.EmitLoadGReg(inst.RB); - if (inst.RA) - addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA)); - ibuild.EmitStoreGReg(ibuild.EmitLoad32(addr), inst.RD); -} - void Jit64::lhax(UGeckoInstruction inst) { INSTRUCTION_START @@ -113,15 +95,24 @@ void Jit64::lha(UGeckoInstruction inst) ibuild.EmitStoreGReg(val, inst.RD); } -void Jit64::lwzux(UGeckoInstruction inst) +void Jit64::lXzx(UGeckoInstruction inst) { INSTRUCTION_START IREmitter::InstLoc addr = ibuild.EmitLoadGReg(inst.RB); if (inst.RA) { addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA)); - ibuild.EmitStoreGReg(addr, inst.RA); + if (inst.SUBOP10 & 32) + ibuild.EmitStoreGReg(addr, inst.RA); } - ibuild.EmitStoreGReg(ibuild.EmitLoad32(addr), inst.RD); + IREmitter::InstLoc val; + switch (inst.SUBOP10 & ~32) + { + default: PanicAlert("lXzx: invalid access size"); + case 23: val = ibuild.EmitLoad32(addr); break; //lwzx + case 279: val = ibuild.EmitLoad16(addr); break; //lhzx + case 87: val = ibuild.EmitLoad8(addr); break; //lbzx + } + ibuild.EmitStoreGReg(val, inst.RD); } // Zero cache line. @@ -183,10 +174,28 @@ void Jit64::stXx(UGeckoInstruction inst) // A few games use these heavily in video codecs. void Jit64::lmw(UGeckoInstruction inst) { - Default(inst); return; + INSTRUCTION_START + IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16); + if (inst.RA) + addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA)); + for (int i = inst.RD; i < 32; i++) + { + IREmitter::InstLoc val = ibuild.EmitLoad32(addr); + ibuild.EmitStoreGReg(val, i); + addr = ibuild.EmitAdd(addr, ibuild.EmitIntConst(4)); + } } void Jit64::stmw(UGeckoInstruction inst) { - Default(inst); return; + INSTRUCTION_START + IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16); + if (inst.RA) + addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA)); + for (int i = inst.RD; i < 32; i++) + { + IREmitter::InstLoc val = ibuild.EmitLoadGReg(i); + ibuild.EmitStore32(val, addr); + addr = ibuild.EmitAdd(addr, ibuild.EmitIntConst(4)); + } } diff --git a/Source/Core/Core/Src/PowerPC/PPCTables.cpp b/Source/Core/Core/Src/PowerPC/PPCTables.cpp index 0f222df854..f55dc8af6c 100644 --- a/Source/Core/Core/Src/PowerPC/PPCTables.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCTables.cpp @@ -167,12 +167,21 @@ static GekkoOPTemplate primarytable[] = {28, Interpreter::andi_rc, &Jit64::reg_imm, {"andi_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}}, {29, Interpreter::andis_rc, &Jit64::reg_imm, {"andis_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}}, +#if JITTEST + {32, Interpreter::lwz, &Jit64::lXz, {"lwz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, + {33, Interpreter::lwzu, &Jit64::lXz, {"lwzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, + {34, Interpreter::lbz, &Jit64::lXz, {"lbz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, + {35, Interpreter::lbzu, &Jit64::lXz, {"lbzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, + {40, Interpreter::lhz, &Jit64::lXz, {"lhz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, + {41, Interpreter::lhzu, &Jit64::lXz, {"lhzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, +#else {32, Interpreter::lwz, &Jit64::lXz, {"lwz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, {33, Interpreter::lwzu, &Jit64::Default, {"lwzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, {34, Interpreter::lbz, &Jit64::lXz, {"lbz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, {35, Interpreter::lbzu, &Jit64::Default, {"lbzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, {40, Interpreter::lhz, &Jit64::lXz, {"lhz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, {41, Interpreter::lhzu, &Jit64::Default, {"lhzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, +#endif {42, Interpreter::lha, &Jit64::lha, {"lha", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, {43, Interpreter::lhau, &Jit64::Default, {"lhau", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, @@ -302,13 +311,33 @@ static GekkoOPTemplate table31[] = {24, Interpreter::slwx, &Jit64::slwx, {"slwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, {54, Interpreter::dcbst, &Jit64::Default, {"dcbst", OPTYPE_DCACHE, 0, 4}}, +#if JITTEST + {86, Interpreter::dcbf, &Jit64::DoNothing, {"dcbf", OPTYPE_DCACHE, 0, 4}}, +#else {86, Interpreter::dcbf, &Jit64::Default, {"dcbf", OPTYPE_DCACHE, 0, 4}}, +#endif {246, Interpreter::dcbtst, &Jit64::Default, {"dcbtst", OPTYPE_DCACHE, 0, 1}}, {278, Interpreter::dcbt, &Jit64::Default, {"dcbt", OPTYPE_DCACHE, 0, 1}}, {470, Interpreter::dcbi, &Jit64::Default, {"dcbi", OPTYPE_DCACHE, 0, 4}}, {758, Interpreter::dcba, &Jit64::Default, {"dcba", OPTYPE_DCACHE, 0, 4}}, {1014, Interpreter::dcbz, &Jit64::dcbz, {"dcbz", OPTYPE_DCACHE, 0, 4}}, +#if JITTEST + //load word + {23, Interpreter::lwzx, &Jit64::lXzx, {"lwzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {55, Interpreter::lwzux, &Jit64::lXzx, {"lwzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, + //load halfword + {279, Interpreter::lhzx, &Jit64::lXzx, {"lhzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {311, Interpreter::lhzux, &Jit64::lXzx, {"lhzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, + + //load halfword signextend + {343, Interpreter::lhax, &Jit64::lhax, {"lhax", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {375, Interpreter::lhaux, &Jit64::Default, {"lhaux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, + + //load byte + {87, Interpreter::lbzx, &Jit64::lXzx, {"lbzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {119, Interpreter::lbzux, &Jit64::lXzx, {"lbzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, +#else //load word {23, Interpreter::lwzx, &Jit64::lwzx, {"lwzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, {55, Interpreter::lwzux, &Jit64::lwzux, {"lwzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, @@ -324,7 +353,7 @@ static GekkoOPTemplate table31[] = //load byte {87, Interpreter::lbzx, &Jit64::lbzx, {"lbzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, {119, Interpreter::lbzux, &Jit64::Default, {"lbzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, - +#endif //load byte reverse {534, Interpreter::lwbrx, &Jit64::Default, {"lwbrx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, {790, Interpreter::lhbrx, &Jit64::Default, {"lhbrx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},