mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	externals: Update dynarmic to 7a2a4c8
This commit is contained in:
		
							parent
							
								
									9b9227089b
								
							
						
					
					
						commit
						75f3d2ba31
					
				
					 5 changed files with 101 additions and 67 deletions
				
			
		|  | @ -3,8 +3,8 @@ | |||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <cstring> | ||||
| #include <dynarmic/context.h> | ||||
| #include <dynarmic/dynarmic.h> | ||||
| #include <dynarmic/A32/a32.h> | ||||
| #include <dynarmic/A32/context.h> | ||||
| #include "common/assert.h" | ||||
| #include "common/microprofile.h" | ||||
| #include "core/arm/dynarmic/arm_dynarmic.h" | ||||
|  | @ -64,86 +64,101 @@ public: | |||
| private: | ||||
|     friend class ARM_Dynarmic; | ||||
| 
 | ||||
|     Dynarmic::Context ctx; | ||||
|     Dynarmic::A32::Context ctx; | ||||
|     u32 fpexc; | ||||
| }; | ||||
| 
 | ||||
| static void InterpreterFallback(u32 pc, Dynarmic::Jit* jit, void* user_arg) { | ||||
|     ARMul_State* state = static_cast<ARMul_State*>(user_arg); | ||||
| class DynarmicUserCallbacks final : public Dynarmic::A32::UserCallbacks { | ||||
| public: | ||||
|     explicit DynarmicUserCallbacks(ARM_Dynarmic& parent) : parent(parent) {} | ||||
|     ~DynarmicUserCallbacks() = default; | ||||
| 
 | ||||
|     state->Reg = jit->Regs(); | ||||
|     state->Cpsr = jit->Cpsr(); | ||||
|     state->Reg[15] = pc; | ||||
|     state->ExtReg = jit->ExtRegs(); | ||||
|     state->VFP[VFP_FPSCR] = jit->Fpscr(); | ||||
|     state->NumInstrsToExecute = 1; | ||||
|     std::uint8_t MemoryRead8(VAddr vaddr) override { | ||||
|         return Memory::Read8(vaddr); | ||||
|     } | ||||
|     std::uint16_t MemoryRead16(VAddr vaddr) override { | ||||
|         return Memory::Read16(vaddr); | ||||
|     } | ||||
|     std::uint32_t MemoryRead32(VAddr vaddr) override { | ||||
|         return Memory::Read32(vaddr); | ||||
|     } | ||||
|     std::uint64_t MemoryRead64(VAddr vaddr) override { | ||||
|         return Memory::Read64(vaddr); | ||||
|     } | ||||
| 
 | ||||
|     InterpreterMainLoop(state); | ||||
|     void MemoryWrite8(VAddr vaddr, std::uint8_t value) override { | ||||
|         Memory::Write8(vaddr, value); | ||||
|     } | ||||
|     void MemoryWrite16(VAddr vaddr, std::uint16_t value) override { | ||||
|         Memory::Write16(vaddr, value); | ||||
|     } | ||||
|     void MemoryWrite32(VAddr vaddr, std::uint32_t value) override { | ||||
|         Memory::Write32(vaddr, value); | ||||
|     } | ||||
|     void MemoryWrite64(VAddr vaddr, std::uint64_t value) override { | ||||
|         Memory::Write64(vaddr, value); | ||||
|     } | ||||
| 
 | ||||
|     bool is_thumb = (state->Cpsr & (1 << 5)) != 0; | ||||
|     state->Reg[15] &= (is_thumb ? 0xFFFFFFFE : 0xFFFFFFFC); | ||||
|     void InterpreterFallback(VAddr pc, size_t num_instructions) override { | ||||
|         parent.interpreter_state->Reg = parent.jit->Regs(); | ||||
|         parent.interpreter_state->Cpsr = parent.jit->Cpsr(); | ||||
|         parent.interpreter_state->Reg[15] = pc; | ||||
|         parent.interpreter_state->ExtReg = parent.jit->ExtRegs(); | ||||
|         parent.interpreter_state->VFP[VFP_FPSCR] = parent.jit->Fpscr(); | ||||
|         parent.interpreter_state->NumInstrsToExecute = num_instructions; | ||||
| 
 | ||||
|     jit->Regs() = state->Reg; | ||||
|     jit->SetCpsr(state->Cpsr); | ||||
|     jit->ExtRegs() = state->ExtReg; | ||||
|     jit->SetFpscr(state->VFP[VFP_FPSCR]); | ||||
|         InterpreterMainLoop(parent.interpreter_state.get()); | ||||
| 
 | ||||
|     state->ServeBreak(); | ||||
| } | ||||
|         bool is_thumb = (parent.interpreter_state->Cpsr & (1 << 5)) != 0; | ||||
|         parent.interpreter_state->Reg[15] &= (is_thumb ? 0xFFFFFFFE : 0xFFFFFFFC); | ||||
| 
 | ||||
| static bool IsReadOnlyMemory(u32 vaddr) { | ||||
|     // TODO(bunnei): ImplementMe
 | ||||
|     return false; | ||||
| } | ||||
|         parent.jit->Regs() = parent.interpreter_state->Reg; | ||||
|         parent.jit->SetCpsr(parent.interpreter_state->Cpsr); | ||||
|         parent.jit->ExtRegs() = parent.interpreter_state->ExtReg; | ||||
|         parent.jit->SetFpscr(parent.interpreter_state->VFP[VFP_FPSCR]); | ||||
| 
 | ||||
| static void AddTicks(u64 ticks) { | ||||
|     CoreTiming::AddTicks(ticks); | ||||
| } | ||||
|         parent.interpreter_state->ServeBreak(); | ||||
|     } | ||||
| 
 | ||||
| static u64 GetTicksRemaining() { | ||||
|     s64 ticks = CoreTiming::GetDowncount(); | ||||
|     return static_cast<u64>(ticks <= 0 ? 0 : ticks); | ||||
| } | ||||
|     void CallSVC(std::uint32_t swi) override { | ||||
|         Kernel::CallSVC(swi); | ||||
|     } | ||||
| 
 | ||||
| static Dynarmic::UserCallbacks GetUserCallbacks( | ||||
|     const std::shared_ptr<ARMul_State>& interpreter_state, Memory::PageTable* current_page_table) { | ||||
|     Dynarmic::UserCallbacks user_callbacks{}; | ||||
|     user_callbacks.InterpreterFallback = &InterpreterFallback; | ||||
|     user_callbacks.user_arg = static_cast<void*>(interpreter_state.get()); | ||||
|     user_callbacks.CallSVC = &Kernel::CallSVC; | ||||
|     user_callbacks.memory.IsReadOnlyMemory = &IsReadOnlyMemory; | ||||
|     user_callbacks.memory.ReadCode = &Memory::Read32; | ||||
|     user_callbacks.memory.Read8 = &Memory::Read8; | ||||
|     user_callbacks.memory.Read16 = &Memory::Read16; | ||||
|     user_callbacks.memory.Read32 = &Memory::Read32; | ||||
|     user_callbacks.memory.Read64 = &Memory::Read64; | ||||
|     user_callbacks.memory.Write8 = &Memory::Write8; | ||||
|     user_callbacks.memory.Write16 = &Memory::Write16; | ||||
|     user_callbacks.memory.Write32 = &Memory::Write32; | ||||
|     user_callbacks.memory.Write64 = &Memory::Write64; | ||||
|     user_callbacks.AddTicks = &AddTicks; | ||||
|     user_callbacks.GetTicksRemaining = &GetTicksRemaining; | ||||
|     user_callbacks.page_table = ¤t_page_table->pointers; | ||||
|     user_callbacks.coprocessors[15] = std::make_shared<DynarmicCP15>(interpreter_state); | ||||
|     return user_callbacks; | ||||
| } | ||||
|     void ExceptionRaised(VAddr pc, Dynarmic::A32::Exception exception) override { | ||||
|         ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:X})", | ||||
|                    static_cast<size_t>(exception), pc); | ||||
|     } | ||||
| 
 | ||||
| ARM_Dynarmic::ARM_Dynarmic(PrivilegeMode initial_mode) { | ||||
|     void AddTicks(std::uint64_t ticks) override { | ||||
|         CoreTiming::AddTicks(ticks); | ||||
|     } | ||||
|     std::uint64_t GetTicksRemaining() override { | ||||
|         s64 ticks = CoreTiming::GetDowncount(); | ||||
|         return static_cast<u64>(ticks <= 0 ? 0 : ticks); | ||||
|     } | ||||
| 
 | ||||
|     ARM_Dynarmic& parent; | ||||
| }; | ||||
| 
 | ||||
| ARM_Dynarmic::ARM_Dynarmic(PrivilegeMode initial_mode) | ||||
|     : cb(std::make_unique<DynarmicUserCallbacks>(*this)) { | ||||
|     interpreter_state = std::make_shared<ARMul_State>(initial_mode); | ||||
|     PageTableChanged(); | ||||
| } | ||||
| 
 | ||||
| ARM_Dynarmic::~ARM_Dynarmic() = default; | ||||
| 
 | ||||
| MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64)); | ||||
| 
 | ||||
| void ARM_Dynarmic::Run() { | ||||
|     ASSERT(Memory::GetCurrentPageTable() == current_page_table); | ||||
|     MICROPROFILE_SCOPE(ARM_Jit); | ||||
| 
 | ||||
|     jit->Run(GetTicksRemaining()); | ||||
|     jit->Run(); | ||||
| } | ||||
| 
 | ||||
| void ARM_Dynarmic::Step() { | ||||
|     InterpreterFallback(jit->Regs()[15], jit, static_cast<void*>(interpreter_state.get())); | ||||
|     cb->InterpreterFallback(jit->Regs()[15], 1); | ||||
| } | ||||
| 
 | ||||
