diff --git a/src/devices/cpu/drcbearm64.cpp b/src/devices/cpu/drcbearm64.cpp index ce343a70839..6581a266fe1 100644 --- a/src/devices/cpu/drcbearm64.cpp +++ b/src/devices/cpu/drcbearm64.cpp @@ -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(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(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); } diff --git a/src/devices/cpu/drcbeut.cpp b/src/devices/cpu/drcbeut.cpp index 96b11a14743..fa22d799cab 100644 --- a/src/devices/cpu/drcbeut.cpp +++ b/src/devices/cpu/drcbeut.cpp @@ -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); -} - //------------------------------------------------- diff --git a/src/devices/cpu/drcbeut.h b/src/devices/cpu/drcbeut.h index 0fc8f12566e..05a4a78fdc2 100644 --- a/src/devices/cpu/drcbeut.h +++ b/src/devices/cpu/drcbeut.h @@ -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 diff --git a/src/devices/cpu/drcbex64.cpp b/src/devices/cpu/drcbex64.cpp index ff22f34be2f..c552bbbb59e 100644 --- a/src/devices/cpu/drcbex64.cpp +++ b/src/devices/cpu/drcbex64.cpp @@ -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(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(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); } diff --git a/src/devices/cpu/drcbex86.cpp b/src/devices/cpu/drcbex86.cpp index 8d5f2b9df4c..0bb540260cb 100644 --- a/src/devices/cpu/drcbex86.cpp +++ b/src/devices/cpu/drcbex86.cpp @@ -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); } diff --git a/src/devices/cpu/drcbex86.h b/src/devices/cpu/drcbex86.h index 2c02c3c939a..25e926eef3c 100644 --- a/src/devices/cpu/drcbex86.h +++ b/src/devices/cpu/drcbex86.h @@ -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