Skip to content

Commit

Permalink
Simplify ldm pc
Browse files Browse the repository at this point in the history
  • Loading branch information
Grarak committed Oct 5, 2024
1 parent c9c9970 commit e0d4cea
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 110 deletions.
1 change: 0 additions & 1 deletion src/jit/assembler/block_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use crate::jit::inst_info::InstInfo;
use crate::jit::reg::{Reg, RegReserve};
use crate::jit::{Cond, MemoryAmount, ShiftType};
use crate::utils::{NoHashMap, NoHashSet};
use std::collections::VecDeque;

pub static mut BLOCK_LOG: bool = false;

Expand Down
6 changes: 3 additions & 3 deletions src/jit/emitter/emit.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::core::CpuType;
use crate::core::CpuType::ARM7;
use crate::jit::assembler::block_asm::BlockAsm;
use crate::jit::assembler::{BlockLabel, BlockReg};
use crate::jit::assembler::BlockReg;
use crate::jit::inst_threag_regs_handler::{register_restore_spsr, restore_thumb_after_restore_spsr, set_pc_arm_mode};
use crate::jit::jit_asm::{JitAsm, JitRuntimeData};
use crate::jit::op::Op;
Expand Down Expand Up @@ -42,15 +42,15 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
}
}

if self.jit_buf.current_inst().out_regs.is_reserved(Reg::PC) && !op.is_multiple_mem_transfer() {
if self.jit_buf.current_inst().out_regs.is_reserved(Reg::PC) {
block_asm.save_context();

let restore_spsr = self.jit_buf.current_inst().out_regs.is_reserved(Reg::CPSR) && op.is_arm_alu();
if restore_spsr {
block_asm.call(register_restore_spsr::<CPU> as *const ());
}

if CPU == ARM7 || !op.is_single_mem_transfer() {
if CPU == ARM7 || (!op.is_single_mem_transfer() && !op.is_multiple_mem_transfer()) {
if restore_spsr {
block_asm.call(restore_thumb_after_restore_spsr::<CPU> as *const ());
} else {
Expand Down
99 changes: 33 additions & 66 deletions src/jit/emitter/emit_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,75 +141,42 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
pre = !pre;
}
let write_back = inst_info.op.mem_transfer_write_back();
let has_pc = rlist.is_reserved(Reg::PC);

let op0 = *inst_info.operands()[0].as_reg_no_shift().unwrap();

let func_addr: *const () = match (inst_info.op.mem_is_write(), inst_info.op.mem_transfer_user(), pre, write_back, decrement, has_pc) {
(false, false, false, false, false, false) => inst_mem_handler_multiple::<CPU, THUMB, false, false, false, false, false, false> as _,
(true, false, false, false, false, false) => inst_mem_handler_multiple::<CPU, THUMB, true, false, false, false, false, false> as _,
(false, true, false, false, false, false) => inst_mem_handler_multiple::<CPU, THUMB, false, true, false, false, false, false> as _,
(true, true, false, false, false, false) => inst_mem_handler_multiple::<CPU, THUMB, true, true, false, false, false, false> as _,
(false, false, true, false, false, false) => inst_mem_handler_multiple::<CPU, THUMB, false, false, true, false, false, false> as _,
(true, false, true, false, false, false) => inst_mem_handler_multiple::<CPU, THUMB, true, false, true, false, false, false> as _,
(false, true, true, false, false, false) => inst_mem_handler_multiple::<CPU, THUMB, false, true, true, false, false, false> as _,
(true, true, true, false, false, false) => inst_mem_handler_multiple::<CPU, THUMB, true, true, true, false, false, false> as _,
(false, false, false, true, false, false) => inst_mem_handler_multiple::<CPU, THUMB, false, false, false, true, false, false> as _,
(true, false, false, true, false, false) => inst_mem_handler_multiple::<CPU, THUMB, true, false, false, true, false, false> as _,
(false, true, false, true, false, false) => inst_mem_handler_multiple::<CPU, THUMB, false, true, false, true, false, false> as _,
(true, true, false, true, false, false) => inst_mem_handler_multiple::<CPU, THUMB, true, true, false, true, false, false> as _,
(false, false, true, true, false, false) => inst_mem_handler_multiple::<CPU, THUMB, false, false, true, true, false, false> as _,
(true, false, true, true, false, false) => inst_mem_handler_multiple::<CPU, THUMB, true, false, true, true, false, false> as _,
(false, true, true, true, false, false) => inst_mem_handler_multiple::<CPU, THUMB, false, true, true, true, false, false> as _,
(true, true, true, true, false, false) => inst_mem_handler_multiple::<CPU, THUMB, true, true, true, true, false, false> as _,
(false, false, false, false, true, false) => inst_mem_handler_multiple::<CPU, THUMB, false, false, false, false, true, false> as _,
(true, false, false, false, true, false) => inst_mem_handler_multiple::<CPU, THUMB, true, false, false, false, true, false> as _,
(false, true, false, false, true, false) => inst_mem_handler_multiple::<CPU, THUMB, false, true, false, false, true, false> as _,
(true, true, false, false, true, false) => inst_mem_handler_multiple::<CPU, THUMB, true, true, false, false, true, false> as _,
(false, false, true, false, true, false) => inst_mem_handler_multiple::<CPU, THUMB, false, false, true, false, true, false> as _,
(true, false, true, false, true, false) => inst_mem_handler_multiple::<CPU, THUMB, true, false, true, false, true, false> as _,
(false, true, true, false, true, false) => inst_mem_handler_multiple::<CPU, THUMB, false, true, true, false, true, false> as _,
(true, true, true, false, true, false) => inst_mem_handler_multiple::<CPU, THUMB, true, true, true, false, true, false> as _,
(false, false, false, true, true, false) => inst_mem_handler_multiple::<CPU, THUMB, false, false, false, true, true, false> as _,
(true, false, false, true, true, false) => inst_mem_handler_multiple::<CPU, THUMB, true, false, false, true, true, false> as _,
(false, true, false, true, true, false) => inst_mem_handler_multiple::<CPU, THUMB, false, true, false, true, true, false> as _,
(true, true, false, true, true, false) => inst_mem_handler_multiple::<CPU, THUMB, true, true, false, true, true, false> as _,
(false, false, true, true, true, false) => inst_mem_handler_multiple::<CPU, THUMB, false, false, true, true, true, false> as _,
(true, false, true, true, true, false) => inst_mem_handler_multiple::<CPU, THUMB, true, false, true, true, true, false> as _,
(false, true, true, true, true, false) => inst_mem_handler_multiple::<CPU, THUMB, false, true, true, true, true, false> as _,
(true, true, true, true, true, false) => inst_mem_handler_multiple::<CPU, THUMB, true, true, true, true, true, false> as _,
(false, false, false, false, false, true) => inst_mem_handler_multiple::<CPU, THUMB, false, false, false, false, false, true> as _,
(true, false, false, false, false, true) => inst_mem_handler_multiple::<CPU, THUMB, true, false, false, false, false, true> as _,
(false, true, false, false, false, true) => inst_mem_handler_multiple::<CPU, THUMB, false, true, false, false, false, true> as _,
(true, true, false, false, false, true) => inst_mem_handler_multiple::<CPU, THUMB, true, true, false, false, false, true> as _,
(false, false, true, false, false, true) => inst_mem_handler_multiple::<CPU, THUMB, false, false, true, false, false, true> as _,
(true, false, true, false, false, true) => inst_mem_handler_multiple::<CPU, THUMB, true, false, true, false, false, true> as _,
(false, true, true, false, false, true) => inst_mem_handler_multiple::<CPU, THUMB, false, true, true, false, false, true> as _,
(true, true, true, false, false, true) => inst_mem_handler_multiple::<CPU, THUMB, true, true, true, false, false, true> as _,
(false, false, false, true, false, true) => inst_mem_handler_multiple::<CPU, THUMB, false, false, false, true, false, true> as _,
(true, false, false, true, false, true) => inst_mem_handler_multiple::<CPU, THUMB, true, false, false, true, false, true> as _,
(false, true, false, true, false, true) => inst_mem_handler_multiple::<CPU, THUMB, false, true, false, true, false, true> as _,
(true, true, false, true, false, true) => inst_mem_handler_multiple::<CPU, THUMB, true, true, false, true, false, true> as _,
(false, false, true, true, false, true) => inst_mem_handler_multiple::<CPU, THUMB, false, false, true, true, false, true> as _,
(true, false, true, true, false, true) => inst_mem_handler_multiple::<CPU, THUMB, true, false, true, true, false, true> as _,
(false, true, true, true, false, true) => inst_mem_handler_multiple::<CPU, THUMB, false, true, true, true, false, true> as _,
(true, true, true, true, false, true) => inst_mem_handler_multiple::<CPU, THUMB, true, true, true, true, false, true> as _,
(false, false, false, false, true, true) => inst_mem_handler_multiple::<CPU, THUMB, false, false, false, false, true, true> as _,
(true, false, false, false, true, true) => inst_mem_handler_multiple::<CPU, THUMB, true, false, false, false, true, true> as _,
(false, true, false, false, true, true) => inst_mem_handler_multiple::<CPU, THUMB, false, true, false, false, true, true> as _,
(true, true, false, false, true, true) => inst_mem_handler_multiple::<CPU, THUMB, true, true, false, false, true, true> as _,
(false, false, true, false, true, true) => inst_mem_handler_multiple::<CPU, THUMB, false, false, true, false, true, true> as _,
(true, false, true, false, true, true) => inst_mem_handler_multiple::<CPU, THUMB, true, false, true, false, true, true> as _,
(false, true, true, false, true, true) => inst_mem_handler_multiple::<CPU, THUMB, false, true, true, false, true, true> as _,
(true, true, true, false, true, true) => inst_mem_handler_multiple::<CPU, THUMB, true, true, true, false, true, true> as _,
(false, false, false, true, true, true) => inst_mem_handler_multiple::<CPU, THUMB, false, false, false, true, true, true> as _,
(true, false, false, true, true, true) => inst_mem_handler_multiple::<CPU, THUMB, true, false, false, true, true, true> as _,
(false, true, false, true, true, true) => inst_mem_handler_multiple::<CPU, THUMB, false, true, false, true, true, true> as _,
(true, true, false, true, true, true) => inst_mem_handler_multiple::<CPU, THUMB, true, true, false, true, true, true> as _,
(false, false, true, true, true, true) => inst_mem_handler_multiple::<CPU, THUMB, false, false, true, true, true, true> as _,
(true, false, true, true, true, true) => inst_mem_handler_multiple::<CPU, THUMB, true, false, true, true, true, true> as _,
(false, true, true, true, true, true) => inst_mem_handler_multiple::<CPU, THUMB, false, true, true, true, true, true> as _,
(true, true, true, true, true, true) => inst_mem_handler_multiple::<CPU, THUMB, true, true, true, true, true, true> as _,
let func_addr: *const () = match (inst_info.op.mem_is_write(), inst_info.op.mem_transfer_user(), pre, write_back, decrement) {
(false, false, false, false, false) => inst_mem_handler_multiple::<CPU, THUMB, false, false, false, false, false> as _,
(true, false, false, false, false) => inst_mem_handler_multiple::<CPU, THUMB, true, false, false, false, false> as _,
(false, true, false, false, false) => inst_mem_handler_multiple::<CPU, THUMB, false, true, false, false, false> as _,
(true, true, false, false, false) => inst_mem_handler_multiple::<CPU, THUMB, true, true, false, false, false> as _,
(false, false, true, false, false) => inst_mem_handler_multiple::<CPU, THUMB, false, false, true, false, false> as _,
(true, false, true, false, false) => inst_mem_handler_multiple::<CPU, THUMB, true, false, true, false, false> as _,
(false, true, true, false, false) => inst_mem_handler_multiple::<CPU, THUMB, false, true, true, false, false> as _,
(true, true, true, false, false) => inst_mem_handler_multiple::<CPU, THUMB, true, true, true, false, false> as _,
(false, false, false, true, false) => inst_mem_handler_multiple::<CPU, THUMB, false, false, false, true, false> as _,
(true, false, false, true, false) => inst_mem_handler_multiple::<CPU, THUMB, true, false, false, true, false> as _,
(false, true, false, true, false) => inst_mem_handler_multiple::<CPU, THUMB, false, true, false, true, false> as _,
(true, true, false, true, false) => inst_mem_handler_multiple::<CPU, THUMB, true, true, false, true, false> as _,
(false, false, true, true, false) => inst_mem_handler_multiple::<CPU, THUMB, false, false, true, true, false> as _,
(true, false, true, true, false) => inst_mem_handler_multiple::<CPU, THUMB, true, false, true, true, false> as _,
(false, true, true, true, false) => inst_mem_handler_multiple::<CPU, THUMB, false, true, true, true, false> as _,
(true, true, true, true, false) => inst_mem_handler_multiple::<CPU, THUMB, true, true, true, true, false> as _,
(false, false, false, false, true) => inst_mem_handler_multiple::<CPU, THUMB, false, false, false, false, true> as _,
(true, false, false, false, true) => inst_mem_handler_multiple::<CPU, THUMB, true, false, false, false, true> as _,
(false, true, false, false, true) => inst_mem_handler_multiple::<CPU, THUMB, false, true, false, false, true> as _,
(true, true, false, false, true) => inst_mem_handler_multiple::<CPU, THUMB, true, true, false, false, true> as _,
(false, false, true, false, true) => inst_mem_handler_multiple::<CPU, THUMB, false, false, true, false, true> as _,
(true, false, true, false, true) => inst_mem_handler_multiple::<CPU, THUMB, true, false, true, false, true> as _,
(false, true, true, false, true) => inst_mem_handler_multiple::<CPU, THUMB, false, true, true, false, true> as _,
(true, true, true, false, true) => inst_mem_handler_multiple::<CPU, THUMB, true, true, true, false, true> as _,
(false, false, false, true, true) => inst_mem_handler_multiple::<CPU, THUMB, false, false, false, true, true> as _,
(true, false, false, true, true) => inst_mem_handler_multiple::<CPU, THUMB, true, false, false, true, true> as _,
(false, true, false, true, true) => inst_mem_handler_multiple::<CPU, THUMB, false, true, false, true, true> as _,
(true, true, false, true, true) => inst_mem_handler_multiple::<CPU, THUMB, true, true, false, true, true> as _,
(false, false, true, true, true) => inst_mem_handler_multiple::<CPU, THUMB, false, false, true, true, true> as _,
(true, false, true, true, true) => inst_mem_handler_multiple::<CPU, THUMB, true, false, true, true, true> as _,
(false, true, true, true, true) => inst_mem_handler_multiple::<CPU, THUMB, false, true, true, true, true> as _,
(true, true, true, true, true) => inst_mem_handler_multiple::<CPU, THUMB, true, true, true, true, true> as _,
};

block_asm.save_context();
Expand Down
7 changes: 5 additions & 2 deletions src/jit/emitter/thumb/emit_thumb.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::core::CpuType;
use crate::core::CpuType::ARM7;
use crate::jit::assembler::block_asm::BlockAsm;
use crate::jit::inst_threag_regs_handler::set_pc_thumb_mode;
use crate::jit::jit_asm::JitAsm;
Expand Down Expand Up @@ -67,10 +68,12 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> {
}
}

if self.jit_buf.current_inst().out_regs.is_reserved(Reg::PC) && !op.is_multiple_mem_transfer() {
if self.jit_buf.current_inst().out_regs.is_reserved(Reg::PC) {
block_asm.save_context();

block_asm.call(set_pc_thumb_mode::<CPU> as *const ());
if CPU == ARM7 || !op.is_multiple_mem_transfer() {
block_asm.call(set_pc_thumb_mode::<CPU> as *const ());
}

self.emit_branch_out_metadata(block_asm);
block_asm.epilogue();
Expand Down
43 changes: 5 additions & 38 deletions src/jit/inst_mem_handler.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use crate::core::emu::{get_mem, get_regs_mut};
use crate::core::emu::get_mem;
use crate::core::CpuType;
use crate::core::CpuType::ARM7;
use crate::get_jit_asm_ptr;
use crate::jit::reg::Reg;
use crate::jit::MemoryAmount;
use crate::{get_jit_asm_ptr, DEBUG_LOG_BRANCH_OUT};
use handler::*;
use std::arch::asm;
use std::hint::unreachable_unchecked;
use std::intrinsics::unlikely;

mod handler {
Expand Down Expand Up @@ -170,8 +168,6 @@ macro_rules! imm_breakout {
std::hint::unreachable_unchecked();
}};
}
use crate::jit::reg::Reg;
use crate::logging::debug_println;
pub(super) use imm_breakout;

pub unsafe extern "C" fn inst_mem_handler<const CPU: CpuType, const THUMB: bool, const WRITE: bool, const AMOUNT: MemoryAmount, const SIGNED: bool, const MMU: bool>(
Expand All @@ -187,43 +183,14 @@ pub unsafe extern "C" fn inst_mem_handler<const CPU: CpuType, const THUMB: bool,
}
}

pub unsafe extern "C" fn inst_mem_handler_multiple<
const CPU: CpuType,
const THUMB: bool,
const WRITE: bool,
const USER: bool,
const PRE: bool,
const WRITE_BACK: bool,
const DECREMENT: bool,
const HAS_PC: bool,
>(
pub unsafe extern "C" fn inst_mem_handler_multiple<const CPU: CpuType, const THUMB: bool, const WRITE: bool, const USER: bool, const PRE: bool, const WRITE_BACK: bool, const DECREMENT: bool>(
op0_rlist: u32,
pc: u32,
total_cycles: u16,
) {
let asm = get_jit_asm_ptr::<CPU>();
handle_multiple_request::<CPU, THUMB, WRITE, USER, PRE, WRITE_BACK, DECREMENT>(pc, (op0_rlist & 0xFFFF) as u16, (op0_rlist >> 16) as u8, (*asm).emu);
if !WRITE && HAS_PC {
debug_println!("{CPU:?} mem handle multiple read load pc, breakout");
if DEBUG_LOG_BRANCH_OUT {
(*asm).runtime_data.branch_out_pc = pc;
}
(*asm).runtime_data.branch_out_total_cycles = total_cycles;
if CPU == ARM7 {
if THUMB {
get_regs_mut!((*asm).emu, CPU).pc |= 1;
} else {
get_regs_mut!((*asm).emu, CPU).pc &= !1;
}
}
// r4-r12,pc since we need an even amount of registers for 8 byte alignment, in case the compiler decides to use neon instructions
asm!(
"mov sp, {}",
"pop {{r4-r12,pc}}",
in(reg) (*asm).runtime_data.host_sp
);
unreachable_unchecked();
} else if WRITE && unlikely(get_mem!((*asm).emu).breakout_imm) {
if WRITE && unlikely(get_mem!((*asm).emu).breakout_imm) {
imm_breakout!((*asm), pc, THUMB, total_cycles);
}
}
Expand Down

0 comments on commit e0d4cea

Please sign in to comment.