From 1686e60b26531eea0b5dc4718e4b0c5550bed2ff Mon Sep 17 00:00:00 2001 From: zilmar Date: Thu, 6 Oct 2016 22:59:03 +1100 Subject: [PATCH] [Android] Fix CArmRecompilerOps::CompileReadTLBMiss --- .../Project64-core/MemoryExceptionFilter.cpp | 57 ++++++++++++++++--- .../Recompiler/Arm/ArmRecompilerOps.cpp | 21 ++++++- .../N64System/Recompiler/Arm/ArmRegInfo.cpp | 37 ++++++------ .../N64System/Recompiler/Arm/ArmRegInfo.h | 1 + 4 files changed, 92 insertions(+), 24 deletions(-) diff --git a/Source/Project64-core/MemoryExceptionFilter.cpp b/Source/Project64-core/MemoryExceptionFilter.cpp index 05bab6f7a..a5bf4d3e5 100644 --- a/Source/Project64-core/MemoryExceptionFilter.cpp +++ b/Source/Project64-core/MemoryExceptionFilter.cpp @@ -380,11 +380,54 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context { if ((int32_t)(MemAddress) < 0 || MemAddress > 0x1FFFFFFF) { + ArmThumbOpcode * OpCode = (ArmThumbOpcode *)context.arm_pc; + Arm32Opcode * OpCode32 = (Arm32Opcode *)context.arm_pc; WriteTrace(TraceExceptionHandler, TraceError, "Invalid memory adderess: %X", MemAddress); - if (bHaveDebugger()) + WriteTrace(TraceExceptionHandler, TraceError, "Program Counter 0x%lx", g_Reg->m_PROGRAM_COUNTER); + for (int i = 0, n = (sizeof(g_BaseSystem->m_LastSuccessSyncPC) / sizeof(g_BaseSystem->m_LastSuccessSyncPC[0])); i < n; i++) { - g_Notify->BreakPoint(__FILE__, __LINE__); + WriteTrace(TraceExceptionHandler, TraceError, "m_LastSuccessSyncPC[%d] = 0x%lx", i, g_BaseSystem->m_LastSuccessSyncPC[i]); } + WriteTrace(TraceExceptionHandler, TraceError, "MemAddress = 0x%lx", MemAddress); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r0 = 0x%lx", context.arm_r0); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r1 = 0x%lx", context.arm_r1); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r2 = 0x%lx", context.arm_r2); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r3 = 0x%lx", context.arm_r3); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r4 = 0x%lx", context.arm_r4); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r5 = 0x%lx", context.arm_r5); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r6 = 0x%lx", context.arm_r6); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r7 = 0x%lx", context.arm_r7); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r8 = 0x%lx", context.arm_r8); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r9 = 0x%lx", context.arm_r9); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_r10 = 0x%lx", context.arm_r10); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_fp = 0x%lx", context.arm_fp); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_ip = 0x%lx", context.arm_ip); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_sp = 0x%lx", context.arm_sp); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_lr = 0x%lx", context.arm_lr); + WriteTrace(TraceExceptionHandler, TraceError, "uc->uc_mcontext.arm_pc = 0x%lx", context.arm_pc); + + uint8_t * TypePos = (uint8_t *)context.arm_pc; + WriteTrace(TraceExceptionHandler, TraceError, "TypePos: %02X %02X %02X %02X %02X %02X %02X %02X %02X",TypePos[0],TypePos[1],TypePos[2],TypePos[3],TypePos[4],TypePos[5],TypePos[6],TypePos[7],TypePos[8]); + + WriteTrace(TraceExceptionHandler, TraceError, "OpCode.Hex: %X",OpCode->Hex); + WriteTrace(TraceExceptionHandler, TraceError, "OpCode.opcode: %X",OpCode->Reg.opcode); + WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rm: %X",OpCode->Reg.rm); + WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rn: %X",OpCode->Reg.rn); + WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rt: %X",OpCode->Reg.rt); + + WriteTrace(TraceExceptionHandler, TraceError, "OpCode32.Hex: %X",OpCode32->Hex); + WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.opcode: %X",OpCode32->uint16.opcode); + WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.rm: %X",OpCode32->uint16.rm); + WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.rn: %X",OpCode32->uint16.rn); + WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.rt: %X",OpCode32->uint16.rt); + WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.imm2: %X",OpCode32->uint16.imm2); + + WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.opcode: %X",OpCode32->uint32.opcode); + WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.rn: %X",OpCode32->uint32.rn); + WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.rt: %X",OpCode32->uint32.rt); + WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.opcode2: %X",OpCode32->uint32.opcode2); + WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint32.rm: %X",OpCode32->uint32.rm); + g_Notify->BreakPoint(__FILE__, __LINE__); return false; } @@ -646,16 +689,16 @@ void CMipsMemoryVM::segv_handler(int signal, siginfo_t *siginfo, void *sigcontex WriteTrace(TraceExceptionHandler, TraceNotice, "%s: si_addr: %p",__FUNCTION__, siginfo->si_addr); uint32_t MemAddress = (char *)siginfo->si_addr - (char *)g_MMU->Rdram(); - WriteTrace(TraceExceptionHandler, TraceNotice, "MemAddress = %X",MemAddress); + WriteTrace(TraceExceptionHandler, TraceNotice, "MemAddress = %X", MemAddress); #ifdef __i386__ - for(int i = 0; i < NGREG; i++) + for (int i = 0; i < NGREG; i++) { WriteTrace(TraceExceptionHandler, TraceNotice, "reg[%02d] = 0x%08x", i, ucontext->uc_mcontext.gregs[i]); } WriteTrace(TraceExceptionHandler, TraceNotice, "REG_EIP = %X", ucontext->uc_mcontext.gregs[REG_EIP]); uint8_t * TypePos = (uint8_t *)ucontext->uc_mcontext.gregs[REG_EIP]; - WriteTrace(TraceExceptionHandler, TraceNotice, "TypePos: %02X %02X %02X %02X %02X %02X %02X %02X %02X",TypePos[0],TypePos[1],TypePos[2],TypePos[3],TypePos[4],TypePos[5],TypePos[6],TypePos[7],TypePos[8]); + WriteTrace(TraceExceptionHandler, TraceNotice, "TypePos: %02X %02X %02X %02X %02X %02X %02X %02X %02X", TypePos[0], TypePos[1], TypePos[2], TypePos[3], TypePos[4], TypePos[5], TypePos[6], TypePos[7], TypePos[8]); X86_CONTEXT context; context.Edi = (uint32_t*)&ucontext->uc_mcontext.gregs[REG_EDI]; @@ -668,14 +711,14 @@ void CMipsMemoryVM::segv_handler(int signal, siginfo_t *siginfo, void *sigcontex context.Esp = (uint32_t*)&ucontext->uc_mcontext.gregs[REG_ESP]; context.Ebp = (uint32_t*)&ucontext->uc_mcontext.gregs[REG_EBP]; - if (FilterX86Exception(MemAddress,context)) + if (FilterX86Exception(MemAddress, context)) { WriteTrace(TraceExceptionHandler, TraceNotice, "Success!"); WriteTrace(TraceExceptionHandler, TraceNotice, "REG_EIP = %X", ucontext->uc_mcontext.gregs[REG_EIP]); return; } #elif defined(__arm__) - if (FilterArmException(MemAddress,ucontext->uc_mcontext)) + if (FilterArmException(MemAddress, ucontext->uc_mcontext)) { WriteTrace(TraceExceptionHandler, TraceNotice, "Success!"); return; diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp index b0a5b83d3..f61bc5842 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp @@ -4198,6 +4198,10 @@ void CArmRecompilerOps::SyncRegState(const CRegInfo & SyncTo) void CArmRecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, CExitInfo::EXIT_REASON reason) { m_RegWorkingSet = ExitRegSet; + for (int32_t i = 0; i < 16; i++) + { + m_RegWorkingSet.SetArmRegProtected((ArmReg)i, false); + } m_RegWorkingSet.WriteBackRegisters(); ExitRegSet = m_RegWorkingSet; @@ -4253,6 +4257,14 @@ void CArmRecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo CallFunction(AddressOf(&CRegisters::DoCopUnusableException), "CRegisters::DoCopUnusableException"); ExitCodeBlock(); break; + case CExitInfo::TLBReadMiss: + bDelay = m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT; + MoveVariableToArmReg(g_TLBLoadAddress, "g_TLBLoadAddress",Arm_R2); + MoveConstToArmReg(Arm_R1, (uint32_t)bDelay, bDelay ? "true" : "false"); + MoveConstToArmReg(Arm_R0, (uint32_t)g_Reg); + CallFunction(AddressOf(&CRegisters::DoTLBReadMiss), "CRegisters::DoTLBReadMiss"); + ExitCodeBlock(); + break; default: g_Notify->BreakPoint(__FILE__, __LINE__); } @@ -4303,7 +4315,14 @@ void CArmRecompilerOps::CompileSystemCheck(uint32_t TargetPC, const CRegInfo & R void CArmRecompilerOps::CompileReadTLBMiss(ArmReg AddressReg, ArmReg LookUpReg) { - CPU_Message("%s: todo",__FUNCTION__); + m_RegWorkingSet.SetArmRegProtected(AddressReg, true); + m_RegWorkingSet.SetArmRegProtected(LookUpReg, true); + + ArmReg TlbLoadReg = Map_Variable(CArmRegInfo::VARIABLE_TLB_LOAD_ADDRESS); + StoreArmRegToArmRegPointer(AddressReg, TlbLoadReg, 0); + CompareArmRegToConst(LookUpReg, 0); + CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::TLBReadMiss, ArmBranch_Equal); + m_RegWorkingSet.SetArmRegProtected(TlbLoadReg, false); } CRegInfo & CArmRecompilerOps::GetRegWorkingSet(void) diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.cpp b/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.cpp index 9169f868a..e0fe0769e 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.cpp +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.cpp @@ -285,11 +285,11 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad) SetArmRegProtected(regHi, true); reglo = FreeArmReg(); - if (reglo < 0) + if (reglo < 0) { if (bHaveDebugger()) { g_Notify->DisplayError("Map_GPR_64bit\n\nOut of registers"); } g_Notify->BreakPoint(__FILE__, __LINE__); - return; + return; } SetArmRegProtected(reglo, true); @@ -303,7 +303,7 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad) { SetArmRegProtected(reglo, true); regHi = FreeArmReg(); - if (regHi < 0) + if (regHi < 0) { if (bHaveDebugger()) { g_Notify->DisplayError("Map_GPR_64bit\n\nOut of registers"); } g_Notify->BreakPoint(__FILE__, __LINE__); @@ -346,16 +346,16 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad) g_Notify->BreakPoint(__FILE__, __LINE__); /*if (IsSigned(MipsRegToLoad)) { - MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), x86Hi); - ShiftRightSignImmed(x86Hi, 31); + MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), x86Hi); + ShiftRightSignImmed(x86Hi, 31); } else { - XorX86RegToX86Reg(x86Hi, x86Hi); + XorX86RegToX86Reg(x86Hi, x86Hi); } if (MipsReg != MipsRegToLoad) { - MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), x86lo); + MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad), x86lo); }*/ } else if (MipsReg != MipsRegToLoad) @@ -371,18 +371,18 @@ void CArmRegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad) /*CPU_Message("Map_GPR_64bit 11"); if (Is32Bit(MipsRegToLoad)) { - if (IsSigned(MipsRegToLoad)) - { - MoveConstToX86reg(GetMipsRegLo_S(MipsRegToLoad) >> 31, x86Hi); - } - else - { - MoveConstToX86reg(0, x86Hi); - } + if (IsSigned(MipsRegToLoad)) + { + MoveConstToX86reg(GetMipsRegLo_S(MipsRegToLoad) >> 31, x86Hi); } else { - MoveConstToX86reg(GetMipsRegHi(MipsRegToLoad), x86Hi); + MoveConstToX86reg(0, x86Hi); + } + } + else + { + MoveConstToX86reg(GetMipsRegHi(MipsRegToLoad), x86Hi); } MoveConstToX86reg(GetMipsRegLo(MipsRegToLoad), x86lo);*/ } @@ -898,6 +898,11 @@ CArmOps::ArmReg CArmRegInfo::Map_Variable(VARIABLE_MAPPED variable) m_Variable_MappedTo[Reg] = variable; MoveConstToArmReg(Reg, (uint32_t)(g_NextTimer), "g_NextTimer"); break; + case VARIABLE_TLB_LOAD_ADDRESS: + CPU_Message(" regcache: allocate %s as pointer to g_TLBLoadAddress", ArmRegName(Reg)); + m_Variable_MappedTo[Reg] = variable; + MoveConstToArmReg(Reg, (uint32_t)(g_TLBLoadAddress), "g_TLBLoadAddress"); + break; default: g_Notify->BreakPoint(__FILE__, __LINE__); return Arm_Unknown; diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.h b/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.h index fbff2d4d1..ab7558521 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.h +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRegInfo.h @@ -38,6 +38,7 @@ public: VARIABLE_FPR = 2, VARIABLE_TLB_READMAP = 3, VARIABLE_NEXT_TIMER = 4, + VARIABLE_TLB_LOAD_ADDRESS = 5, }; CArmRegInfo();