diff --git a/Source/Core/Core/PowerPC/Jit64IL/JitIL_Tables.cpp b/Source/Core/Core/PowerPC/Jit64IL/JitIL_Tables.cpp index 19df5e1617..a36a86aea1 100644 --- a/Source/Core/Core/PowerPC/Jit64IL/JitIL_Tables.cpp +++ b/Source/Core/Core/PowerPC/Jit64IL/JitIL_Tables.cpp @@ -72,7 +72,7 @@ static GekkoOPTemplate primarytable[] = {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}}, - {43, &JitIL::FallBackToInterpreter}, //"lhau", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, + {43, &JitIL::lhau}, //"lhau", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, {44, &JitIL::stX}, //"sth", OPTYPE_STORE, FL_IN_A | FL_IN_S}}, {45, &JitIL::stX}, //"sthu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, @@ -85,14 +85,14 @@ static GekkoOPTemplate primarytable[] = {47, &JitIL::stmw}, //"stmw", OPTYPE_SYSTEM, FL_EVIL, 10}}, {48, &JitIL::lfs}, //"lfs", OPTYPE_LOADFP, FL_IN_A}}, - {49, &JitIL::FallBackToInterpreter}, //"lfsu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}}, + {49, &JitIL::lfsu}, //"lfsu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}}, {50, &JitIL::lfd}, //"lfd", OPTYPE_LOADFP, FL_IN_A}}, - {51, &JitIL::FallBackToInterpreter}, //"lfdu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}}, + {51, &JitIL::lfdu}, //"lfdu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}}, {52, &JitIL::stfs}, //"stfs", OPTYPE_STOREFP, FL_IN_A}}, {53, &JitIL::stfs}, //"stfsu", OPTYPE_STOREFP, FL_OUT_A | FL_IN_A}}, {54, &JitIL::stfd}, //"stfd", OPTYPE_STOREFP, FL_IN_A}}, - {55, &JitIL::FallBackToInterpreter}, //"stfdu", OPTYPE_STOREFP, FL_OUT_A | FL_IN_A}}, + {55, &JitIL::stfd}, //"stfdu", OPTYPE_STOREFP, FL_OUT_A | FL_IN_A}}, {56, &JitIL::psq_l}, //"psq_l", OPTYPE_PS, FL_IN_A}}, {57, &JitIL::psq_l}, //"psq_lu", OPTYPE_PS, FL_OUT_A | FL_IN_A}}, @@ -216,7 +216,7 @@ static GekkoOPTemplate table31[] = //load halfword signextend {343, &JitIL::lhax}, //"lhax", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, - {375, &JitIL::FallBackToInterpreter}, //"lhaux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, + {375, &JitIL::lhaux}, //"lhaux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, //load byte {87, &JitIL::lXzx}, //"lbzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, diff --git a/Source/Core/Core/PowerPC/JitILCommon/JitILBase.h b/Source/Core/Core/PowerPC/JitILCommon/JitILBase.h index 70bd92f41c..84aa9b04af 100644 --- a/Source/Core/Core/PowerPC/JitILCommon/JitILBase.h +++ b/Source/Core/Core/PowerPC/JitILCommon/JitILBase.h @@ -53,6 +53,7 @@ public: // LoadStore void lXzx(UGeckoInstruction inst); void lhax(UGeckoInstruction inst); + void lhaux(UGeckoInstruction inst); void stXx(UGeckoInstruction inst); void lmw(UGeckoInstruction inst); void stmw(UGeckoInstruction inst); @@ -60,6 +61,7 @@ public: void lXz(UGeckoInstruction inst); void lbzu(UGeckoInstruction inst); void lha(UGeckoInstruction inst); + void lhau(UGeckoInstruction inst); // System Registers void mtspr(UGeckoInstruction inst); @@ -112,7 +114,9 @@ public: void cntlzwx(UGeckoInstruction inst); void lfs(UGeckoInstruction inst); + void lfsu(UGeckoInstruction inst); void lfd(UGeckoInstruction inst); + void lfdu(UGeckoInstruction inst); void stfd(UGeckoInstruction inst); void stfs(UGeckoInstruction inst); void stfsx(UGeckoInstruction inst); diff --git a/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStore.cpp b/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStore.cpp index 58e886bb9d..46ca149d65 100644 --- a/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStore.cpp @@ -20,6 +20,21 @@ void JitILBase::lhax(UGeckoInstruction inst) ibuild.EmitStoreGReg(val, inst.RD); } +void JitILBase::lhaux(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITLoadStoreOff); + FALLBACK_IF(js.memcheck); + + IREmitter::InstLoc addr = ibuild.EmitLoadGReg(inst.RB); + addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA)); + + IREmitter::InstLoc val = ibuild.EmitLoad16(addr); + val = ibuild.EmitSExt16(val); + ibuild.EmitStoreGReg(val, inst.RD); + ibuild.EmitStoreGReg(addr, inst.RA); +} + void JitILBase::lXz(UGeckoInstruction inst) { INSTRUCTION_START @@ -98,6 +113,22 @@ void JitILBase::lha(UGeckoInstruction inst) ibuild.EmitStoreGReg(val, inst.RD); } +void JitILBase::lhau(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITLoadStoreOff); + FALLBACK_IF(js.memcheck); + + IREmitter::InstLoc addr = ibuild.EmitIntConst((s32)inst.SIMM_16); + + addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA)); + + IREmitter::InstLoc val = ibuild.EmitLoad16(addr); + val = ibuild.EmitSExt16(val); + ibuild.EmitStoreGReg(val, inst.RD); + ibuild.EmitStoreGReg(addr, inst.RA); +} + void JitILBase::lXzx(UGeckoInstruction inst) { INSTRUCTION_START diff --git a/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStoreFloating.cpp b/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStoreFloating.cpp index 3a2f45d5e8..5401846467 100644 --- a/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStoreFloating.cpp +++ b/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStoreFloating.cpp @@ -15,16 +15,29 @@ void JitILBase::lfs(UGeckoInstruction inst) JITDISABLE(bJITLoadStoreFloatingOff); FALLBACK_IF(js.memcheck); - IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16), val; + IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16); if (inst.RA) addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA)); - val = ibuild.EmitDupSingleToMReg(ibuild.EmitLoadSingle(addr)); - ibuild.EmitStoreFReg(val, inst.RD); - return; + IREmitter::InstLoc val = ibuild.EmitDupSingleToMReg(ibuild.EmitLoadSingle(addr)); + ibuild.EmitStoreFReg(val, inst.FD); } +void JitILBase::lfsu(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITLoadStoreFloatingOff); + FALLBACK_IF(js.memcheck); + + IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16); + + addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA)); + + IREmitter::InstLoc val = ibuild.EmitDupSingleToMReg(ibuild.EmitLoadSingle(addr)); + ibuild.EmitStoreFReg(val, inst.FD); + ibuild.EmitStoreGReg(addr, inst.RA); +} void JitILBase::lfd(UGeckoInstruction inst) { @@ -32,16 +45,31 @@ void JitILBase::lfd(UGeckoInstruction inst) JITDISABLE(bJITLoadStoreFloatingOff); FALLBACK_IF(js.memcheck); - IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16), val; + IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16); if (inst.RA) addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA)); - val = ibuild.EmitLoadFReg(inst.RD); + IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.RD); val = ibuild.EmitInsertDoubleInMReg(ibuild.EmitLoadDouble(addr), val); ibuild.EmitStoreFReg(val, inst.RD); } +void JitILBase::lfdu(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITLoadStoreFloatingOff); + FALLBACK_IF(js.memcheck); + + IREmitter::InstLoc addr = ibuild.EmitIntConst(inst.SIMM_16); + + addr = ibuild.EmitAdd(addr, ibuild.EmitLoadGReg(inst.RA)); + + IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FD); + val = ibuild.EmitInsertDoubleInMReg(ibuild.EmitLoadDouble(addr), val); + ibuild.EmitStoreFReg(val, inst.FD); + ibuild.EmitStoreGReg(addr, inst.RA); +} void JitILBase::stfd(UGeckoInstruction inst) {