Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Grarak committed Nov 14, 2024
1 parent f4be5f4 commit 8efea7e
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 30 deletions.
45 changes: 45 additions & 0 deletions src/jit/inst_branch_handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use crate::core::emu::{get_jit, get_regs_mut};
use crate::core::CpuType;
use crate::jit::jit_asm::RETURN_STACK_SIZE;
use crate::jit::jit_asm_common_funs::{exit_guest_context, JitAsmCommonFuns, MAX_LOOP_CYCLE_COUNT};
use crate::{get_jit_asm_ptr, DEBUG_LOG, IS_DEBUG};
use std::intrinsics::unlikely;
use std::mem;
use CpuType::{ARM7, ARM9};

pub unsafe extern "C" fn branch_reg<const CPU: CpuType>(total_cycles: u16, lr: u32, target_pc: u32, current_pc: u32) {
let asm = get_jit_asm_ptr::<CPU>().as_mut_unchecked();
asm.runtime_data.accumulated_cycles += total_cycles + 2 - asm.runtime_data.pre_cycle_count_sum;
let max_count = match CPU {
ARM9 => MAX_LOOP_CYCLE_COUNT * 2,
ARM7 => MAX_LOOP_CYCLE_COUNT,
};

if unlikely(asm.runtime_data.accumulated_cycles >= max_count as u16) {
if IS_DEBUG {
asm.runtime_data.branch_out_pc = current_pc;
}
exit_guest_context!(asm);
} else {
asm.runtime_data.pre_cycle_count_sum = 0;
let return_stack_ptr = asm.runtime_data.return_stack_ptr & (RETURN_STACK_SIZE as u8 - 1);
*asm.runtime_data.return_stack.get_unchecked_mut(return_stack_ptr as usize) = lr;
asm.runtime_data.return_stack_ptr = return_stack_ptr + 1;

if DEBUG_LOG {
JitAsmCommonFuns::<CPU>::debug_push_return_stack(current_pc, lr, return_stack_ptr);
JitAsmCommonFuns::<CPU>::debug_branch_reg(current_pc, target_pc);
}

let thumb = target_pc & 1 != 0;
get_regs_mut!(asm.emu, CPU).set_thumb(thumb);
let aligned_pc_mask = !(1 | ((!thumb as u32) << 1));
let aligned_pc = target_pc & aligned_pc_mask;

let jit_entry = get_jit!(asm.emu).get_jit_start_addr::<CPU>(aligned_pc);
let jit_entry: extern "C" fn(bool) = unsafe { mem::transmute(jit_entry) };
jit_entry(false);

asm.runtime_data.pre_cycle_count_sum = total_cycles;
}
}
13 changes: 4 additions & 9 deletions src/jit/inst_mem_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mod handler {
use crate::jit::reg::{Reg, RegReserve};
use crate::jit::MemoryAmount;
use crate::logging::debug_println;
use std::hint::unreachable_unchecked;
use std::intrinsics::{likely, unlikely};

pub fn handle_request<const CPU: CpuType, const WRITE: bool, const AMOUNT: MemoryAmount, const SIGNED: bool>(op0: &mut u32, addr: u32, emu: &mut Emu) {
Expand Down Expand Up @@ -81,7 +82,7 @@ mod handler {
*get_regs_mut!(emu, CPU).get_reg_mut(op0) += 0x40;
}
if CPU == CpuType::ARM7 {
todo!()
unsafe { unreachable_unchecked() }
}
return;
}
Expand Down Expand Up @@ -135,7 +136,7 @@ mod handler {
}

if USER && unlikely(rlist.is_reserved(Reg::PC)) {
todo!("restore spsr")
unsafe { unreachable_unchecked() }
}
}

