diff --git a/src/ARMJIT_x64/ARMJIT_Branch.cpp b/src/ARMJIT_x64/ARMJIT_Branch.cpp index 1f95a900..6ae4aad5 100644 --- a/src/ARMJIT_x64/ARMJIT_Branch.cpp +++ b/src/ARMJIT_x64/ARMJIT_Branch.cpp @@ -35,6 +35,7 @@ void Compiler::Comp_JumpTo(u32 addr, bool forceNonConstantCycles) u32 newregion = addr >> 24; u32 regionCodeCycles = cpu9->MemTimings[addr >> 12][0]; + u32 compileTimeCodeCycles = cpu9->RegionCodeCycles; cpu9->RegionCodeCycles = regionCodeCycles; MOV(32, MDisp(RCPU, offsetof(ARMv5, RegionCodeCycles)), Imm32(regionCodeCycles)); @@ -53,7 +54,7 @@ void Compiler::Comp_JumpTo(u32 addr, bool forceNonConstantCycles) if (addr & 0x2) { nextInstr[0] = cpu9->CodeRead32(addr-2, true) >> 16; - cycles += CurCPU->CodeCycles; + cycles += cpu9->CodeCycles; nextInstr[1] = cpu9->CodeRead32(addr+2, false); cycles += CurCPU->CodeCycles; } @@ -61,7 +62,7 @@ void Compiler::Comp_JumpTo(u32 addr, bool forceNonConstantCycles) { nextInstr[0] = cpu9->CodeRead32(addr, true); nextInstr[1] = nextInstr[0] >> 16; - cycles += CurCPU->CodeCycles; + cycles += cpu9->CodeCycles; } } else @@ -74,6 +75,10 @@ void Compiler::Comp_JumpTo(u32 addr, bool forceNonConstantCycles) nextInstr[1] = cpu9->CodeRead32(addr+4, false); cycles += cpu9->CodeCycles; } + + cpu9->RegionCodeCycles = compileTimeCodeCycles; + if (setupRegion) + cpu9->SetupCodeMem(R15); } else { @@ -86,26 +91,40 @@ void Compiler::Comp_JumpTo(u32 addr, bool forceNonConstantCycles) cpu7->CodeCycles = codeCycles; MOV(32, MDisp(RCPU, offsetof(ARM, CodeRegion)), Imm32(codeRegion)); - MOV(32, MDisp(RCPU, offsetof(ARM, CodeRegion)), Imm32(codeCycles)); + MOV(32, MDisp(RCPU, offsetof(ARM, CodeCycles)), Imm32(codeCycles)); if (addr & 0x1) { addr &= ~0x1; newPC = addr+2; + // this is necessary because ARM7 bios protection + u32 compileTimePC = CurCPU->R[15]; + CurCPU->R[15] = newPC; + nextInstr[0] = ((ARMv4*)CurCPU)->CodeRead16(addr); nextInstr[1] = ((ARMv4*)CurCPU)->CodeRead16(addr+2); cycles += NDS::ARM7MemTimings[codeCycles][0] + NDS::ARM7MemTimings[codeCycles][1]; + + CurCPU->R[15] = compileTimePC; } else { addr &= ~0x3; newPC = addr+4; + u32 compileTimePC = CurCPU->R[15]; + CurCPU->R[15] = newPC; + nextInstr[0] = cpu7->CodeRead32(addr); nextInstr[1] = cpu7->CodeRead32(addr+4); cycles += NDS::ARM7MemTimings[codeCycles][2] + NDS::ARM7MemTimings[codeCycles][3]; + + CurCPU->R[15] = compileTimePC; } + + cpu7->CodeRegion = R15 >> 24; + cpu7->CodeCycles = addr >> 15; } MOV(32, MDisp(RCPU, offsetof(ARM, R[15])), Imm32(newPC)); @@ -204,7 +223,7 @@ void Compiler::T_Comp_BCOND() FixupBranch skipFailed = J(); SetJumpTarget(skipExecute); Comp_AddCycles_C(true); - SetJumpTarget(skipFailed); + SetJumpTarget(skipFailed); } void Compiler::T_Comp_B() diff --git a/src/ARMJIT_x64/ARMJIT_Compiler.cpp b/src/ARMJIT_x64/ARMJIT_Compiler.cpp index 18cb27e9..1e871fdd 100644 --- a/src/ARMJIT_x64/ARMJIT_Compiler.cpp +++ b/src/ARMJIT_x64/ARMJIT_Compiler.cpp @@ -354,8 +354,6 @@ CompiledBlock Compiler::CompileBlock(ARM* cpu, FetchedInstr instrs[], int instrs if (IsAlmostFull()) InvalidateBlockCache(); - CompiledBlock res = (CompiledBlock)GetWritableCodePtr(); - ConstantCycles = 0; Thumb = cpu->CPSR & 0x20; Num = cpu->Num; @@ -363,6 +361,13 @@ CompiledBlock Compiler::CompileBlock(ARM* cpu, FetchedInstr instrs[], int instrs CodeRegion = cpu->CodeRegion; CurCPU = cpu; + CompiledBlock res = (CompiledBlock)GetWritableCodePtr(); + + if (!IsMapped(Num, R15 - Thumb ? 2 : 4)) + { + printf("Trying to compile a block in unmapped memory\n"); + } + bool mergedThumbBL = false; ABI_PushRegistersAndAdjustStack(BitSet32(ABI_ALL_CALLEE_SAVED & ABI_ALL_GPRS & ~BitSet32({RSP})), 8); @@ -383,7 +388,8 @@ CompiledBlock Compiler::CompileBlock(ARM* cpu, FetchedInstr instrs[], int instrs ? T_Comp[CurInstr.Info.Kind] : A_Comp[CurInstr.Info.Kind]; - if (comp == NULL || i == instrsCount - 1) + bool isConditional = Thumb ? CurInstr.Info.Kind == ARMInstrInfo::tk_BCOND : CurInstr.Cond() < 0xE; + if (comp == NULL || (i == instrsCount - 1 && (!CurInstr.Info.Branches() || isConditional))) { MOV(32, MDisp(RCPU, offsetof(ARM, R[15])), Imm32(R15)); MOV(32, MDisp(RCPU, offsetof(ARM, CodeCycles)), Imm32(CurInstr.CodeCycles)); @@ -454,10 +460,9 @@ CompiledBlock Compiler::CompileBlock(ARM* cpu, FetchedInstr instrs[], int instrs else (this->*comp)(); - FixupBranch skipFailed; if (CurInstr.Cond() < 0xE) { - skipFailed = J(); + FixupBranch skipFailed = J(); SetJumpTarget(skipExecute); Comp_AddCycles_C(); diff --git a/src/ARM_InstrInfo.cpp b/src/ARM_InstrInfo.cpp index c36d6c1e..5db24711 100644 --- a/src/ARM_InstrInfo.cpp +++ b/src/ARM_InstrInfo.cpp @@ -178,7 +178,6 @@ enum { T_ReadR13 = 1 << 9, T_WriteR13 = 1 << 10, - T_ReadR15 = 1 << 11, T_BranchAlways = 1 << 12, T_ReadR14 = 1 << 13, @@ -222,7 +221,7 @@ const u32 T_ADD_HIREG = T_WriteHi0 | T_ReadHi0 | T_ReadHi3 | tk(tk_ADD_HIREG); const u32 T_CMP_HIREG = T_ReadHi0 | T_ReadHi3 | tk(tk_CMP_HIREG); const u32 T_MOV_HIREG = T_WriteHi0 | T_ReadHi3 | tk(tk_MOV_HIREG); -const u32 T_ADD_PCREL = T_Write8 | T_ReadR15 | tk(tk_ADD_PCREL); +const u32 T_ADD_PCREL = T_Write8 | tk(tk_ADD_PCREL); const u32 T_ADD_SPREL = T_Write8 | T_ReadR13 | tk(tk_ADD_SPREL); const u32 T_ADD_SP = T_WriteR13 | tk(tk_ADD_SP); @@ -257,11 +256,11 @@ const u32 T_BCOND = T_BranchAlways | tk(tk_BCOND); const u32 T_BX = T_BranchAlways | T_ReadHi3 | tk(tk_BX); const u32 T_BLX_REG = T_BranchAlways | T_WriteR14 | T_ReadHi3 | tk(tk_BLX_REG); const u32 T_B = T_BranchAlways | tk(tk_B); -const u32 T_BL_LONG_1 = T_WriteR14 | T_ReadR15 | tk(tk_BL_LONG_1); -const u32 T_BL_LONG_2 = T_BranchAlways | T_ReadR14 | T_WriteR14 | T_ReadR15 | tk(tk_BL_LONG_2); +const u32 T_BL_LONG_1 = T_WriteR14 | tk(tk_BL_LONG_1); +const u32 T_BL_LONG_2 = T_BranchAlways | T_ReadR14 | T_WriteR14 | tk(tk_BL_LONG_2); const u32 T_UNK = T_BranchAlways | T_WriteR14 | tk(tk_UNK); -const u32 T_SVC = T_BranchAlways | T_WriteR14 | T_ReadR15 | tk(tk_SVC); +const u32 T_SVC = T_BranchAlways | T_WriteR14 | tk(tk_SVC); #define INSTRFUNC_PROTO(x) u32 x #include "ARM_InstrTable.h" @@ -299,8 +298,6 @@ Info Decode(bool thumb, u32 num, u32 instr) res.SrcRegs |= (1 << 13); if (data & T_WriteR13) res.DstRegs |= (1 << 13); - if (data & T_ReadR15) - res.SrcRegs |= (1 << 15); if (data & T_WriteR14) res.DstRegs |= (1 << 14); if (data & T_ReadR14)