From ccf1cee2032fa0b419541e795c5b414e91ff00b1 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sat, 13 Apr 2013 05:00:41 +0000 Subject: [PATCH] Implement a few more store instructions on ARM --- Source/Core/Core/Src/PowerPC/JitArm32/Jit.h | 3 + .../Src/PowerPC/JitArm32/JitArm_BackPatch.cpp | 28 ++-- .../Src/PowerPC/JitArm32/JitArm_LoadStore.cpp | 124 ++++++++++++++++-- .../Src/PowerPC/JitArm32/JitArm_Tables.cpp | 6 +- 4 files changed, 141 insertions(+), 20 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h index 7067e3a3a4..b610ec1eec 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h @@ -171,6 +171,9 @@ public: void lhz(UGeckoInstruction _inst); void lwz(UGeckoInstruction _inst); void lwzx(UGeckoInstruction _inst); + void stbu(UGeckoInstruction _inst); + void sth(UGeckoInstruction _inst); + void sthu(UGeckoInstruction _inst); void stw(UGeckoInstruction _inst); void stwu(UGeckoInstruction _inst); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_BackPatch.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_BackPatch.cpp index 2da8d9056b..9d01332f57 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_BackPatch.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_BackPatch.cpp @@ -50,38 +50,48 @@ static void BackPatchError(const std::string &text, u8 *codePtr, u32 emAddress) bool DisamLoadStore(const u32 inst, ARMReg &rD, u8 &accessSize, bool &Store) { u8 op = (inst >> 20) & 0xFF; + rD = (ARMReg)((inst >> 12) & 0xF); + switch (op) { case 0x58: // STR { - rD = (ARMReg)((inst >> 12) & 0xF); Store = true; accessSize = 32; } break; case 0x59: // LDR { - rD = (ARMReg)((inst >> 12) & 0xF); Store = false; accessSize = 32; } break; - case 0x05: // LDRH + case 0x1D: // LDRH { - rD = (ARMReg)((inst >> 12) & 0xF); Store = false; accessSize = 16; } break; case 0x45 + 0x18: // LDRB { - rD = (ARMReg)((inst >> 12) & 0xF); Store = false; - accessSize = 8; + accessSize = 8; + } + break; + case 0x5C: // STRB + { + Store = true; + accessSize = 8; + } + break; + case 0x1C: // STRH + { + Store = true; + accessSize = 16; } break; - case 0x44 + 0x18: // STRB default: + printf("Op is 0x%02x\n", op); return false; } return true; @@ -110,11 +120,11 @@ const u8 *JitArm::BackPatch(u8 *codePtr, int accessType, u32 emAddress, void *ct switch (accessSize) { case 8: // 8bit - //emitter.MOVI2R(R14, (u32)&Memory::Write_U8, false); // 1-2 + emitter.MOVI2R(R14, (u32)&Memory::Write_U8, false); // 1-2 return 0; break; case 16: // 16bit - //emitter.MOVI2R(R14, (u32)&Memory::Write_U16, false); // 1-2 + emitter.MOVI2R(R14, (u32)&Memory::Write_U16, false); // 1-2 return 0; break; case 32: // 32bit diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp index 2ed961afb6..bcfc45a22c 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp @@ -36,6 +36,118 @@ #else #define FASTMEM 1 #endif +void JitArm::stbu(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStore) + ARMReg RA = gpr.R(inst.RA); + ARMReg RS = gpr.R(inst.RS); + ARMReg ValueReg = gpr.GetReg(); + ARMReg Addr = gpr.GetReg(); + ARMReg Function = gpr.GetReg(); + + MOVI2R(Addr, inst.SIMM_16); + ADD(Addr, Addr, RA); + + // Check for DSI exception prior to writing back address + LDR(Function, R9, PPCSTATE_OFF(Exceptions)); + CMP(Function, EXCEPTION_DSI); + FixupBranch DoNotWrite = B_CC(CC_EQ); + MOV(RA, Addr); + SetJumpTarget(DoNotWrite); + + MOV(ValueReg, RS); + + MOVI2R(Function, (u32)&Memory::Write_U8); + PUSH(4, R0, R1, R2, R3); + MOV(R0, ValueReg); + MOV(R1, Addr); + BL(Function); + POP(4, R0, R1, R2, R3); + + gpr.Unlock(ValueReg, Addr, Function); +} +void JitArm::sth(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStore) + + ARMReg RS = gpr.R(inst.RS); +#if 0 // FASTMEM + // R10 contains the dest address + ARMReg Value = R11; + ARMReg RA; + if (inst.RA) + RA = gpr.R(inst.RA); + MOV(Value, RS); + if (inst.RA) + { + MOVI2R(R10, inst.SIMM_16, false); + ADD(R10, R10, RA); + } + else + { + MOVI2R(R10, (u32)inst.SIMM_16, false); + NOP(1); + } + StoreFromReg(R10, Value, 16, 0); +#else + ARMReg ValueReg = gpr.GetReg(); + ARMReg Addr = gpr.GetReg(); + ARMReg Function = gpr.GetReg(); + + MOV(ValueReg, RS); + if (inst.RA) + { + MOVI2R(Addr, inst.SIMM_16); + ARMReg RA = gpr.R(inst.RA); + ADD(Addr, Addr, RA); + } + else + MOVI2R(Addr, (u32)inst.SIMM_16); + + MOVI2R(Function, (u32)&Memory::Write_U16); + PUSH(4, R0, R1, R2, R3); + MOV(R0, ValueReg); + MOV(R1, Addr); + BL(Function); + POP(4, R0, R1, R2, R3); + gpr.Unlock(ValueReg, Addr, Function); +#endif +} +void JitArm::sthu(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStore) + + ARMReg RA = gpr.R(inst.RA); + ARMReg RS = gpr.R(inst.RS); + ARMReg ValueReg = gpr.GetReg(); + ARMReg Addr = gpr.GetReg(); + ARMReg Function = gpr.GetReg(); + + MOVI2R(Addr, inst.SIMM_16); + ADD(Addr, Addr, RA); + + // Check for DSI exception prior to writing back address + LDR(Function, R9, PPCSTATE_OFF(Exceptions)); + CMP(Function, EXCEPTION_DSI); + FixupBranch DoNotWrite = B_CC(CC_EQ); + MOV(RA, Addr); + SetJumpTarget(DoNotWrite); + + MOV(ValueReg, RS); + + MOVI2R(Function, (u32)&Memory::Write_U16); + PUSH(4, R0, R1, R2, R3); + MOV(R0, ValueReg); + MOV(R1, Addr); + BL(Function); + POP(4, R0, R1, R2, R3); + + gpr.Unlock(ValueReg, Addr, Function); +} + void JitArm::stw(UGeckoInstruction inst) { INSTRUCTION_START @@ -98,8 +210,7 @@ void JitArm::stwu(UGeckoInstruction inst) MOVI2R(Addr, inst.SIMM_16); ADD(Addr, Addr, RA); - // Check and set the update before writing since calling a function can - // mess with the "special registers R11+ which may cause some issues. + // Check for DSI exception prior to writing back address LDR(Function, R9, PPCSTATE_OFF(Exceptions)); CMP(Function, EXCEPTION_DSI); FixupBranch DoNotWrite = B_CC(CC_EQ); @@ -144,10 +255,10 @@ void JitArm::StoreFromReg(ARMReg dest, ARMReg value, int accessSize, s32 offset) STR(value, dest); // 8 break; case 16: - // Not implemented + STRH(value, dest); break; case 8: - // Not implemented + STRB(value, dest); break; } gpr.Unlock(rA); @@ -256,14 +367,11 @@ void JitArm::lhz(UGeckoInstruction inst) if (inst.RA) { ARMReg RA = gpr.R(inst.RA); - printf("lhz jump to here: 0x%08x\n", (u32)GetCodePtr()); MOV(R10, RA); // - 4 } else - { - printf("lhz jump to here: 0x%08x\n", (u32)GetCodePtr()); MOV(R10, 0); // - 4 - } + LoadToReg(RD, R10, 16, (u32)inst.SIMM_16); #else diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp index 1929705df2..7a873f724b 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp @@ -87,12 +87,12 @@ static GekkoOPTemplate primarytable[] = {42, &JitArm::Default}, //"lha", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, {43, &JitArm::Default}, //"lhau", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, - {44, &JitArm::Default}, //"sth", OPTYPE_STORE, FL_IN_A | FL_IN_S}}, - {45, &JitArm::Default}, //"sthu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, + {44, &JitArm::sth}, //"sth", OPTYPE_STORE, FL_IN_A | FL_IN_S}}, + {45, &JitArm::sthu}, //"sthu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, {36, &JitArm::stw}, //"stw", OPTYPE_STORE, FL_IN_A | FL_IN_S}}, {37, &JitArm::stwu}, //"stwu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, {38, &JitArm::Default}, //"stb", OPTYPE_STORE, FL_IN_A | FL_IN_S}}, - {39, &JitArm::Default}, //"stbu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, + {39, &JitArm::stbu}, //"stbu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, {46, &JitArm::Default}, //"lmw", OPTYPE_SYSTEM, FL_EVIL, 10}}, {47, &JitArm::Default}, //"stmw", OPTYPE_SYSTEM, FL_EVIL, 10}},