Expand All @@ -159,13 +160,7 @@ macro_rules! imm_breakout {
$asm.runtime_data.accumulated_cycles += $total_cycles - $asm.runtime_data.pre_cycle_count_sum;
crate::core::emu::get_regs_mut!($asm.emu, CPU).pc = $pc + if $thumb { 3 } else { 4 };
crate::core::emu::get_mem_mut!($asm.emu).breakout_imm = false;
// r4-r12,pc since we need an even amount of registers for 8 byte alignment, in case the compiler decides to use neon instructions
std::arch::asm!(
"mov sp, {}",
"pop {{r4-r12,pc}}",
in(reg) $asm.runtime_data.host_sp
);
std::hint::unreachable_unchecked();
crate::jit::jit_asm_common_funs::exit_guest_context!($asm);
}};
}
pub(super) use imm_breakout;
Expand Down
14 changes: 2 additions & 12 deletions src/jit/jit_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ use crate::jit::assembler::BlockAsmBuf;
use crate::jit::disassembler::lookup_table::lookup_opcode;
use crate::jit::disassembler::thumb::lookup_table_thumb::lookup_thumb_opcode;
use crate::jit::inst_info::InstInfo;
use crate::jit::jit_asm_common_funs::JitAsmCommonFuns;
use crate::jit::jit_asm_common_funs::{exit_guest_context, JitAsmCommonFuns};
use crate::jit::op::Op;
use crate::jit::reg::Reg;
use crate::jit::reg::{reg_reserve, RegReserve};
use crate::logging::debug_println;
use crate::{get_jit_asm_ptr, DEBUG_LOG, IS_DEBUG};
use std::arch::asm;
use std::cell::UnsafeCell;
use std::hint::unreachable_unchecked;
use std::intrinsics::unlikely;
use std::{mem, ptr};

