@@ -225,13 +225,13 @@ const auto ppu_gateway = build_function_asm<void(*)(ppu_thread*)>("ppu_gateway",
225225 c.mov (x86::rbp, args[0 ]);
226226 c.mov (x86::edx, x86::dword_ptr (x86::rbp, ::offset32 (&ppu_thread::cia))); // Load PC
227227
228- c.mov (x86::rax, x86::qword_ptr (x86::r13, x86::edx , 1 , 0 )); // Load call target
229- c.mov (x86::rdx, x86::rax );
230- c.shl (x86::rax, 16 );
231- c.shr (x86::rax, 16 );
232- c.shr (x86::rdx, 48 );
228+ c.mov (x86::rax, x86::qword_ptr (x86::r13, x86::rdx , 1 , 0 )); // Load call target
229+ c.movabs (x86::r12, vm::g_exec_addr_seg_offset );
230+ c.add (x86::r12, x86::r13 );
231+ c.shr (x86::edx, 1 );
232+ c.mov (x86::edx, x86::word_ptr (x86::r12, x86::edx)); // Load relocation base
233233 c.shl (x86::edx, 13 );
234- c.mov (x86::r12d, x86::edx); // Load relocation base
234+ c.mov (x86::r12d, x86::edx); // Set relocation base
235235
236236 c.movabs (x86::rbx, reinterpret_cast <u64 >(&vm::g_base_addr));
237237 c.mov (x86::rbx, x86::qword_ptr (x86::rbx));
@@ -348,14 +348,11 @@ const auto ppu_gateway = build_function_asm<void(*)(ppu_thread*)>("ppu_gateway",
348348 c.ldr (call_target, arm::Mem (a64::x19, pc));
349349 // Compute REG_Hp
350350 const arm::GpX reg_hp = a64::x21;
351- c.mov (reg_hp, call_target);
352- c.lsr (reg_hp, reg_hp, 48 );
351+ c.mov (reg_hp, Imm (vm::g_exec_addr_seg_offset));
352+ c.add (reg_hp, reg_hp, pc, arm::Shift (arm::ShiftOp::kLSR , 2 ));
353+ c.ldrh (reg_hp.w (), arm::Mem (a64::x19, reg_hp));
353354 c.lsl (reg_hp.w (), reg_hp.w (), 13 );
354355
355- // Zero top 16 bits of call target
356- c.lsl (call_target, call_target, Imm (16 ));
357- c.lsr (call_target, call_target, Imm (16 ));
358-
359356 // Load registers
360357 c.mov (a64::x22, Imm (reinterpret_cast <u64 >(&vm::g_base_addr)));
361358 c.ldr (a64::x22, arm::Mem (a64::x22));
@@ -475,6 +472,11 @@ static inline u8* ppu_ptr(u32 addr)
475472 return vm::g_exec_addr + u64 {addr} * 2 ;
476473}
477474
475+ static inline u8 * ppu_seg_ptr (u32 addr)
476+ {
477+ return vm::g_exec_addr + vm::g_exec_addr_seg_offset + (addr >> 1 );
478+ }
479+
478480static inline ppu_intrp_func_t ppu_read (u32 addr)
479481{
480482 return read_from_ptr<ppu_intrp_func_t >(ppu_ptr (addr));
@@ -520,7 +522,7 @@ void ppu_recompiler_fallback(ppu_thread& ppu)
520522
521523 while (true )
522524 {
523- if (uptr func = uptr (ppu_read (ppu.cia )); ( func << 16 >> 16 ) != reinterpret_cast <uptr>(ppu_recompiler_fallback_ghc))
525+ if (uptr func = uptr (ppu_read (ppu.cia )); func != reinterpret_cast <uptr>(ppu_recompiler_fallback_ghc))
524526 {
525527 // We found a recompiler function at cia, return
526528 break ;
@@ -775,6 +777,9 @@ extern void ppu_register_range(u32 addr, u32 size)
775777 utils::memory_commit (ppu_ptr (addr), u64 {size} * 2 , utils::protection::rw);
776778 ensure (vm::page_protect (addr, size, 0 , vm::page_executable));
777779
780+ // Segment data
781+ utils::memory_commit (ppu_seg_ptr (addr), size >> 1 , utils::protection::rw);
782+
778783 if (g_cfg.core .ppu_debug )
779784 {
780785 utils::memory_commit (vm::g_stat_addr + addr, size);
@@ -787,12 +792,13 @@ extern void ppu_register_range(u32 addr, u32 size)
787792 if (g_cfg.core .ppu_decoder == ppu_decoder_type::llvm)
788793 {
789794 // Assume addr is the start of first segment of PRX
790- const uptr entry_value = reinterpret_cast <uptr>(ppu_recompiler_fallback_ghc) | (seg_base << ( 32 + 3 ));
791- write_to_ptr<uptr>( ppu_ptr (addr), entry_value );
795+ write_to_ptr <uptr>(ppu_ptr (addr), std::bit_cast<uptr>(ppu_recompiler_fallback_ghc ));
796+ write_to_ptr<u16 >( ppu_seg_ptr (addr), static_cast < u16 >(seg_base >> 13 ) );
792797 }
793798 else
794799 {
795800 write_to_ptr<ppu_intrp_func_t >(ppu_ptr (addr), ppu_fallback);
801+ write_to_ptr<u16 >(ppu_seg_ptr (addr), 0 );
796802 }
797803
798804 addr += 4 ;
@@ -807,7 +813,7 @@ extern void ppu_register_function_at(u32 addr, u32 size, ppu_intrp_func_t ptr =
807813 // Initialize specific function
808814 if (ptr)
809815 {
810- write_to_ptr<uptr>(ppu_ptr (addr), ( reinterpret_cast <uptr>(ptr) & 0xffff'ffff'ffffu ) | ( uptr ( ppu_read (addr)) & ~ 0xffff'ffff'ffffu ));
816+ write_to_ptr<uptr>(ppu_ptr (addr), std::bit_cast <uptr>(ptr));
811817 return ;
812818 }
813819
@@ -5087,14 +5093,14 @@ bool ppu_initialize(const ppu_module<lv2_obj>& info, bool check_only, u64 file_s
50875093 c.mov (x86::rax, x86::qword_ptr (x86::rax));
50885094 c.mov (x86::dword_ptr (x86::rbp, ::offset32 (&ppu_thread::cia)), x86::edx);
50895095
5090- c.mov (x86::rax , x86::qword_ptr (x86::rax, x86::rdx, 1 , 0 )); // Load call target
5091- c.mov (x86::rdx, x86::rax );
5092- c.shl (x86::rax, 16 );
5093- c.shr (x86::rax, 16 );
5094- c.shr (x86::rdx, 48 );
5096+ c.mov (x86::rcx , x86::qword_ptr (x86::rax, x86::rdx, 1 , 0 )); // Load call target
5097+ c.movabs (x86::r12, vm::g_exec_addr_seg_offset );
5098+ c.add (x86::rax, x86::r12 );
5099+ c.shr (x86::edx, 1 );
5100+ c.mov (x86::edx, x86::word_ptr (x86::rax, x86::edx)); // Load relocation base
50955101 c.shl (x86::edx, 13 );
5096- c.mov (x86::r12d, x86::edx); // Load relocation base
5097- c.jmp (x86::rax );
5102+ c.mov (x86::r12d, x86::edx); // Set relocation base
5103+ c.jmp (x86::rcx );
50985104#else
50995105 // Load REG_Base - use absolute jump target to bypass rel jmp range limits
51005106 // X19 contains vm::g_exec_addr
@@ -5130,14 +5136,11 @@ bool ppu_initialize(const ppu_module<lv2_obj>& info, bool check_only, u64 file_s
51305136
51315137 // Compute REG_Hp
51325138 const arm::GpX reg_hp = a64::x21;
5133- c.mov (reg_hp, call_target);
5134- c.lsr (reg_hp, reg_hp, 48 );
5139+ c.mov (reg_hp, Imm (vm::g_exec_addr_seg_offset));
5140+ c.add (reg_hp, reg_hp, pc, arm::Shift (arm::ShiftOp::kLSR , 2 ));
5141+ c.ldrh (reg_hp.w (), arm::Mem (exec_addr, reg_hp));
51355142 c.lsl (reg_hp.w (), reg_hp.w (), 13 );
51365143
5137- // Zero top 16 bits of call target
5138- c.lsl (call_target, call_target, 16 );
5139- c.lsr (call_target, call_target, 16 );
5140-
51415144 // Execute LLE call
51425145 c.br (call_target);
51435146#endif
@@ -5405,7 +5408,7 @@ bool ppu_initialize(const ppu_module<lv2_obj>& info, bool check_only, u64 file_s
54055408 settings += ppu_settings::contains_symbol_resolver; // Avoid invalidating all modules for this purpose
54065409
54075410 // Write version, hash, CPU, settings
5408- fmt::append (obj_name, " v6 -kusa-%s-%s-%s.obj" , fmt::base57 (output, 16 ), fmt::base57 (settings), jit_compiler::cpu (g_cfg.core .llvm_cpu ));
5411+ fmt::append (obj_name, " v7 -kusa-%s-%s-%s.obj" , fmt::base57 (output, 16 ), fmt::base57 (settings), jit_compiler::cpu (g_cfg.core .llvm_cpu ));
54095412 }
54105413
54115414 if (cpu ? cpu->state .all_of (cpu_flag::exit) : Emu.IsStopped ())
@@ -5717,7 +5720,7 @@ bool ppu_initialize(const ppu_module<lv2_obj>& info, bool check_only, u64 file_s
57175720
57185721 for (u32 addr = info.segs [0 ].addr ; addr < info.segs [0 ].addr + info.segs [0 ].size ; addr += 4 , inst_ptr++)
57195722 {
5720- if (*inst_ptr == ppu_instructions::BLR () && ( reinterpret_cast <uptr>(ppu_read (addr)) << 16 >> 16 ) == reinterpret_cast <uptr>(ppu_recompiler_fallback_ghc))
5723+ if (*inst_ptr == ppu_instructions::BLR () && reinterpret_cast <uptr>(ppu_read (addr)) == reinterpret_cast <uptr>(ppu_recompiler_fallback_ghc))
57215724 {
57225725 write_to_ptr<ppu_intrp_func_t >(ppu_ptr (addr), BLR_func);
57235726 }
0 commit comments