Skip to content

Commit 6dcc4ad

Browse files
committed
WIP
1 parent f8150ce commit 6dcc4ad

File tree

2 files changed

+68
-94
lines changed

2 files changed

+68
-94
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/jit_memory.rs

Lines changed: 64 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ const JIT_LIVE_RANGE_PAGE_SIZE: u32 = 1 << JIT_LIVE_RANGE_PAGE_SIZE_SHIFT;
3636
const JIT_ARM9_MEMORY_SIZE: usize = 28 * 1024 * 1024;
3737
const JIT_ARM7_MEMORY_SIZE: usize = JIT_MEMORY_SIZE - JIT_ARM9_MEMORY_SIZE;
3838

39-
const SLOW_MEM_SINGLE_WRITE_LENGTH_THUMB: usize = 14;
40-
const SLOW_MEM_SINGLE_READ_LENGTH_THUMB: usize = 14;
39+
const SLOW_MEM_SINGLE_WRITE_LENGTH_THUMB: usize = 22;
40+
const SLOW_MEM_SINGLE_READ_LENGTH_THUMB: usize = 22;
4141
const SLOW_MEM_MULTIPLE_LENGTH_THUMB: usize = 26;
4242

43-
const SLOW_MEM_SINGLE_WRITE_LENGTH_ARM: usize = 20;
44-
const SLOW_MEM_SINGLE_READ_LENGTH_ARM: usize = 20;
43+
const SLOW_MEM_SINGLE_WRITE_LENGTH_ARM: usize = 28;
44+
const SLOW_MEM_SINGLE_READ_LENGTH_ARM: usize = 28;
4545
const SLOW_MEM_MULTIPLE_LENGTH_ARM: usize = 28;
46-
pub const SLOW_SWP_MEM_SINGLE_WRITE_LENGTH_ARM: usize = 12;
47-
pub const SLOW_SWP_MEM_SINGLE_READ_LENGTH_ARM: usize = 12;
46+
pub const SLOW_SWP_MEM_SINGLE_WRITE_LENGTH_ARM: usize = 20;
47+
pub const SLOW_SWP_MEM_SINGLE_READ_LENGTH_ARM: usize = 20;
4848

4949
#[derive(Copy, Clone)]
5050
pub struct JitEntry(pub *const extern "C" fn(u32));
@@ -356,7 +356,7 @@ impl JitMemory {
356356
jit_data.start = (freed_start as usize) << PAGE_SHIFT;
357357
jit_data.end = (freed_end as usize) << PAGE_SHIFT;
358358

359-
debug_println!("{cpu_type:?} Jit memory reset from {:x} - {:x}", jit_data.start, jit_data.end);
359+
println!("{cpu_type:?} Jit memory reset from {:x} - {:x}", jit_data.start, jit_data.end);
360360
}
361361

362362
fn allocate_block(&mut self, required_size: usize, cpu_type: CpuType) -> (usize, bool) {
@@ -410,7 +410,7 @@ impl JitMemory {
410410
*live_range &= !(1 << live_ranges_bit);
411411

412412
let guest_addr_start = $guest_addr & !(JIT_LIVE_RANGE_PAGE_SIZE - 1);
413-
debug_println!("Invalidating jit {guest_addr_start:x} - {:x}", guest_addr_start + JIT_LIVE_RANGE_PAGE_SIZE);
413+
println!("Invalidating jit {guest_addr_start:x} - {:x}", guest_addr_start + JIT_LIVE_RANGE_PAGE_SIZE);
414414
self.jit_memory_map.write_jit_entries(guest_addr_start, JIT_LIVE_RANGE_PAGE_SIZE as usize, DEFAULT_JIT_ENTRY);
415415
}
416416
}};
@@ -430,22 +430,22 @@ impl JitMemory {
430430
}
431431
}
432432