Expand Down Expand Up @@ -117,15 +115,7 @@ pub extern "C" fn hle_bios_uninterrupt<const CPU: CpuType>(store_host_sp: bool)
bios::uninterrupt::<CPU>(asm.emu);
if unlikely(get_cpu_regs!(asm.emu, CPU).is_halted()) {
if !store_host_sp {
// r4-r12,pc since we need an even amount of registers for 8 byte alignment, in case the compiler decides to use neon instructions
unsafe {
asm!(
"mov sp, {}",
"pop {{r4-r12,pc}}",
in(reg) asm.runtime_data.host_sp
);
unreachable_unchecked();
}
unsafe { exit_guest_context!(asm) };
}
} else {
let jit_entry = get_jit!(asm.emu).get_jit_start_addr::<CPU>(get_regs!(asm.emu, CPU).pc);
Expand Down
31 changes: 25 additions & 6 deletions src/jit/jit_asm_common_funs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,23 @@ use crate::jit::{jit_memory_map, Cond, ShiftType};
use crate::{DEBUG_LOG, IS_DEBUG};
use std::ptr;

pub const MAX_LOOP_CYCLE_COUNT: u32 = 255;

macro_rules! exit_guest_context {
($asm:expr) => {{
// r4-r12,pc since we need an even amount of registers for 8 byte alignment, in case the compiler decides to use neon instructions
std::arch::asm!(
"mov sp, {}",
"pop {{r4-r12,pc}}",
in(reg) $asm.runtime_data.host_sp
);
std::hint::unreachable_unchecked();
}};
}

use crate::jit::inst_branch_handler::branch_reg;
pub(crate) use exit_guest_context;

pub struct JitAsmCommonFuns<const CPU: CpuType> {
branch_return_stack: usize,
branch_reg: usize,
Expand All @@ -34,7 +51,8 @@ impl<const CPU: CpuType> JitAsmCommonFuns<CPU> {
};
JitAsmCommonFuns {
branch_return_stack: create_function(Self::emit_branch_return_stack, &format!("{CPU:?}_branch_return_stack")),
branch_reg: create_function(Self::emit_branch_reg, &format!("{CPU:?}_branch_reg")),
// branch_reg: create_function(Self::emit_branch_reg, &format!("{CPU:?}_branch_reg")),
branch_reg: 0,
}
}

Expand Down Expand Up @@ -131,7 +149,6 @@ impl<const CPU: CpuType> JitAsmCommonFuns<CPU> {
let result_accumulated_cycles_reg = block_asm.new_reg();
Self::emit_count_cycles(block_asm, total_cycles_reg, runtime_data_addr_reg, result_accumulated_cycles_reg);

const MAX_LOOP_CYCLE_COUNT: u32 = 255;
block_asm.cmp(
result_accumulated_cycles_reg,
match CPU {
Expand Down Expand Up @@ -336,17 +353,19 @@ impl<const CPU: CpuType> JitAsmCommonFuns<CPU> {

pub fn emit_call_branch_reg(&self, block_asm: &mut BlockAsm, total_cycles: u16, lr_reg: BlockReg, target_pc_reg: BlockReg, current_pc: u32) {
if IS_DEBUG {
block_asm.call4_common(self.branch_reg, total_cycles as u32, lr_reg, target_pc_reg, current_pc);
// block_asm.call4_common(self.branch_reg, total_cycles as u32, lr_reg, target_pc_reg, current_pc);
block_asm.call4(branch_reg::<CPU> as *const (), total_cycles as u32, lr_reg, target_pc_reg, current_pc);
} else {
block_asm.call3_common(self.branch_reg, total_cycles as u32, lr_reg, target_pc_reg);
// block_asm.call3_common(self.branch_reg, total_cycles as u32, lr_reg, target_pc_reg);
block_asm.call3(branch_reg::<CPU> as *const (), total_cycles as u32, lr_reg, target_pc_reg);
}
}

extern "C" fn debug_push_return_stack(current_pc: u32, lr_pc: u32, stack_size: u8) {
pub extern "C" fn debug_push_return_stack(current_pc: u32, lr_pc: u32, stack_size: u8) {
println!("{CPU:?} push {lr_pc:x} to return stack with size {stack_size} at {current_pc:x}")
}

extern "C" fn debug_branch_reg(current_pc: u32, target_pc: u32) {
pub extern "C" fn debug_branch_reg(current_pc: u32, target_pc: u32) {
println!("{CPU:?} branch reg from {current_pc:x} to {target_pc:x}")
}

Expand Down
1 change: 1 addition & 0 deletions src/jit/jit_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ impl JitMemory {
unsafe { (*self.jit_memory_map.get_jit_entry::<CPU>(guest_pc)).0 }
}

#[inline(never)]
pub fn invalidate_block<const REGION: JitRegion>(&mut self, guest_addr: u32, size: usize) {
macro_rules! invalidate {
($guest_addr:expr, $cpu:expr, [$($cpu_entry:expr),+]) => {{
Expand Down
11 changes: 8 additions & 3 deletions src/jit/jit_memory_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ impl JitMemoryMap {
let addr = (addr & 0x0FFFFFFF) >> 1;
macro_rules! get_jit_entry {
($map:expr) => {{
unsafe { ($map[(addr >> BLOCK_SHIFT) as usize] as *mut JitEntry).add((addr as usize) & (BLOCK_SIZE - 1)) }
unsafe { ((*$map.get_unchecked((addr >> BLOCK_SHIFT) as usize)) as *mut JitEntry).add((addr as usize) & (BLOCK_SIZE - 1)) }
}};
}
match CPU {
Expand All @@ -124,9 +124,14 @@ impl JitMemoryMap {
}

pub fn get_live_range<const CPU: CpuType>(&self, addr: u32) -> *mut u8 {
macro_rules! get_live_range {
($map:expr) => {{
unsafe { (*$map.get_unchecked((addr >> (JIT_LIVE_RANGE_PAGE_SIZE_SHIFT + 3)) as usize)) as _ }
}};
}
match CPU {
ARM9 => self.live_ranges_map_arm9[(addr >> (JIT_LIVE_RANGE_PAGE_SIZE_SHIFT + 3)) as usize] as _,
ARM7 => self.live_ranges_map_arm7[(addr >> (JIT_LIVE_RANGE_PAGE_SIZE_SHIFT + 3)) as usize] as _,
ARM9 => get_live_range!(self.live_ranges_map_arm9),
ARM7 => get_live_range!(self.live_ranges_map_arm7),
}
}

Expand Down
1 change: 1 addition & 0 deletions src/jit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::{mem, ops};
pub mod assembler;
pub mod disassembler;
mod emitter;
mod inst_branch_handler;
mod inst_cp15_handler;
mod inst_cpu_regs_handler;
mod inst_exception_handler;
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ pub fn actual_main() {
.name("cpu".to_owned())
.spawn(move || {
set_thread_prio_affinity(ThreadPriority::High, ThreadAffinity::Core2);
println!("Start cpu {:?}", thread::current().id());
run_cpu(
cartridge_io,
fps_clone,
Expand Down

0 comments on commit 8efea7e

Please sign in to comment.