diff --git a/Source/Core/Common/Src/ArmEmitter.cpp b/Source/Core/Common/Src/ArmEmitter.cpp index 3b3bf7c550..a56724b78b 100644 --- a/Source/Core/Common/Src/ArmEmitter.cpp +++ b/Source/Core/Common/Src/ArmEmitter.cpp @@ -533,15 +533,15 @@ void ARMXEmitter::MRS (ARMReg dest) Write32(condition | (16 << 20) | (15 << 16) | (dest << 12)); } -void ARMXEmitter::WriteStoreOp(u32 op, ARMReg dest, ARMReg src, Operand2 op2) +void ARMXEmitter::WriteStoreOp(u32 op, ARMReg dest, ARMReg src, s16 op2) { - if (op2.GetData() == 0) // set the preindex bit, but not the W bit! - Write32(condition | 0x01800000 | (op << 20) | (dest << 16) | (src << 12) | op2.Imm12()); - else - Write32(condition | (op << 20) | (3 << 23) | (dest << 16) | (src << 12) | op2.Imm12()); + bool Index = op2 != 0 ? true : false; + bool Add = op2 >= 0 ? true : false; + u32 imm = abs(op2); + Write32(condition | (op << 20) | (Index << 24) | (Add << 23) | (dest << 16) | (src << 12) | imm); } -void ARMXEmitter::STR (ARMReg dest, ARMReg src, Operand2 op) { WriteStoreOp(0x40, dest, src, op);} -void ARMXEmitter::STRB(ARMReg dest, ARMReg src, Operand2 op) { WriteStoreOp(0x44, dest, src, op);} +void ARMXEmitter::STR (ARMReg dest, ARMReg src, s16 op) { WriteStoreOp(0x40, dest, src, op);} +void ARMXEmitter::STRB(ARMReg dest, ARMReg src, s16 op) { WriteStoreOp(0x44, dest, src, op);} void ARMXEmitter::STR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add) { Write32(condition | (0x60 << 20) | (Index << 24) | (Add << 23) | (dest << 16) | (base << 12) | offset); @@ -564,13 +564,13 @@ void ARMXEmitter::SVC(Operand2 op) Write32(condition | (0x0F << 24) | op.Imm24()); } -void ARMXEmitter::LDR (ARMReg dest, ARMReg src, Operand2 op) { WriteStoreOp(0x41, src, dest, op);} +void ARMXEmitter::LDR (ARMReg dest, ARMReg src, s16 op) { WriteStoreOp(0x41, src, dest, op);} void ARMXEmitter::LDRH(ARMReg dest, ARMReg src, Operand2 op) { u8 Imm = op.Imm8(); Write32(condition | (0x05 << 20) | (src << 16) | (dest << 12) | ((Imm >> 4) << 8) | (0xB << 4) | (Imm & 0x0F)); } -void ARMXEmitter::LDRB(ARMReg dest, ARMReg src, Operand2 op) { WriteStoreOp(0x45, src, dest, op);} +void ARMXEmitter::LDRB(ARMReg dest, ARMReg src, s16 op) { WriteStoreOp(0x45, src, dest, op);} void ARMXEmitter::LDR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add) { @@ -661,14 +661,18 @@ void ARMXEmitter::VSUB(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) // VFP Specific -void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, u16 offset) +void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, s16 offset) { _assert_msg_(DYNA_REC, Dest >= S0 && Dest <= D31, "Passed Invalid dest register to VLDR"); _assert_msg_(DYNA_REC, Base <= R15, "Passed invalid Base register to VLDR"); - _assert_msg_(DYNA_REC, (offset & 0xC03) == 0, "VLDR: Offset needs to be word aligned and small enough"); - if (offset & 0xC03) { - ERROR_LOG(DYNA_REC, "VLDR: Bad offset %08x", offset); + bool Add = offset >= 0 ? true : false; + u32 imm = abs(offset); + + _assert_msg_(DYNA_REC, (imm & 0xC03) == 0, "VLDR: Offset needs to be word aligned and small enough"); + + if (imm & 0xC03) { + ERROR_LOG(DYNA_REC, "VLDR: Bad offset %08x", imm); } bool single_reg = Dest < D0; @@ -677,24 +681,28 @@ void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, u16 offset) if (single_reg) { - Write32(NO_COND | (0x1B << 23) | ((Dest & 0x1) << 22) | (1 << 20) | (Base << 16) \ - | ((Dest & 0x1E) << 11) | (10 << 8) | (offset >> 2)); + Write32(NO_COND | (0xD << 24) | (Add << 23) | ((Dest & 0x1) << 22) | (1 << 20) | (Base << 16) \ + | ((Dest & 0x1E) << 11) | (10 << 8) | (imm >> 2)); } else { - Write32(NO_COND | (0x1B << 23) | ((Dest & 0x10) << 18) | (1 << 20) | (Base << 16) \ - | ((Dest & 0xF) << 12) | (11 << 8) | (offset >> 2)); + Write32(NO_COND | (0xD << 24) | (Add << 23) | ((Dest & 0x10) << 18) | (1 << 20) | (Base << 16) \ + | ((Dest & 0xF) << 12) | (11 << 8) | (imm >> 2)); } } -void ARMXEmitter::VSTR(ARMReg Src, ARMReg Base, u16 offset) +void ARMXEmitter::VSTR(ARMReg Src, ARMReg Base, s16 offset) { _assert_msg_(DYNA_REC, Src >= S0 && Src <= D31, "Passed invalid src register to VSTR"); _assert_msg_(DYNA_REC, Base <= R15, "Passed invalid base register to VSTR"); - _assert_msg_(DYNA_REC, (offset & 0xC03) == 0, "VSTR: Offset needs to be word aligned"); - if (offset & 0xC03) { - ERROR_LOG(DYNA_REC, "VSTR: Bad offset %08x", offset); + bool Add = offset >= 0 ? true : false; + u32 imm = abs(offset); + + _assert_msg_(DYNA_REC, (imm & 0xC03) == 0, "VSTR: Offset needs to be word aligned and small enough"); + + if (imm & 0xC03) { + ERROR_LOG(DYNA_REC, "VSTR: Bad offset %08x", imm); } bool single_reg = Src < D0; @@ -703,14 +711,14 @@ void ARMXEmitter::VSTR(ARMReg Src, ARMReg Base, u16 offset) if (single_reg) { - Write32(NO_COND | (0x1B << 23) | ((Src & 0x1) << 22) | (Base << 16) \ - | ((Src & 0x1E) << 11) | (10 << 8) | (offset >> 2)); + Write32(NO_COND | (0xD << 24) | (Add << 23) | ((Src & 0x1) << 22) | (Base << 16) \ + | ((Src & 0x1E) << 11) | (10 << 8) | (imm >> 2)); } else { - Write32(NO_COND | (0x1B << 23) | ((Src & 0x10) << 18) | (Base << 16) \ - | ((Src & 0xF) << 12) | (11 << 8) | (offset >> 2)); + Write32(NO_COND | (0xD << 24) | (Add << 23) | ((Src & 0x10) << 18) | (Base << 16) \ + | ((Src & 0xF) << 12) | (11 << 8) | (imm >> 2)); } } void ARMXEmitter::VCMP(ARMReg Vd, ARMReg Vm) diff --git a/Source/Core/Common/Src/ArmEmitter.h b/Source/Core/Common/Src/ArmEmitter.h index a3ff7d25ae..d3155285f3 100644 --- a/Source/Core/Common/Src/ArmEmitter.h +++ b/Source/Core/Common/Src/ArmEmitter.h @@ -208,7 +208,7 @@ public: Value = base; Type = TYPE_IMMSREG; } - const u32 GetData() + u32 GetData() { switch(Type) { @@ -225,45 +225,45 @@ public: return 0; } } - const u32 IMMSR() // IMM shifted register + u32 IMMSR() // IMM shifted register { _assert_msg_(DYNA_REC, Type == TYPE_IMMSREG, "IMMSR must be imm shifted register"); return ((IndexOrShift & 0x1f) << 7 | (Shift << 5) | Value); } - const u32 RSR() // Register shifted register + u32 RSR() // Register shifted register { _assert_msg_(DYNA_REC, Type == TYPE_RSR, "RSR must be RSR Of Course"); return (IndexOrShift << 8) | (Shift << 5) | 0x10 | Value; } - const u32 Rm() + u32 Rm() { _assert_msg_(DYNA_REC, Type == TYPE_REG, "Rm must be with Reg"); return Value; } - const u32 Imm5() + u32 Imm5() { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm5 not IMM value"); return ((Value & 0x0000001F) << 7); } - const u32 Imm8() + u32 Imm8() { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm8Rot not IMM value"); return Value & 0xFF; } - const u32 Imm8Rot() // IMM8 with Rotation + u32 Imm8Rot() // IMM8 with Rotation { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm8Rot not IMM value"); _assert_msg_(DYNA_REC, (Rotation & 0xE1) != 0, "Invalid Operand2: immediate rotation %u", Rotation); return (1 << 25) | (Rotation << 7) | (Value & 0x000000FF); } - const u32 Imm12() + u32 Imm12() { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm12 not IMM"); return (Value & 0x00000FFF); } - const u32 Imm12Mod() + u32 Imm12Mod() { // This is a IMM12 with the top four bits being rotation and the // bottom eight being a IMM. This is for instructions that need to @@ -273,32 +273,32 @@ public: _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm12Mod not IMM"); return ((Rotation & 0xF) << 8) | (Value & 0xFF); } - const u32 Imm16() + u32 Imm16() { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm16 not IMM"); return ( (Value & 0xF000) << 4) | (Value & 0x0FFF); } - const u32 Imm16Low() + u32 Imm16Low() { return Imm16(); } - const u32 Imm16High() // Returns high 16bits + u32 Imm16High() // Returns high 16bits { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm16 not IMM"); return ( ((Value >> 16) & 0xF000) << 4) | ((Value >> 16) & 0x0FFF); } - const u32 Imm24() + u32 Imm24() { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm16 not IMM"); return (Value & 0x0FFFFFFF); } // NEON and ASIMD specific - const u32 Imm8ASIMD() + u32 Imm8ASIMD() { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm8ASIMD not IMM"); return ((Value & 0x80) << 17) | ((Value & 0x70) << 12) | (Value & 0xF); } - const u32 Imm8VFP() + u32 Imm8VFP() { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm8VFP not IMM"); return ((Value & 0xF0) << 12) | (Value & 0xF); @@ -337,7 +337,7 @@ private: u8 *lastCacheFlushEnd; u32 condition; - void WriteStoreOp(u32 op, ARMReg dest, ARMReg src, Operand2 op2); + void WriteStoreOp(u32 op, ARMReg dest, ARMReg src, s16 op2); void WriteRegStoreOp(u32 op, ARMReg dest, bool WriteBack, u16 RegList); void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, ARMReg op2); void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, Operand2 op2); @@ -467,16 +467,16 @@ public: void MRS (ARMReg dest); // Memory load/store operations - void LDR (ARMReg dest, ARMReg src, Operand2 op2 = 0); + void LDR (ARMReg dest, ARMReg src, s16 op2 = 0); // Offset adds to the base register in LDR void LDR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); void LDRH(ARMReg dest, ARMReg src, Operand2 op = 0); - void LDRB(ARMReg dest, ARMReg src, Operand2 op2 = 0); - void STR (ARMReg dest, ARMReg src, Operand2 op2 = 0); + void LDRB(ARMReg dest, ARMReg src, s16 op2 = 0); + void STR (ARMReg dest, ARMReg src, s16 op2 = 0); // Offset adds on to the destination register in STR void STR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); - void STRB(ARMReg dest, ARMReg src, Operand2 op2 = 0); + void STRB(ARMReg dest, ARMReg src, s16 op2 = 0); void STMFD(ARMReg dest, bool WriteBack, const int Regnum, ...); void LDMFD(ARMReg dest, bool WriteBack, const int Regnum, ...); @@ -499,8 +499,8 @@ public: void VSUB(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm); // VFP Only - void VLDR(ARMReg Dest, ARMReg Base, u16 offset); - void VSTR(ARMReg Src, ARMReg Base, u16 offset); + void VLDR(ARMReg Dest, ARMReg Base, s16 offset); + void VSTR(ARMReg Src, ARMReg Base, s16 offset); void VCMP(ARMReg Vd, ARMReg Vm); // Compares against zero void VCMP(ARMReg Vd); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp index e4b0ffd714..3b2ee45111 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp @@ -100,7 +100,7 @@ void JitArm::HLEFunction(UGeckoInstruction _inst) MOVI2R(R1, _inst.hex); QuickCallFunction(R14, (void*)&HLE::Execute); ARMReg rA = gpr.GetReg(); - LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, npc)); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, npc)); WriteExitDestInR(rA); } @@ -161,7 +161,7 @@ void JitArm::DoDownCount() } void JitArm::WriteExitDestInR(ARMReg Reg) { - STR(R9, Reg, STRUCT_OFF(PowerPC::ppcState, pc)); + STR(R9, Reg, PPCSTATE_OFF(PowerPC::ppcState, pc)); Cleanup(); DoDownCount(); MOVI2R(Reg, (u32)asm_routines.dispatcher); @@ -170,7 +170,7 @@ void JitArm::WriteExitDestInR(ARMReg Reg) } void JitArm::WriteRfiExitDestInR(ARMReg Reg) { - STR(R9, Reg, STRUCT_OFF(PowerPC::ppcState, pc)); + STR(R9, Reg, PPCSTATE_OFF(PowerPC::ppcState, pc)); Cleanup(); DoDownCount(); @@ -209,7 +209,7 @@ void JitArm::WriteExit(u32 destination, int exit_num) { ARMReg A = gpr.GetReg(false); MOVI2R(A, destination); - STR(R9, A, STRUCT_OFF(PowerPC::ppcState, pc)); + STR(R9, A, PPCSTATE_OFF(PowerPC::ppcState, pc)); MOVI2R(A, (u32)asm_routines.dispatcher); B(A); } @@ -303,7 +303,6 @@ void JitArm::Break(UGeckoInstruction inst) const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlock *b) { int blockSize = code_buf->GetSize(); - // Memory exception on instruction fetch bool memory_exception = false; @@ -382,10 +381,10 @@ const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlo ARMReg C = gpr.GetReg(); Operand2 Shift(2, 10); // 1 << 13 MOVI2R(C, js.blockStart); // R3 - LDR(A, R9, STRUCT_OFF(PowerPC::ppcState, msr)); + LDR(A, R9, PPCSTATE_OFF(PowerPC::ppcState, msr)); TST(A, Shift); FixupBranch b1 = B_CC(CC_NEQ); - STR(R9, C, STRUCT_OFF(PowerPC::ppcState, pc)); + STR(R9, C, PPCSTATE_OFF(PowerPC::ppcState, pc)); MOVI2R(A, (u32)asm_routines.fpException); B(A); SetJumpTarget(b1); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h index c736ae77a1..1dde0fa55f 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h @@ -47,7 +47,7 @@ if (Core::g_CoreStartupParameter.bJITOff || \ Core::g_CoreStartupParameter.bJIT##type##Off) \ {Default(inst); return;} - +#define PPCSTATE_OFF(str, elem) ((s32)STRUCT_OFF(PowerPC::ppcState, elem) - (s32)STRUCT_OFF(PowerPC::ppcState, spr[0])) class JitArm : public JitBase, public ArmGen::ARMXCodeBlock { private: diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.cpp index 296ca736a9..dd85699a6d 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.cpp @@ -36,10 +36,9 @@ using namespace ArmGen; void JitArmBlockCache::WriteDestroyBlock(const u8* location, u32 address) { ARMXEmitter emit((u8 *)location); - emit.MOVI2R(R10, (u32)&PC); emit.MOVI2R(R11, address); emit.MOVI2R(R12, (u32)jit->GetAsmRoutines()->dispatcher); - emit.STR(R10, R11); + emit.STR(R9, R11, PPCSTATE_OFF(PowerPC::ppcState, pc)); emit.B(R12); } diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp index 27d5c23141..1c401771d7 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp @@ -50,9 +50,9 @@ void JitArm::sc(UGeckoInstruction inst) ARMABI_MOVI2M((u32)&PC, js.compilerPC + 4); // Destroys R12 and R14 ARMReg rA = gpr.GetReg(); - LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); ORR(rA, rA, EXCEPTION_SYSCALL); - STR(R9, rA, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + STR(R9, rA, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); gpr.Unlock(rA); WriteExceptionExit(); @@ -78,25 +78,22 @@ void JitArm::rfi(UGeckoInstruction inst) ARMReg rB = gpr.GetReg(); ARMReg rC = gpr.GetReg(); ARMReg rD = gpr.GetReg(); - MOVI2R(rA, (u32)&MSR); MOVI2R(rB, (~mask) & clearMSR13); MOVI2R(rC, mask & clearMSR13); - LDR(rD, rA); + LDR(rD, R9, PPCSTATE_OFF(PowerPC::ppcState, msr)); AND(rD, rD, rB); // rD = Masked MSR - STR(rA, rD); + STR(R9, rD, PPCSTATE_OFF(PowerPC::ppcState, msr)); - MOVI2R(rB, (u32)&SRR1); - LDR(rB, rB); // rB contains SRR1 here + LDR(rB, R9, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_SRR1])); // rB contains SRR1 here AND(rB, rB, rC); // rB contains masked SRR1 here ORR(rB, rD, rB); // rB = Masked MSR OR masked SRR1 - STR(rA, rB); // STR rB in to rA + STR(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, msr)); // STR rB in to rA - MOVI2R(rA, (u32)&SRR0); - LDR(rA, rA); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_SRR0])); gpr.Unlock(rB, rC, rD); WriteRfiExitDestInR(rA); // rA gets unlocked here @@ -116,8 +113,13 @@ void JitArm::bx(UGeckoInstruction inst) // We must always process the following sentence // even if the blocks are merged by PPCAnalyst::Flatten(). if (inst.LK) - ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); - + { + ARMReg rA = gpr.GetReg(false); + u32 Jumpto = js.compilerPC + 4; + MOVI2R(rA, Jumpto); + STR(R9, rA, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_LR])); + //ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); + } // If this is not the last instruction of a block, // we will skip the rest process. // Because PPCAnalyst::Flatten() merged the blocks. @@ -164,10 +166,9 @@ void JitArm::bcx(UGeckoInstruction inst) FixupBranch pCTRDontBranch; if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) // Decrement and test CTR { - MOVI2R(rA, (u32)&CTR); - LDR(rB, rA); + LDR(rB, R9, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_CTR])); SUBS(rB, rB, 1); - STR(rA, rB); + STR(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_CTR])); //SUB(32, M(&CTR), Imm8(1)); if (inst.BO & BO_BRANCH_IF_CTR_0) @@ -179,7 +180,7 @@ void JitArm::bcx(UGeckoInstruction inst) FixupBranch pConditionDontBranch; if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) // Test a CR bit { - LDRB(rA, R9, STRUCT_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); + LDRB(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); TST(rA, 8 >> (inst.BI & 3)); //TEST(8, M(&PowerPC::ppcState.cr_fast[inst.BI >> 2]), Imm8(8 >> (inst.BI & 3))); @@ -188,10 +189,15 @@ void JitArm::bcx(UGeckoInstruction inst) else pConditionDontBranch = B_CC(CC_NEQ); // Not Zero } - gpr.Unlock(rA, rB); if (inst.LK) - ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); // Careful, destroys R14, R12 - + { + u32 Jumpto = js.compilerPC + 4; + MOVI2R(rB, Jumpto); + STR(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_LR])); + //ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); // Careful, destroys R14, R12 + } + gpr.Unlock(rA, rB); + u32 destination; if(inst.AA) destination = SignExt16(inst.BD << 2); @@ -222,13 +228,18 @@ void JitArm::bcctrx(UGeckoInstruction inst) // BO_2 == 1z1zz -> b always //NPC = CTR & 0xfffffffc; - if(inst.LK_3) - ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); - MOVI2R(rA, (u32)&CTR); + + if(inst.LK_3) + { + u32 Jumpto = js.compilerPC + 4; + MOVI2R(rA, Jumpto); + STR(R9, rA, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_LR])); + // ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); + } MVN(rB, 0x3); // 0xFFFFFFFC - LDR(rA, rA); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_CTR])); AND(rA, rA, rB); gpr.Unlock(rB); WriteExitDestInR(rA); @@ -242,7 +253,7 @@ void JitArm::bcctrx(UGeckoInstruction inst) ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); - LDRB(rA, R9, STRUCT_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); + LDRB(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); TST(rA, 8 >> (inst.BI & 3)); CCFlags branch; if (inst.BO_2 & BO_BRANCH_IF_TRUE) @@ -251,17 +262,14 @@ void JitArm::bcctrx(UGeckoInstruction inst) branch = CC_NEQ; FixupBranch b = B_CC(branch); - MOVI2R(rA, (u32)&CTR); - LDR(rA, rA); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_CTR])); MVN(rB, 0x3); // 0xFFFFFFFC AND(rA, rA, rB); if (inst.LK_3){ - ARMReg rC = gpr.GetReg(false); u32 Jumpto = js.compilerPC + 4; - MOVI2R(rB, (u32)&LR); - MOVI2R(rC, Jumpto); - STR(rB, rC); + MOVI2R(rB, Jumpto); + STR(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_LR])); //ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); } gpr.Unlock(rB); // rA gets unlocked in WriteExitDestInR @@ -279,7 +287,11 @@ void JitArm::bclrx(UGeckoInstruction inst) (inst.BO & (1 << 4)) && (inst.BO & (1 << 2))) { if (inst.LK) { - ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); + ARMReg rA = gpr.GetReg(false); + u32 Jumpto = js.compilerPC + 4; + MOVI2R(rA, Jumpto); + STR(R9, rA, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_LR])); + // ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); } return; } @@ -291,10 +303,9 @@ void JitArm::bclrx(UGeckoInstruction inst) FixupBranch pCTRDontBranch; if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) // Decrement and test CTR { - MOVI2R(rA, (u32)&CTR); - LDR(rB, rA); + LDR(rB, R9, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_CTR])); SUBS(rB, rB, 1); - STR(rA, rB); + STR(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_CTR])); //SUB(32, M(&CTR), Imm8(1)); if (inst.BO & BO_BRANCH_IF_CTR_0) @@ -306,7 +317,7 @@ void JitArm::bclrx(UGeckoInstruction inst) FixupBranch pConditionDontBranch; if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) // Test a CR bit { - LDRB(rA, R9, STRUCT_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); + LDRB(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); TST(rA, 8 >> (inst.BI & 3)); //TEST(8, M(&PowerPC::ppcState.cr_fast[inst.BI >> 2]), Imm8(8 >> (inst.BI & 3))); if (inst.BO & BO_BRANCH_IF_TRUE) // Conditional branch @@ -324,16 +335,13 @@ void JitArm::bclrx(UGeckoInstruction inst) //MOV(32, R(EAX), M(&LR)); //AND(32, R(EAX), Imm32(0xFFFFFFFC)); - MOVI2R(rA, (u32)&LR); MVN(rB, 0x3); // 0xFFFFFFFC - LDR(rA, rA); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_LR])); AND(rA, rA, rB); if (inst.LK){ - ARMReg rC = gpr.GetReg(false); u32 Jumpto = js.compilerPC + 4; - MOVI2R(rB, (u32)&LR); - MOVI2R(rC, Jumpto); - STR(rB, rC); + MOVI2R(rB, Jumpto); + STR(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_LR])); //ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); } gpr.Unlock(rB); // rA gets unlocked in WriteExitDestInR diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp index 753568c9d3..4b77830ef3 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp @@ -40,7 +40,7 @@ void JitArm::GenerateRC(int cr) { SetCC(CC_MI); MOV(rB, 0x8); // Result < 0 SetCC(); - STRB(R9, rB, STRUCT_OFF(PowerPC::ppcState, cr_fast) + cr); + STRB(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, cr_fast) + cr); gpr.Unlock(rB); } void JitArm::ComputeRC(int cr) { @@ -51,7 +51,7 @@ void JitArm::ComputeRC(int cr) { SetCC(CC_GT); MOV(rB, 0x4); // Result > 0 SetCC(); - STRB(R9, rB, STRUCT_OFF(PowerPC::ppcState, cr_fast) + cr); + STRB(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, cr_fast) + cr); gpr.Unlock(rB); } @@ -232,7 +232,7 @@ void JitArm::cmpli(UGeckoInstruction inst) SetCC(CC_HI); MOV(rA, 0x4); // Result > 0 SetCC(); - STRB(R9, rA, STRUCT_OFF(PowerPC::ppcState, cr_fast) + crf); + STRB(R9, rA, PPCSTATE_OFF(PowerPC::ppcState, cr_fast) + crf); gpr.Unlock(rA); } diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp index 80c8a96cbb..dd9f7cd807 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp @@ -100,7 +100,7 @@ void JitArm::stwu(UGeckoInstruction inst) // Check and set the update before writing since calling a function can // mess with the "special registers R11+ which may cause some issues. - LDR(Function, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(Function, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); CMP(Function, EXCEPTION_DSI); FixupBranch DoNotWrite = B_CC(CC_EQ); MOV(RA, Addr); @@ -198,7 +198,7 @@ void JitArm::lbz(UGeckoInstruction inst) ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); ARMReg RD = gpr.R(inst.RD); - LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); CMP(rA, EXCEPTION_DSI); FixupBranch DoNotLoad = B_CC(CC_EQ); #if FASTMEM @@ -245,7 +245,7 @@ void JitArm::lhz(UGeckoInstruction inst) ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); ARMReg RD = gpr.R(inst.RD); - LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); CMP(rA, EXCEPTION_DSI); FixupBranch DoNotLoad = B_CC(CC_EQ); #if 0 // FASTMEM @@ -295,7 +295,7 @@ void JitArm::lwz(UGeckoInstruction inst) ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); ARMReg RD = gpr.R(inst.RD); - LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); CMP(rA, EXCEPTION_DSI); FixupBranch DoNotLoad = B_CC(CC_EQ); @@ -369,7 +369,7 @@ void JitArm::lwzx(UGeckoInstruction inst) ARMReg RB = gpr.R(inst.RB); ARMReg RD = gpr.R(inst.RD); - LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); CMP(rA, EXCEPTION_DSI); FixupBranch DoNotLoad = B_CC(CC_EQ); #if FASTMEM diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp index d9e320ab22..5134dd9e88 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp @@ -40,7 +40,7 @@ void JitArm::lfs(UGeckoInstruction inst) ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); - LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); CMP(rA, EXCEPTION_DSI); FixupBranch DoNotLoad = B_CC(CC_EQ); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp index a99114df67..512240537a 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp @@ -70,9 +70,7 @@ void JitArm::mtspr(UGeckoInstruction inst) } // OK, this is easy. - ARMReg rA = gpr.GetReg(false); - MOVI2R(rA, (u32)&PowerPC::ppcState.spr); - STR(rA, RD, iIndex * 4); + STR(R9, RD, PPCSTATE_OFF(PowerPC::ppcState, spr) + iIndex * 4); } void JitArm::mfspr(UGeckoInstruction inst) @@ -91,9 +89,7 @@ void JitArm::mfspr(UGeckoInstruction inst) Default(inst); return; default: - ARMReg rA = gpr.GetReg(false); - MOVI2R(rA, (u32)&PowerPC::ppcState.spr); - LDR(RD, rA, iIndex * 4); + LDR(RD, R9, PPCSTATE_OFF(PowerPC::ppcState, spr) + iIndex * 4); break; } } @@ -103,9 +99,6 @@ void JitArm::mtmsr(UGeckoInstruction inst) // Don't interpret this, if we do we get thrown out //JITDISABLE(SystemRegisters) - ARMReg rA = gpr.GetReg(); - MOVI2R(rA, (u32)&MSR); - STR(rA, gpr.R(inst.RS)); - gpr.Unlock(rA); + STR(R9, gpr.R(inst.RS), PPCSTATE_OFF(PowerPC::ppcState, msr)); WriteExit(js.compilerPC + 4, 0); } diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp index e45058b57b..5084ab44d6 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp @@ -47,7 +47,7 @@ void JitArmAsmRoutineManager::Generate() PUSH(2, R11, _LR); // R11 is frame pointer in Debug. MOVI2R(R0, (u32)&CoreTiming::downcount); - MOVI2R(R9, (u32)&PowerPC::ppcState); + MOVI2R(R9, (u32)&PowerPC::ppcState.spr[0]); FixupBranch skipToRealDispatcher = B(); dispatcher = GetCodePtr(); @@ -63,7 +63,7 @@ void JitArmAsmRoutineManager::Generate() // This block of code gets the address of the compiled block of code // It runs though to the compiling portion if it isn't found - LDR(R12, R9, STRUCT_OFF(PowerPC::ppcState, pc));// Load the current PC into R12 + LDR(R12, R9, PPCSTATE_OFF(PowerPC::ppcState, pc));// Load the current PC into R12 MOVI2R(R14, JIT_ICACHE_MASK); // Potential for optimization AND(R12, R12, R14); // R12 contains PC & JIT_ICACHE_MASK here. @@ -92,7 +92,7 @@ void JitArmAsmRoutineManager::Generate() // If we get to this point, that means that we don't have the block cached to execute // So call ArmJit to compile the block and then execute it. MOVI2R(R14, (u32)&Jit); - LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, pc)); + LDR(R0, R9, PPCSTATE_OFF(PowerPC::ppcState, pc)); BL(R14); B(dispatcherNoCheck); @@ -100,12 +100,12 @@ void JitArmAsmRoutineManager::Generate() // fpException() // Floating Point Exception Check, Jumped to if false fpException = GetCodePtr(); - LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(R0, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); ORR(R0, R0, EXCEPTION_FPU_UNAVAILABLE); - STR(R9, R0, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + STR(R9, R0, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); QuickCallFunction(R14, (void*)&PowerPC::CheckExceptions); - LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, npc)); - STR(R9, R0, STRUCT_OFF(PowerPC::ppcState, pc)); + LDR(R0, R9, PPCSTATE_OFF(PowerPC::ppcState, npc)); + STR(R9, R0, PPCSTATE_OFF(PowerPC::ppcState, pc)); B(dispatcher); SetJumpTarget(bail); @@ -116,11 +116,11 @@ void JitArmAsmRoutineManager::Generate() // Does exception checking testExceptions = GetCodePtr(); - LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, pc)); - STR(R9, R0, STRUCT_OFF(PowerPC::ppcState, npc)); + LDR(R0, R9, PPCSTATE_OFF(PowerPC::ppcState, pc)); + STR(R9, R0, PPCSTATE_OFF(PowerPC::ppcState, npc)); QuickCallFunction(R14, (void*)&PowerPC::CheckExceptions); - LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, npc)); - STR(R9, R0, STRUCT_OFF(PowerPC::ppcState, pc)); + LDR(R0, R9, PPCSTATE_OFF(PowerPC::ppcState, npc)); + STR(R9, R0, PPCSTATE_OFF(PowerPC::ppcState, pc)); // Check the state pointer to see if we are exiting // Gets checked on every exception check MOVI2R(R0, (u32)PowerPC::GetStatePtr()); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp index 08f10df826..99139d2c71 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp @@ -15,6 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include "Jit.h" #include "JitFPRCache.h" ArmFPRCache::ArmFPRCache() @@ -122,7 +123,7 @@ ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad) for (u8 a = 0; a < NUMPPCREG; ++a) if (ArmCRegs[a].PPCReg == 33) { - u16 offset = STRUCT_OFF(PowerPC::ppcState, ps) + (preg * 16) + (PS1 ? 8 : 0); + u16 offset = PPCSTATE_OFF(PowerPC::ppcState, ps) + (preg * 16) + (PS1 ? 8 : 0); if (preLoad) emit->VLDR(ArmCRegs[a].Reg, R9, offset); ArmCRegs[a].PPCReg = preg; @@ -131,10 +132,10 @@ ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad) return ArmCRegs[a].Reg; } // Alright, we couldn't get a free space, dump that least used register - u16 offsetOld = STRUCT_OFF(PowerPC::ppcState, ps) + (ArmCRegs[Num].PPCReg * 16) + (ArmCRegs[Num].PS1 ? 8 : 0); + u16 offsetOld = PPCSTATE_OFF(PowerPC::ppcState, ps) + (ArmCRegs[Num].PPCReg * 16) + (ArmCRegs[Num].PS1 ? 8 : 0); emit->VSTR(ArmCRegs[Num].Reg, R9, offsetOld); - u16 offsetNew = STRUCT_OFF(PowerPC::ppcState, ps) + (preg * 16) + (PS1 ? 8 : 0); + u16 offsetNew = PPCSTATE_OFF(PowerPC::ppcState, ps) + (preg * 16) + (PS1 ? 8 : 0); if (preLoad) emit->VLDR(ArmCRegs[Num].Reg, R9, offsetNew); ArmCRegs[Num].PPCReg = preg; @@ -159,7 +160,7 @@ void ArmFPRCache::Flush() for(u8 a = 0; a < NUMPPCREG; ++a) if (ArmCRegs[a].PPCReg != 33) { - u16 offset = STRUCT_OFF(PowerPC::ppcState, ps) + (ArmCRegs[a].PPCReg * 16) + (ArmCRegs[a].PS1 ? 8 : 0); + u16 offset = PPCSTATE_OFF(PowerPC::ppcState, ps) + (ArmCRegs[a].PPCReg * 16) + (ArmCRegs[a].PS1 ? 8 : 0); emit->VSTR(ArmCRegs[a].Reg, R9, offset); ArmCRegs[a].PPCReg = 33; ArmCRegs[a].LastLoad = 0; diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.cpp index 9c6ffdbac4..0e5bc8d68a 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.cpp @@ -15,6 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include "Jit.h" #include "JitRegCache.h" ArmRegCache::ArmRegCache() @@ -141,14 +142,14 @@ ARMReg ArmRegCache::R(u32 preg) for (u8 a = 0; a < NUMPPCREG; ++a) if (ArmCRegs[a].PPCReg == 33) { - emit->LDR(ArmCRegs[a].Reg, R9, STRUCT_OFF(PowerPC::ppcState, gpr) + preg * 4); + emit->LDR(ArmCRegs[a].Reg, R9, PPCSTATE_OFF(PowerPC::ppcState, gpr) + preg * 4); ArmCRegs[a].PPCReg = preg; ArmCRegs[a].LastLoad = 0; return ArmCRegs[a].Reg; } // Alright, we couldn't get a free space, dump that least used register - emit->STR(R9, ArmCRegs[Num].Reg, STRUCT_OFF(PowerPC::ppcState, gpr) + ArmCRegs[Num].PPCReg * 4); - emit->LDR(ArmCRegs[Num].Reg, R9, STRUCT_OFF(PowerPC::ppcState, gpr) + preg * 4); + emit->STR(R9, ArmCRegs[Num].Reg, PPCSTATE_OFF(PowerPC::ppcState, gpr) + ArmCRegs[Num].PPCReg * 4); + emit->LDR(ArmCRegs[Num].Reg, R9, PPCSTATE_OFF(PowerPC::ppcState, gpr) + preg * 4); ArmCRegs[Num].PPCReg = preg; ArmCRegs[Num].LastLoad = 0; return ArmCRegs[Num].Reg; @@ -159,7 +160,7 @@ void ArmRegCache::Flush() for(u8 a = 0; a < NUMPPCREG; ++a) if (ArmCRegs[a].PPCReg != 33) { - emit->STR(R9, ArmCRegs[a].Reg, STRUCT_OFF(PowerPC::ppcState, gpr) + ArmCRegs[a].PPCReg * 4); + emit->STR(R9, ArmCRegs[a].Reg, PPCSTATE_OFF(PowerPC::ppcState, gpr) + ArmCRegs[a].PPCReg * 4); ArmCRegs[a].PPCReg = 33; ArmCRegs[a].LastLoad = 0; }