Skip to content

Commit

Permalink
cpu: Got rid of the rest of the static member function trampolines.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
cuavas committed Feb 3, 2025
1 parent c6b97a6 commit 88a26bb
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 67 deletions.
14 changes: 3 additions & 11 deletions src/devices/cpu/drcbearm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
Expand Down
5 changes: 0 additions & 5 deletions src/devices/cpu/drcbeut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}



//-------------------------------------------------
Expand Down
3 changes: 0 additions & 3 deletions src/devices/cpu/drcbeut.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@ class drc_map_variables
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
Expand Down
75 changes: 44 additions & 31 deletions src/devices/cpu/drcbex64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,23 +146,44 @@
Exit point:
Assumes exit value is in RAX.
Entry stack:
[rsp] - return
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
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
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
***************************************************************************/

Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}


Expand Down
52 changes: 35 additions & 17 deletions src/devices/cpu/drcbex86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
}
}
Expand Down Expand Up @@ -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);
}


Expand Down
2 changes: 2 additions & 0 deletions src/devices/cpu/drcbex86.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,8 @@ class drcbe_x86 : public drcbe_interface
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
Expand Down

0 comments on commit 88a26bb

Please sign in to comment.