Skip to content

Commit bc903ac

Browse files
committed
WIP
1 parent bbb3a00 commit bc903ac

File tree

6 files changed

+312
-339
lines changed

6 files changed

+312
-339
lines changed

src/core/memory/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ impl Main {
2525
}
2626

2727
pub fn write_slice<T: Convert>(&mut self, addr_offset: u32, slice: &[T]) {
28-
utils::write_to_mem_slice(self.main.deref_mut(), addr_offset & (regions::MAIN_MEMORY_SIZE - 1), slice);
28+
utils::write_to_mem_slice(self.main.deref_mut(), (addr_offset & (regions::MAIN_MEMORY_SIZE - 1)) as usize, slice);
2929
}
3030
}

src/core/memory/mem.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::core::memory::wram::Wram;
1515
use crate::core::spu::SoundSampler;
1616
use crate::core::CpuType;
1717
use crate::core::CpuType::ARM9;
18-
use crate::jit::jit_memory::JitMemory;
18+
use crate::jit::jit_memory::{JitMemory, JitRegion};
1919
use crate::logging::debug_println;
2020
use crate::utils::Convert;
2121
use std::intrinsics::{likely, unlikely};
@@ -36,7 +36,6 @@ pub struct Memory {
3636
pub jit: JitMemory,
3737
pub bios_arm9: BiosArm9,
3838
pub bios_arm7: BiosArm7,
39-
pub current_jit_block_addr: u32, // Check if the jit block we are currently executing gets written to
4039
pub breakout_imm: bool,
4140
pub mmu_arm9: MmuArm9,
4241
pub mmu_arm7: MmuArm7,
@@ -66,7 +65,6 @@ impl Memory {
6665
jit: JitMemory::new(),
6766
bios_arm9: BiosArm9::new(),
6867
bios_arm7: BiosArm7::new(),
69-
current_jit_block_addr: 0,
7068
breakout_imm: false,
7169
mmu_arm9: MmuArm9::new(),
7270
mmu_arm7: MmuArm7::new(),
@@ -199,8 +197,6 @@ impl Memory {
199197
}
200198
}
201199

202-
let mut invalidate_jit = || self.breakout_imm = self.jit.invalidate_block::<CPU>(aligned_addr, size_of::<T>(), self.current_jit_block_addr);
203-
204200
match addr_base {
205201
regions::INSTRUCTION_TCM_OFFSET | regions::INSTRUCTION_TCM_MIRROR_OFFSET => match CPU {
206202
ARM9 => {
@@ -209,7 +205,7 @@ impl Memory {
209205
if aligned_addr < cp15.itcm_size && cp15.itcm_state != TcmState::Disabled {
210206
self.tcm.write_itcm(aligned_addr, value);
211207
debug_println!("{:?} itcm write at {:x} with value {:x}", CPU, aligned_addr, value.into(),);
212-
invalidate_jit();
208+
self.jit.invalidate_block::<{ JitRegion::Itcm }>(aligned_addr, size_of::<T>());
213209
}
214210
}
215211
}
@@ -220,12 +216,12 @@ impl Memory {
220216
},
221217
regions::MAIN_MEMORY_OFFSET => {
222218
self.main.write(addr_offset, value);
223-
invalidate_jit();
219+
self.jit.invalidate_block::<{ JitRegion::Main }>(aligned_addr, size_of::<T>());
224220
}
225221
regions::SHARED_WRAM_OFFSET => {
226222
self.wram.write::<CPU, _>(addr_offset, value);
227223
if CPU == ARM7 {
228-
invalidate_jit();
224+
self.jit.invalidate_block::<{ JitRegion::Wram }>(aligned_addr, size_of::<T>());
229225
}
230226
}
231227
regions::IO_PORTS_OFFSET => match CPU {
@@ -247,7 +243,7 @@ impl Memory {
247243
regions::VRAM_OFFSET => {
248244
self.vram.write::<CPU, _>(addr_offset, value);
249245
if CPU == ARM7 {
250-
invalidate_jit();
246+
self.jit.invalidate_block::<{ JitRegion::VramArm7 }>(aligned_addr, size_of::<T>());
251247
}
252248
}
253249
regions::OAM_OFFSET => self.oam.write(addr_offset, value),

src/jit/jit_asm.rs

Lines changed: 79 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,85 @@ impl JitRuntimeData {
103103
}
104104
}
105105

106+
pub extern "C" fn emit_code_block<const CPU: CpuType, const THUMB: bool>() {
107+
let asm = unsafe { get_jit_asm_ptr::<CPU>().as_mut().unwrap_unchecked() };
108+
109+
let guest_pc = get_regs!(asm.emu, CPU).pc;
110+
let guest_pc = if THUMB { guest_pc & !1 } else { guest_pc & !3 };
111+
112+
{
113+
let mut index = 0;
114+
loop {
115+
let inst_info = if THUMB {
116+
let opcode = asm.emu.mem_read::<CPU, u16>(guest_pc + index);
117+
let (op, func) = lookup_thumb_opcode(opcode);
118+
InstInfo::from(func(opcode, *op))
119+
} else {
120+
let opcode = asm.emu.mem_read::<CPU, u32>(guest_pc + index);
121+
let (op, func) = lookup_opcode(opcode);
122+
func(opcode, *op)
123+
};
124+
125+
if let Some(last) = asm.jit_buf.insts_cycle_counts.last() {
126+
assert!(u16::MAX - last >= inst_info.cycle as u16, "{CPU:?} {guest_pc:x} {inst_info:?}");
127+
asm.jit_buf.insts_cycle_counts.push(last + inst_info.cycle as u16);
128+
} else {
129+
asm.jit_buf.insts_cycle_counts.push(inst_info.cycle as u16);
130+
assert!(asm.jit_buf.insts_cycle_counts.len() <= u16::MAX as usize, "{CPU:?} {guest_pc:x} {inst_info:?}")
131+
}
132+
133+
// let is_unreturnable_branch = !inst_info.out_regs.is_reserved(Reg::LR) && inst_info.is_uncond_branch() && !inst_info.op.is_labelled_branch();
134+
let is_uncond_branch = inst_info.is_uncond_branch();
135+
let is_unknown = inst_info.op == Op::UnkArm || inst_info.op == Op::UnkThumb;
136+
137+
asm.jit_buf.insts.push(inst_info);
138+
139+
index += if THUMB { 2 } else { 4 };
140+
if is_uncond_branch || is_unknown {
141+
break;
142+
}
143+
}
144+
}
145+
146+
// unsafe { BLOCK_LOG = guest_pc == 0x238015c };
147+
148+
let thread_regs = get_regs!(asm.emu, CPU);
149+
let mut block_asm = unsafe { (*asm.block_asm_buf.get()).new_asm(thread_regs) };
150+
151+
for i in 0..asm.jit_buf.insts.len() {
152+
asm.jit_buf.current_index = i;
153+
asm.jit_buf.current_pc = guest_pc + (i << if THUMB { 1 } else { 2 }) as u32;
154+
debug_println!("{CPU:?} emitting {:?} at pc: {:x}", asm.jit_buf.current_inst(), asm.jit_buf.current_pc);
155+
156+
if THUMB {
157+
asm.emit_thumb(&mut block_asm);
158+
} else {
159+
asm.emit(&mut block_asm);
160+
}
161+
162+
// if DEBUG_LOG {
163+
// block_asm.save_context();
164+
// block_asm.call2(debug_after_exec_op::<CPU> as *const (), self.jit_buf.current_pc, self.jit_buf.current_inst().opcode);
165+
// block_asm.restore_reg(Reg::CPSR);
166+
// }
167+
}
168+
169+
let opcodes = block_asm.finalize(guest_pc, THUMB);
170+
if unsafe { BLOCK_LOG } {
171+
for &opcode in &opcodes {
172+
println!("0x{opcode:x},");
173+
}
174+
todo!();
175+
}
176+
get_jit_mut!(asm.emu).insert_block::<CPU, THUMB>(&opcodes, JitInsertArgs::new(guest_pc, asm.jit_buf.insts_cycle_counts.clone()));
177+
178+
if DEBUG_LOG {
179+
let (jit_addr, _) = get_jit!(asm.emu).get_jit_start_addr::<CPU, THUMB>(guest_pc).unwrap();
180+
println!("{:?} Mapping {:#010x} to {:#010x}", CPU, guest_pc, jit_addr);
181+
}
182+
asm.jit_buf.clear_all();
183+
}
184+
106185
pub struct JitAsm<'a, const CPU: CpuType> {
107186
pub emu: &'a mut Emu,
108187
pub jit_buf: JitBuf,
@@ -123,81 +202,6 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
123202
}
124203
}
125204

126-
#[inline(never)]
127-
fn emit_code_block<const THUMB: bool>(&mut self, guest_pc: u32) {
128-
{
129-
let mut index = 0;
130-
loop {
131-
let inst_info = if THUMB {
132-
let opcode = self.emu.mem_read::<CPU, u16>(guest_pc + index);
133-
let (op, func) = lookup_thumb_opcode(opcode);
134-
InstInfo::from(func(opcode, *op))
135-
} else {
136-
let opcode = self.emu.mem_read::<CPU, u32>(guest_pc + index);
137-
let (op, func) = lookup_opcode(opcode);
138-
func(opcode, *op)
139-
};
140-
141-
if let Some(last) = self.jit_buf.insts_cycle_counts.last() {
142-
assert!(u16::MAX - last >= inst_info.cycle as u16, "{CPU:?} {guest_pc:x} {inst_info:?}");
143-
self.jit_buf.insts_cycle_counts.push(last + inst_info.cycle as u16);
144-
} else {
145-
self.jit_buf.insts_cycle_counts.push(inst_info.cycle as u16);
146-
assert!(self.jit_buf.insts_cycle_counts.len() <= u16::MAX as usize, "{CPU:?} {guest_pc:x} {inst_info:?}")
147-
}
148-
149-
// let is_unreturnable_branch = !inst_info.out_regs.is_reserved(Reg::LR) && inst_info.is_uncond_branch() && !inst_info.op.is_labelled_branch();
150-
let is_uncond_branch = inst_info.is_uncond_branch();
151-
let is_unknown = inst_info.op == Op::UnkArm || inst_info.op == Op::UnkThumb;
152-
153-
self.jit_buf.insts.push(inst_info);
154-
155-
index += if THUMB { 2 } else { 4 };
156-
if is_uncond_branch || is_unknown {
157-
break;
158-
}
159-
}
160-
}
161-
162-
// unsafe { BLOCK_LOG = guest_pc == 0x238015c };
163-
164-
let thread_regs = get_regs!(self.emu, CPU);
165-
let mut block_asm = unsafe { (*self.block_asm_buf.get()).new_asm(thread_regs) };
166-
167-
for i in 0..self.jit_buf.insts.len() {
168-
self.jit_buf.current_index = i;
169-
self.jit_buf.current_pc = guest_pc + (i << if THUMB { 1 } else { 2 }) as u32;
170-
debug_println!("{CPU:?} emitting {:?} at pc: {:x}", self.jit_buf.current_inst(), self.jit_buf.current_pc);
171-
172-
if THUMB {
173-
self.emit_thumb(&mut block_asm);
174-
} else {
175-
self.emit(&mut block_asm);
176-
}
177-
178-
// if DEBUG_LOG {
179-
// block_asm.save_context();
180-
// block_asm.call2(debug_after_exec_op::<CPU> as *const (), self.jit_buf.current_pc, self.jit_buf.current_inst().opcode);
181-
// block_asm.restore_reg(Reg::CPSR);
182-
// }
183-
}
184-
185-
let opcodes = block_asm.finalize(guest_pc, THUMB);
186-
if unsafe { BLOCK_LOG } {
187-
for &opcode in &opcodes {
188-
println!("0x{opcode:x},");
189-
}
190-
todo!();
191-
}
192-
get_jit_mut!(self.emu).insert_block::<CPU, THUMB>(&opcodes, JitInsertArgs::new(guest_pc, self.jit_buf.insts_cycle_counts.clone()));
193-
194-
if DEBUG_LOG {
195-
let (jit_addr, _) = get_jit!(self.emu).get_jit_start_addr::<CPU, THUMB>(guest_pc).unwrap();
196-
println!("{:?} Mapping {:#010x} to {:#010x}", CPU, guest_pc, jit_addr);
197-
}
198-
self.jit_buf.clear_all();
199-
}
200-
201205
#[inline(always)]
202206
pub fn execute(&mut self) -> u16 {
203207
let entry = get_regs!(self.emu, CPU).pc;

0 commit comments

Comments
 (0)