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