mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
cpu: Got rid of the rest of the static member function trampolines.
cpu/drcbearm64.cpp, cpu/drcbex64.cpp: Removed static trampoline fallbacks for get map variable value and debugger instrcution hook functions. cpu/drcbex86.cpp: Removed static trampolines for get map variable value and debugger instrcution hook functions. cpu/drcbex64.cpp: Corrected stack diagram in comment.
This commit is contained in:
parent
c6b97a6e23
commit
88a26bb838
@ -973,10 +973,7 @@ drcbe_arm64::drcbe_arm64(drcuml_state &drcuml, device_t &device, drc_cache &cach
|
||||
// resolve the actual addresses of member functions we need to call
|
||||
m_drcmap_get_value.set(m_map, &drc_map_variables::get_value);
|
||||
if (!m_drcmap_get_value)
|
||||
{
|
||||
m_drcmap_get_value.obj = uintptr_t(&m_map);
|
||||
m_drcmap_get_value.func = reinterpret_cast<uint8_t *>(uintptr_t(&drc_map_variables::static_get_value));
|
||||
}
|
||||
throw emu_fatalerror("Error resolving map variable get value function!\n");
|
||||
m_resolved_accessors.resize(m_space.size());
|
||||
for (int space = 0; m_space.size() > space; ++space)
|
||||
{
|
||||
@ -1096,12 +1093,7 @@ void drcbe_arm64::generate(drcuml_block &block, const instruction *instlist, uin
|
||||
{
|
||||
m_debug_cpu_instruction_hook.set(*m_device.debug(), &device_debug::instruction_hook);
|
||||
if (!m_debug_cpu_instruction_hook)
|
||||
{
|
||||
m_debug_cpu_instruction_hook.obj = uintptr_t(m_device.debug());
|
||||
using debugger_hook_func = void (*)(device_debug *, offs_t);
|
||||
static const auto debugger_inst_hook = [] (device_debug *dbg, offs_t pc) { dbg->instruction_hook(pc); };
|
||||
m_debug_cpu_instruction_hook.func = reinterpret_cast<uint8_t *>(uintptr_t(debugger_hook_func(debugger_inst_hook)));
|
||||
}
|
||||
throw emu_fatalerror("Error resolving debugger instruction hook member function!\n");
|
||||
}
|
||||
|
||||
// tell all of our utility objects that a block is beginning
|
||||
@ -1200,7 +1192,7 @@ void drcbe_arm64::op_handle(a64::Assembler &a, const uml::instruction &inst)
|
||||
// register the current pointer for the handle
|
||||
inst.param(0).handle().set_codeptr(drccodeptr(a.code()->baseAddress() + a.offset()));
|
||||
|
||||
// the handle points to prolog code that creates a minimal non-leaf frame
|
||||
// the handle points to prologue code that creates a minimal non-leaf frame
|
||||
a.stp(a64::x29, a64::x30, arm::Mem(a64::sp, -16).pre());
|
||||
a.bind(skip);
|
||||
}
|
||||
|
@ -407,11 +407,6 @@ uint32_t drc_map_variables::get_value(drccodeptr codebase, uint32_t mapvar) cons
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t drc_map_variables::static_get_value(drc_map_variables &map, drccodeptr codebase, uint32_t mapvar)
|
||||
{
|
||||
return map.get_value(codebase, mapvar);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
|
@ -98,9 +98,6 @@ public:
|
||||
uint32_t get_value(drccodeptr codebase, uint32_t mapvar) const;
|
||||
uint32_t get_last_value(uint32_t mapvar);
|
||||
|
||||
// static accessors to be called directly by generated code
|
||||
static uint32_t static_get_value(drc_map_variables &map, drccodeptr codebase, uint32_t mapvar);
|
||||
|
||||
private:
|
||||
// internal state
|
||||
drc_cache & m_cache; // pointer to the cache
|
||||
|
@ -146,23 +146,44 @@
|
||||
Exit point:
|
||||
Assumes exit value is in RAX.
|
||||
|
||||
Entry stack:
|
||||
[rsp] - return
|
||||
Top-level generated code frame:
|
||||
[rsp+0x00] - rcx home/scratch
|
||||
[rsp+0x08] - rdx home/scratch
|
||||
[rsp+0x10] - r8 home/scratch
|
||||
[rsp+0x18] - r9 home/scratch
|
||||
[rsp+0x20] - scratch
|
||||
[rsp+0x28] - saved r15
|
||||
[rsp+0x30] - saved r14
|
||||
[rsp+0x38] - saved r13
|
||||
[rsp+0x40] - saved r12
|
||||
[rsp+0x48] - saved rbp
|
||||
[rsp+0x50] - saved rdi
|
||||
[rsp+0x58] - saved rsi
|
||||
[rsp+0x60] - saved rbx
|
||||
[rsp+0x68] - ret
|
||||
|
||||
Runtime stack:
|
||||
[rsp] - r9 home
|
||||
[rsp+8] - r8 home
|
||||
[rsp+16] - rdx home
|
||||
[rsp+24] - rcx home
|
||||
[rsp+40] - saved r15
|
||||
[rsp+48] - saved r14
|
||||
[rsp+56] - saved r13
|
||||
[rsp+64] - saved r12
|
||||
[rsp+72] - saved rbp
|
||||
[rsp+80] - saved rdi
|
||||
[rsp+88] - saved rsi
|
||||
[rsp+96] - saved rbx
|
||||
[rsp+104] - ret
|
||||
Generated code subroutine call frame:
|
||||
[rsp+0x00] - rcx home/scratch
|
||||
[rsp+0x08] - rdx home/scratch
|
||||
[rsp+0x10] - r8 home/scratch
|
||||
[rsp+0x18] - r9 home/scratch
|
||||
[rsp+0x20] - scratch
|
||||
[rsp+0x28] - ret
|
||||
...
|
||||
- rcx home/scratch
|
||||
- rdx home/scratch
|
||||
- r8 home/scratch
|
||||
- r9 home/scratch
|
||||
- scratch
|
||||
- saved r15
|
||||
- saved r14
|
||||
- saved r13
|
||||
- saved r12
|
||||
- saved rdi
|
||||
- saved rsi
|
||||
- saved rbp
|
||||
- saved rbx
|
||||
- ret
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
@ -689,10 +710,7 @@ drcbe_x64::drcbe_x64(drcuml_state &drcuml, device_t &device, drc_cache &cache, u
|
||||
// resolve the actual addresses of member functions we need to call
|
||||
m_drcmap_get_value.set(m_map, &drc_map_variables::get_value);
|
||||
if (!m_drcmap_get_value)
|
||||
{
|
||||
m_drcmap_get_value.obj = uintptr_t(&m_map);
|
||||
m_drcmap_get_value.func = reinterpret_cast<uint8_t *>(uintptr_t(&drc_map_variables::static_get_value));
|
||||
}
|
||||
throw emu_fatalerror("Error resolving map variable get value function!\n");
|
||||
m_resolved_accessors.resize(m_space.size());
|
||||
for (int space = 0; m_space.size() > space; ++space)
|
||||
{
|
||||
@ -872,12 +890,7 @@ void drcbe_x64::generate(drcuml_block &block, const instruction *instlist, uint3
|
||||
{
|
||||
m_debug_cpu_instruction_hook.set(*m_device.debug(), &device_debug::instruction_hook);
|
||||
if (!m_debug_cpu_instruction_hook)
|
||||
{
|
||||
m_debug_cpu_instruction_hook.obj = uintptr_t(m_device.debug());
|
||||
using debugger_hook_func = void (*)(device_debug *, offs_t);
|
||||
static const auto debugger_inst_hook = [] (device_debug *dbg, offs_t pc) { dbg->instruction_hook(pc); };
|
||||
m_debug_cpu_instruction_hook.func = reinterpret_cast<uint8_t *>(uintptr_t(debugger_hook_func(debugger_inst_hook)));
|
||||
}
|
||||
throw emu_fatalerror("Error resolving debugger instruction hook member function!\n");
|
||||
}
|
||||
|
||||
// tell all of our utility objects that a block is beginning
|
||||
@ -1420,14 +1433,14 @@ void drcbe_x64::op_handle(Assembler &a, const instruction &inst)
|
||||
|
||||
// emit a jump around the stack adjust in case code falls through here
|
||||
Label skip = a.newLabel();
|
||||
a.short_().jmp(skip); // jmp skip
|
||||
a.short_().jmp(skip);
|
||||
|
||||
// register the current pointer for the handle
|
||||
inst.param(0).handle().set_codeptr(drccodeptr(a.code()->baseAddress() + a.offset()));
|
||||
|
||||
// by default, the handle points to prolog code that moves the stack pointer
|
||||
a.lea(rsp, ptr(rsp, -40)); // lea rsp,[rsp-40]
|
||||
a.bind(skip); // skip:
|
||||
// by default, the handle points to prologue code that moves the stack pointer
|
||||
a.lea(rsp, ptr(rsp, -40));
|
||||
a.bind(skip);
|
||||
}
|
||||
|
||||
|
||||
|
@ -602,6 +602,9 @@ drcbe_x86::drcbe_x86(drcuml_state &drcuml, device_t &device, drc_cache &cache, u
|
||||
}
|
||||
|
||||
// resolve the actual addresses of member functions we need to call
|
||||
m_drcmap_get_value.set(m_map, &drc_map_variables::get_value);
|
||||
if (!m_drcmap_get_value)
|
||||
throw emu_fatalerror("Error resolving map variable get value function!\n");
|
||||
m_memory_accessors.resize(m_space.size());
|
||||
for (int space = 0; m_space.size() > space; ++space)
|
||||
{
|
||||
@ -856,6 +859,14 @@ int drcbe_x86::execute(code_handle &entry)
|
||||
|
||||
void drcbe_x86::generate(drcuml_block &block, const instruction *instlist, uint32_t numinst)
|
||||
{
|
||||
// do this here because device.debug() isn't initialised at construction time
|
||||
if (!m_debug_cpu_instruction_hook && (m_device.machine().debug_flags & DEBUG_FLAG_ENABLED))
|
||||
{
|
||||
m_debug_cpu_instruction_hook.set(*m_device.debug(), &device_debug::instruction_hook);
|
||||
if (!m_debug_cpu_instruction_hook)
|
||||
throw emu_fatalerror("Error resolving debugger instruction hook member function!\n");
|
||||
}
|
||||
|
||||
// tell all of our utility objects that a block is beginning
|
||||
m_hash.block_begin(block, instlist, numinst);
|
||||
m_map.block_begin(block);
|
||||
@ -2535,25 +2546,27 @@ void drcbe_x86::op_debug(Assembler &a, const instruction &inst)
|
||||
assert_no_condition(inst);
|
||||
assert_no_flags(inst);
|
||||
|
||||
using debugger_hook_func = void (*)(device_debug *, offs_t);
|
||||
static const debugger_hook_func debugger_inst_hook = [] (device_debug *dbg, offs_t pc) { dbg->instruction_hook(pc); }; // TODO: kill trampoline if possible
|
||||
|
||||
if ((m_device.machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
|
||||
{
|
||||
// normalize parameters
|
||||
be_parameter const pcp(*this, inst.param(0), PTYPE_MRI);
|
||||
|
||||
// test and branch
|
||||
a.test(MABS(&m_device.machine().debug_flags, 4), DEBUG_FLAG_CALL_HOOK); // test [debug_flags],DEBUG_FLAG_CALL_HOOK
|
||||
a.test(MABS(&m_device.machine().debug_flags, 4), DEBUG_FLAG_CALL_HOOK);
|
||||
Label skip = a.newLabel();
|
||||
a.short_().jz(skip); // jz skip
|
||||
a.short_().jz(skip);
|
||||
|
||||
// push the parameter
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, 4), pcp); // mov [esp+4],pcp
|
||||
a.mov(dword_ptr(esp, 0), imm(m_device.debug())); // mov [esp],device.debug
|
||||
a.call(imm(debugger_inst_hook)); // call debugger_inst_hook
|
||||
emit_mov_m32_p32(a, dword_ptr(esp, USE_THISCALL ? 0 : 4), pcp);
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(m_debug_cpu_instruction_hook.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(m_debug_cpu_instruction_hook.obj));
|
||||
a.call(imm(m_debug_cpu_instruction_hook.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 4);
|
||||
|
||||
a.bind(skip); // skip:
|
||||
a.bind(skip);
|
||||
reset_last_upper_lower_reg();
|
||||
}
|
||||
}
|
||||
@ -2856,14 +2869,19 @@ void drcbe_x86::op_recover(Assembler &a, const instruction &inst)
|
||||
be_parameter dstp(*this, inst.param(0), PTYPE_MR);
|
||||
|
||||
// call the recovery code
|
||||
a.mov(eax, MABS(&m_stacksave)); // mov eax,stacksave
|
||||
a.mov(eax, ptr(eax, -4)); // mov eax,[eax-4]
|
||||
a.sub(eax, 1); // sub eax,1
|
||||
a.mov(dword_ptr(esp, 8), inst.param(1).mapvar()); // mov [esp+8],param1
|
||||
a.mov(ptr(esp, 4), eax); // mov [esp+4],eax
|
||||
a.mov(dword_ptr(esp, 0), imm(&m_map)); // mov [esp],m_map
|
||||
a.call(imm(&drc_map_variables::static_get_value)); // call drcmap_get_value
|
||||
emit_mov_p32_r32(a, dstp, eax); // mov dstp,eax
|
||||
a.mov(eax, MABS(&m_stacksave));
|
||||
a.mov(eax, ptr(eax, -4));
|
||||
a.sub(eax, 1);
|
||||
a.mov(dword_ptr(esp, USE_THISCALL ? 4 : 8), inst.param(1).mapvar());
|
||||
a.mov(ptr(esp, USE_THISCALL ? 0 : 4), eax);
|
||||
if (USE_THISCALL)
|
||||
a.mov(ecx, imm(m_drcmap_get_value.obj));
|
||||
else
|
||||
a.mov(dword_ptr(esp, 0), imm(m_drcmap_get_value.obj));
|
||||
a.call(imm(m_drcmap_get_value.func));
|
||||
if (USE_THISCALL)
|
||||
a.sub(esp, 8);
|
||||
emit_mov_p32_r32(a, dstp, eax);
|
||||
}
|
||||
|
||||
|
||||
|
@ -292,6 +292,8 @@ private:
|
||||
uint64_t m_reshi; // extended high result
|
||||
|
||||
// resolved memory handler functions
|
||||
resolved_member_function m_debug_cpu_instruction_hook;
|
||||
resolved_member_function m_drcmap_get_value;
|
||||
resolved_memory_accessors_vector m_memory_accessors;
|
||||
|
||||
// globals
|
||||
|
Loading…
Reference in New Issue
Block a user