diff --git a/src/devices/cpu/drcbearm64.cpp b/src/devices/cpu/drcbearm64.cpp index 71002364461..fa625ba5953 100644 --- a/src/devices/cpu/drcbearm64.cpp +++ b/src/devices/cpu/drcbearm64.cpp @@ -47,10 +47,10 @@ FP -> SP + 0x00 previous FP Stack layout in nested generated code subroutine call frame: -SP -> SP + 0x00 previous FP +SP -> SP + 0x00 saved FP SP + 0x08 return address ... - FP - 0x10 previous FP + FP - 0x10 saved FP FP - 0x08 return address FP -> FP + 0x00 previous FP FP + 0x08 top-level return address @@ -492,6 +492,20 @@ void drcbe_arm64::get_imm_relative(a64::Assembler &a, const a64::Gp ®, const return; } + const uint64_t pagebase = codeoffs & ~make_bitmask(12); + const int64_t pagerel = (int64_t)ptr - pagebase; + if (is_valid_immediate_signed(pagerel, 33)) + { + const uint64_t targetpage = (uint64_t)ptr & ~make_bitmask(12); + const uint64_t pageoffs = (uint64_t)ptr & util::make_bitmask(12); + + a.adrp(reg, targetpage); + if (pageoffs != 0) + a.add(reg, reg, pageoffs); + + return; + } + a.mov(reg, ptr); } @@ -953,7 +967,7 @@ drcbe_arm64::drcbe_arm64(drcuml_state &drcuml, device_t &device, drc_cache &cach , m_entry(nullptr) , m_exit(nullptr) , m_nocode(nullptr) - , m_baseptr(cache.near() + 0x80) + , m_baseptr(cache.near() + 0x100) , m_near(*(near_state *)cache.alloc_near(sizeof(m_near))) { m_near.emulated_flags = 0; diff --git a/src/devices/cpu/drcbex64.cpp b/src/devices/cpu/drcbex64.cpp index b57c48828d1..7538ee25b83 100644 --- a/src/devices/cpu/drcbex64.cpp +++ b/src/devices/cpu/drcbex64.cpp @@ -1287,7 +1287,13 @@ void drcbe_x64::mov_r64_imm(Assembler &a, Gp const ®, uint64_t const imm) else if (s32(imm) == imm) a.mov(reg.r64(), s32(imm)); else - a.mov(reg.r64(), imm); + { + const int64_t delta = imm - (a.code()->baseAddress() + a.offset() + 7); + if (short_immediate(delta)) + a.lea(reg.r64(), ptr(rip, delta)); + else + a.mov(reg.r64(), imm); + } }