| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -23,12 +23,46 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Log_SetChannel(CPU::Core);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				namespace CPU {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void SetPC(u32 new_pc);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void UpdateLoadDelay();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void Branch(u32 target);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void FlushPipeline();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static u32 GetExceptionVector(bool debug_exception = false);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void RaiseException(u32 CAUSE_bits, u32 EPC, u32 vector);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static u32 ReadReg(Reg rs);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void WriteReg(Reg rd, u32 value);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void WriteRegDelayed(Reg rd, u32 value);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static u32 ReadCop0Reg(Cop0Reg reg);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void WriteCop0Reg(Cop0Reg reg, u32 value);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void DispatchCop0Breakpoint();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void Cop0ExecutionBreakpointCheck();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template<MemoryAccessType type>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void Cop0DataBreakpointCheck(VirtualMemoryAddress address);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static bool BreakpointCheck();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#ifdef _DEBUG
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void TracePrintInstruction();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#endif
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void DisassembleAndPrint(u32 addr, const char* prefix);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void PrintInstruction(u32 bits, u32 pc, Registers* regs, const char* prefix);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void LogInstruction(u32 bits, u32 pc, Registers* regs);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void HandleWriteSyscall();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void HandlePutcSyscall();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void HandlePutsSyscall();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void ExecuteDebug();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template<PGXPMode pgxp_mode, bool debug>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void ExecuteInstruction();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template<PGXPMode pgxp_mode, bool debug>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				[[noreturn]] static void ExecuteImpl();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				State g_state;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool TRACE_EXECUTION = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -44,13 +78,14 @@ static u32 s_breakpoint_counter = 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static u32 s_last_breakpoint_check_pc = INVALID_BREAKPOINT_PC;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static bool s_single_step = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static bool s_single_step_done = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				} // namespace CPU
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool IsTraceEnabled()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool CPU::IsTraceEnabled()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return s_trace_to_log;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void StartTrace()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::StartTrace()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (s_trace_to_log)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -59,7 +94,7 @@ void StartTrace()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  UpdateDebugDispatcherFlag();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void StopTrace()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::StopTrace()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (!s_trace_to_log)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -72,7 +107,7 @@ void StopTrace()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  UpdateDebugDispatcherFlag();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void WriteToExecutionLog(const char* format, ...)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::WriteToExecutionLog(const char* format, ...)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (!s_log_file_opened)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -93,7 +128,7 @@ void WriteToExecutionLog(const char* format, ...)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void Initialize()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::Initialize()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // From nocash spec.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.cop0_regs.PRID = UINT32_C(0x00000002);
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -109,13 +144,13 @@ void Initialize()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  GTE::Initialize();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void Shutdown()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::Shutdown()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ClearBreakpoints();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  StopTrace();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void Reset()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::Reset()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.pending_ticks = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.downcount = 0;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -141,7 +176,7 @@ void Reset()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  SetPC(RESET_VECTOR);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool DoState(StateWrapper& sw)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool CPU::DoState(StateWrapper& sw)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  sw.Do(&g_state.pending_ticks);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  sw.Do(&g_state.downcount);
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -180,8 +215,10 @@ bool DoState(StateWrapper& sw)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // Compatibility with old states.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (sw.GetVersion() < 59)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    g_state.load_delay_reg = static_cast<Reg>(std::min(static_cast<u8>(g_state.load_delay_reg), static_cast<u8>(Reg::count)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    g_state.next_load_delay_reg = static_cast<Reg>(std::min(static_cast<u8>(g_state.load_delay_reg), static_cast<u8>(Reg::count)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    g_state.load_delay_reg =
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      static_cast<Reg>(std::min(static_cast<u8>(g_state.load_delay_reg), static_cast<u8>(Reg::count)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    g_state.next_load_delay_reg =
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      static_cast<Reg>(std::min(static_cast<u8>(g_state.load_delay_reg), static_cast<u8>(Reg::count)));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  sw.Do(&g_state.cache_control.bits);
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -210,7 +247,7 @@ bool DoState(StateWrapper& sw)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return !sw.HasError();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void UpdateFastmemBase()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::UpdateFastmemBase()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (g_state.cop0_regs.sr.Isc)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    g_state.fastmem_base = nullptr;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -218,14 +255,14 @@ void UpdateFastmemBase()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    g_state.fastmem_base = Bus::GetFastmemBase();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void SetPC(u32 new_pc)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void CPU::SetPC(u32 new_pc)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  DebugAssert(Common::IsAlignedPow2(new_pc, 4));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.npc = new_pc;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  FlushPipeline();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void Branch(u32 target)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void CPU::Branch(u32 target)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (!Common::IsAlignedPow2(target, 4))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -239,13 +276,13 @@ ALWAYS_INLINE_RELEASE void Branch(u32 target)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.branch_was_taken = true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE static u32 GetExceptionVector(bool debug_exception = false)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE u32 CPU::GetExceptionVector(bool debug_exception /* = false*/)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const u32 base = g_state.cop0_regs.sr.BEV ? UINT32_C(0xbfc00100) : UINT32_C(0x80000000);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return base | (debug_exception ? UINT32_C(0x00000040) : UINT32_C(0x00000080));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE static void RaiseException(u32 CAUSE_bits, u32 EPC, u32 vector)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void CPU::RaiseException(u32 CAUSE_bits, u32 EPC, u32 vector)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.cop0_regs.EPC = EPC;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.cop0_regs.cause.bits = (g_state.cop0_regs.cause.bits & ~Cop0Registers::CAUSE::EXCEPTION_WRITE_MASK) |
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -287,7 +324,7 @@ ALWAYS_INLINE_RELEASE static void RaiseException(u32 CAUSE_bits, u32 EPC, u32 ve
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  FlushPipeline();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE static void DispatchCop0Breakpoint()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void CPU::DispatchCop0Breakpoint()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // When a breakpoint address match occurs the PSX jumps to 80000040h (ie. unlike normal exceptions, not to 80000080h).
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // The Excode value in the CAUSE register is set to 09h (same as BREAK opcode), and EPC contains the return address,
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -299,12 +336,12 @@ ALWAYS_INLINE_RELEASE static void DispatchCop0Breakpoint()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                 g_state.current_instruction_pc, GetExceptionVector(true));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void RaiseException(u32 CAUSE_bits, u32 EPC)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::RaiseException(u32 CAUSE_bits, u32 EPC)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  RaiseException(CAUSE_bits, EPC, GetExceptionVector());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void RaiseException(Exception excode)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::RaiseException(Exception excode)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  RaiseException(Cop0Registers::CAUSE::MakeValueForException(excode, g_state.current_instruction_in_branch_delay_slot,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                                             g_state.current_instruction_was_branch_taken,
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -312,7 +349,7 @@ void RaiseException(Exception excode)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                 g_state.current_instruction_pc, GetExceptionVector());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void RaiseBreakException(u32 CAUSE_bits, u32 EPC, u32 instruction_bits)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::RaiseBreakException(u32 CAUSE_bits, u32 EPC, u32 instruction_bits)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (PCDrv::HandleSyscall(instruction_bits, g_state.regs))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -326,18 +363,18 @@ void RaiseBreakException(u32 CAUSE_bits, u32 EPC, u32 instruction_bits)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  RaiseException(CAUSE_bits, EPC, GetExceptionVector());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void SetExternalInterrupt(u8 bit)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::SetExternalInterrupt(u8 bit)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.cop0_regs.cause.Ip |= static_cast<u8>(1u << bit);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  CheckForPendingInterrupt();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void ClearExternalInterrupt(u8 bit)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::ClearExternalInterrupt(u8 bit)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.cop0_regs.cause.Ip &= static_cast<u8>(~(1u << bit));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE static void UpdateLoadDelay()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void CPU::UpdateLoadDelay()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // the old value is needed in case the delay slot instruction overwrites the same register
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.regs.r[static_cast<u8>(g_state.load_delay_reg)] = g_state.load_delay_value;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -346,7 +383,7 @@ ALWAYS_INLINE_RELEASE static void UpdateLoadDelay()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.next_load_delay_reg = Reg::count;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE static void FlushPipeline()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void CPU::FlushPipeline()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // loads are flushed
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.next_load_delay_reg = Reg::count;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -367,12 +404,12 @@ ALWAYS_INLINE_RELEASE static void FlushPipeline()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.current_instruction_was_branch_taken = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE static u32 ReadReg(Reg rs)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE u32 CPU::ReadReg(Reg rs)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return g_state.regs.r[static_cast<u8>(rs)];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE static void WriteReg(Reg rd, u32 value)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE void CPU::WriteReg(Reg rd, u32 value)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.regs.r[static_cast<u8>(rd)] = value;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.load_delay_reg = (rd == g_state.load_delay_reg) ? Reg::count : g_state.load_delay_reg;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -381,7 +418,7 @@ ALWAYS_INLINE static void WriteReg(Reg rd, u32 value)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.regs.zero = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE static void WriteRegDelayed(Reg rd, u32 value)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void CPU::WriteRegDelayed(Reg rd, u32 value)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  DebugAssert(g_state.next_load_delay_reg == Reg::count);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (rd == Reg::zero)
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -396,7 +433,7 @@ ALWAYS_INLINE_RELEASE static void WriteRegDelayed(Reg rd, u32 value)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.next_load_delay_value = value;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE static u32 ReadCop0Reg(Cop0Reg reg)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE u32 CPU::ReadCop0Reg(Cop0Reg reg)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  switch (reg)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -438,7 +475,7 @@ ALWAYS_INLINE_RELEASE static u32 ReadCop0Reg(Cop0Reg reg)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE static void WriteCop0Reg(Cop0Reg reg, u32 value)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void CPU::WriteCop0Reg(Cop0Reg reg, u32 value)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  switch (reg)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -509,7 +546,7 @@ ALWAYS_INLINE_RELEASE static void WriteCop0Reg(Cop0Reg reg, u32 value)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void Cop0ExecutionBreakpointCheck()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void CPU::Cop0ExecutionBreakpointCheck()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (!g_state.cop0_regs.dcic.ExecutionBreakpointsEnabled())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -529,7 +566,7 @@ ALWAYS_INLINE_RELEASE void Cop0ExecutionBreakpointCheck()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template<MemoryAccessType type>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void Cop0DataBreakpointCheck(VirtualMemoryAddress address)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void CPU::Cop0DataBreakpointCheck(VirtualMemoryAddress address)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if constexpr (type == MemoryAccessType::Read)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -562,7 +599,7 @@ ALWAYS_INLINE_RELEASE void Cop0DataBreakpointCheck(VirtualMemoryAddress address)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#ifdef _DEBUG
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void TracePrintInstruction()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::TracePrintInstruction()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const u32 pc = g_state.current_instruction_pc;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const u32 bits = g_state.current_instruction.bits;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -584,7 +621,7 @@ static void TracePrintInstruction()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#endif
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void PrintInstruction(u32 bits, u32 pc, Registers* regs, const char* prefix)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::PrintInstruction(u32 bits, u32 pc, Registers* regs, const char* prefix)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  TinyString instr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  TinyString comment;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -601,7 +638,7 @@ static void PrintInstruction(u32 bits, u32 pc, Registers* regs, const char* pref
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Log_DevPrintf("%s%08x: %08x %s", prefix, pc, bits, instr.c_str());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void LogInstruction(u32 bits, u32 pc, Registers* regs)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::LogInstruction(u32 bits, u32 pc, Registers* regs)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  TinyString instr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  TinyString comment;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -618,7 +655,7 @@ static void LogInstruction(u32 bits, u32 pc, Registers* regs)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  WriteToExecutionLog("%08x: %08x %s\n", pc, bits, instr.c_str());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void HandleWriteSyscall()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::HandleWriteSyscall()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const auto& regs = g_state.regs;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (regs.a0 != 1) // stdout
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -636,14 +673,14 @@ static void HandleWriteSyscall()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void HandlePutcSyscall()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::HandlePutcSyscall()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const auto& regs = g_state.regs;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (regs.a0 != 0)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Bus::AddTTYCharacter(static_cast<char>(regs.a0));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void HandlePutsSyscall()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::HandlePutsSyscall()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const auto& regs = g_state.regs;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -658,7 +695,7 @@ static void HandlePutsSyscall()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void HandleA0Syscall()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::HandleA0Syscall()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const auto& regs = g_state.regs;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const u32 call = regs.t1;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -670,7 +707,7 @@ void HandleA0Syscall()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    HandlePutsSyscall();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void HandleB0Syscall()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::HandleB0Syscall()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const auto& regs = g_state.regs;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const u32 call = regs.t1;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -682,113 +719,113 @@ void HandleB0Syscall()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    HandlePutsSyscall();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				const std::array<DebuggerRegisterListEntry, NUM_DEBUGGER_REGISTER_LIST_ENTRIES> g_debugger_register_list = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {{"zero", &CPU::g_state.regs.zero},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"at", &CPU::g_state.regs.at},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"v0", &CPU::g_state.regs.v0},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"v1", &CPU::g_state.regs.v1},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"a0", &CPU::g_state.regs.a0},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"a1", &CPU::g_state.regs.a1},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"a2", &CPU::g_state.regs.a2},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"a3", &CPU::g_state.regs.a3},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"t0", &CPU::g_state.regs.t0},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"t1", &CPU::g_state.regs.t1},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"t2", &CPU::g_state.regs.t2},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"t3", &CPU::g_state.regs.t3},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"t4", &CPU::g_state.regs.t4},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"t5", &CPU::g_state.regs.t5},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"t6", &CPU::g_state.regs.t6},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"t7", &CPU::g_state.regs.t7},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"s0", &CPU::g_state.regs.s0},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"s1", &CPU::g_state.regs.s1},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"s2", &CPU::g_state.regs.s2},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"s3", &CPU::g_state.regs.s3},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"s4", &CPU::g_state.regs.s4},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"s5", &CPU::g_state.regs.s5},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"s6", &CPU::g_state.regs.s6},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"s7", &CPU::g_state.regs.s7},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"t8", &CPU::g_state.regs.t8},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"t9", &CPU::g_state.regs.t9},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"k0", &CPU::g_state.regs.k0},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"k1", &CPU::g_state.regs.k1},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"gp", &CPU::g_state.regs.gp},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"sp", &CPU::g_state.regs.sp},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"fp", &CPU::g_state.regs.fp},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"ra", &CPU::g_state.regs.ra},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"hi", &CPU::g_state.regs.hi},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"lo", &CPU::g_state.regs.lo},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"pc", &CPU::g_state.pc},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"npc", &CPU::g_state.npc},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"COP0_SR", &CPU::g_state.cop0_regs.sr.bits},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"COP0_CAUSE", &CPU::g_state.cop0_regs.cause.bits},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"COP0_EPC", &CPU::g_state.cop0_regs.EPC},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"COP0_BadVAddr", &CPU::g_state.cop0_regs.BadVaddr},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"V0_XY", &CPU::g_state.gte_regs.r32[0]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"V0_Z", &CPU::g_state.gte_regs.r32[1]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"V1_XY", &CPU::g_state.gte_regs.r32[2]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"V1_Z", &CPU::g_state.gte_regs.r32[3]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"V2_XY", &CPU::g_state.gte_regs.r32[4]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"V2_Z", &CPU::g_state.gte_regs.r32[5]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"RGBC", &CPU::g_state.gte_regs.r32[6]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"OTZ", &CPU::g_state.gte_regs.r32[7]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"IR0", &CPU::g_state.gte_regs.r32[8]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"IR1", &CPU::g_state.gte_regs.r32[9]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"IR2", &CPU::g_state.gte_regs.r32[10]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"IR3", &CPU::g_state.gte_regs.r32[11]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"SXY0", &CPU::g_state.gte_regs.r32[12]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"SXY1", &CPU::g_state.gte_regs.r32[13]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"SXY2", &CPU::g_state.gte_regs.r32[14]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"SXYP", &CPU::g_state.gte_regs.r32[15]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"SZ0", &CPU::g_state.gte_regs.r32[16]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"SZ1", &CPU::g_state.gte_regs.r32[17]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"SZ2", &CPU::g_state.gte_regs.r32[18]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"SZ3", &CPU::g_state.gte_regs.r32[19]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"RGB0", &CPU::g_state.gte_regs.r32[20]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"RGB1", &CPU::g_state.gte_regs.r32[21]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"RGB2", &CPU::g_state.gte_regs.r32[22]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"RES1", &CPU::g_state.gte_regs.r32[23]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"MAC0", &CPU::g_state.gte_regs.r32[24]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"MAC1", &CPU::g_state.gte_regs.r32[25]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"MAC2", &CPU::g_state.gte_regs.r32[26]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"MAC3", &CPU::g_state.gte_regs.r32[27]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"IRGB", &CPU::g_state.gte_regs.r32[28]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"ORGB", &CPU::g_state.gte_regs.r32[29]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"LZCS", &CPU::g_state.gte_regs.r32[30]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"LZCR", &CPU::g_state.gte_regs.r32[31]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"RT_0", &CPU::g_state.gte_regs.r32[32]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"RT_1", &CPU::g_state.gte_regs.r32[33]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"RT_2", &CPU::g_state.gte_regs.r32[34]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"RT_3", &CPU::g_state.gte_regs.r32[35]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"RT_4", &CPU::g_state.gte_regs.r32[36]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"TRX", &CPU::g_state.gte_regs.r32[37]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"TRY", &CPU::g_state.gte_regs.r32[38]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"TRZ", &CPU::g_state.gte_regs.r32[39]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"LLM_0", &CPU::g_state.gte_regs.r32[40]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"LLM_1", &CPU::g_state.gte_regs.r32[41]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"LLM_2", &CPU::g_state.gte_regs.r32[42]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"LLM_3", &CPU::g_state.gte_regs.r32[43]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"LLM_4", &CPU::g_state.gte_regs.r32[44]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"RBK", &CPU::g_state.gte_regs.r32[45]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"GBK", &CPU::g_state.gte_regs.r32[46]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"BBK", &CPU::g_state.gte_regs.r32[47]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"LCM_0", &CPU::g_state.gte_regs.r32[48]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"LCM_1", &CPU::g_state.gte_regs.r32[49]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"LCM_2", &CPU::g_state.gte_regs.r32[50]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"LCM_3", &CPU::g_state.gte_regs.r32[51]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"LCM_4", &CPU::g_state.gte_regs.r32[52]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"RFC", &CPU::g_state.gte_regs.r32[53]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"GFC", &CPU::g_state.gte_regs.r32[54]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"BFC", &CPU::g_state.gte_regs.r32[55]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"OFX", &CPU::g_state.gte_regs.r32[56]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"OFY", &CPU::g_state.gte_regs.r32[57]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"H", &CPU::g_state.gte_regs.r32[58]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"DQA", &CPU::g_state.gte_regs.r32[59]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"DQB", &CPU::g_state.gte_regs.r32[60]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"ZSF3", &CPU::g_state.gte_regs.r32[61]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"ZSF4", &CPU::g_state.gte_regs.r32[62]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   {"FLAG", &CPU::g_state.gte_regs.r32[63]}}};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				const std::array<CPU::DebuggerRegisterListEntry, CPU::NUM_DEBUGGER_REGISTER_LIST_ENTRIES>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  CPU::g_debugger_register_list = {{{"zero", &CPU::g_state.regs.zero},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"at", &CPU::g_state.regs.at},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"v0", &CPU::g_state.regs.v0},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"v1", &CPU::g_state.regs.v1},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"a0", &CPU::g_state.regs.a0},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"a1", &CPU::g_state.regs.a1},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"a2", &CPU::g_state.regs.a2},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"a3", &CPU::g_state.regs.a3},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"t0", &CPU::g_state.regs.t0},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"t1", &CPU::g_state.regs.t1},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"t2", &CPU::g_state.regs.t2},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"t3", &CPU::g_state.regs.t3},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"t4", &CPU::g_state.regs.t4},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"t5", &CPU::g_state.regs.t5},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"t6", &CPU::g_state.regs.t6},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"t7", &CPU::g_state.regs.t7},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"s0", &CPU::g_state.regs.s0},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"s1", &CPU::g_state.regs.s1},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"s2", &CPU::g_state.regs.s2},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"s3", &CPU::g_state.regs.s3},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"s4", &CPU::g_state.regs.s4},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"s5", &CPU::g_state.regs.s5},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"s6", &CPU::g_state.regs.s6},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"s7", &CPU::g_state.regs.s7},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"t8", &CPU::g_state.regs.t8},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"t9", &CPU::g_state.regs.t9},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"k0", &CPU::g_state.regs.k0},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"k1", &CPU::g_state.regs.k1},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"gp", &CPU::g_state.regs.gp},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"sp", &CPU::g_state.regs.sp},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"fp", &CPU::g_state.regs.fp},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"ra", &CPU::g_state.regs.ra},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"hi", &CPU::g_state.regs.hi},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"lo", &CPU::g_state.regs.lo},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"pc", &CPU::g_state.pc},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"npc", &CPU::g_state.npc},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"COP0_SR", &CPU::g_state.cop0_regs.sr.bits},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"COP0_CAUSE", &CPU::g_state.cop0_regs.cause.bits},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"COP0_EPC", &CPU::g_state.cop0_regs.EPC},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"COP0_BadVAddr", &CPU::g_state.cop0_regs.BadVaddr},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"V0_XY", &CPU::g_state.gte_regs.r32[0]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"V0_Z", &CPU::g_state.gte_regs.r32[1]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"V1_XY", &CPU::g_state.gte_regs.r32[2]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"V1_Z", &CPU::g_state.gte_regs.r32[3]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"V2_XY", &CPU::g_state.gte_regs.r32[4]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"V2_Z", &CPU::g_state.gte_regs.r32[5]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"RGBC", &CPU::g_state.gte_regs.r32[6]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"OTZ", &CPU::g_state.gte_regs.r32[7]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"IR0", &CPU::g_state.gte_regs.r32[8]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"IR1", &CPU::g_state.gte_regs.r32[9]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"IR2", &CPU::g_state.gte_regs.r32[10]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"IR3", &CPU::g_state.gte_regs.r32[11]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"SXY0", &CPU::g_state.gte_regs.r32[12]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"SXY1", &CPU::g_state.gte_regs.r32[13]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"SXY2", &CPU::g_state.gte_regs.r32[14]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"SXYP", &CPU::g_state.gte_regs.r32[15]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"SZ0", &CPU::g_state.gte_regs.r32[16]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"SZ1", &CPU::g_state.gte_regs.r32[17]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"SZ2", &CPU::g_state.gte_regs.r32[18]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"SZ3", &CPU::g_state.gte_regs.r32[19]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"RGB0", &CPU::g_state.gte_regs.r32[20]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"RGB1", &CPU::g_state.gte_regs.r32[21]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"RGB2", &CPU::g_state.gte_regs.r32[22]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"RES1", &CPU::g_state.gte_regs.r32[23]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"MAC0", &CPU::g_state.gte_regs.r32[24]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"MAC1", &CPU::g_state.gte_regs.r32[25]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"MAC2", &CPU::g_state.gte_regs.r32[26]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"MAC3", &CPU::g_state.gte_regs.r32[27]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"IRGB", &CPU::g_state.gte_regs.r32[28]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"ORGB", &CPU::g_state.gte_regs.r32[29]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"LZCS", &CPU::g_state.gte_regs.r32[30]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"LZCR", &CPU::g_state.gte_regs.r32[31]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"RT_0", &CPU::g_state.gte_regs.r32[32]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"RT_1", &CPU::g_state.gte_regs.r32[33]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"RT_2", &CPU::g_state.gte_regs.r32[34]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"RT_3", &CPU::g_state.gte_regs.r32[35]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"RT_4", &CPU::g_state.gte_regs.r32[36]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"TRX", &CPU::g_state.gte_regs.r32[37]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"TRY", &CPU::g_state.gte_regs.r32[38]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"TRZ", &CPU::g_state.gte_regs.r32[39]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"LLM_0", &CPU::g_state.gte_regs.r32[40]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"LLM_1", &CPU::g_state.gte_regs.r32[41]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"LLM_2", &CPU::g_state.gte_regs.r32[42]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"LLM_3", &CPU::g_state.gte_regs.r32[43]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"LLM_4", &CPU::g_state.gte_regs.r32[44]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"RBK", &CPU::g_state.gte_regs.r32[45]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"GBK", &CPU::g_state.gte_regs.r32[46]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"BBK", &CPU::g_state.gte_regs.r32[47]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"LCM_0", &CPU::g_state.gte_regs.r32[48]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"LCM_1", &CPU::g_state.gte_regs.r32[49]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"LCM_2", &CPU::g_state.gte_regs.r32[50]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"LCM_3", &CPU::g_state.gte_regs.r32[51]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"LCM_4", &CPU::g_state.gte_regs.r32[52]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"RFC", &CPU::g_state.gte_regs.r32[53]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"GFC", &CPU::g_state.gte_regs.r32[54]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"BFC", &CPU::g_state.gte_regs.r32[55]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"OFX", &CPU::g_state.gte_regs.r32[56]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"OFY", &CPU::g_state.gte_regs.r32[57]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"H", &CPU::g_state.gte_regs.r32[58]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"DQA", &CPU::g_state.gte_regs.r32[59]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"DQB", &CPU::g_state.gte_regs.r32[60]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"ZSF3", &CPU::g_state.gte_regs.r32[61]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"ZSF4", &CPU::g_state.gte_regs.r32[62]},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                    {"FLAG", &CPU::g_state.gte_regs.r32[63]}}};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE static constexpr bool AddOverflow(u32 old_value, u32 add_value, u32 new_value)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -800,14 +837,14 @@ ALWAYS_INLINE static constexpr bool SubOverflow(u32 old_value, u32 sub_value, u3
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return (((new_value ^ old_value) & (old_value ^ sub_value)) & UINT32_C(0x80000000)) != 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void DisassembleAndPrint(u32 addr, const char* prefix)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::DisassembleAndPrint(u32 addr, const char* prefix)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  u32 bits = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  SafeReadMemoryWord(addr, &bits);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  PrintInstruction(bits, addr, &g_state.regs, prefix);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void DisassembleAndPrint(u32 addr, u32 instructions_before /* = 0 */, u32 instructions_after /* = 0 */)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::DisassembleAndPrint(u32 addr, u32 instructions_before /* = 0 */, u32 instructions_after /* = 0 */)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  u32 disasm_addr = addr - (instructions_before * sizeof(u32));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  for (u32 i = 0; i < instructions_before; i++)
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -825,7 +862,7 @@ void DisassembleAndPrint(u32 addr, u32 instructions_before /* = 0 */, u32 instru
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template<PGXPMode pgxp_mode, bool debug>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE static void ExecuteInstruction()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE void CPU::ExecuteInstruction()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				restart_instruction:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const Instruction inst = g_state.current_instruction;
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -1798,7 +1835,7 @@ restart_instruction:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void DispatchInterrupt()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::DispatchInterrupt()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // If the instruction we're about to execute is a GTE instruction, delay dispatching the interrupt until the next
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // instruction. For some reason, if we don't do this, we end up with incorrectly sorted polygons and flickering..
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1819,7 +1856,7 @@ void DispatchInterrupt()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  TimingEvents::UpdateCPUDowncount();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void UpdateDebugDispatcherFlag()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::UpdateDebugDispatcherFlag()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const bool has_any_breakpoints = !s_breakpoints.empty();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1840,7 +1877,7 @@ void UpdateDebugDispatcherFlag()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    ExitExecution();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void ExitExecution()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::ExitExecution()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // can't exit while running events without messing things up
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (TimingEvents::IsRunningEvents())
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1849,12 +1886,12 @@ void ExitExecution()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    fastjmp_jmp(&s_jmp_buf, 1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool HasAnyBreakpoints()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool CPU::HasAnyBreakpoints()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return !s_breakpoints.empty();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool HasBreakpointAtAddress(VirtualMemoryAddress address)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool CPU::HasBreakpointAtAddress(VirtualMemoryAddress address)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  for (const Breakpoint& bp : s_breakpoints)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1865,7 +1902,7 @@ bool HasBreakpointAtAddress(VirtualMemoryAddress address)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				BreakpointList GetBreakpointList(bool include_auto_clear, bool include_callbacks)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				CPU::BreakpointList CPU::GetBreakpointList(bool include_auto_clear, bool include_callbacks)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  BreakpointList bps;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  bps.reserve(s_breakpoints.size());
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1883,7 +1920,7 @@ BreakpointList GetBreakpointList(bool include_auto_clear, bool include_callbacks
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return bps;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool AddBreakpoint(VirtualMemoryAddress address, bool auto_clear, bool enabled)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool CPU::AddBreakpoint(VirtualMemoryAddress address, bool auto_clear, bool enabled)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (HasBreakpointAtAddress(address))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return false;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1896,14 +1933,13 @@ bool AddBreakpoint(VirtualMemoryAddress address, bool auto_clear, bool enabled)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (!auto_clear)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Host::ReportFormattedDebuggerMessage(TRANSLATE("DebuggerMessage", "Added breakpoint at 0x%08X."),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                         address);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Host::ReportFormattedDebuggerMessage(TRANSLATE("DebuggerMessage", "Added breakpoint at 0x%08X."), address);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool AddBreakpointWithCallback(VirtualMemoryAddress address, BreakpointCallback callback)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool CPU::AddBreakpointWithCallback(VirtualMemoryAddress address, BreakpointCallback callback)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (HasBreakpointAtAddress(address))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return false;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1916,15 +1952,14 @@ bool AddBreakpointWithCallback(VirtualMemoryAddress address, BreakpointCallback
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool RemoveBreakpoint(VirtualMemoryAddress address)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool CPU::RemoveBreakpoint(VirtualMemoryAddress address)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  auto it = std::find_if(s_breakpoints.begin(), s_breakpoints.end(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                         [address](const Breakpoint& bp) { return bp.address == address; });
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (it == s_breakpoints.end())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Host::ReportFormattedDebuggerMessage(TRANSLATE("DebuggerMessage", "Removed breakpoint at 0x%08X."),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                       address);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Host::ReportFormattedDebuggerMessage(TRANSLATE("DebuggerMessage", "Removed breakpoint at 0x%08X."), address);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  s_breakpoints.erase(it);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  UpdateDebugDispatcherFlag();
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1935,7 +1970,7 @@ bool RemoveBreakpoint(VirtualMemoryAddress address)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void ClearBreakpoints()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::ClearBreakpoints()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  s_breakpoints.clear();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  s_breakpoint_counter = 0;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1943,7 +1978,7 @@ void ClearBreakpoints()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  UpdateDebugDispatcherFlag();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool AddStepOverBreakpoint()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool CPU::AddStepOverBreakpoint()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  u32 bp_pc = g_state.pc;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1955,8 +1990,7 @@ bool AddStepOverBreakpoint()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (!IsCallInstruction(inst))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Host::ReportFormattedDebuggerMessage(TRANSLATE("DebuggerMessage", "0x%08X is not a call instruction."),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                         g_state.pc);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Host::ReportFormattedDebuggerMessage(TRANSLATE("DebuggerMessage", "0x%08X is not a call instruction."), g_state.pc);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1965,8 +1999,8 @@ bool AddStepOverBreakpoint()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (IsBranchInstruction(inst))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Host::ReportFormattedDebuggerMessage(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      TRANSLATE("DebuggerMessage", "Can't step over double branch at 0x%08X"), g_state.pc);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Host::ReportFormattedDebuggerMessage(TRANSLATE("DebuggerMessage", "Can't step over double branch at 0x%08X"),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                         g_state.pc);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1978,7 +2012,7 @@ bool AddStepOverBreakpoint()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return AddBreakpoint(bp_pc, true);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool AddStepOutBreakpoint(u32 max_instructions_to_search)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool CPU::AddStepOutBreakpoint(u32 max_instructions_to_search)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // find the branch-to-ra instruction.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  u32 ret_pc = g_state.pc;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -1990,8 +2024,7 @@ bool AddStepOutBreakpoint(u32 max_instructions_to_search)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!SafeReadInstruction(ret_pc, &inst.bits))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      Host::ReportFormattedDebuggerMessage(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        TRANSLATE("DebuggerMessage", "Instruction read failed at %08X while searching for function end."),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ret_pc);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        TRANSLATE("DebuggerMessage", "Instruction read failed at %08X while searching for function end."), ret_pc);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -2010,7 +2043,7 @@ bool AddStepOutBreakpoint(u32 max_instructions_to_search)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ALWAYS_INLINE_RELEASE static bool BreakpointCheck()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool CPU::BreakpointCheck()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const u32 pc = g_state.pc;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -2085,7 +2118,7 @@ ALWAYS_INLINE_RELEASE static bool BreakpointCheck()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template<PGXPMode pgxp_mode, bool debug>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				[[noreturn]] static void ExecuteImpl()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				[[noreturn]] void CPU::ExecuteImpl()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  for (;;)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -2148,7 +2181,7 @@ template<PGXPMode pgxp_mode, bool debug>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static void ExecuteDebug()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::ExecuteDebug()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (g_settings.gpu_pgxp_enable)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -2163,7 +2196,7 @@ static void ExecuteDebug()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void Execute()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::Execute()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const CPUExecutionMode exec_mode = g_settings.cpu_execution_mode;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const bool use_debug_dispatcher = g_state.use_debug_dispatcher;
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -2208,7 +2241,7 @@ void Execute()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void SingleStep()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::SingleStep()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  s_single_step = true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  s_single_step_done = false;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -2217,10 +2250,8 @@ void SingleStep()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Host::ReportFormattedDebuggerMessage("Stepped to 0x%08X.", g_state.pc);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				namespace CodeCache {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template<PGXPMode pgxp_mode>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void InterpretCachedBlock(const CodeBlock& block)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::CodeCache::InterpretCachedBlock(const CodeBlock& block)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // set up the state so we've already fetched the instruction
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  DebugAssert(g_state.pc == block.GetPC());
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -2256,12 +2287,12 @@ void InterpretCachedBlock(const CodeBlock& block)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.next_instruction_is_branch_delay_slot = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template void InterpretCachedBlock<PGXPMode::Disabled>(const CodeBlock& block);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template void InterpretCachedBlock<PGXPMode::Memory>(const CodeBlock& block);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template void InterpretCachedBlock<PGXPMode::CPU>(const CodeBlock& block);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template void CPU::CodeCache::InterpretCachedBlock<PGXPMode::Disabled>(const CodeBlock& block);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template void CPU::CodeCache::InterpretCachedBlock<PGXPMode::Memory>(const CodeBlock& block);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template void CPU::CodeCache::InterpretCachedBlock<PGXPMode::CPU>(const CodeBlock& block);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template<PGXPMode pgxp_mode>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void InterpretUncachedBlock()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void CPU::CodeCache::InterpretUncachedBlock()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  g_state.npc = g_state.pc;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (!FetchInstructionForInterpreterFallback())
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -2311,26 +2342,18 @@ void InterpretUncachedBlock()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template void InterpretUncachedBlock<PGXPMode::Disabled>();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template void InterpretUncachedBlock<PGXPMode::Memory>();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template void InterpretUncachedBlock<PGXPMode::CPU>();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				} // namespace CodeCache
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				namespace Recompiler::Thunks {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template void CPU::CodeCache::InterpretUncachedBlock<PGXPMode::Disabled>();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template void CPU::CodeCache::InterpretUncachedBlock<PGXPMode::Memory>();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				template void CPU::CodeCache::InterpretUncachedBlock<PGXPMode::CPU>();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool InterpretInstruction()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool CPU::Recompiler::Thunks::InterpretInstruction()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ExecuteInstruction<PGXPMode::Disabled, false>();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return g_state.exception_raised;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool InterpretInstructionPGXP()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool CPU::Recompiler::Thunks::InterpretInstructionPGXP()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ExecuteInstruction<PGXPMode::Memory, false>();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return g_state.exception_raised;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				} // namespace Recompiler::Thunks
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				} // namespace CPU
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |