From 2447f2f36055428a4deb053da9aff474dad49eda Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 30 Jan 2017 21:42:17 +0000 Subject: [PATCH] callbacks: Factorize memory callbacks into inner structure --- include/dynarmic/callbacks.h | 42 ++++++++++--------- src/backend_x64/block_of_code.cpp | 16 +++---- src/backend_x64/emit_x64.cpp | 24 +++++------ src/backend_x64/interface_x64.cpp | 2 +- tests/arm/fuzz_arm.cpp | 20 ++++----- tests/arm/fuzz_thumb.cpp | 20 ++++----- tests/arm/test_thumb_instructions.cpp | 4 +- .../dyncom/arm_dyncom_interpreter.cpp | 2 +- .../skyeye_common/armstate.cpp | 16 +++---- 9 files changed, 74 insertions(+), 72 deletions(-) diff --git a/include/dynarmic/callbacks.h b/include/dynarmic/callbacks.h index dffc2542..83203a8d 100644 --- a/include/dynarmic/callbacks.h +++ b/include/dynarmic/callbacks.h @@ -18,29 +18,31 @@ class Jit; /// These function pointers may be inserted into compiled code. struct UserCallbacks { - // All reads through this callback are 4-byte aligned. - // Memory must be interpreted as little endian. - std::uint32_t (*MemoryReadCode)(std::uint32_t vaddr); + struct Memory { + // All reads through this callback are 4-byte aligned. + // Memory must be interpreted as little endian. + std::uint32_t (*ReadCode)(std::uint32_t vaddr); - // Reads through these callbacks may not be aligned. - // Memory must be interpreted as if ENDIANSTATE == 0, endianness will be corrected by the JIT. - std::uint8_t (*MemoryRead8)(std::uint32_t vaddr); - std::uint16_t (*MemoryRead16)(std::uint32_t vaddr); - std::uint32_t (*MemoryRead32)(std::uint32_t vaddr); - std::uint64_t (*MemoryRead64)(std::uint32_t vaddr); + // Reads through these callbacks may not be aligned. + // Memory must be interpreted as if ENDIANSTATE == 0, endianness will be corrected by the JIT. + std::uint8_t (*Read8)(std::uint32_t vaddr); + std::uint16_t (*Read16)(std::uint32_t vaddr); + std::uint32_t (*Read32)(std::uint32_t vaddr); + std::uint64_t (*Read64)(std::uint32_t vaddr); - // Writes through these callbacks may not be aligned. - // Memory must be interpreted as if ENDIANSTATE == 0, endianness will be corrected by the JIT. - void (*MemoryWrite8)(std::uint32_t vaddr, std::uint8_t value); - void (*MemoryWrite16)(std::uint32_t vaddr, std::uint16_t value); - void (*MemoryWrite32)(std::uint32_t vaddr, std::uint32_t value); - void (*MemoryWrite64)(std::uint32_t vaddr, std::uint64_t value); + // Writes through these callbacks may not be aligned. + // Memory must be interpreted as if ENDIANSTATE == 0, endianness will be corrected by the JIT. + void (*Write8)(std::uint32_t vaddr, std::uint8_t value); + void (*Write16)(std::uint32_t vaddr, std::uint16_t value); + void (*Write32)(std::uint32_t vaddr, std::uint32_t value); + void (*Write64)(std::uint32_t vaddr, std::uint64_t value); - // If this callback returns true, the JIT will assume MemoryRead* callbacks will always - // return the same value at any point in time for this vaddr. The JIT may use this information - // in optimizations. - // An conservative implementation that always returns false is safe. - bool (*IsReadOnlyMemory)(std::uint32_t vaddr); + // If this callback returns true, the JIT will assume MemoryRead* callbacks will always + // return the same value at any point in time for this vaddr. The JIT may use this information + // in optimizations. + // An conservative implementation that always returns false is safe. + bool (*IsReadOnlyMemory)(std::uint32_t vaddr); + } memory = {}; /// The intrepreter must execute only one instruction at PC. void (*InterpreterFallback)(std::uint32_t pc, Jit* jit, void* user_arg); diff --git a/src/backend_x64/block_of_code.cpp b/src/backend_x64/block_of_code.cpp index 3ffc3003..5771dc92 100644 --- a/src/backend_x64/block_of_code.cpp +++ b/src/backend_x64/block_of_code.cpp @@ -124,56 +124,56 @@ void BlockOfCode::GenMemoryAccessors() { align(); read_memory_8 = getCurr(); ABI_PushCallerSaveRegistersAndAdjustStack(this); - CallFunction(cb.MemoryRead8); + CallFunction(cb.memory.Read8); ABI_PopCallerSaveRegistersAndAdjustStack(this); ret(); align(); read_memory_16 = getCurr(); ABI_PushCallerSaveRegistersAndAdjustStack(this); - CallFunction(cb.MemoryRead16); + CallFunction(cb.memory.Read16); ABI_PopCallerSaveRegistersAndAdjustStack(this); ret(); align(); read_memory_32 = getCurr(); ABI_PushCallerSaveRegistersAndAdjustStack(this); - CallFunction(cb.MemoryRead32); + CallFunction(cb.memory.Read32); ABI_PopCallerSaveRegistersAndAdjustStack(this); ret(); align(); read_memory_64 = getCurr(); ABI_PushCallerSaveRegistersAndAdjustStack(this); - CallFunction(cb.MemoryRead64); + CallFunction(cb.memory.Read64); ABI_PopCallerSaveRegistersAndAdjustStack(this); ret(); align(); write_memory_8 = getCurr(); ABI_PushCallerSaveRegistersAndAdjustStack(this); - CallFunction(cb.MemoryWrite8); + CallFunction(cb.memory.Write8); ABI_PopCallerSaveRegistersAndAdjustStack(this); ret(); align(); write_memory_16 = getCurr(); ABI_PushCallerSaveRegistersAndAdjustStack(this); - CallFunction(cb.MemoryWrite16); + CallFunction(cb.memory.Write16); ABI_PopCallerSaveRegistersAndAdjustStack(this); ret(); align(); write_memory_32 = getCurr(); ABI_PushCallerSaveRegistersAndAdjustStack(this); - CallFunction(cb.MemoryWrite32); + CallFunction(cb.memory.Write32); ABI_PopCallerSaveRegistersAndAdjustStack(this); ret(); align(); write_memory_64 = getCurr(); ABI_PushCallerSaveRegistersAndAdjustStack(this); - CallFunction(cb.MemoryWrite64); + CallFunction(cb.memory.Write64); ABI_PopCallerSaveRegistersAndAdjustStack(this); ret(); } diff --git a/src/backend_x64/emit_x64.cpp b/src/backend_x64/emit_x64.cpp index b5d68e4f..eb0c1e0a 100644 --- a/src/backend_x64/emit_x64.cpp +++ b/src/backend_x64/emit_x64.cpp @@ -2866,35 +2866,35 @@ static void WriteMemory(BlockOfCode* code, RegAlloc& reg_alloc, IR::Inst* inst, } void EmitX64::EmitReadMemory8(IR::Block&, IR::Inst* inst) { - ReadMemory(code, reg_alloc, inst, cb, 8, cb.MemoryRead8); + ReadMemory(code, reg_alloc, inst, cb, 8, cb.memory.Read8); } void EmitX64::EmitReadMemory16(IR::Block&, IR::Inst* inst) { - ReadMemory(code, reg_alloc, inst, cb, 16, cb.MemoryRead16); + ReadMemory(code, reg_alloc, inst, cb, 16, cb.memory.Read16); } void EmitX64::EmitReadMemory32(IR::Block&, IR::Inst* inst) { - ReadMemory(code, reg_alloc, inst, cb, 32, cb.MemoryRead32); + ReadMemory(code, reg_alloc, inst, cb, 32, cb.memory.Read32); } void EmitX64::EmitReadMemory64(IR::Block&, IR::Inst* inst) { - ReadMemory(code, reg_alloc, inst, cb, 64, cb.MemoryRead64); + ReadMemory(code, reg_alloc, inst, cb, 64, cb.memory.Read64); } void EmitX64::EmitWriteMemory8(IR::Block&, IR::Inst* inst) { - WriteMemory(code, reg_alloc, inst, cb, 8, cb.MemoryWrite8); + WriteMemory(code, reg_alloc, inst, cb, 8, cb.memory.Write8); } void EmitX64::EmitWriteMemory16(IR::Block&, IR::Inst* inst) { - WriteMemory(code, reg_alloc, inst, cb, 16, cb.MemoryWrite16); + WriteMemory(code, reg_alloc, inst, cb, 16, cb.memory.Write16); } void EmitX64::EmitWriteMemory32(IR::Block&, IR::Inst* inst) { - WriteMemory(code, reg_alloc, inst, cb, 32, cb.MemoryWrite32); + WriteMemory(code, reg_alloc, inst, cb, 32, cb.memory.Write32); } void EmitX64::EmitWriteMemory64(IR::Block&, IR::Inst* inst) { - WriteMemory(code, reg_alloc, inst, cb, 64, cb.MemoryWrite64); + WriteMemory(code, reg_alloc, inst, cb, 64, cb.memory.Write64); } template @@ -2920,15 +2920,15 @@ static void ExclusiveWrite(BlockOfCode* code, RegAlloc& reg_alloc, IR::Inst* ins } void EmitX64::EmitExclusiveWriteMemory8(IR::Block&, IR::Inst* inst) { - ExclusiveWrite(code, reg_alloc, inst, cb.MemoryWrite8); + ExclusiveWrite(code, reg_alloc, inst, cb.memory.Write8); } void EmitX64::EmitExclusiveWriteMemory16(IR::Block&, IR::Inst* inst) { - ExclusiveWrite(code, reg_alloc, inst, cb.MemoryWrite16); + ExclusiveWrite(code, reg_alloc, inst, cb.memory.Write16); } void EmitX64::EmitExclusiveWriteMemory32(IR::Block&, IR::Inst* inst) { - ExclusiveWrite(code, reg_alloc, inst, cb.MemoryWrite32); + ExclusiveWrite(code, reg_alloc, inst, cb.memory.Write32); } void EmitX64::EmitExclusiveWriteMemory64(IR::Block&, IR::Inst* inst) { @@ -2952,7 +2952,7 @@ void EmitX64::EmitExclusiveWriteMemory64(IR::Block&, IR::Inst* inst) { code->mov(value.cvt32(), value.cvt32()); // zero extend to 64-bits code->shl(value_hi, 32); code->or_(value, value_hi); - code->CallFunction(cb.MemoryWrite64); + code->CallFunction(cb.memory.Write64); code->xor_(passed, passed); code->L(end); } diff --git a/src/backend_x64/interface_x64.cpp b/src/backend_x64/interface_x64.cpp index 84c00a16..78123370 100644 --- a/src/backend_x64/interface_x64.cpp +++ b/src/backend_x64/interface_x64.cpp @@ -103,7 +103,7 @@ private: if (block) return *block; - IR::Block ir_block = Arm::Translate(descriptor, callbacks.MemoryReadCode); + IR::Block ir_block = Arm::Translate(descriptor, callbacks.memory.ReadCode); Optimization::GetSetElimination(ir_block); Optimization::DeadCodeElimination(ir_block); Optimization::VerificationPass(ir_block); diff --git a/tests/arm/fuzz_arm.cpp b/tests/arm/fuzz_arm.cpp index 7f6e705c..cdd56978 100644 --- a/tests/arm/fuzz_arm.cpp +++ b/tests/arm/fuzz_arm.cpp @@ -127,16 +127,16 @@ static Dynarmic::UserCallbacks GetUserCallbacks() { Dynarmic::UserCallbacks user_callbacks{}; user_callbacks.InterpreterFallback = &InterpreterFallback; user_callbacks.CallSVC = (void (*)(u32)) &Fail; - user_callbacks.IsReadOnlyMemory = &IsReadOnlyMemory; - user_callbacks.MemoryRead8 = &MemoryRead8; - user_callbacks.MemoryRead16 = &MemoryRead16; - user_callbacks.MemoryRead32 = &MemoryRead32; - user_callbacks.MemoryRead64 = &MemoryRead64; - user_callbacks.MemoryReadCode = &MemoryReadCode; - user_callbacks.MemoryWrite8 = &MemoryWrite8; - user_callbacks.MemoryWrite16 = &MemoryWrite16; - user_callbacks.MemoryWrite32 = &MemoryWrite32; - user_callbacks.MemoryWrite64 = &MemoryWrite64; + user_callbacks.memory.IsReadOnlyMemory = &IsReadOnlyMemory; + user_callbacks.memory.Read8 = &MemoryRead8; + user_callbacks.memory.Read16 = &MemoryRead16; + user_callbacks.memory.Read32 = &MemoryRead32; + user_callbacks.memory.Read64 = &MemoryRead64; + user_callbacks.memory.ReadCode = &MemoryReadCode; + user_callbacks.memory.Write8 = &MemoryWrite8; + user_callbacks.memory.Write16 = &MemoryWrite16; + user_callbacks.memory.Write32 = &MemoryWrite32; + user_callbacks.memory.Write64 = &MemoryWrite64; return user_callbacks; } diff --git a/tests/arm/fuzz_thumb.cpp b/tests/arm/fuzz_thumb.cpp index 38f4db0e..e1287c10 100644 --- a/tests/arm/fuzz_thumb.cpp +++ b/tests/arm/fuzz_thumb.cpp @@ -118,16 +118,16 @@ static Dynarmic::UserCallbacks GetUserCallbacks() { Dynarmic::UserCallbacks user_callbacks{}; user_callbacks.InterpreterFallback = &InterpreterFallback; user_callbacks.CallSVC = (void (*)(u32)) &Fail; - user_callbacks.IsReadOnlyMemory = &IsReadOnlyMemory; - user_callbacks.MemoryRead8 = &MemoryRead8; - user_callbacks.MemoryRead16 = &MemoryRead16; - user_callbacks.MemoryRead32 = &MemoryRead32; - user_callbacks.MemoryRead64 = &MemoryRead64; - user_callbacks.MemoryReadCode = &MemoryReadCode; - user_callbacks.MemoryWrite8 = &MemoryWrite8; - user_callbacks.MemoryWrite16 = &MemoryWrite16; - user_callbacks.MemoryWrite32 = &MemoryWrite32; - user_callbacks.MemoryWrite64 = &MemoryWrite64; + user_callbacks.memory.IsReadOnlyMemory = &IsReadOnlyMemory; + user_callbacks.memory.Read8 = &MemoryRead8; + user_callbacks.memory.Read16 = &MemoryRead16; + user_callbacks.memory.Read32 = &MemoryRead32; + user_callbacks.memory.Read64 = &MemoryRead64; + user_callbacks.memory.ReadCode = &MemoryReadCode; + user_callbacks.memory.Write8 = &MemoryWrite8; + user_callbacks.memory.Write16 = &MemoryWrite16; + user_callbacks.memory.Write32 = &MemoryWrite32; + user_callbacks.memory.Write64 = &MemoryWrite64; return user_callbacks; } diff --git a/tests/arm/test_thumb_instructions.cpp b/tests/arm/test_thumb_instructions.cpp index 6f992d58..07fdcbd4 100644 --- a/tests/arm/test_thumb_instructions.cpp +++ b/tests/arm/test_thumb_instructions.cpp @@ -48,8 +48,8 @@ static void InterpreterFallback(u32 pc, Dynarmic::Jit* jit, void*) { static Dynarmic::UserCallbacks GetUserCallbacks() { Dynarmic::UserCallbacks user_callbacks{}; - user_callbacks.MemoryRead32 = &MemoryRead32; - user_callbacks.MemoryReadCode = &MemoryReadCode; + user_callbacks.memory.Read32 = &MemoryRead32; + user_callbacks.memory.ReadCode = &MemoryReadCode; user_callbacks.InterpreterFallback = &InterpreterFallback; return user_callbacks; } diff --git a/tests/skyeye_interpreter/dyncom/arm_dyncom_interpreter.cpp b/tests/skyeye_interpreter/dyncom/arm_dyncom_interpreter.cpp index 3c12697e..6a8b70c4 100644 --- a/tests/skyeye_interpreter/dyncom/arm_dyncom_interpreter.cpp +++ b/tests/skyeye_interpreter/dyncom/arm_dyncom_interpreter.cpp @@ -803,7 +803,7 @@ enum { static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, const u32 phys_addr, ARM_INST_PTR& inst_base) { unsigned int inst_size = 4; - unsigned int inst = (*cpu->user_callbacks.MemoryReadCode)(phys_addr & 0xFFFFFFFC); + unsigned int inst = (*cpu->user_callbacks.memory.ReadCode)(phys_addr & 0xFFFFFFFC); // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM instruction if (cpu->TFlag) { diff --git a/tests/skyeye_interpreter/skyeye_common/armstate.cpp b/tests/skyeye_interpreter/skyeye_common/armstate.cpp index cbf08a78..d57d1b9e 100644 --- a/tests/skyeye_interpreter/skyeye_common/armstate.cpp +++ b/tests/skyeye_interpreter/skyeye_common/armstate.cpp @@ -204,14 +204,14 @@ u8 ARMul_State::ReadMemory8(u32 address) const { // CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); - return (*user_callbacks.MemoryRead8)(address); + return (*user_callbacks.memory.Read8)(address); } u16 ARMul_State::ReadMemory16(u32 address) const { // CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); - u16 data = (*user_callbacks.MemoryRead16)(address); + u16 data = (*user_callbacks.memory.Read16)(address); if (InBigEndianMode()) data = Common::swap16(data); @@ -223,7 +223,7 @@ u32 ARMul_State::ReadMemory32(u32 address) const { // CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); - u32 data = (*user_callbacks.MemoryRead32)(address); + u32 data = (*user_callbacks.memory.Read32)(address); if (InBigEndianMode()) data = Common::swap32(data); @@ -235,7 +235,7 @@ u64 ARMul_State::ReadMemory64(u32 address) const { // CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); - u64 data = (*user_callbacks.MemoryRead64)(address); + u64 data = (*user_callbacks.memory.Read64)(address); if (InBigEndianMode()) data = Common::swap64(data); @@ -247,7 +247,7 @@ void ARMul_State::WriteMemory8(u32 address, u8 data) { // CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write); - (*user_callbacks.MemoryWrite8)(address, data); + (*user_callbacks.memory.Write8)(address, data); } void ARMul_State::WriteMemory16(u32 address, u16 data) @@ -257,7 +257,7 @@ void ARMul_State::WriteMemory16(u32 address, u16 data) if (InBigEndianMode()) data = Common::swap16(data); - (*user_callbacks.MemoryWrite16)(address, data); + (*user_callbacks.memory.Write16)(address, data); } void ARMul_State::WriteMemory32(u32 address, u32 data) @@ -267,7 +267,7 @@ void ARMul_State::WriteMemory32(u32 address, u32 data) if (InBigEndianMode()) data = Common::swap32(data); - (*user_callbacks.MemoryWrite32)(address, data); + (*user_callbacks.memory.Write32)(address, data); } void ARMul_State::WriteMemory64(u32 address, u64 data) @@ -277,7 +277,7 @@ void ARMul_State::WriteMemory64(u32 address, u64 data) if (InBigEndianMode()) data = Common::swap64(data); - (*user_callbacks.MemoryWrite64)(address, data); + (*user_callbacks.memory.Write64)(address, data); }