diff --git a/src/jit/assembler/block_asm.rs b/src/jit/assembler/block_asm.rs index e8ddfb4..e35ae0f 100644 --- a/src/jit/assembler/block_asm.rs +++ b/src/jit/assembler/block_asm.rs @@ -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; diff --git a/src/jit/emitter/emit.rs b/src/jit/emitter/emit.rs index 3039f20..cdc4ccb 100644 --- a/src/jit/emitter/emit.rs +++ b/src/jit/emitter/emit.rs @@ -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; @@ -42,7 +42,7 @@ 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(); @@ -50,7 +50,7 @@ impl<'a, const CPU: CpuType> JitAsm<'a, CPU> { block_asm.call(register_restore_spsr:: 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:: as *const ()); } else { diff --git a/src/jit/emitter/emit_transfer.rs b/src/jit/emitter/emit_transfer.rs index 79c75fd..c3a3c7f 100644 --- a/src/jit/emitter/emit_transfer.rs +++ b/src/jit/emitter/emit_transfer.rs @@ -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:: as _, - (true, false, false, false, false, false) => inst_mem_handler_multiple:: as _, - (false, true, false, false, false, false) => inst_mem_handler_multiple:: as _, - (true, true, false, false, false, false) => inst_mem_handler_multiple:: as _, - (false, false, true, false, false, false) => inst_mem_handler_multiple:: as _, - (true, false, true, false, false, false) => inst_mem_handler_multiple:: as _, - (false, true, true, false, false, false) => inst_mem_handler_multiple:: as _, - (true, true, true, false, false, false) => inst_mem_handler_multiple:: as _, - (false, false, false, true, false, false) => inst_mem_handler_multiple:: as _, - (true, false, false, true, false, false) => inst_mem_handler_multiple:: as _, - (false, true, false, true, false, false) => inst_mem_handler_multiple:: as _, - (true, true, false, true, false, false) => inst_mem_handler_multiple:: as _, - (false, false, true, true, false, false) => inst_mem_handler_multiple:: as _, - (true, false, true, true, false, false) => inst_mem_handler_multiple:: as _, - (false, true, true, true, false, false) => inst_mem_handler_multiple:: as _, - (true, true, true, true, false, false) => inst_mem_handler_multiple:: as _, - (false, false, false, false, true, false) => inst_mem_handler_multiple:: as _, - (true, false, false, false, true, false) => inst_mem_handler_multiple:: as _, - (false, true, false, false, true, false) => inst_mem_handler_multiple:: as _, - (true, true, false, false, true, false) => inst_mem_handler_multiple:: as _, - (false, false, true, false, true, false) => inst_mem_handler_multiple:: as _, - (true, false, true, false, true, false) => inst_mem_handler_multiple:: as _, - (false, true, true, false, true, false) => inst_mem_handler_multiple:: as _, - (true, true, true, false, true, false) => inst_mem_handler_multiple:: as _, - (false, false, false, true, true, false) => inst_mem_handler_multiple:: as _, - (true, false, false, true, true, false) => inst_mem_handler_multiple:: as _, - (false, true, false, true, true, false) => inst_mem_handler_multiple:: as _, - (true, true, false, true, true, false) => inst_mem_handler_multiple:: as _, - (false, false, true, true, true, false) => inst_mem_handler_multiple:: as _, - (true, false, true, true, true, false) => inst_mem_handler_multiple:: as _, - (false, true, true, true, true, false) => inst_mem_handler_multiple:: as _, - (true, true, true, true, true, false) => inst_mem_handler_multiple:: as _, - (false, false, false, false, false, true) => inst_mem_handler_multiple:: as _, - (true, false, false, false, false, true) => inst_mem_handler_multiple:: as _, - (false, true, false, false, false, true) => inst_mem_handler_multiple:: as _, - (true, true, false, false, false, true) => inst_mem_handler_multiple:: as _, - (false, false, true, false, false, true) => inst_mem_handler_multiple:: as _, - (true, false, true, false, false, true) => inst_mem_handler_multiple:: as _, - (false, true, true, false, false, true) => inst_mem_handler_multiple:: as _, - (true, true, true, false, false, true) => inst_mem_handler_multiple:: as _, - (false, false, false, true, false, true) => inst_mem_handler_multiple:: as _, - (true, false, false, true, false, true) => inst_mem_handler_multiple:: as _, - (false, true, false, true, false, true) => inst_mem_handler_multiple:: as _, - (true, true, false, true, false, true) => inst_mem_handler_multiple:: as _, - (false, false, true, true, false, true) => inst_mem_handler_multiple:: as _, - (true, false, true, true, false, true) => inst_mem_handler_multiple:: as _, - (false, true, true, true, false, true) => inst_mem_handler_multiple:: as _, - (true, true, true, true, false, true) => inst_mem_handler_multiple:: as _, - (false, false, false, false, true, true) => inst_mem_handler_multiple:: as _, - (true, false, false, false, true, true) => inst_mem_handler_multiple:: as _, - (false, true, false, false, true, true) => inst_mem_handler_multiple:: as _, - (true, true, false, false, true, true) => inst_mem_handler_multiple:: as _, - (false, false, true, false, true, true) => inst_mem_handler_multiple:: as _, - (true, false, true, false, true, true) => inst_mem_handler_multiple:: as _, - (false, true, true, false, true, true) => inst_mem_handler_multiple:: as _, - (true, true, true, false, true, true) => inst_mem_handler_multiple:: as _, - (false, false, false, true, true, true) => inst_mem_handler_multiple:: as _, - (true, false, false, true, true, true) => inst_mem_handler_multiple:: as _, - (false, true, false, true, true, true) => inst_mem_handler_multiple:: as _, - (true, true, false, true, true, true) => inst_mem_handler_multiple:: as _, - (false, false, true, true, true, true) => inst_mem_handler_multiple:: as _, - (true, false, true, true, true, true) => inst_mem_handler_multiple:: as _, - (false, true, true, true, true, true) => inst_mem_handler_multiple:: as _, - (true, true, true, true, true, true) => inst_mem_handler_multiple:: 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:: as _, + (true, false, false, false, false) => inst_mem_handler_multiple:: as _, + (false, true, false, false, false) => inst_mem_handler_multiple:: as _, + (true, true, false, false, false) => inst_mem_handler_multiple:: as _, + (false, false, true, false, false) => inst_mem_handler_multiple:: as _, + (true, false, true, false, false) => inst_mem_handler_multiple:: as _, + (false, true, true, false, false) => inst_mem_handler_multiple:: as _, + (true, true, true, false, false) => inst_mem_handler_multiple:: as _, + (false, false, false, true, false) => inst_mem_handler_multiple:: as _, + (true, false, false, true, false) => inst_mem_handler_multiple:: as _, + (false, true, false, true, false) => inst_mem_handler_multiple:: as _, + (true, true, false, true, false) => inst_mem_handler_multiple:: as _, + (false, false, true, true, false) => inst_mem_handler_multiple:: as _, + (true, false, true, true, false) => inst_mem_handler_multiple:: as _, + (false, true, true, true, false) => inst_mem_handler_multiple:: as _, + (true, true, true, true, false) => inst_mem_handler_multiple:: as _, + (false, false, false, false, true) => inst_mem_handler_multiple:: as _, + (true, false, false, false, true) => inst_mem_handler_multiple:: as _, + (false, true, false, false, true) => inst_mem_handler_multiple:: as _, + (true, true, false, false, true) => inst_mem_handler_multiple:: as _, + (false, false, true, false, true) => inst_mem_handler_multiple:: as _, + (true, false, true, false, true) => inst_mem_handler_multiple:: as _, + (false, true, true, false, true) => inst_mem_handler_multiple:: as _, + (true, true, true, false, true) => inst_mem_handler_multiple:: as _, + (false, false, false, true, true) => inst_mem_handler_multiple:: as _, + (true, false, false, true, true) => inst_mem_handler_multiple:: as _, + (false, true, false, true, true) => inst_mem_handler_multiple:: as _, + (true, true, false, true, true) => inst_mem_handler_multiple:: as _, + (false, false, true, true, true) => inst_mem_handler_multiple:: as _, + (true, false, true, true, true) => inst_mem_handler_multiple:: as _, + (false, true, true, true, true) => inst_mem_handler_multiple:: as _, + (true, true, true, true, true) => inst_mem_handler_multiple:: as _, }; block_asm.save_context(); diff --git a/src/jit/emitter/thumb/emit_thumb.rs b/src/jit/emitter/thumb/emit_thumb.rs index 655848f..9bc3d9c 100644 --- a/src/jit/emitter/thumb/emit_thumb.rs +++ b/src/jit/emitter/thumb/emit_thumb.rs @@ -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; @@ -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:: as *const ()); + if CPU == ARM7 || !op.is_multiple_mem_transfer() { + block_asm.call(set_pc_thumb_mode:: as *const ()); + } self.emit_branch_out_metadata(block_asm); block_asm.epilogue(); diff --git a/src/jit/inst_mem_handler.rs b/src/jit/inst_mem_handler.rs index 7b1d64c..9d0f30c 100644 --- a/src/jit/inst_mem_handler.rs +++ b/src/jit/inst_mem_handler.rs @@ -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 { @@ -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( @@ -187,43 +183,14 @@ pub unsafe extern "C" fn inst_mem_handler( +pub unsafe extern "C" fn inst_mem_handler_multiple( op0_rlist: u32, pc: u32, total_cycles: u16, ) { let asm = get_jit_asm_ptr::(); handle_multiple_request::(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); } }