mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-20 17:36:10 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b42fe803f |
@@ -23,66 +23,30 @@
|
|||||||
|
|
||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
|
||||||
static void* EmitCallReadTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
|
||||||
using namespace oaknut::util;
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
|
||||||
oaknut::Label l_addr, l_this;
|
|
||||||
void* target = code.xptr<void*>();
|
|
||||||
// params = { this, vaddr, bitsize }
|
|
||||||
code.LDR(X0, l_this);
|
|
||||||
// X1 = vaddr
|
|
||||||
code.MOV(X2, bitsize);
|
|
||||||
code.LDR(Xscratch0, l_addr);
|
|
||||||
code.BR(Xscratch0);
|
|
||||||
code.align(8);
|
|
||||||
code.l(l_this);
|
|
||||||
code.dx(info.this_ptr);
|
|
||||||
code.l(l_addr);
|
|
||||||
code.dx(info.fn_ptr);
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
|
||||||
static void* EmitCallWriteTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
|
||||||
using namespace oaknut::util;
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
|
||||||
oaknut::Label l_addr, l_this;
|
|
||||||
void* target = code.xptr<void*>();
|
|
||||||
// params = { this, vaddr, value, bitsize }
|
|
||||||
code.LDR(X0, l_this);
|
|
||||||
// X1 = vaddr
|
|
||||||
// X2 = value
|
|
||||||
code.MOV(X3, bitsize);
|
|
||||||
code.LDR(Xscratch0, l_addr);
|
|
||||||
code.BR(Xscratch0);
|
|
||||||
code.align(8);
|
|
||||||
code.l(l_this);
|
|
||||||
code.dx(info.this_ptr);
|
|
||||||
code.l(l_addr);
|
|
||||||
code.dx(info.fn_ptr);
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
template<auto mfp, typename T>
|
||||||
static void* EmitCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
static void* EmitCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
|
|
||||||
oaknut::Label l_addr, l_this;
|
oaknut::Label l_addr, l_this;
|
||||||
|
|
||||||
void* target = code.xptr<void*>();
|
void* target = code.xptr<void*>();
|
||||||
code.LDR(X0, l_this);
|
code.LDR(X0, l_this);
|
||||||
code.LDR(Xscratch0, l_addr);
|
code.LDR(Xscratch0, l_addr);
|
||||||
code.BR(Xscratch0);
|
code.BR(Xscratch0);
|
||||||
|
|
||||||
code.align(8);
|
code.align(8);
|
||||||
code.l(l_this);
|
code.l(l_this);
|
||||||
code.dx(info.this_ptr);
|
code.dx(info.this_ptr);
|
||||||
code.l(l_addr);
|
code.l(l_addr);
|
||||||
code.dx(info.fn_ptr);
|
code.dx(info.fn_ptr);
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
template<auto mfp, typename T>
|
||||||
static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
@@ -95,7 +59,6 @@ static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_
|
|||||||
ABI_PushRegisters(code, save_regs, 0);
|
ABI_PushRegisters(code, save_regs, 0);
|
||||||
code.LDR(X0, l_this);
|
code.LDR(X0, l_this);
|
||||||
code.MOV(X1, Xscratch0);
|
code.MOV(X1, Xscratch0);
|
||||||
code.MOV(X2, bitsize);
|
|
||||||
code.LDR(Xscratch0, l_addr);
|
code.LDR(Xscratch0, l_addr);
|
||||||
code.BLR(Xscratch0);
|
code.BLR(Xscratch0);
|
||||||
code.MOV(Xscratch0, X0);
|
code.MOV(Xscratch0, X0);
|
||||||
@@ -138,7 +101,7 @@ static void* EmitExclusiveReadCallTrampoline(oaknut::CodeGenerator& code, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
template<auto mfp, typename T>
|
||||||
static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
@@ -152,7 +115,6 @@ static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this
|
|||||||
code.LDR(X0, l_this);
|
code.LDR(X0, l_this);
|
||||||
code.MOV(X1, Xscratch0);
|
code.MOV(X1, Xscratch0);
|
||||||
code.MOV(X2, Xscratch1);
|
code.MOV(X2, Xscratch1);
|
||||||
code.MOV(X3, bitsize);
|
|
||||||
code.LDR(Xscratch0, l_addr);
|
code.LDR(Xscratch0, l_addr);
|
||||||
code.BLR(Xscratch0);
|
code.BLR(Xscratch0);
|
||||||
ABI_PopRegisters(code, save_regs, 0);
|
ABI_PopRegisters(code, save_regs, 0);
|
||||||
@@ -214,27 +176,14 @@ void A32AddressSpace::EmitPrelude() {
|
|||||||
|
|
||||||
UnprotectCodeMemory();
|
UnprotectCodeMemory();
|
||||||
|
|
||||||
|
prelude_info.read_memory = EmitCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks);
|
||||||
prelude_info.read_memory_8 = EmitCallReadTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u8));
|
prelude_info.wrapped_read_memory = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks);
|
||||||
prelude_info.read_memory_16 = EmitCallReadTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u16));
|
|
||||||
prelude_info.read_memory_32 = EmitCallReadTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u32));
|
|
||||||
prelude_info.read_memory_64 = EmitCallReadTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u64));
|
|
||||||
prelude_info.wrapped_read_memory_8 = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u8));
|
|
||||||
prelude_info.wrapped_read_memory_16 = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u16));
|
|
||||||
prelude_info.wrapped_read_memory_32 = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u32));
|
|
||||||
prelude_info.wrapped_read_memory_64 = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u64));
|
|
||||||
prelude_info.exclusive_read_memory_8 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u8>(code, conf);
|
prelude_info.exclusive_read_memory_8 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u8>(code, conf);
|
||||||
prelude_info.exclusive_read_memory_16 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u16>(code, conf);
|
prelude_info.exclusive_read_memory_16 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u16>(code, conf);
|
||||||
prelude_info.exclusive_read_memory_32 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u32>(code, conf);
|
prelude_info.exclusive_read_memory_32 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u32>(code, conf);
|
||||||
prelude_info.exclusive_read_memory_64 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u64>(code, conf);
|
prelude_info.exclusive_read_memory_64 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u64>(code, conf);
|
||||||
prelude_info.write_memory_8 = EmitCallWriteTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u8));
|
prelude_info.write_memory = EmitCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks);
|
||||||
prelude_info.write_memory_16 = EmitCallWriteTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u16));
|
prelude_info.wrapped_write_memory = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks);
|
||||||
prelude_info.write_memory_32 = EmitCallWriteTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u32));
|
|
||||||
prelude_info.write_memory_64 = EmitCallWriteTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u64));
|
|
||||||
prelude_info.wrapped_write_memory_8 = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u8));
|
|
||||||
prelude_info.wrapped_write_memory_16 = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u16));
|
|
||||||
prelude_info.wrapped_write_memory_32 = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u32));
|
|
||||||
prelude_info.wrapped_write_memory_64 = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u64));
|
|
||||||
prelude_info.exclusive_write_memory_8 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive8, u8>(code, conf);
|
prelude_info.exclusive_write_memory_8 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive8, u8>(code, conf);
|
||||||
prelude_info.exclusive_write_memory_16 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive16, u16>(code, conf);
|
prelude_info.exclusive_write_memory_16 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive16, u16>(code, conf);
|
||||||
prelude_info.exclusive_write_memory_32 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive32, u32>(code, conf);
|
prelude_info.exclusive_write_memory_32 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive32, u32>(code, conf);
|
||||||
|
|||||||
@@ -22,66 +22,30 @@
|
|||||||
|
|
||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
|
||||||
static void* EmitCallReadTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
|
||||||
using namespace oaknut::util;
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
|
||||||
oaknut::Label l_addr, l_this;
|
|
||||||
void* target = code.xptr<void*>();
|
|
||||||
// params = { this, vaddr, bitsize }
|
|
||||||
code.LDR(X0, l_this);
|
|
||||||
// X1 = vaddr
|
|
||||||
code.MOV(X2, bitsize);
|
|
||||||
code.LDR(Xscratch0, l_addr);
|
|
||||||
code.BR(Xscratch0);
|
|
||||||
code.align(8);
|
|
||||||
code.l(l_this);
|
|
||||||
code.dx(info.this_ptr);
|
|
||||||
code.l(l_addr);
|
|
||||||
code.dx(info.fn_ptr);
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
|
||||||
static void* EmitCallWriteTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
|
||||||
using namespace oaknut::util;
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
|
||||||
oaknut::Label l_addr, l_this;
|
|
||||||
void* target = code.xptr<void*>();
|
|
||||||
// params = { this, vaddr, value, bitsize }
|
|
||||||
code.LDR(X0, l_this);
|
|
||||||
// X1 = vaddr
|
|
||||||
// X2 = value
|
|
||||||
code.MOV(X3, bitsize);
|
|
||||||
code.LDR(Xscratch0, l_addr);
|
|
||||||
code.BR(Xscratch0);
|
|
||||||
code.align(8);
|
|
||||||
code.l(l_this);
|
|
||||||
code.dx(info.this_ptr);
|
|
||||||
code.l(l_addr);
|
|
||||||
code.dx(info.fn_ptr);
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
template<auto mfp, typename T>
|
||||||
static void* EmitCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
static void* EmitCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
|
|
||||||
oaknut::Label l_addr, l_this;
|
oaknut::Label l_addr, l_this;
|
||||||
|
|
||||||
void* target = code.xptr<void*>();
|
void* target = code.xptr<void*>();
|
||||||
code.LDR(X0, l_this);
|
code.LDR(X0, l_this);
|
||||||
code.LDR(Xscratch0, l_addr);
|
code.LDR(Xscratch0, l_addr);
|
||||||
code.BR(Xscratch0);
|
code.BR(Xscratch0);
|
||||||
|
|
||||||
code.align(8);
|
code.align(8);
|
||||||
code.l(l_this);
|
code.l(l_this);
|
||||||
code.dx(info.this_ptr);
|
code.dx(info.this_ptr);
|
||||||
code.l(l_addr);
|
code.l(l_addr);
|
||||||
code.dx(info.fn_ptr);
|
code.dx(info.fn_ptr);
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
template<auto mfp, typename T>
|
||||||
static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
@@ -94,7 +58,6 @@ static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_
|
|||||||
ABI_PushRegisters(code, save_regs, 0);
|
ABI_PushRegisters(code, save_regs, 0);
|
||||||
code.LDR(X0, l_this);
|
code.LDR(X0, l_this);
|
||||||
code.MOV(X1, Xscratch0);
|
code.MOV(X1, Xscratch0);
|
||||||
code.MOV(X2, bitsize);
|
|
||||||
code.LDR(Xscratch0, l_addr);
|
code.LDR(Xscratch0, l_addr);
|
||||||
code.BLR(Xscratch0);
|
code.BLR(Xscratch0);
|
||||||
code.MOV(Xscratch0, X0);
|
code.MOV(Xscratch0, X0);
|
||||||
@@ -137,7 +100,7 @@ static void* EmitExclusiveReadCallTrampoline(oaknut::CodeGenerator& code, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
template<auto mfp, typename T>
|
||||||
static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
@@ -151,7 +114,6 @@ static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this
|
|||||||
code.LDR(X0, l_this);
|
code.LDR(X0, l_this);
|
||||||
code.MOV(X1, Xscratch0);
|
code.MOV(X1, Xscratch0);
|
||||||
code.MOV(X2, Xscratch1);
|
code.MOV(X2, Xscratch1);
|
||||||
code.MOV(X3, bitsize);
|
|
||||||
code.LDR(Xscratch0, l_addr);
|
code.LDR(Xscratch0, l_addr);
|
||||||
code.BLR(Xscratch0);
|
code.BLR(Xscratch0);
|
||||||
ABI_PopRegisters(code, save_regs, 0);
|
ABI_PopRegisters(code, save_regs, 0);
|
||||||
@@ -380,30 +342,18 @@ void A64AddressSpace::EmitPrelude() {
|
|||||||
|
|
||||||
UnprotectCodeMemory();
|
UnprotectCodeMemory();
|
||||||
|
|
||||||
prelude_info.read_memory_8 = EmitCallReadTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u8));
|
prelude_info.read_memory = EmitCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks);
|
||||||
prelude_info.read_memory_16 = EmitCallReadTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u16));
|
|
||||||
prelude_info.read_memory_32 = EmitCallReadTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u32));
|
|
||||||
prelude_info.read_memory_64 = EmitCallReadTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u64));
|
|
||||||
prelude_info.read_memory_128 = EmitRead128CallTrampoline(code, conf.callbacks);
|
prelude_info.read_memory_128 = EmitRead128CallTrampoline(code, conf.callbacks);
|
||||||
prelude_info.wrapped_read_memory_8 = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u8));
|
prelude_info.wrapped_read_memory = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks);
|
||||||
prelude_info.wrapped_read_memory_16 = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u16));
|
|
||||||
prelude_info.wrapped_read_memory_32 = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u32));
|
|
||||||
prelude_info.wrapped_read_memory_64 = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u64));
|
|
||||||
prelude_info.wrapped_read_memory_128 = EmitWrappedRead128CallTrampoline(code, conf.callbacks);
|
prelude_info.wrapped_read_memory_128 = EmitWrappedRead128CallTrampoline(code, conf.callbacks);
|
||||||
prelude_info.exclusive_read_memory_8 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u8>(code, conf);
|
prelude_info.exclusive_read_memory_8 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u8>(code, conf);
|
||||||
prelude_info.exclusive_read_memory_16 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u16>(code, conf);
|
prelude_info.exclusive_read_memory_16 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u16>(code, conf);
|
||||||
prelude_info.exclusive_read_memory_32 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u32>(code, conf);
|
prelude_info.exclusive_read_memory_32 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u32>(code, conf);
|
||||||
prelude_info.exclusive_read_memory_64 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u64>(code, conf);
|
prelude_info.exclusive_read_memory_64 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u64>(code, conf);
|
||||||
prelude_info.exclusive_read_memory_128 = EmitExclusiveRead128CallTrampoline(code, conf);
|
prelude_info.exclusive_read_memory_128 = EmitExclusiveRead128CallTrampoline(code, conf);
|
||||||
prelude_info.write_memory_8 = EmitCallWriteTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u8));
|
prelude_info.write_memory = EmitCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks);
|
||||||
prelude_info.write_memory_16 = EmitCallWriteTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u16));
|
|
||||||
prelude_info.write_memory_32 = EmitCallWriteTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u32));
|
|
||||||
prelude_info.write_memory_64 = EmitCallWriteTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u64));
|
|
||||||
prelude_info.write_memory_128 = EmitWrite128CallTrampoline(code, conf.callbacks);
|
prelude_info.write_memory_128 = EmitWrite128CallTrampoline(code, conf.callbacks);
|
||||||
prelude_info.wrapped_write_memory_8 = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u8));
|
prelude_info.wrapped_write_memory = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks);
|
||||||
prelude_info.wrapped_write_memory_16 = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u16));
|
|
||||||
prelude_info.wrapped_write_memory_32 = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u32));
|
|
||||||
prelude_info.wrapped_write_memory_64 = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u64));
|
|
||||||
prelude_info.wrapped_write_memory_128 = EmitWrappedWrite128CallTrampoline(code, conf.callbacks);
|
prelude_info.wrapped_write_memory_128 = EmitWrappedWrite128CallTrampoline(code, conf.callbacks);
|
||||||
prelude_info.exclusive_write_memory_8 = EmitExclusiveWriteCallTrampoline<&A64::UserCallbacks::MemoryWriteExclusive8, u8>(code, conf);
|
prelude_info.exclusive_write_memory_8 = EmitExclusiveWriteCallTrampoline<&A64::UserCallbacks::MemoryWriteExclusive8, u8>(code, conf);
|
||||||
prelude_info.exclusive_write_memory_16 = EmitExclusiveWriteCallTrampoline<&A64::UserCallbacks::MemoryWriteExclusive16, u16>(code, conf);
|
prelude_info.exclusive_write_memory_16 = EmitExclusiveWriteCallTrampoline<&A64::UserCallbacks::MemoryWriteExclusive16, u16>(code, conf);
|
||||||
|
|||||||
@@ -147,37 +147,44 @@ void AddressSpace::Link(EmittedBlockInfo& block_info) {
|
|||||||
break;
|
break;
|
||||||
// { this, vaddr, size }
|
// { this, vaddr, size }
|
||||||
case LinkTarget::ReadMemory8:
|
case LinkTarget::ReadMemory8:
|
||||||
c.BL(prelude_info.read_memory_8);
|
c.LDR(X2, 1);
|
||||||
|
c.BL(prelude_info.read_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::ReadMemory16:
|
case LinkTarget::ReadMemory16:
|
||||||
c.BL(prelude_info.read_memory_16);
|
c.LDR(X2, 2);
|
||||||
|
c.BL(prelude_info.read_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::ReadMemory32:
|
case LinkTarget::ReadMemory32:
|
||||||
c.BL(prelude_info.read_memory_32);
|
c.LDR(X2, 4);
|
||||||
|
c.BL(prelude_info.read_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::ReadMemory64:
|
case LinkTarget::ReadMemory64:
|
||||||
c.BL(prelude_info.read_memory_64);
|
c.LDR(X2, 8);
|
||||||
|
c.BL(prelude_info.read_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::ReadMemory128:
|
case LinkTarget::ReadMemory128:
|
||||||
c.BL(prelude_info.read_memory_128);
|
c.BL(prelude_info.read_memory_128);
|
||||||
break;
|
break;
|
||||||
// { this, vaddr, size }
|
// { this, vaddr, size }
|
||||||
case LinkTarget::WrappedReadMemory8:
|
case LinkTarget::WrappedReadMemory8:
|
||||||
c.BL(prelude_info.wrapped_read_memory_8);
|
c.LDR(X2, 1);
|
||||||
|
c.BL(prelude_info.wrapped_read_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedReadMemory16:
|
case LinkTarget::WrappedReadMemory16:
|
||||||
c.BL(prelude_info.wrapped_read_memory_16);
|
c.LDR(X2, 2);
|
||||||
|
c.BL(prelude_info.wrapped_read_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedReadMemory32:
|
case LinkTarget::WrappedReadMemory32:
|
||||||
c.BL(prelude_info.wrapped_read_memory_32);
|
c.LDR(X2, 4);
|
||||||
|
c.BL(prelude_info.wrapped_read_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedReadMemory64:
|
case LinkTarget::WrappedReadMemory64:
|
||||||
c.BL(prelude_info.wrapped_read_memory_64);
|
c.LDR(X2, 8);
|
||||||
|
c.BL(prelude_info.wrapped_read_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedReadMemory128:
|
case LinkTarget::WrappedReadMemory128:
|
||||||
c.BL(prelude_info.wrapped_read_memory_128);
|
c.BL(prelude_info.wrapped_read_memory_128);
|
||||||
break;
|
break;
|
||||||
//
|
|
||||||
case LinkTarget::ExclusiveReadMemory8:
|
case LinkTarget::ExclusiveReadMemory8:
|
||||||
c.BL(prelude_info.exclusive_read_memory_8);
|
c.BL(prelude_info.exclusive_read_memory_8);
|
||||||
break;
|
break;
|
||||||
@@ -195,37 +202,43 @@ void AddressSpace::Link(EmittedBlockInfo& block_info) {
|
|||||||
break;
|
break;
|
||||||
// { this, vaddr, value, size }
|
// { this, vaddr, value, size }
|
||||||
case LinkTarget::WriteMemory8:
|
case LinkTarget::WriteMemory8:
|
||||||
c.BL(prelude_info.write_memory_8);
|
c.LDR(X3, 1);
|
||||||
|
c.BL(prelude_info.write_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WriteMemory16:
|
case LinkTarget::WriteMemory16:
|
||||||
c.BL(prelude_info.write_memory_16);
|
c.LDR(X3, 2);
|
||||||
|
c.BL(prelude_info.write_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WriteMemory32:
|
case LinkTarget::WriteMemory32:
|
||||||
c.BL(prelude_info.write_memory_32);
|
c.LDR(X3, 4);
|
||||||
|
c.BL(prelude_info.write_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WriteMemory64:
|
case LinkTarget::WriteMemory64:
|
||||||
c.BL(prelude_info.write_memory_64);
|
c.LDR(X3, 8);
|
||||||
|
c.BL(prelude_info.write_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WriteMemory128:
|
case LinkTarget::WriteMemory128:
|
||||||
c.BL(prelude_info.write_memory_128);
|
c.BL(prelude_info.write_memory_128);
|
||||||
break;
|
break;
|
||||||
//
|
|
||||||
case LinkTarget::WrappedWriteMemory8:
|
case LinkTarget::WrappedWriteMemory8:
|
||||||
c.BL(prelude_info.wrapped_write_memory_8);
|
c.LDR(X3, 1);
|
||||||
|
c.BL(prelude_info.wrapped_write_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedWriteMemory16:
|
case LinkTarget::WrappedWriteMemory16:
|
||||||
c.BL(prelude_info.wrapped_write_memory_16);
|
c.LDR(X3, 2);
|
||||||
|
c.BL(prelude_info.wrapped_write_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedWriteMemory32:
|
case LinkTarget::WrappedWriteMemory32:
|
||||||
c.BL(prelude_info.wrapped_write_memory_32);
|
c.LDR(X3, 4);
|
||||||
|
c.BL(prelude_info.wrapped_write_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedWriteMemory64:
|
case LinkTarget::WrappedWriteMemory64:
|
||||||
c.BL(prelude_info.wrapped_write_memory_64);
|
c.LDR(X3, 8);
|
||||||
|
c.BL(prelude_info.wrapped_write_memory);
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedWriteMemory128:
|
case LinkTarget::WrappedWriteMemory128:
|
||||||
c.BL(prelude_info.wrapped_write_memory_128);
|
c.BL(prelude_info.wrapped_write_memory_128);
|
||||||
break;
|
break;
|
||||||
//
|
|
||||||
case LinkTarget::ExclusiveWriteMemory8:
|
case LinkTarget::ExclusiveWriteMemory8:
|
||||||
c.BL(prelude_info.exclusive_write_memory_8);
|
c.BL(prelude_info.exclusive_write_memory_8);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -93,30 +93,18 @@ protected:
|
|||||||
void* return_to_dispatcher;
|
void* return_to_dispatcher;
|
||||||
void* return_from_run_code;
|
void* return_from_run_code;
|
||||||
|
|
||||||
void* read_memory_8;
|
void* read_memory;
|
||||||
void* read_memory_16;
|
|
||||||
void* read_memory_32;
|
|
||||||
void* read_memory_64;
|
|
||||||
void* read_memory_128;
|
void* read_memory_128;
|
||||||
void* wrapped_read_memory_8;
|
void* wrapped_read_memory;
|
||||||
void* wrapped_read_memory_16;
|
|
||||||
void* wrapped_read_memory_32;
|
|
||||||
void* wrapped_read_memory_64;
|
|
||||||
void* wrapped_read_memory_128;
|
void* wrapped_read_memory_128;
|
||||||
void* exclusive_read_memory_8;
|
void* exclusive_read_memory_8;
|
||||||
void* exclusive_read_memory_16;
|
void* exclusive_read_memory_16;
|
||||||
void* exclusive_read_memory_32;
|
void* exclusive_read_memory_32;
|
||||||
void* exclusive_read_memory_64;
|
void* exclusive_read_memory_64;
|
||||||
void* exclusive_read_memory_128;
|
void* exclusive_read_memory_128;
|
||||||
void* write_memory_8;
|
void* write_memory;
|
||||||
void* write_memory_16;
|
|
||||||
void* write_memory_32;
|
|
||||||
void* write_memory_64;
|
|
||||||
void* write_memory_128;
|
void* write_memory_128;
|
||||||
void* wrapped_write_memory_8;
|
void* wrapped_write_memory;
|
||||||
void* wrapped_write_memory_16;
|
|
||||||
void* wrapped_write_memory_32;
|
|
||||||
void* wrapped_write_memory_64;
|
|
||||||
void* wrapped_write_memory_128;
|
void* wrapped_write_memory_128;
|
||||||
void* exclusive_write_memory_8;
|
void* exclusive_write_memory_8;
|
||||||
void* exclusive_write_memory_16;
|
void* exclusive_write_memory_16;
|
||||||
|
|||||||
@@ -39,8 +39,16 @@ Block::iterator Block::PrependNewInst(iterator insertion_point, Opcode opcode, s
|
|||||||
// just pool it!!! - reason why there is an inline buffer is because many small blocks are created
|
// just pool it!!! - reason why there is an inline buffer is because many small blocks are created
|
||||||
// with few instructions due to subpar optimisations on other passes... plus branch-heavy code will
|
// with few instructions due to subpar optimisations on other passes... plus branch-heavy code will
|
||||||
// hugely benefit from the coherency of faster allocations...
|
// hugely benefit from the coherency of faster allocations...
|
||||||
inlined_inst.emplace_back(opcode);
|
IR::Inst* inst;
|
||||||
auto* inst = &inlined_inst[inlined_inst.size() - 1];
|
if (inlined_inst.size() < inlined_inst.max_size()) {
|
||||||
|
inlined_inst.emplace_back(opcode);
|
||||||
|
inst = &inlined_inst[inlined_inst.size() - 1];
|
||||||
|
} else {
|
||||||
|
if (pooled_inst.empty() || pooled_inst.back().size() == pooled_inst.back().max_size())
|
||||||
|
pooled_inst.emplace_back();
|
||||||
|
pooled_inst.back().emplace_back(opcode);
|
||||||
|
inst = &pooled_inst.back()[pooled_inst.back().size() - 1];
|
||||||
|
}
|
||||||
DEBUG_ASSERT(args.size() == inst->NumArgs());
|
DEBUG_ASSERT(args.size() == inst->NumArgs());
|
||||||
std::for_each(args.begin(), args.end(), [&inst, index = size_t(0)](const auto& arg) mutable {
|
std::for_each(args.begin(), args.end(), [&inst, index = size_t(0)](const auto& arg) mutable {
|
||||||
inst->SetArg(index, arg);
|
inst->SetArg(index, arg);
|
||||||
@@ -53,6 +61,7 @@ void Block::Reset(LocationDescriptor location_) noexcept {
|
|||||||
mcl::intrusive_list<IR::Inst> tmp = {};
|
mcl::intrusive_list<IR::Inst> tmp = {};
|
||||||
instructions.swap(tmp);
|
instructions.swap(tmp);
|
||||||
inlined_inst.clear();
|
inlined_inst.clear();
|
||||||
|
pooled_inst.clear();
|
||||||
cond_failed.reset();
|
cond_failed.reset();
|
||||||
location = location_;
|
location = location_;
|
||||||
end_location = location_;
|
end_location = location_;
|
||||||
|
|||||||
@@ -142,9 +142,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "Hot cache" for small blocks so we don't call global allocator
|
/// "Hot cache" for small blocks so we don't call global allocator
|
||||||
boost::container::static_vector<Inst, 65536> inlined_inst = {};
|
boost::container::static_vector<Inst, 30> inlined_inst;
|
||||||
/// List of instructions in this block.
|
/// List of instructions in this block.
|
||||||
instruction_list_type instructions;
|
instruction_list_type instructions;
|
||||||
|
/// "Long/far" memory pool
|
||||||
|
boost::container::stable_vector<boost::container::static_vector<Inst, 32>> pooled_inst;
|
||||||
/// Block to execute next if `cond` did not pass.
|
/// Block to execute next if `cond` did not pass.
|
||||||
std::optional<LocationDescriptor> cond_failed = {};
|
std::optional<LocationDescriptor> cond_failed = {};
|
||||||
/// Description of the starting location of this block
|
/// Description of the starting location of this block
|
||||||
@@ -160,7 +162,7 @@ public:
|
|||||||
/// Number of cycles this block takes to execute.
|
/// Number of cycles this block takes to execute.
|
||||||
size_t cycle_count = 0;
|
size_t cycle_count = 0;
|
||||||
};
|
};
|
||||||
//static_assert(sizeof(Block) == 4096);
|
static_assert(sizeof(Block) == 4096);
|
||||||
|
|
||||||
/// Returns a string representation of the contents of block. Intended for debugging.
|
/// Returns a string representation of the contents of block. Intended for debugging.
|
||||||
std::string DumpBlock(const IR::Block& block) noexcept;
|
std::string DumpBlock(const IR::Block& block) noexcept;
|
||||||
|
|||||||
@@ -761,9 +761,6 @@ void EmulatedController::StartMotionCalibration() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index, Common::UUID uuid) {
|
void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index, Common::UUID uuid) {
|
||||||
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
|
|
||||||
const auto& player = Settings::values.players.GetValue()[player_index];
|
|
||||||
|
|
||||||
if (index >= controller.button_values.size()) {
|
if (index >= controller.button_values.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -916,21 +913,10 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_connected) {
|
const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
|
||||||
if (npad_type == NpadStyleIndex::Handheld) {
|
const auto& player = Settings::values.players.GetValue()[player_index];
|
||||||
if (npad_id_type == NpadIdType::Handheld) {
|
if (player.connected) {
|
||||||
Connect();
|
Connect();
|
||||||
controller_connected[player_index] = true;
|
|
||||||
}
|
|
||||||
} else if (npad_type != NpadStyleIndex::Handheld) {
|
|
||||||
if (npad_id_type == NpadIdType::Player1) {
|
|
||||||
Connect();
|
|
||||||
controller_connected[player_index] = true;
|
|
||||||
} else if (player.connected && !controller_connected[player_index]) {
|
|
||||||
Connect();
|
|
||||||
controller_connected[player_index] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TriggerOnChange(ControllerTriggerType::Button, true);
|
TriggerOnChange(ControllerTriggerType::Button, true);
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/vector_math.h"
|
#include "common/vector_math.h"
|
||||||
#include "hid_core/frontend/motion_input.h"
|
#include "hid_core/frontend/motion_input.h"
|
||||||
#include "hid_core/hid_core.h"
|
|
||||||
#include "hid_core/hid_types.h"
|
#include "hid_core/hid_types.h"
|
||||||
#include "hid_core/irsensor/irs_types.h"
|
#include "hid_core/irsensor/irs_types.h"
|
||||||
|
|
||||||
@@ -585,7 +584,6 @@ private:
|
|||||||
std::array<VibrationValue, 2> last_vibration_value{DEFAULT_VIBRATION_VALUE,
|
std::array<VibrationValue, 2> last_vibration_value{DEFAULT_VIBRATION_VALUE,
|
||||||
DEFAULT_VIBRATION_VALUE};
|
DEFAULT_VIBRATION_VALUE};
|
||||||
std::array<std::chrono::steady_clock::time_point, 2> last_vibration_timepoint{};
|
std::array<std::chrono::steady_clock::time_point, 2> last_vibration_timepoint{};
|
||||||
std::array<bool, HIDCore::available_controllers> controller_connected{};
|
|
||||||
|
|
||||||
// Atomically synched values
|
// Atomically synched values
|
||||||
std::atomic<HID::NpadStyleIndex> npad_type{HID::NpadStyleIndex::None};
|
std::atomic<HID::NpadStyleIndex> npad_type{HID::NpadStyleIndex::None};
|
||||||
|
|||||||
Reference in New Issue
Block a user