From ec965c6014df2eb252d9da498684e94fe41fece4 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Tue, 4 Feb 2020 17:28:51 +0100 Subject: [PATCH] improve nop handling and proper behaviour for LDM^ fixes dslinux --- src/ARM.cpp | 2 ++ src/ARMJIT.cpp | 13 +++++++++---- src/ARMJIT_RegisterCache.h | 2 +- src/ARMJIT_x64/ARMJIT_Branch.cpp | 6 +++--- src/ARMJIT_x64/ARMJIT_Compiler.cpp | 1 + src/ARMJIT_x64/ARMJIT_Compiler.h | 2 ++ src/ARMJIT_x64/ARMJIT_LoadStore.cpp | 5 +++-- src/ARM_InstrInfo.cpp | 2 ++ src/ARM_InstrInfo.h | 2 ++ 9 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/ARM.cpp b/src/ARM.cpp index 896bb5c8..fc0b8982 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -768,6 +768,8 @@ void ARMv4::ExecuteJIT() return; } + //printf("executing armv4 at %08x\n", instrAddr); + ARMJIT::JitBlockEntry block = ARMJIT::LookUpBlock<1>(instrAddr); if (block) Cycles += block(); diff --git a/src/ARMJIT.cpp b/src/ARMJIT.cpp index c7387c99..8fd77083 100644 --- a/src/ARMJIT.cpp +++ b/src/ARMJIT.cpp @@ -273,6 +273,8 @@ bool IsIdleLoop(FetchedInstr* instrs, int instrsCount) typedef void (*InterpreterFunc)(ARM* cpu); +void NOP(ARM* cpu) {} + #define F(x) &ARMInterpreter::A_##x #define F_ALU(name, s) \ F(name##_REG_LSL_IMM##s), F(name##_REG_LSR_IMM##s), F(name##_REG_ASR_IMM##s), F(name##_REG_ROR_IMM##s), \ @@ -320,7 +322,8 @@ InterpreterFunc InterpretARM[ARMInstrInfo::ak_Count] = F(LDM), F(STM), F(B), F(BL), F(BLX_IMM), F(BX), F(BLX_REG), - F(UNK), F(MSR_IMM), F(MSR_REG), F(MRS), F(MCR), F(MRC), F(SVC) + F(UNK), F(MSR_IMM), F(MSR_REG), F(MRS), F(MCR), F(MRC), F(SVC), + NOP }; #undef F_ALU #undef F_MEM_WB @@ -387,8 +390,8 @@ void CompileBlock(ARM* cpu) u32 nextInstr[2] = {cpu->NextInstr[0], cpu->NextInstr[1]}; u32 nextInstrAddr[2] = {blockAddr, r15}; - JIT_DEBUGPRINT("start block %x (%x) %p %p (region invalidates %dx)\n", - blockAddr, pseudoPhysicalAddr, FastBlockAccess[pseudoPhysicalAddr / 2], + JIT_DEBUGPRINT("start block %x %08x (%x) %p %p (region invalidates %dx)\n", + blockAddr, cpu->CPSR, pseudoPhysicalAddr, FastBlockAccess[pseudoPhysicalAddr / 2], cpu->Num == 0 ? LookUpBlock<0>(blockAddr) : LookUpBlock<1>(blockAddr), CodeRanges[pseudoPhysicalAddr / 512].TimesInvalidated); @@ -473,7 +476,9 @@ void CompileBlock(ARM* cpu) else { u32 icode = ((instrs[i].Instr >> 4) & 0xF) | ((instrs[i].Instr >> 16) & 0xFF0); - assert(InterpretARM[instrs[i].Info.Kind] == ARMInterpreter::ARMInstrTable[icode] || instrs[i].Info.Kind == ARMInstrInfo::ak_MOV_REG_LSL_IMM); + assert(InterpretARM[instrs[i].Info.Kind] == ARMInterpreter::ARMInstrTable[icode] + || instrs[i].Info.Kind == ARMInstrInfo::ak_MOV_REG_LSL_IMM + || instrs[i].Info.Kind == ARMInstrInfo::ak_Nop); if (cpu->CheckCondition(instrs[i].Cond())) InterpretARM[instrs[i].Info.Kind](cpu); else diff --git a/src/ARMJIT_RegisterCache.h b/src/ARMJIT_RegisterCache.h index 2222bc2b..b8946571 100644 --- a/src/ARMJIT_RegisterCache.h +++ b/src/ARMJIT_RegisterCache.h @@ -152,7 +152,7 @@ public: needValueLoaded = BitSet16(instr.Info.SrcRegs); for (int reg : needToBeLoaded) LoadRegister(reg, needValueLoaded[reg]); - } + } { BitSet16 loadedSet(LoadedRegs); BitSet16 loadRegs(instr.Info.NotStrictlyNeeded & futureNeeded & ~LoadedRegs); diff --git a/src/ARMJIT_x64/ARMJIT_Branch.cpp b/src/ARMJIT_x64/ARMJIT_Branch.cpp index 0dedb3f8..e02865df 100644 --- a/src/ARMJIT_x64/ARMJIT_Branch.cpp +++ b/src/ARMJIT_x64/ARMJIT_Branch.cpp @@ -134,7 +134,7 @@ void Compiler::Comp_JumpTo(Gen::X64Reg addr, bool restoreCPSR) { IrregularCycles = true; - BitSet16 hiRegsLoaded(RegCache.DirtyRegs & 0xFF00); + BitSet16 hiRegsLoaded(RegCache.LoadedRegs & 0x7F00); bool previouslyDirty = CPSRDirty; SaveCPSR(); @@ -156,12 +156,12 @@ void Compiler::Comp_JumpTo(Gen::X64Reg addr, bool restoreCPSR) if (!restoreCPSR) XOR(32, R(ABI_PARAM3), R(ABI_PARAM3)); else - MOV(32, R(ABI_PARAM3), Imm32(restoreCPSR)); + MOV(32, R(ABI_PARAM3), Imm32(true)); // what a waste if (Num == 0) CALL((void*)&ARMv5::JumpTo); else CALL((void*)&ARMv4::JumpTo); - + if (!Thumb && restoreCPSR && CurInstr.Cond() < 0xE) { for (int reg : hiRegsLoaded) diff --git a/src/ARMJIT_x64/ARMJIT_Compiler.cpp b/src/ARMJIT_x64/ARMJIT_Compiler.cpp index fd38724c..5afe8424 100644 --- a/src/ARMJIT_x64/ARMJIT_Compiler.cpp +++ b/src/ARMJIT_x64/ARMJIT_Compiler.cpp @@ -308,6 +308,7 @@ const Compiler::CompileFunc A_Comp[ARMInstrInfo::ak_Count] = F(A_Comp_BranchImm), F(A_Comp_BranchImm), F(A_Comp_BranchImm), F(A_Comp_BranchXchangeReg), F(A_Comp_BranchXchangeReg), // system stuff NULL, NULL, NULL, NULL, NULL, NULL, NULL, + F(Nop) }; const Compiler::CompileFunc T_Comp[ARMInstrInfo::tk_Count] = { diff --git a/src/ARMJIT_x64/ARMJIT_Compiler.h b/src/ARMJIT_x64/ARMJIT_Compiler.h index 792ff66b..2cb57dc5 100644 --- a/src/ARMJIT_x64/ARMJIT_Compiler.h +++ b/src/ARMJIT_x64/ARMJIT_Compiler.h @@ -79,6 +79,8 @@ public: opInvertOp2 = 1 << 5, }; + void Nop() {} + void A_Comp_Arith(); void A_Comp_MovOp(); void A_Comp_CmpOp(); diff --git a/src/ARMJIT_x64/ARMJIT_LoadStore.cpp b/src/ARMJIT_x64/ARMJIT_LoadStore.cpp index b66f304f..4cafc1c9 100644 --- a/src/ARMJIT_x64/ARMJIT_LoadStore.cpp +++ b/src/ARMJIT_x64/ARMJIT_LoadStore.cpp @@ -531,7 +531,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc { if (regs[reg]) { - if (usermode && reg >= 8 && reg < 15) + if (usermode && !regs[15] && reg >= 8 && reg < 15) { if (firstUserMode) { @@ -545,7 +545,8 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc FixupBranch sucessfulWritten = J_CC(CC_NC); if (RegCache.Mapping[reg] != INVALID_REG) MOV(32, R(RegCache.Mapping[reg]), R(ABI_PARAM3)); - SaveReg(reg, ABI_PARAM3); + else + SaveReg(reg, ABI_PARAM3); SetJumpTarget(sucessfulWritten); } else if (RegCache.Mapping[reg] == INVALID_REG) diff --git a/src/ARM_InstrInfo.cpp b/src/ARM_InstrInfo.cpp index 8f8bd35e..08e2f0a6 100644 --- a/src/ARM_InstrInfo.cpp +++ b/src/ARM_InstrInfo.cpp @@ -392,6 +392,8 @@ Info Decode(bool thumb, u32 num, u32 instr) u32 data = ARMInstrTable[((instr >> 4) & 0xF) | ((instr >> 16) & 0xFF0)]; if (num == 0 && (instr & 0xFE000000) == 0xFA000000) data = A_BLX_IMM; + else if ((instr >> 28) == 0xF) + data = ak(ak_Nop); if (data & A_UnkOnARM7 && num != 0) data = A_UNK; diff --git a/src/ARM_InstrInfo.h b/src/ARM_InstrInfo.h index 2732181d..6ab49298 100644 --- a/src/ARM_InstrInfo.h +++ b/src/ARM_InstrInfo.h @@ -139,6 +139,8 @@ enum ak_MRC, ak_SVC, + ak_Nop, + ak_Count, tk_LSL_IMM = 0,