use hashmap for lut (#994)

This commit is contained in:
Logan McNaughton
2026-05-31 09:45:02 +02:00
committed by GitHub
parent 5c7170268e
commit 19432f33ba
4 changed files with 43 additions and 58 deletions
+2 -2
View File
@@ -310,8 +310,8 @@ impl Device {
is_event: false,
instrs: [cop0::reserved; 32],
instrs2: [cop0::reserved; 32],
tlb_lut_w: vec![],
tlb_lut_r: vec![],
tlb_lut_w: rustc_hash::FxHashMap::default(),
tlb_lut_r: rustc_hash::FxHashMap::default(),
tlb_entries: [tlb::TlbEntry {
mask: 0,
vpn2: 0,
+2 -5
View File
@@ -100,10 +100,8 @@ pub struct Cop0 {
pub instrs: [fn(&mut device::Device, u32); 32],
#[serde(skip, default = "savestates::default_instructions")]
pub instrs2: [fn(&mut device::Device, u32); 32],
#[serde(skip)]
pub tlb_lut_r: Vec<device::tlb::TlbLut>,
#[serde(skip)]
pub tlb_lut_w: Vec<device::tlb::TlbLut>,
pub tlb_lut_r: rustc_hash::FxHashMap<u64, device::tlb::TlbLut>,
pub tlb_lut_w: rustc_hash::FxHashMap<u64, device::tlb::TlbLut>,
pub tlb_entries: [device::tlb::TlbEntry; 32],
pub is_event: bool,
}
@@ -371,7 +369,6 @@ pub fn init(device: &mut device::Device) {
];
map_instructions(device);
device::tlb::init(device);
// taken from VR4300 manual
device.cpu.cop0.regs[COP0_RANDOM_REG] = 0b00000000000000000000000000011111;
+39 -46
View File
@@ -30,23 +30,6 @@ pub struct TlbEntry {
pub phys_odd: u64,
}
pub fn init(device: &mut device::Device) {
device.cpu.cop0.tlb_lut_r.resize(
0x100000,
device::tlb::TlbLut {
address: 0,
cached: false,
},
);
device.cpu.cop0.tlb_lut_w.resize(
0x100000,
device::tlb::TlbLut {
address: 0,
cached: false,
},
);
}
pub fn read(device: &mut device::Device, index: u64) {
if index > 31 {
return;
@@ -166,15 +149,13 @@ fn tlb_unmap(device: &mut device::Device, index: u64) {
if e.v_even != 0 {
let mut i = e.start_even;
while i < e.end_even {
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].address = 0;
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].cached = false;
device.cpu.cop0.tlb_lut_r.remove(&(i >> 12));
i += 0x1000
}
if e.d_even != 0 {
let mut i = e.start_even;
while i < e.end_even {
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].address = 0;
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].cached = false;
device.cpu.cop0.tlb_lut_w.remove(&(i >> 12));
i += 0x1000
}
}
@@ -183,22 +164,20 @@ fn tlb_unmap(device: &mut device::Device, index: u64) {
if e.v_odd != 0 {
let mut i = e.start_odd;
while i < e.end_odd {
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].address = 0;
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].cached = false;
device.cpu.cop0.tlb_lut_r.remove(&(i >> 12));
i += 0x1000
}
if e.d_odd != 0 {
let mut i = e.start_odd;
while i < e.end_odd {
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].address = 0;
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].cached = false;
device.cpu.cop0.tlb_lut_w.remove(&(i >> 12));
i += 0x1000
}
}
}
}
pub fn tlb_map(device: &mut device::Device, index: u64) {
fn tlb_map(device: &mut device::Device, index: u64) {
let e = &device.cpu.cop0.tlb_entries[index as usize];
if e.v_even != 0
@@ -208,17 +187,25 @@ pub fn tlb_map(device: &mut device::Device, index: u64) {
{
let mut i = e.start_even;
while i < e.end_even {
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].address =
0x80000000 | (e.phys_even + (i - e.start_even) + 0xFFF);
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].cached = e.c_even != 2;
device.cpu.cop0.tlb_lut_r.insert(
i >> 12,
device::tlb::TlbLut {
address: 0x80000000 | (e.phys_even + (i - e.start_even) + 0xFFF),
cached: e.c_even != 2,
},
);
i += 0x1000
}
if e.d_even != 0 {
let mut i = e.start_even;
while i < e.end_even {
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].address =
0x80000000 | (e.phys_even + (i - e.start_even) + 0xFFF);
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].cached = e.c_even != 2;
device.cpu.cop0.tlb_lut_w.insert(
i >> 12,
device::tlb::TlbLut {
address: 0x80000000 | (e.phys_even + (i - e.start_even) + 0xFFF),
cached: e.c_even != 2,
},
);
i += 0x1000
}
}
@@ -231,17 +218,25 @@ pub fn tlb_map(device: &mut device::Device, index: u64) {
{
let mut i = e.start_odd;
while i < e.end_odd {
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].address =
0x80000000 | (e.phys_odd + (i - e.start_odd) + 0xFFF);
device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].cached = e.c_odd != 2;
device.cpu.cop0.tlb_lut_r.insert(
i >> 12,
device::tlb::TlbLut {
address: 0x80000000 | (e.phys_odd + (i - e.start_odd) + 0xFFF),
cached: e.c_odd != 2,
},
);
i += 0x1000
}
if e.d_odd != 0 {
let mut i = e.start_odd;
while i < e.end_odd {
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].address =
0x80000000 | (e.phys_odd + (i - e.start_odd) + 0xFFF);
device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].cached = e.c_odd != 2;
device.cpu.cop0.tlb_lut_w.insert(
i >> 12,
device::tlb::TlbLut {
address: 0x80000000 | (e.phys_odd + (i - e.start_odd) + 0xFFF),
cached: e.c_odd != 2,
},
);
i += 0x1000
}
}
@@ -256,19 +251,17 @@ pub fn get_physical_address(
address &= 0xffffffff;
if access_type == device::memory::AccessType::Write {
if device.cpu.cop0.tlb_lut_w[(address >> 12) as usize].address != 0 {
if let Some(lut) = device.cpu.cop0.tlb_lut_w.get(&(address >> 12)) {
return (
(device.cpu.cop0.tlb_lut_w[(address >> 12) as usize].address & 0x1FFFF000)
| (address & 0xFFF),
device.cpu.cop0.tlb_lut_w[(address >> 12) as usize].cached,
(lut.address & 0x1FFFF000) | (address & 0xFFF),
lut.cached,
false,
);
}
} else if device.cpu.cop0.tlb_lut_r[(address >> 12) as usize].address != 0 {
} else if let Some(lut) = device.cpu.cop0.tlb_lut_r.get(&(address >> 12)) {
return (
(device.cpu.cop0.tlb_lut_r[(address >> 12) as usize].address & 0x1FFFF000)
| (address & 0xFFF),
device.cpu.cop0.tlb_lut_r[(address >> 12) as usize].cached,
(lut.address & 0x1FFFF000) | (address & 0xFFF),
lut.cached,
false,
);
}
-5
View File
@@ -247,11 +247,6 @@ pub fn load_savestate(device: &mut device::Device, rewind: bool) {
}
}
device::tlb::init(device);
for i in 0..32 {
device::tlb::tlb_map(device, i);
}
device::pif::connect_pif_channels(device);
for i in 0..4 {
if let Some(handler) = device.pif.channels[i].pak_handler {