Skip to content

Commit 9bd798f

Browse files
committed
Pass metadata ptr to slow mem path
1 parent f8150ce commit 9bd798f

File tree

3 files changed

+114
-118
lines changed

3 files changed

+114
-118
lines changed

src/jit/assembler/block_asm.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,18 @@ pub struct GuestInstMetadataFastMem {
2424
pub op: Op,
2525
pub operands: Operands,
2626
pub op0: Reg,
27+
pub opcode_offset: usize,
2728
}
2829

2930
impl GuestInstMetadataFastMem {
30-
fn new(start_offset: u16, size: u16, op: Op, operands: Operands, op0: Reg) -> Self {
31+
fn new(start_offset: u16, size: u16, op: Op, operands: Operands, op0: Reg, opcode_offset: usize) -> Self {
3132
GuestInstMetadataFastMem {
3233
start_offset,
3334
size,
3435
op,
3536
operands,
3637
op0,
38+
opcode_offset,
3739
}
3840
}
3941
}
@@ -59,7 +61,6 @@ impl GuestInstMetadataShared {
5961
#[derive(Clone)]
6062
pub struct GuestInstMetadata {
6163
pub s: GuestInstMetadataShared,
62-
pub opcode_offset: usize,
6364
pub pc: u32,
6465
pub total_cycle_count: u16,
6566
pub dirty_guest_regs: RegReserve,
@@ -80,8 +81,7 @@ impl GuestInstMetadata {
8081
mapped_guest_regs: [Reg; GUEST_REGS_LENGTH],
8182
) -> Self {
8283
GuestInstMetadata {
83-
s: GuestInstMetadataShared::new(GuestInstMetadataFastMem::new(fast_mem_start_offset, fast_mem_size, op, operands, op0)),
84-
opcode_offset,
84+
s: GuestInstMetadataShared::new(GuestInstMetadataFastMem::new(fast_mem_start_offset, fast_mem_size, op, operands, op0, opcode_offset)),
8585
pc,
8686
total_cycle_count,
8787
dirty_guest_regs,

src/jit/inst_mem_handler.rs

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use handler::*;
1212
use std::arch::naked_asm;
1313
use std::hint::{assert_unchecked, unreachable_unchecked};
1414
use std::intrinsics::{likely, unlikely};
15-
use std::mem;
15+
use std::{mem, ptr};
1616

1717
mod handler {
1818
use crate::core::emu::Emu;
@@ -201,11 +201,11 @@ macro_rules! imm_breakout {
201201
}
202202
pub(super) use imm_breakout;
203203

204-
unsafe extern "C" fn breakout_after_write<const CPU: CpuType>(guest_return_lr: usize, host_regs: &[usize; GUEST_REG_ALLOCATIONS.len()]) {
204+
unsafe extern "C" fn breakout_after_write<const CPU: CpuType>(metadata: *const GuestInstMetadata, host_regs: &[usize; GUEST_REG_ALLOCATIONS.len()]) {
205205
let asm = get_jit_asm_ptr::<CPU>().as_mut_unchecked();
206206
debug_println!("{CPU:?} breakout after write");
207207

208-
let metadata: &'static GuestInstMetadata = mem::transmute(asm.emu.jit.find_guest_inst_metadata(guest_return_lr));
208+
let metadata = metadata.as_ref_unchecked();
209209

210210
for dirty_guest_reg in metadata.dirty_guest_regs - Reg::CPSR {
211211
let mapped_reg = *metadata.mapped_guest_regs.get_unchecked(dirty_guest_reg as usize);
@@ -216,38 +216,43 @@ unsafe extern "C" fn breakout_after_write<const CPU: CpuType>(guest_return_lr: u
216216
imm_breakout!(CPU, asm, metadata.pc, metadata.total_cycle_count);
217217
}
218218

219-
unsafe extern "C" fn _inst_write_mem_handler<const CPU: CpuType, const AMOUNT: MemoryAmount>(value0: u32, value1: u32, addr: u32, guest_return_lr: usize) -> usize {
219+
unsafe extern "C" fn _inst_write_mem_handler<const CPU: CpuType, const AMOUNT: MemoryAmount>(value0: u32, value1: u32, addr: u32, metadata: *const GuestInstMetadata) -> *const GuestInstMetadata {
220220
debug_println!("{CPU:?} handle write request addr {addr:x}");
221221

222222
let asm = get_jit_asm_ptr::<CPU>().as_mut_unchecked();
223223
handle_request_write::<CPU, AMOUNT>(value0, value1, addr, asm.emu);
224224
if unlikely(asm.emu.breakout_imm) {
225-
guest_return_lr
225+
metadata
226226
} else {
227-
0
227+
ptr::null()
228228
}
229229
}
230230

231-
unsafe extern "C" fn _inst_write_io_mem_handler<const CPU: CpuType, const AMOUNT: MemoryAmount>(value0: u32, value1: u32, addr: u32, guest_return_lr: usize) -> usize {
231+
unsafe extern "C" fn _inst_write_io_mem_handler<const CPU: CpuType, const AMOUNT: MemoryAmount>(
232+
value0: u32,
233+
value1: u32,
234+
addr: u32,
235+
metadata_ptr: *const GuestInstMetadata,
236+
) -> *const GuestInstMetadata {
232237
if AMOUNT == MemoryAmount::Double {
233238
unreachable_unchecked();
234239
}
235240

236241
debug_println!("{CPU:?} handle write request addr {addr:x}");
237242

238243
let asm = get_jit_asm_ptr::<CPU>().as_mut_unchecked();
239-
let metadata: &'static GuestInstMetadata = mem::transmute(asm.emu.jit.find_guest_inst_metadata(guest_return_lr));
244+
let metadata = metadata_ptr.as_ref_unchecked();
240245

241246
if likely(addr == metadata.s.slow.initial_patch_addr) {
242247
let func: fn(&mut Emu, u32) = mem::transmute(metadata.s.slow.io_func);
243248
func(asm.emu, value0);
244-
0
249+
ptr::null()
245250
} else {
246251
handle_request_write::<CPU, AMOUNT>(value0, value1, addr, asm.emu);
247252
if unlikely(asm.emu.breakout_imm) {
248-
guest_return_lr
253+
metadata_ptr
249254
} else {
250-
0
255+
ptr::null()
251256
}
252257
}
253258
}
@@ -259,10 +264,10 @@ macro_rules! write_mem_handler_cpsr {
259264
#[rustfmt::skip]
260265
naked_asm!(
261266
"push {{r3, lr}}",
262-
"mrs r12, cpsr",
263-
"lsrs r12, r12, 24",
264-
"strb r12, [r3, {cpsr_bits}]",
265-
"mov r3, lr",
267+
"mrs lr, cpsr",
268+
"lsrs lr, lr, 24",
269+
"strb lr, [r3, {cpsr_bits}]",
270+
"mov r3, r12",
266271
"bl {handler}",
267272
"cbnz r0, 1f",
268273
"pop {{r3, lr}}",
@@ -289,7 +294,7 @@ macro_rules! write_mem_handler {
289294
#[rustfmt::skip]
290295
naked_asm!(
291296
"push {{r3, lr}}",
292-
"mov r3, lr",
297+
"mov r3, r12",
293298
"bl {}",
294299
"cbnz r0, 1f",
295300
"pop {{r3, pc}}",
@@ -358,15 +363,20 @@ pub unsafe extern "C" fn inst_read_mem_handler_with_cpsr<const CPU: CpuType, con
358363
);
359364
}
360365

361-
pub unsafe extern "C" fn _inst_read_io_mem_handler<const CPU: CpuType, const AMOUNT: MemoryAmount, const SIGNED: bool>(_: u8, _: u32, addr: u32, guest_return_lr: usize) -> u32 {
366+
pub unsafe extern "C" fn _inst_read_io_mem_handler<const CPU: CpuType, const AMOUNT: MemoryAmount, const SIGNED: bool>(
367+
metadata: *const GuestInstMetadata,
368+
_: u32,
369+
addr: u32,
370+
guest_return_lr: usize,
371+
) -> u32 {
362372
if AMOUNT == MemoryAmount::Double || (AMOUNT == MemoryAmount::Word && SIGNED) {
363373
unreachable_unchecked();
364374
}
365375

366376
debug_println!("{CPU:?} handle read request addr {addr:x}");
367377

368378
let asm = get_jit_asm_ptr::<CPU>().as_mut_unchecked();
369-
let metadata: &'static GuestInstMetadata = mem::transmute(asm.emu.jit.find_guest_inst_metadata(guest_return_lr));
379+
let metadata = metadata.as_ref_unchecked();
370380

371381
if likely(addr == metadata.s.slow.initial_patch_addr) {
372382
let func: fn(&mut Emu) -> u32 = mem::transmute(metadata.s.slow.io_func);
@@ -377,7 +387,7 @@ pub unsafe extern "C" fn _inst_read_io_mem_handler<const CPU: CpuType, const AMO
377387
}
378388

379389
#[unsafe(naked)]
380-
pub unsafe extern "C" fn inst_read_io_mem_handler<const CPU: CpuType, const AMOUNT: MemoryAmount, const SIGNED: bool>(_: u8, _: u32, _: u32) {
390+
pub unsafe extern "C" fn inst_read_io_mem_handler<const CPU: CpuType, const AMOUNT: MemoryAmount, const SIGNED: bool>(_: *const GuestInstMetadata, _: u32, _: u32) {
381391
#[rustfmt::skip]
382392
naked_asm!(
383393
"push {{r3, lr}}",
@@ -389,7 +399,7 @@ pub unsafe extern "C" fn inst_read_io_mem_handler<const CPU: CpuType, const AMOU
389399
}
390400

391401
#[unsafe(naked)]
392-
pub unsafe extern "C" fn inst_read_io_mem_handler_with_cpsr<const CPU: CpuType, const AMOUNT: MemoryAmount, const SIGNED: bool>(_: u8, _: u32, _: u32) {
402+
pub unsafe extern "C" fn inst_read_io_mem_handler_with_cpsr<const CPU: CpuType, const AMOUNT: MemoryAmount, const SIGNED: bool>(_: *const GuestInstMetadata, _: u32, _: u32) {
393403
#[rustfmt::skip]
394404
naked_asm!(
395405
"push {{r3, lr}}",
@@ -601,19 +611,24 @@ pub unsafe extern "C" fn inst_read_mem_handler_multiple<const CPU: CpuType, cons
601611
);
602612
}
603613

604-
unsafe extern "C" fn _inst_mem_handler_write_gx_fifo<const CPU: CpuType, const AMOUNT: MemoryAmount>(value0: u32, value1: u32, addr: u32, guest_context_lr: usize) -> usize {
614+
unsafe extern "C" fn _inst_mem_handler_write_gx_fifo<const CPU: CpuType, const AMOUNT: MemoryAmount>(
615+
value0: u32,
616+
value1: u32,
617+
addr: u32,
618+
metadata: *const GuestInstMetadata,
619+
) -> *const GuestInstMetadata {
605620
unsafe { assert_unchecked(CPU == ARM9 && AMOUNT == MemoryAmount::Word) };
606621

607622
if likely(addr >= 0x4000400 && addr < 0x4000440) {
608623
let asm = get_jit_asm_ptr::<{ ARM9 }>().as_mut_unchecked();
609624
asm.emu.regs_3d_set_gx_fifo(value0, value0);
610625
if unlikely(asm.emu.breakout_imm) {
611-
guest_context_lr
626+
metadata
612627
} else {
613-
0
628+
ptr::null()
614629
}
615630
} else {
616-
_inst_write_mem_handler::<{ ARM9 }, { MemoryAmount::Word }>(value0, value1, addr, guest_context_lr)
631+
_inst_write_mem_handler::<{ ARM9 }, { MemoryAmount::Word }>(value0, value1, addr, metadata)
617632
}
618633
}
619634

0 commit comments

Comments
 (0)