| void ARM_Dynarmic::SetPC(u32 pc) { | ||||
|  | @ -251,6 +266,16 @@ void ARM_Dynarmic::PageTableChanged() { | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     jit = new Dynarmic::Jit(GetUserCallbacks(interpreter_state, current_page_table)); | ||||
|     jits.emplace(current_page_table, std::unique_ptr<Dynarmic::Jit>(jit)); | ||||
|     auto new_jit = MakeJit(); | ||||
|     jit = new_jit.get(); | ||||
|     jits.emplace(current_page_table, std::move(new_jit)); | ||||
| } | ||||
| 
 | ||||
| std::unique_ptr<Dynarmic::A32::Jit> ARM_Dynarmic::MakeJit() { | ||||
|     Dynarmic::A32::UserConfig config; | ||||
|     config.callbacks = cb.get(); | ||||
|     config.page_table = ¤t_page_table->pointers; | ||||
|     config.coprocessors[15] = std::make_shared<DynarmicCP15>(interpreter_state); | ||||
|     config.define_unpredictable_behaviour = true; | ||||
|     return std::make_unique<Dynarmic::A32::Jit>(config); | ||||
| } | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ | |||
| 
 | ||||
| #include <map> | ||||
| #include <memory> | ||||
| #include <dynarmic/dynarmic.h> | ||||
| #include <dynarmic/A32/a32.h> | ||||
| #include "common/common_types.h" | ||||
| #include "core/arm/arm_interface.h" | ||||
| #include "core/arm/skyeye_common/armstate.h" | ||||
|  | @ -15,9 +15,12 @@ namespace Memory { | |||
| struct PageTable; | ||||
| } // namespace Memory
 | ||||
| 
 | ||||
| class DynarmicUserCallbacks; | ||||
| 
 | ||||
| class ARM_Dynarmic final : public ARM_Interface { | ||||
| public: | ||||
|     explicit ARM_Dynarmic(PrivilegeMode initial_mode); | ||||
|     ~ARM_Dynarmic(); | ||||
| 
 | ||||
|     void Run() override; | ||||
|     void Step() override; | ||||
|  | @ -46,8 +49,12 @@ public: | |||
|     void PageTableChanged() override; | ||||
| 
 | ||||
| private: | ||||
|     Dynarmic::Jit* jit = nullptr; | ||||
|     friend class DynarmicUserCallbacks; | ||||
|     std::unique_ptr<DynarmicUserCallbacks> cb; | ||||
|     std::unique_ptr<Dynarmic::A32::Jit> MakeJit(); | ||||
| 
 | ||||
|     Dynarmic::A32::Jit* jit = nullptr; | ||||
|     Memory::PageTable* current_page_table = nullptr; | ||||
|     std::map<Memory::PageTable*, std::unique_ptr<Dynarmic::Jit>> jits; | ||||
|     std::map<Memory::PageTable*, std::unique_ptr<Dynarmic::A32::Jit>> jits; | ||||
|     std::shared_ptr<ARMul_State> interpreter_state; | ||||
| }; | ||||
|  |  | |||
|  | @ -6,9 +6,9 @@ | |||
| #include "core/arm/skyeye_common/arm_regformat.h" | ||||
| #include "core/arm/skyeye_common/armstate.h" | ||||
| 
 | ||||
| using Callback = Dynarmic::Coprocessor::Callback; | ||||
| using CallbackOrAccessOneWord = Dynarmic::Coprocessor::CallbackOrAccessOneWord; | ||||
| using CallbackOrAccessTwoWords = Dynarmic::Coprocessor::CallbackOrAccessTwoWords; | ||||
| using Callback = Dynarmic::A32::Coprocessor::Callback; | ||||
| using CallbackOrAccessOneWord = Dynarmic::A32::Coprocessor::CallbackOrAccessOneWord; | ||||
| using CallbackOrAccessTwoWords = Dynarmic::A32::Coprocessor::CallbackOrAccessTwoWords; | ||||
| 
 | ||||
| DynarmicCP15::DynarmicCP15(const std::shared_ptr<ARMul_State>& state) : interpreter_state(state) {} | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,13 +5,15 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <memory> | ||||
| #include <dynarmic/coprocessor.h> | ||||
| #include <dynarmic/A32/coprocessor.h> | ||||
| #include "common/common_types.h" | ||||
| 
 | ||||
| struct ARMul_State; | ||||
| 
 | ||||
| class DynarmicCP15 final : public Dynarmic::Coprocessor { | ||||
| class DynarmicCP15 final : public Dynarmic::A32::Coprocessor { | ||||
| public: | ||||
|     using CoprocReg = Dynarmic::A32::CoprocReg; | ||||
| 
 | ||||
|     explicit DynarmicCP15(const std::shared_ptr<ARMul_State>&); | ||||
|     ~DynarmicCP15() override; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue