summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/devices/cpu/drcbearm64.cpp2
-rw-r--r--src/devices/cpu/drcbex64.cpp48
-rw-r--r--src/devices/cpu/drcbex86.cpp44
-rw-r--r--src/lib/util/delegate.cpp4
-rw-r--r--src/lib/util/mfpresolve.h12
5 files changed, 55 insertions, 55 deletions
diff --git a/src/devices/cpu/drcbearm64.cpp b/src/devices/cpu/drcbearm64.cpp
index bc956d84c38..d6e5e03d024 100644
--- a/src/devices/cpu/drcbearm64.cpp
+++ b/src/devices/cpu/drcbearm64.cpp
@@ -911,7 +911,7 @@ drcbe_arm64::drcbe_arm64(drcuml_state &drcuml, device_t &device, drc_cache &cach
auto const resolve_accessor =
[] (resolved_handler &handler, address_space &space, auto accessor)
{
- auto const [entrypoint, adjusted] = util::resolve_member_function(accessor, &space);
+ auto const [entrypoint, adjusted] = util::resolve_member_function(accessor, space);
handler.func = reinterpret_cast<uint8_t *>(entrypoint);
handler.obj = adjusted;
};
diff --git a/src/devices/cpu/drcbex64.cpp b/src/devices/cpu/drcbex64.cpp
index aa7b3dc68e2..880ad231868 100644
--- a/src/devices/cpu/drcbex64.cpp
+++ b/src/devices/cpu/drcbex64.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles
/***************************************************************************
- drcbex64.c
+ drcbex64.cpp
64-bit x64 back-end for the universal machine language.
@@ -158,10 +158,10 @@
[rsp+48] - saved r14
[rsp+56] - saved r13
[rsp+64] - saved r12
- [rsp+72] - saved ebp
- [rsp+80] - saved edi
- [rsp+88] - saved esi
- [rsp+96] - saved ebx
+ [rsp+72] - saved rbp
+ [rsp+80] - saved rdi
+ [rsp+88] - saved rsi
+ [rsp+96] - saved rbx
[rsp+104] - ret
***************************************************************************/
@@ -696,7 +696,7 @@ drcbe_x64::drcbe_x64(drcuml_state &drcuml, device_t &device, drc_cache &cache, u
auto const resolve_accessor =
[] (resolved_handler &handler, address_space &space, auto accessor)
{
- auto const [entrypoint, adjusted] = util::resolve_member_function(accessor, &space);
+ auto const [entrypoint, adjusted] = util::resolve_member_function(accessor, space);
handler.func = reinterpret_cast<x86code *>(entrypoint);
handler.obj = adjusted;
};
@@ -837,9 +837,8 @@ void drcbe_x64::reset()
a.emitProlog(frame);
a.emitArgsAssignment(frame, args);
- a.sub(rsp, 32);
+ a.sub(rsp, 40);
a.mov(MABS(&m_near.hashstacksave), rsp);
- a.sub(rsp, 8);
a.mov(MABS(&m_near.stacksave), rsp);
a.stmxcsr(MABS(&m_near.ssemode));
a.jmp(Gpq(REG_PARAM2));
@@ -849,13 +848,13 @@ void drcbe_x64::reset()
a.bind(a.newNamedLabel("exit_point"));
a.ldmxcsr(MABS(&m_near.ssemode));
a.mov(rsp, MABS(&m_near.hashstacksave));
- a.add(rsp, 32);
+ a.add(rsp, 40);
a.emitEpilog(frame);
// generate a no code point
m_nocode = dst + a.offset();
a.bind(a.newNamedLabel("nocode_point"));
- a.ret();
+ a.jmp(Gpq(REG_PARAM1));
// emit the generated code
size_t bytes = emit(ch);
@@ -1612,30 +1611,32 @@ void drcbe_x64::op_hashjmp(Assembler &a, const instruction &inst)
smart_call_m64(a, &m_near.debug_log_hashjmp);
}
- // load the stack base one word early so we end up at the right spot after our call below
+ // load the stack base
+ Label nocode = a.newLabel();
a.mov(rsp, MABS(&m_near.hashstacksave)); // mov rsp,[hashstacksave]
// fixed mode cases
if (modep.is_immediate() && m_hash.is_mode_populated(modep.immediate()))
{
- // a straight immediate jump is direct, though we need the PC in EAX in case of failure
if (pcp.is_immediate())
{
+ // a straight immediate jump is direct, though we need the PC in EAX in case of failure
uint32_t l1val = (pcp.immediate() >> m_hash.l1shift()) & m_hash.l1mask();
uint32_t l2val = (pcp.immediate() >> m_hash.l2shift()) & m_hash.l2mask();
- a.call(MABS(&m_hash.base()[modep.immediate()][l1val][l2val])); // call hash[modep][l1val][l2val]
+ a.short_().lea(Gpq(REG_PARAM1), ptr(nocode)); // lea rcx,[rip+nocode]
+ a.jmp(MABS(&m_hash.base()[modep.immediate()][l1val][l2val])); // jmp hash[modep][l1val][l2val]
}
-
- // a fixed mode but variable PC
else
{
+ // a fixed mode but variable PC
mov_reg_param(a, eax, pcp); // mov eax,pcp
a.mov(edx, eax); // mov edx,eax
a.shr(edx, m_hash.l1shift()); // shr edx,l1shift
a.and_(eax, m_hash.l2mask() << m_hash.l2shift()); // and eax,l2mask << l2shift
a.mov(rdx, ptr(rbp, rdx, 3, offset_from_rbp(&m_hash.base()[modep.immediate()][0])));
// mov rdx,hash[modep+edx*8]
- a.call(ptr(rdx, rax, 3 - m_hash.l2shift())); // call [rdx+rax*shift]
+ a.short_().lea(Gpq(REG_PARAM1), ptr(nocode)); // lea rcx,[rip+nocode]
+ a.jmp(ptr(rdx, rax, 3 - m_hash.l2shift())); // jmp [rdx+rax*shift]
}
}
else
@@ -1645,31 +1646,30 @@ void drcbe_x64::op_hashjmp(Assembler &a, const instruction &inst)
mov_reg_param(a, modereg, modep); // mov modereg,modep
a.mov(rcx, ptr(rbp, modereg, 3, offset_from_rbp(m_hash.base()))); // mov rcx,hash[modereg*8]
- // fixed PC
if (pcp.is_immediate())
{
+ // fixed PC
uint32_t l1val = (pcp.immediate() >> m_hash.l1shift()) & m_hash.l1mask();
uint32_t l2val = (pcp.immediate() >> m_hash.l2shift()) & m_hash.l2mask();
a.mov(rdx, ptr(rcx, l1val * 8)); // mov rdx,[rcx+l1val*8]
- a.call(ptr(rdx, l2val * 8)); // call [l2val*8]
+ a.short_().lea(Gpq(REG_PARAM1), ptr(nocode)); // lea rcx,[rip+nocode]
+ a.jmp(ptr(rdx, l2val * 8)); // jmp [l2val*8]
}
-
- // variable PC
else
{
+ // variable PC
mov_reg_param(a, eax, pcp); // mov eax,pcp
a.mov(edx, eax); // mov edx,eax
a.shr(edx, m_hash.l1shift()); // shr edx,l1shift
a.mov(rdx, ptr(rcx, rdx, 3)); // mov rdx,[rcx+rdx*8]
a.and_(eax, m_hash.l2mask() << m_hash.l2shift()); // and eax,l2mask << l2shift
- a.call(ptr(rdx, rax, 3 - m_hash.l2shift())); // call [rdx+rax*shift]
+ a.short_().lea(Gpq(REG_PARAM1), ptr(nocode)); // lea rcx,[rip+nocode]
+ a.jmp(ptr(rdx, rax, 3 - m_hash.l2shift())); // jmp [rdx+rax*shift]
}
}
- // fix stack alignment if "no code" landing returned from abuse of call with misaligned stack
- a.sub(rsp, 8); // sub rsp,8
-
// in all cases, if there is no code, we return here to generate the exception
+ a.bind(nocode);
if (LOG_HASHJMPS)
smart_call_m64(a, &m_near.debug_log_hashjmp_fail);
diff --git a/src/devices/cpu/drcbex86.cpp b/src/devices/cpu/drcbex86.cpp
index f97ef780468..6d7c6c1de1d 100644
--- a/src/devices/cpu/drcbex86.cpp
+++ b/src/devices/cpu/drcbex86.cpp
@@ -2173,11 +2173,11 @@ void drcbe_x86::emit_rcl_r64_p64(Assembler &a, Gp const &reglo, Gp const &reghi,
a.and_(ecx, 63);
a.popfd();
- a.jecxz(skipall);
+ a.short_().jecxz(skipall);
a.lea(ecx, ptr(ecx, -1));
a.bind(loop);
- a.jecxz(skiploop);
+ a.short_().jecxz(skiploop);
a.lea(ecx, ptr(ecx, -1));
a.rcl(reglo, 1);
a.rcl(reghi, 1);
@@ -2231,11 +2231,11 @@ void drcbe_x86::emit_rcr_r64_p64(Assembler &a, Gp const &reglo, Gp const &reghi,
a.and_(ecx, 63);
a.popfd();
- a.jecxz(skipall);
+ a.short_().jecxz(skipall);
a.lea(ecx, ptr(ecx, -1));
a.bind(loop);
- a.jecxz(skiploop);
+ a.short_().jecxz(skiploop);
a.lea(ecx, ptr(ecx, -1));
a.rcr(reghi, 1);
a.rcr(reglo, 1);
@@ -2674,9 +2674,9 @@ void drcbe_x86::op_jmp(Assembler &a, const instruction &inst)
jmptarget = a.newNamedLabel(labelName.c_str());
if (inst.condition() == uml::COND_ALWAYS)
- a.jmp(jmptarget); // jmp target
+ a.jmp(jmptarget);
else
- a.j(X86_CONDITION(inst.condition()), jmptarget); // jcc target
+ a.j(X86_CONDITION(inst.condition()), jmptarget);
}
@@ -2774,7 +2774,7 @@ void drcbe_x86::op_ret(Assembler &a, const instruction &inst)
if (inst.condition() != uml::COND_ALWAYS)
{
skip = a.newLabel();
- a.j(X86_NOT_CONDITION(inst.condition()), skip); // jcc skip
+ a.short_().j(X86_NOT_CONDITION(inst.condition()), skip);
}
// return
@@ -2811,17 +2811,17 @@ void drcbe_x86::op_callc(Assembler &a, const instruction &inst)
if (inst.condition() != uml::COND_ALWAYS)
{
skip = a.newLabel();
- a.j(X86_NOT_CONDITION(inst.condition()), skip); // jcc skip
+ a.short_().j(X86_NOT_CONDITION(inst.condition()), skip);
}
// perform the call
- a.mov(dword_ptr(esp, 0), imm(paramp.memory())); // mov [esp],paramp
- a.call(imm(funcp.cfunc())); // call funcp
+ a.mov(dword_ptr(esp, 0), imm(paramp.memory()));
+ a.call(imm(funcp.cfunc()));
// resolve the conditional link
if (inst.condition() != uml::COND_ALWAYS)
{
- a.bind(skip); // skip:
+ a.bind(skip);
reset_last_upper_lower_reg();
}
}
@@ -3738,7 +3738,7 @@ void drcbe_x86::op_carry(Assembler &a, const instruction &inst)
Label higher = a.newLabel();
a.cmp(ecx, 32);
- a.jge(higher);
+ a.short_().jge(higher);
if (srcp.is_memory())
{
@@ -4795,7 +4795,7 @@ void drcbe_x86::op_divu(Assembler &a, const instruction &inst)
a.add(eax, eax); // add eax,eax
}
Label skip = a.newLabel();
- a.jecxz(skip); // jecxz skip
+ a.short_().jecxz(skip); // jecxz skip
emit_mov_r32_p32(a, eax, src1p); // mov eax,src1p
a.xor_(edx, edx); // xor edx,edx
a.div(ecx); // div ecx
@@ -4866,7 +4866,7 @@ void drcbe_x86::op_divs(Assembler &a, const instruction &inst)
a.add(eax, eax); // add eax,eax
}
Label skip = a.newLabel();
- a.jecxz(skip); // jecxz skip
+ a.short_().jecxz(skip); // jecxz skip
emit_mov_r32_p32(a, eax, src1p); // mov eax,src1p
a.cdq(); // cdq
a.idiv(ecx); // idiv ecx
@@ -5430,7 +5430,7 @@ void drcbe_x86::op_lzcnt(Assembler &a, const instruction &inst)
Label end = a.newLabel();
a.bsr(edx, edx);
- a.jz(skip);
+ a.short_().jz(skip);
a.xor_(edx, 31 ^ 63);
a.mov(dstreg, edx);
a.short_().jmp(end);
@@ -5494,7 +5494,7 @@ void drcbe_x86::op_tzcnt(Assembler &a, const instruction &inst)
Label skip = a.newLabel();
emit_mov_r64_p64(a, dstreg, edx, srcp); // mov dstreg:edx,srcp
a.bsf(dstreg, dstreg); // bsf dstreg,dstreg
- a.jnz(skip); // jnz skip
+ a.short_().jnz(skip); // jnz skip
a.mov(ecx, 32); // mov ecx,32
a.bsf(dstreg, edx); // bsf dstreg,edx
a.cmovz(dstreg, ecx); // cmovz dstreg,ecx
@@ -6126,21 +6126,21 @@ void drcbe_x86::op_fmov(Assembler &a, const instruction &inst)
if (inst.condition() != uml::COND_ALWAYS)
{
skip = a.newLabel();
- a.j(X86_NOT_CONDITION(inst.condition()), skip); // jcc skip
+ a.short_().j(X86_NOT_CONDITION(inst.condition()), skip);
}
// general case
- a.mov(eax, MABS(srcp.memory(0))); // mov eax,[srcp]
+ a.mov(eax, MABS(srcp.memory(0)));
if (inst.size() == 8)
- a.mov(edx, MABS(srcp.memory(4))); // mov edx,[srcp + 4]
- a.mov(MABS(dstp.memory(0)), eax); // mov [dstp],eax
+ a.mov(edx, MABS(srcp.memory(4)));
+ a.mov(MABS(dstp.memory(0)), eax);
if (inst.size() == 8)
- a.mov(MABS(dstp.memory(4)), edx); // mov [dstp + 4],edx
+ a.mov(MABS(dstp.memory(4)), edx);
// resolve the jump
if (inst.condition() != uml::COND_ALWAYS)
{
- a.bind(skip); // skip:
+ a.bind(skip);
reset_last_upper_lower_reg();
}
}
diff --git a/src/lib/util/delegate.cpp b/src/lib/util/delegate.cpp
index 67fb7e72d42..fb2fd4e2091 100644
--- a/src/lib/util/delegate.cpp
+++ b/src/lib/util/delegate.cpp
@@ -72,7 +72,7 @@ const delegate_mfp_compatible::raw_mfp_data delegate_mfp_compatible::s_null_mfp
delegate_generic_function delegate_mfp_itanium::convert_to_generic(delegate_generic_class *&object) const
{
- auto const [entrypoint, adjusted] = detail::resolve_member_function_itanium(m_function, m_this_delta, object);
+ auto const [entrypoint, adjusted] = resolve_member_function_itanium(m_function, m_this_delta, object);
object = reinterpret_cast<delegate_generic_class *>(adjusted);
return reinterpret_cast<delegate_generic_function>(entrypoint);
}
@@ -87,7 +87,7 @@ delegate_generic_function delegate_mfp_itanium::convert_to_generic(delegate_gene
delegate_generic_function delegate_mfp_msvc::adjust_this_pointer(delegate_generic_class *&object) const
{
- auto const [entrypoint, adjusted] = detail::resolve_member_function_msvc(&m_function, m_size, object);
+ auto const [entrypoint, adjusted] = resolve_member_function_msvc(&m_function, m_size, object);
object = reinterpret_cast<delegate_generic_class *>(adjusted);
return reinterpret_cast<delegate_generic_function>(entrypoint);
}
diff --git a/src/lib/util/mfpresolve.h b/src/lib/util/mfpresolve.h
index eee3711ebea..7661623572a 100644
--- a/src/lib/util/mfpresolve.h
+++ b/src/lib/util/mfpresolve.h
@@ -42,18 +42,18 @@ inline T bypass_member_function_thunks(T entrypoint, U const *object) noexcept
template <typename T, typename Ret, typename... Params>
-inline std::pair<std::uintptr_t, std::uintptr_t> resolve_member_function(Ret (T::*function)(Params...), T *object) noexcept
+inline std::pair<std::uintptr_t, std::uintptr_t> resolve_member_function(Ret (T::*function)(Params...), T &object) noexcept
{
if (MAME_ABI_CXX_TYPE == MAME_ABI_CXX_ITANIUM)
{
struct { std::uintptr_t ptr; std::ptrdiff_t adj; } equiv;
assert(sizeof(function) == sizeof(equiv));
*reinterpret_cast<decltype(function) *>(&equiv) = function;
- return detail::resolve_member_function_itanium(equiv.ptr, equiv.adj, object);
+ return detail::resolve_member_function_itanium(equiv.ptr, equiv.adj, &object);
}
else if (MAME_ABI_CXX_TYPE == MAME_ABI_CXX_MSVC)
{
- return detail::resolve_member_function_msvc(&function, sizeof(function), object);
+ return detail::resolve_member_function_msvc(&function, sizeof(function), &object);
}
else
{
@@ -63,18 +63,18 @@ inline std::pair<std::uintptr_t, std::uintptr_t> resolve_member_function(Ret (T:
template <typename T, typename Ret, typename... Params>
-inline std::pair<std::uintptr_t, std::uintptr_t> resolve_member_function(Ret (T::*function)(Params...) const, T const *object) noexcept
+inline std::pair<std::uintptr_t, std::uintptr_t> resolve_member_function(Ret (T::*function)(Params...) const, T const &object) noexcept
{
if (MAME_ABI_CXX_TYPE == MAME_ABI_CXX_ITANIUM)
{
struct { std::uintptr_t ptr; std::ptrdiff_t adj; } equiv;
assert(sizeof(function) == sizeof(equiv));
*reinterpret_cast<decltype(function) *>(&equiv) = function;
- return detail::resolve_member_function_itanium(equiv.ptr, equiv.adj, object);
+ return detail::resolve_member_function_itanium(equiv.ptr, equiv.adj, &object);
}
else if (MAME_ABI_CXX_TYPE == MAME_ABI_CXX_MSVC)
{
- return detail::resolve_member_function_msvc(&function, sizeof(function), object);
+ return detail::resolve_member_function_msvc(&function, sizeof(function), &object);
}
else
{