433-
pub fn find_guest_inst_metadata(&mut self, jit_pc: usize) -> &mut GuestInstMetadata {
433+
unsafe fn find_guest_inst_metadata(&mut self, jit_pc: usize) -> &mut GuestInstMetadata {
434434
let jit_mem_offset = jit_pc - self.mem.as_ptr() as usize;
435435
let metadata_block_page = jit_mem_offset >> PAGE_SHIFT;
436436
let opcode_offset = (jit_mem_offset & (PAGE_SIZE - 1)) & !1;
437437
let guest_inst_metadata_list = unsafe { self.guest_inst_metadata.get_unchecked_mut(metadata_block_page) };
438438

439439
for guest_inst_metadata in guest_inst_metadata_list {
440-
if opcode_offset == guest_inst_metadata.opcode_offset {
440+
if opcode_offset == guest_inst_metadata.s.fast.opcode_offset {
441441
return guest_inst_metadata;
442442
}
443443
}
444444

445445
unsafe { unreachable_unchecked() }
446446
}
447447

448-
fn get_inst_mem_handler_fun<const CPU: CpuType>(is_write: bool, transfer: SingleTransfer, guest_memory_addr: u32, cpsr_dirty: bool) -> *const () {
448+
fn get_inst_mem_handler_fun<const CPU: CpuType>(is_write: bool, transfer: SingleTransfer, guest_memory_addr: u32, cpsr_dirty: bool, io_func: &mut Option<*const ()>) -> *const () {
449449
macro_rules! _get_inst_mem_handler_fun {
450450
($is_write:expr, $size:expr, $signed:expr, $write_func:ident, $read_func:ident, $read_func_64:ident) => {
451451
match ($is_write, $size) {
@@ -475,7 +475,7 @@ impl JitMemory {
475475
}
476476

477477
if CPU == ARM9 && is_write && guest_memory_addr >= 0x4000400 && guest_memory_addr < 0x4000440 && transfer.size() == 2 {
478-
if cpsr_dirty {
478+
return if cpsr_dirty {
479479
_get_inst_mem_handler_fun!(
480480
is_write,
481481
transfer.size(),
@@ -493,53 +493,57 @@ impl JitMemory {
493493
inst_read_mem_handler,
494494
inst_read64_mem_handler
495495
)
496-
}
497-
} else if transfer.size() != 3 && guest_memory_addr & 0xFF000000 == regions::IO_PORTS_OFFSET && {
496+
};
497+
}
498+
499+
if transfer.size() != 3 && guest_memory_addr & 0xFF000000 == regions::IO_PORTS_OFFSET {
498500
let io_addr = guest_memory_addr & 0xFFFFFF;
499501
let dma_range = 0xB0..=0xEC;
500502
let spu_range = 0x400..=0x4FC;
501503
let size = 1 << transfer.size();
502504
let aligned_addr = io_addr & !(size - 1);
503-
match CPU {
504-
ARM9 => {
505-
!dma_range.contains(&io_addr)
506-
&& if is_write {
507-
io_arm9::get_write_with_size(aligned_addr, size as usize).is_some()
508-
} else {
509-
io_arm9::get_read_with_size(aligned_addr, size as usize).is_some()
510-
}
505+
*io_func = match CPU {
506+
ARM9 if !dma_range.contains(&io_addr) => {
507+
if is_write {
508+
io_arm9::get_write_with_size(aligned_addr, size as usize).map(|f| f as _)
509+
} else {
510+
io_arm9::get_read_with_size(aligned_addr, size as usize).map(|f| f as _)
511+
}
511512
}
512-
ARM7 => {
513-
!dma_range.contains(&io_addr)
514-
&& !spu_range.contains(&io_addr)
515-
&& if is_write {
516-
io_arm7::get_write_with_size(aligned_addr, size as usize).is_some()
517-
} else {
518-
io_arm7::get_read_with_size(aligned_addr, size as usize).is_some()
519-
}
513+
ARM7 if !dma_range.contains(&io_addr) && !spu_range.contains(&io_addr) => {
514+
if is_write {
515+
io_arm7::get_write_with_size(aligned_addr, size as usize).map(|f| f as _)
516+
} else {
517+
io_arm7::get_read_with_size(aligned_addr, size as usize).map(|f| f as _)
518+
}
520519
}
520+
_ => None,
521+
};
522+
523+
if io_func.is_some() {
524+
return if cpsr_dirty {
525+
_get_inst_mem_handler_fun!(
526+
is_write,
527+
transfer.size(),
528+
transfer.signed(),
529+
inst_write_io_mem_handler_with_cpsr,
530+
inst_read_io_mem_handler_with_cpsr,
531+
inst_read64_mem_handler_with_cpsr
532+
)
533+
} else {
534+
_get_inst_mem_handler_fun!(
535+
is_write,
536+
transfer.size(),
537+
transfer.signed(),
538+
inst_write_io_mem_handler,
539+
inst_read_io_mem_handler,
540+
inst_read64_mem_handler
541+
)
542+
};
521543
}
522-
} {
523-
if cpsr_dirty {
524-
_get_inst_mem_handler_fun!(
525-
is_write,
526-
transfer.size(),
527-
transfer.signed(),
528-
inst_write_io_mem_handler_with_cpsr,
529-
inst_read_io_mem_handler_with_cpsr,
530-
inst_read64_mem_handler_with_cpsr
531-
)
532-
} else {
533-
_get_inst_mem_handler_fun!(
534-
is_write,
535-
transfer.size(),
536-
transfer.signed(),
537-
inst_write_io_mem_handler,
538-
inst_read_io_mem_handler,
539-
inst_read64_mem_handler
540-
)
541-
}
542-
} else if cpsr_dirty {
544+
}
545+
546+
if cpsr_dirty {
543547
_get_inst_mem_handler_fun!(
544548
is_write,
545549
transfer.size(),
@@ -729,10 +733,11 @@ impl JitMemory {
729733
};
730734

731735
let is_write = guest_inst_metadata.s.fast.op.is_write_mem_transfer();
736+
let mut io_func = None;
732737

733738
let inst_mem_func = match cpu {
734-
ARM9 => Self::get_inst_mem_handler_fun::<{ ARM9 }>(is_write, transfer, guest_memory_addr, guest_inst_metadata.dirty_guest_regs.is_reserved(Reg::CPSR)),
735-
ARM7 => Self::get_inst_mem_handler_fun::<{ ARM7 }>(is_write, transfer, guest_memory_addr, guest_inst_metadata.dirty_guest_regs.is_reserved(Reg::CPSR)),
739+
ARM9 => Self::get_inst_mem_handler_fun::<{ ARM9 }>(is_write, transfer, guest_memory_addr, guest_inst_metadata.dirty_guest_regs.is_reserved(Reg::CPSR), &mut io_func),
740+
ARM7 => Self::get_inst_mem_handler_fun::<{ ARM7 }>(is_write, transfer, guest_memory_addr, guest_inst_metadata.dirty_guest_regs.is_reserved(Reg::CPSR), &mut io_func),
736741
};
737742
Self::fast_mem_mov::<THUMB>(fast_mem, &mut slow_mem_length, Reg::LR, inst_mem_func as u32);
738743

@@ -749,11 +754,6 @@ impl JitMemory {
749754

750755
Self::fast_mem_blx::<THUMB>(fast_mem, &mut slow_mem_length, Reg::LR);
751756

752-
let host_pc_page = *host_pc >> PAGE_SHIFT;
753-
let slow_mem_return_page = (fast_mem.as_ptr() as usize + slow_mem_length) >> PAGE_SHIFT;
754-
debug_assert_eq!(host_pc_page, slow_mem_return_page);
755-
guest_inst_metadata.opcode_offset = guest_inst_metadata.opcode_offset - guest_inst_metadata.s.fast.start_offset as usize + slow_mem_length;
756-
757757
if !is_write {
758758
Self::fast_mem_mov_reg::<THUMB>(fast_mem, &mut slow_mem_length, guest_inst_metadata.s.fast.op0, Reg::R0);
759759
if transfer.size() == 3 {
@@ -765,31 +765,9 @@ impl JitMemory {
765765
let max_length = Self::get_slow_mem_length(guest_inst_metadata.s.fast.op);
766766
debug_assert!(slow_mem_length <= max_length, "{slow_mem_length} <= {max_length}");
767767

768-
if guest_memory_addr & 0xF000000 == regions::IO_PORTS_OFFSET {
769-
let size = 1 << transfer.size();
770-
let io_addr = guest_memory_addr & 0xFFFFFF;
771-
let aligned_addr = io_addr & !(size - 1);
772-
let func_addr = match cpu {
773-
ARM9 => {
774-
if is_write {
775-
io_arm9::get_write_with_size(aligned_addr, size as usize).map(|func| func as *const ())
776-
} else {
777-
io_arm9::get_read_with_size(aligned_addr, size as usize).map(|func| func as *const ())
778-
}
779-
}
780-
ARM7 => {
781-
if is_write {
782-
io_arm7::get_write_with_size(aligned_addr, size as usize).map(|func| func as *const ())
783-
} else {
784-
io_arm7::get_read_with_size(aligned_addr, size as usize).map(|func| func as *const ())
785-
}
786-
}
787-
};
788-
789-
if let Some(func_addr) = func_addr {
790-
guest_inst_metadata.s.slow.initial_patch_addr = guest_memory_addr;
791-
guest_inst_metadata.s.slow.io_func = func_addr;
792-
}
768+
if let Some(io_func) = io_func {
769+
guest_inst_metadata.s.slow.initial_patch_addr = guest_memory_addr;
770+
guest_inst_metadata.s.slow.io_func = io_func;
793771
}
794772
} else if guest_inst_metadata.s.fast.op.is_multiple_mem_transfer() {
795773
let transfer = match guest_inst_metadata.s.fast.op {
@@ -842,6 +820,7 @@ impl JitMemory {
842820
debug_assert!(slow_mem_length <= max_length, "{slow_mem_length} <= {max_length}");
843821
} else if !THUMB && matches!(guest_inst_metadata.s.fast.op, Op::Swpb | Op::Swp) {
844822
let is_write = guest_inst_metadata.s.fast.op0 == Reg::R1;
823+
let mut io_func = None;
845824

846825
let size = match guest_inst_metadata.s.fast.op {
847826
Op::Swpb => 0,
@@ -850,18 +829,13 @@ impl JitMemory {
850829
};
851830
let transfer = SingleTransfer::new(false, false, false, false, size);
852831
let inst_mem_func = match cpu {
853-
ARM9 => Self::get_inst_mem_handler_fun::<{ ARM9 }>(is_write, transfer, guest_memory_addr, guest_inst_metadata.dirty_guest_regs.is_reserved(Reg::CPSR)),
854-
ARM7 => Self::get_inst_mem_handler_fun::<{ ARM7 }>(is_write, transfer, guest_memory_addr, guest_inst_metadata.dirty_guest_regs.is_reserved(Reg::CPSR)),
832+
ARM9 => Self::get_inst_mem_handler_fun::<{ ARM9 }>(is_write, transfer, guest_memory_addr, guest_inst_metadata.dirty_guest_regs.is_reserved(Reg::CPSR), &mut io_func),
833+
ARM7 => Self::get_inst_mem_handler_fun::<{ ARM7 }>(is_write, transfer, guest_memory_addr, guest_inst_metadata.dirty_guest_regs.is_reserved(Reg::CPSR), &mut io_func),
855834
};
856835
Self::fast_mem_mov::<THUMB>(fast_mem, &mut slow_mem_length, Reg::LR, inst_mem_func as u32);
857836

858837
Self::fast_mem_blx::<THUMB>(fast_mem, &mut slow_mem_length, Reg::LR);
859838

860-
let host_pc_page = *host_pc >> PAGE_SHIFT;
861-
let slow_mem_return_page = (fast_mem.as_ptr() as usize + slow_mem_length) >> PAGE_SHIFT;
862-
debug_assert_eq!(host_pc_page, slow_mem_return_page);
863-
guest_inst_metadata.opcode_offset = guest_inst_metadata.opcode_offset - guest_inst_metadata.s.fast.start_offset as usize + slow_mem_length;
864-
865839
let max_length = if is_write { SLOW_SWP_MEM_SINGLE_WRITE_LENGTH_ARM } else { SLOW_SWP_MEM_SINGLE_READ_LENGTH_ARM };
866840
debug_assert!(slow_mem_length <= max_length, "{slow_mem_length} <= {max_length}");
867841
} else {

0 commit comments

Comments
 (0)