Skip to content

Commit ce95399

Browse files
committed
Generate jump table for io writes
1 parent 95be7b7 commit ce95399

File tree

8 files changed

+324
-392
lines changed

8 files changed

+324
-392
lines changed

macros/src/lib.rs

Lines changed: 236 additions & 241 deletions
Large diffs are not rendered by default.

src/core/graphics/gpu_3d/registers_3d.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,7 @@ impl Gpu3DRegisters {
692692
max(self.cmd_fifo.len() as isize - 4, 0) as usize
693693
}
694694

695+
#[inline(never)]
695696
fn get_clip_matrix(&mut self) -> &Matrix {
696697
if unlikely(self.mtx_flags.is_clip_dirty()) {
697698
self.mtx_flags.set_clip_dirty_bool(false);

src/core/memory/io_arm7.rs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,44 @@
11
use crate::core::emu::Emu;
22
use crate::core::memory::io_arm7_lut::*;
33
use crate::utils::Convert;
4+
use std::intrinsics::{likely, unlikely};
45

56
impl Emu {
67
pub fn io_arm7_read<T: Convert>(&mut self, addr_offset: u32) -> T {
7-
let ret = unsafe {
8-
match addr_offset & 0xF00000 {
9-
0x0 if io_arm7::is_in_range(addr_offset) => io_arm7::read(addr_offset, size_of::<T>(), self),
10-
0x100000 if io_arm7_upper::is_in_range(addr_offset) => io_arm7_upper::read(addr_offset, size_of::<T>(), self),
11-
0x800000 if io_arm7_wifi::is_in_range(addr_offset) => io_arm7_wifi::read(addr_offset, size_of::<T>(), self),
12-
_ => 0,
13-
}
14-
};
15-
T::from(ret)
8+
unsafe {
9+
T::from(if likely(io_arm7_read::is_in_range(addr_offset)) {
10+
io_arm7_read::read(addr_offset, size_of::<T>(), self)
11+
} else if unlikely(io_arm7_read_upper::is_in_range(addr_offset)) {
12+
io_arm7_read_upper::read(addr_offset, size_of::<T>(), self)
13+
} else if unlikely(io_arm7_read_wifi::is_in_range(addr_offset)) {
14+
io_arm7_read_wifi::read(addr_offset, size_of::<T>(), self)
15+
} else {
16+
0
17+
})
18+
}
1619
}
1720

1821
pub fn io_arm7_write<T: Convert>(&mut self, addr_offset: u32, value: T) {
19-
match addr_offset & 0xF00000 {
20-
0x0 if IoArm7WriteLut::is_in_range(addr_offset) => IoArm7WriteLut::write(value.into(), addr_offset, size_of::<T>() as u8, self),
21-
0x800000 if IoArm7WriteLutWifi::is_in_range(addr_offset) => IoArm7WriteLutWifi::write(value.into(), addr_offset, size_of::<T>() as u8, self),
22-
_ => {}
22+
unsafe {
23+
if likely(io_arm7_write::is_in_range(addr_offset)) {
24+
io_arm7_write::write(value.into(), addr_offset, size_of::<T>(), self);
25+
} else if unlikely(io_arm7_write_wifi::is_in_range(addr_offset)) {
26+
io_arm7_write_wifi::write(value.into(), addr_offset, size_of::<T>(), self);
27+
}
2328
}
2429
}
2530

2631
pub fn io_arm7_write_fixed_slice<T: Convert>(&mut self, addr_offset: u32, slice: &[T]) {
27-
match addr_offset & 0xF00000 {
28-
0x0 if IoArm7WriteLut::is_in_range(addr_offset) => IoArm7WriteLut::write_fixed_slice(addr_offset, slice, self),
29-
0x800000 if IoArm7WriteLutWifi::is_in_range(addr_offset) => IoArm7WriteLutWifi::write_fixed_slice(addr_offset, slice, self),
30-
_ => {}
32+
unsafe {
33+
if likely(io_arm7_write::is_in_range(addr_offset)) {
34+
for value in slice {
35+
io_arm7_write::write((*value).into(), addr_offset, size_of::<T>(), self);
36+
}
37+
} else if unlikely(io_arm7_write_wifi::is_in_range(addr_offset)) {
38+
for value in slice {
39+
io_arm7_write_wifi::write((*value).into(), addr_offset, size_of::<T>(), self);
40+
}
41+
}
3142
}
3243
}
3344
}

src/core/memory/io_arm7_lut.rs

Lines changed: 15 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
use crate::core::emu::Emu;
2-
use crate::core::wifi::PaketType;
3-
use crate::core::CpuType::ARM7;
4-
use crate::utils::Convert;
5-
use dsvita_macros::io_write;
6-
7-
pub mod io_arm7 {
1+
pub mod io_arm7_read {
82
use crate::core::CpuType::ARM7;
93
use dsvita_macros::io_read;
104
io_read!(
@@ -73,13 +67,13 @@ pub mod io_arm7 {
7367
);
7468
}
7569

76-
pub mod io_arm7_upper {
70+
pub mod io_arm7_read_upper {
7771
use crate::core::CpuType::ARM7;
7872
use dsvita_macros::io_read;
7973
io_read!((io32(0x100000), |emu| emu.ipc_fifo_recv(ARM7)), (io32(0x100010), |emu| todo!()));
8074
}
8175

82-
pub mod io_arm7_wifi {
76+
pub mod io_arm7_read_wifi {
8377
use crate::core::wifi::PaketType;
8478
use dsvita_macros::io_read;
8579
io_read!(
@@ -157,9 +151,11 @@ pub mod io_arm7_wifi {
157151
);
158152
}
159153

160-
io_write!(
161-
IoArm7WriteLut,
162-
[
154+
pub mod io_arm7_write {
155+
use crate::core::CpuType::ARM7;
156+
use dsvita_macros::io_write;
157+
158+
io_write!(
163159
(io8(0x0), |mask, value, emu| {}),
164160
(io16(0x4), |mask, value, emu| emu.gpu.set_disp_stat(ARM7, mask, value)),
165161
(io32(0xB0), |mask, value, emu| emu.dma_set_sad(ARM7, 0, mask, value)),
@@ -286,12 +282,13 @@ io_write!(
286282
(io16(0x514), |mask, value, emu| emu.spu_set_snd_cap_len(0, mask, value)),
287283
(io32(0x518), |mask, value, emu| emu.spu_set_snd_cap_dad(1, mask, value)),
288284
(io16(0x51C), |mask, value, emu| emu.spu_set_snd_cap_len(1, mask, value)),
289-
]
290-
);
285+
);
286+
}
291287

292-
io_write!(
293-
IoArm7WriteLutWifi,
294-
[
288+
pub mod io_arm7_write_wifi {
289+
use crate::core::wifi::PaketType;
290+
use dsvita_macros::io_write;
291+
io_write!(
295292
(io16(0x800000), |mask, value, emu| {}),
296293
(io16(0x800006), |mask, value, emu| emu.wifi_set_w_mode_wep(mask, value)),
297294
(io16(0x800008), |mask, value, emu| emu.wifi_set_w_txstat_cnt(mask, value)),
@@ -362,45 +359,5 @@ io_write!(
362359
(io16(0x800158), |mask, value, emu| emu.wifi_set_w_bb_cnt(mask, value)),
363360
(io16(0x80015A), |mask, value, emu| emu.wifi_set_w_bb_write(mask, value)),
364361
(io16(0x80021C), |mask, value, emu| emu.wifi_set_w_irf_set(mask, value)),
365-
]
366-
);
367-
368-
impl IoArm7WriteLut {
369-
pub fn write_fixed_slice<T: Convert>(addr: u32, slice: &[T], emu: &mut Emu) {
370-
let lut_addr = addr - Self::MIN_ADDR;
371-
let (func, write_size, offset) = unsafe { Self::_LUT.get_unchecked(lut_addr as usize) };
372-
373-
if *write_size < size_of::<T>() as u8 {
374-
for value in slice {
375-
Self::write((*value).into(), addr, size_of::<T>() as u8, emu);
376-
}
377-
} else {
378-
let mask = 0xFFFFFFFF >> ((4 - size_of::<T>()) << 3);
379-
let mask = mask << *offset;
380-
for value in slice {
381-
let value = (*value).into() << *offset;
382-
func(mask, value, emu)
383-
}
384-
}
385-
}
386-
}
387-
388-
impl IoArm7WriteLutWifi {
389-
pub fn write_fixed_slice<T: Convert>(addr: u32, slice: &[T], emu: &mut Emu) {
390-
let lut_addr = addr - Self::MIN_ADDR;
391-
let (func, write_size, offset) = unsafe { Self::_LUT.get_unchecked(lut_addr as usize) };
392-
393-
if *write_size < size_of::<T>() as u8 {
394-
for value in slice {
395-
Self::write((*value).into(), addr, size_of::<T>() as u8, emu);
396-
}
397-
} else {
398-
let mask = 0xFFFFFFFF >> ((4 - size_of::<T>()) << 3);
399-
let mask = mask << *offset;
400-
for value in slice {
401-
let value = (*value).into() << *offset;
402-
func(mask, value, emu)
403-
}
404-
}
405-
}
362+
);
406363
}

src/core/memory/io_arm9.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,32 @@
1-
use std::intrinsics::likely;
2-
31
use crate::core::emu::Emu;
42
use crate::core::memory::io_arm9_lut::*;
53
use crate::utils::Convert;
4+
use std::intrinsics::{likely, unlikely};
65

76
impl Emu {
87
pub fn io_arm9_read<T: Convert>(&mut self, addr_offset: u32) -> T {
98
unsafe {
10-
T::from(if likely(io_arm9::is_in_range(addr_offset)) {
11-
io_arm9::read(addr_offset, size_of::<T>(), self)
12-
} else if likely(io_arm9_upper::is_in_range(addr_offset)) {
13-
io_arm9_upper::read(addr_offset, size_of::<T>(), self)
9+
T::from(if likely(io_arm9_read::is_in_range(addr_offset)) {
10+
io_arm9_read::read(addr_offset, size_of::<T>(), self)
11+
} else if unlikely(io_arm9_read_upper::is_in_range(addr_offset)) {
12+
io_arm9_read_upper::read(addr_offset, size_of::<T>(), self)
1413
} else {
1514
0
1615
})
1716
}
1817
}
1918

2019
pub fn io_arm9_write<T: Convert>(&mut self, addr_offset: u32, value: T) {
21-
if likely(IoArm9WriteLut::is_in_range(addr_offset)) {
22-
IoArm9WriteLut::write(value.into(), addr_offset, size_of::<T>() as u8, self);
20+
if likely(io_arm9_write::is_in_range(addr_offset)) {
21+
unsafe { io_arm9_write::write(value.into(), addr_offset, size_of::<T>(), self) };
2322
}
2423
}
2524

2625
pub fn io_arm9_write_fixed_slice<T: Convert>(&mut self, addr_offset: u32, slice: &[T]) {
27-
if likely(IoArm9WriteLut::is_in_range(addr_offset)) {
28-
IoArm9WriteLut::write_fixed_slice(addr_offset, slice, self);
26+
if likely(io_arm9_write::is_in_range(addr_offset)) {
27+
for value in slice {
28+
unsafe { io_arm9_write::write((*value).into(), addr_offset, size_of::<T>(), self) };
29+
}
2930
}
3031
}
3132
}

src/core/memory/io_arm9_lut.rs

Lines changed: 7 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
use crate::core::emu::Emu;
2-
use crate::core::CpuType::ARM9;
3-
use crate::utils::Convert;
4-
use dsvita_macros::io_write;
5-
6-
pub mod io_arm9 {
1+
pub mod io_arm9_read {
72
use crate::core::CpuType::ARM9;
83
use dsvita_macros::io_read;
94
io_read!(
@@ -126,15 +121,16 @@ pub mod io_arm9 {
126121
);
127122
}
128123

129-
pub mod io_arm9_upper {
124+
pub mod io_arm9_read_upper {
130125
use crate::core::CpuType::ARM9;
131126
use dsvita_macros::io_read;
132127
io_read!((io32(0x100000), |emu| emu.ipc_fifo_recv(ARM9)), (io32(0x100010), |emu| emu.cartridge_get_rom_data_in(ARM9)));
133128
}
134129

135-
io_write!(
136-
IoArm9WriteLut,
137-
[
130+
pub mod io_arm9_write {
131+
use crate::core::CpuType::ARM9;
132+
use dsvita_macros::io_write;
133+
io_write!(
138134
(io32(0x0), |mask, value, emu| emu.gpu.gpu_2d_regs_a.set_disp_cnt(mask, value)),
139135
(io16(0x4), |mask, value, emu| emu.gpu.set_disp_stat(ARM9, mask, value)),
140136
(io16(0x8), |mask, value, emu| emu.gpu.gpu_2d_regs_a.set_bg_cnt(0, mask, value)),
@@ -395,42 +391,5 @@ io_write!(
395391
(io16(0x1052), |mask, value, emu| emu.gpu.gpu_2d_regs_b.set_bld_alpha(mask, value)),
396392
(io8(0x1054), |value, emu| emu.gpu.gpu_2d_regs_b.set_bld_y(value)),
397393
(io16(0x106C), |mask, value, emu| emu.gpu.gpu_2d_regs_b.set_master_bright(mask, value)),
398-
]
399-
);
400-
401-
macro_rules! create_write_fixed_slice {
402-
($($structs:tt),*) => {
403-
$(
404-
impl $structs {
405-
pub fn write_fixed_slice<T: Convert>(addr: u32, slice: &[T], emu: &mut Emu) {
406-
let lut_addr = addr - Self::MIN_ADDR;
407-
let (func, write_size, offset) = unsafe { Self::_LUT.get_unchecked(lut_addr as usize) };
408-
409-
if *write_size < size_of::<T>() as u8 {
410-
for value in slice {
411-
Self::write((*value).into(), addr, size_of::<T>() as u8, emu);
412-
}
413-
} else {
414-
let mask = 0xFFFFFFFF >> ((4 - size_of::<T>()) << 3);
415-
let mask = mask << *offset;
416-
for value in slice {
417-
let value = (*value).into() << *offset;
418-
func(mask, value, emu)
419-
}
420-
}
421-
}
422-
}
423-
)*
424-
};
394+
);
425395
}
426-
427-
create_write_fixed_slice!(
428-
IoArm9WriteLut
429-
// IoArm9Write1Lut,
430-
// IoArm9Write2Lut,
431-
// IoArm9Write3Lut,
432-
// IoArm9Write4Lut,
433-
// IoArm9Write5Lut,
434-
// IoArm9Write6Lut,
435-
// IoArm9WriteGpuBLut
436-
);

src/core/memory/mmu.rs

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ impl Emu {
9797
let wram = &self.mem.wram;
9898

9999
for addr in (SHARED_WRAM_OFFSET..IO_PORTS_OFFSET).step_by(MMU_PAGE_SIZE) {
100-
let mmu_read = &mut self.mem.mmu_arm9.mmu_read[(addr as usize) >> MMU_PAGE_SHIFT];
101-
let mmu_write = &mut self.mem.mmu_arm9.mmu_write[(addr as usize) >> MMU_PAGE_SHIFT];
100+
let shifted_addr = (addr as usize) >> MMU_PAGE_SHIFT;
101+
let mmu_read = unsafe { self.mem.mmu_arm9.mmu_read.get_unchecked_mut(shifted_addr) };
102+
let mmu_write = unsafe { self.mem.mmu_arm9.mmu_write.get_unchecked_mut(shifted_addr) };
102103

103104
let shm_offset = wram.get_shm_offset::<{ ARM9 }>(addr);
104105
if shm_offset != usize::MAX {
@@ -126,8 +127,9 @@ impl Emu {
126127
let jit_mmu = &self.jit.jit_memory_map;
127128

128129
for addr in (start..end).step_by(MMU_PAGE_SIZE) {
129-
let mmu_read = &mut self.mem.mmu_arm9.mmu_read_tcm[(addr as usize) >> MMU_PAGE_SHIFT];
130-
let mmu_write = &mut self.mem.mmu_arm9.mmu_write_tcm[(addr as usize) >> MMU_PAGE_SHIFT];
130+
let shifted_addr = (addr as usize) >> MMU_PAGE_SHIFT;
131+
let mmu_read = unsafe { self.mem.mmu_arm9.mmu_read_tcm.get_unchecked_mut(shifted_addr) };
132+
let mmu_write = unsafe { self.mem.mmu_arm9.mmu_write_tcm.get_unchecked_mut(shifted_addr) };
131133
*mmu_read = 0;
132134
*mmu_write = 0;
133135

@@ -265,10 +267,11 @@ impl Emu {
265267
let start = start | VRAM_OFFSET;
266268
let end = end | VRAM_OFFSET;
267269
for addr in (start..end).step_by(MMU_PAGE_SIZE) {
268-
let mmu_read = &mut self.mem.mmu_arm9.mmu_read[(addr as usize) >> MMU_PAGE_SHIFT];
269-
let mmu_write = &mut self.mem.mmu_arm9.mmu_write[(addr as usize) >> MMU_PAGE_SHIFT];
270-
let mmu_read_tcm = &mut self.mem.mmu_arm9.mmu_read_tcm[(addr as usize) >> MMU_PAGE_SHIFT];
271-
let mmu_write_tcm = &mut self.mem.mmu_arm9.mmu_write_tcm[(addr as usize) >> MMU_PAGE_SHIFT];
270+
let shifted_addr = (addr as usize) >> MMU_PAGE_SHIFT;
271+
let mmu_read = unsafe { self.mem.mmu_arm9.mmu_read.get_unchecked_mut(shifted_addr) };
272+
let mmu_write = unsafe { self.mem.mmu_arm9.mmu_write.get_unchecked_mut(shifted_addr) };
273+
let mmu_read_tcm = unsafe { self.mem.mmu_arm9.mmu_read_tcm.get_unchecked_mut(shifted_addr) };
274+
let mmu_write_tcm = unsafe { self.mem.mmu_arm9.mmu_write_tcm.get_unchecked_mut(shifted_addr) };
272275
*mmu_read = 0;
273276
*mmu_write = 0;
274277
*mmu_read_tcm = 0;
@@ -280,10 +283,11 @@ impl Emu {
280283
let start = start | VRAM_OFFSET;
281284
let end = end | VRAM_OFFSET;
282285
for addr in (start..end).step_by(MMU_PAGE_SIZE) {
283-
let mmu_read = &mut self.mem.mmu_arm9.mmu_read[(addr as usize) >> MMU_PAGE_SHIFT];
284-
let mmu_write = &mut self.mem.mmu_arm9.mmu_write[(addr as usize) >> MMU_PAGE_SHIFT];
285-
let mmu_read_tcm = &mut self.mem.mmu_arm9.mmu_read_tcm[(addr as usize) >> MMU_PAGE_SHIFT];
286-
let mmu_write_tcm = &mut self.mem.mmu_arm9.mmu_write_tcm[(addr as usize) >> MMU_PAGE_SHIFT];
286+
let shifted_addr = (addr as usize) >> MMU_PAGE_SHIFT;
287+
let mmu_read = unsafe { self.mem.mmu_arm9.mmu_read.get_unchecked_mut(shifted_addr) };
288+
let mmu_write = unsafe { self.mem.mmu_arm9.mmu_write.get_unchecked_mut(shifted_addr) };
289+
let mmu_read_tcm = unsafe { self.mem.mmu_arm9.mmu_read_tcm.get_unchecked_mut(shifted_addr) };
290+
let mmu_write_tcm = unsafe { self.mem.mmu_arm9.mmu_write_tcm.get_unchecked_mut(shifted_addr) };
287291

288292
let shm_offset = self.mem.vram.get_shm_offset::<{ ARM9 }>(addr);
289293

@@ -373,8 +377,9 @@ impl Emu {
373377

374378
fn update_wram_arm7(&mut self) {
375379
for addr in (SHARED_WRAM_OFFSET..IO_PORTS_OFFSET).step_by(MMU_PAGE_SIZE) {
376-
let mmu_read = &mut self.mem.mmu_arm7.mmu_read[(addr as usize) >> MMU_PAGE_SHIFT];
377-
let mmu_write = &mut self.mem.mmu_arm7.mmu_write[(addr as usize) >> MMU_PAGE_SHIFT];
380+
let shifted_addr = (addr as usize) >> MMU_PAGE_SHIFT;
381+
let mmu_read = unsafe { self.mem.mmu_arm7.mmu_read.get_unchecked_mut(shifted_addr) };
382+
let mmu_write = unsafe { self.mem.mmu_arm7.mmu_write.get_unchecked_mut(shifted_addr) };
378383

379384
let shm_offset = self.mem.wram.get_shm_offset::<{ ARM7 }>(addr);
380385
*mmu_read = shm_offset;
@@ -396,8 +401,9 @@ impl Emu {
396401
let start = start | VRAM_OFFSET;
397402
let end = end | VRAM_OFFSET;
398403
for addr in (start..end).step_by(MMU_PAGE_SIZE) {
399-
let mmu_read = &mut self.mem.mmu_arm7.mmu_read[(addr as usize) >> MMU_PAGE_SHIFT];
400-
let mmu_write = &mut self.mem.mmu_arm7.mmu_write[(addr as usize) >> MMU_PAGE_SHIFT];
404+
let shifted_addr = (addr as usize) >> MMU_PAGE_SHIFT;
405+
let mmu_read = unsafe { self.mem.mmu_arm7.mmu_read.get_unchecked_mut(shifted_addr) };
406+
let mmu_write = unsafe { self.mem.mmu_arm7.mmu_write.get_unchecked_mut(shifted_addr) };
401407
*mmu_read = 0;
402408
*mmu_write = 0;
403409
}
@@ -407,8 +413,9 @@ impl Emu {
407413
let start = start | VRAM_OFFSET;
408414
let end = end | VRAM_OFFSET;
409415
for addr in (start..end).step_by(MMU_PAGE_SIZE) {
410-
let mmu_read = &mut self.mem.mmu_arm7.mmu_read[(addr as usize) >> MMU_PAGE_SHIFT];
411-
let mmu_write = &mut self.mem.mmu_arm7.mmu_write[(addr as usize) >> MMU_PAGE_SHIFT];
416+
let shifted_addr = (addr as usize) >> MMU_PAGE_SHIFT;
417+
let mmu_read = unsafe { self.mem.mmu_arm7.mmu_read.get_unchecked_mut(shifted_addr) };
418+
let mmu_write = unsafe { self.mem.mmu_arm7.mmu_write.get_unchecked_mut(shifted_addr) };
412419

413420
let shm_offset = self.mem.vram.get_shm_offset::<{ ARM7 }>(addr);
414421

src/core/memory/vram.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,7 @@ impl Emu {
801801

802802
pub fn vram_set_cnt(&mut self, bank: usize, value: u8) {
803803
const MASKS: [u8; 9] = [0x9B, 0x9B, 0x9F, 0x9F, 0x87, 0x9F, 0x9F, 0x83, 0x83];
804+
unsafe { assert_unchecked(bank < MASKS.len()) };
804805
let value = value & MASKS[bank];
805806
if self.mem.vram.cnt[bank] == value {
806807
return;

0 commit comments

Comments
 (0)