diff --git a/core/build.rs b/core/build.rs index 2ec3479..4f520fb 100644 --- a/core/build.rs +++ b/core/build.rs @@ -338,7 +338,17 @@ fn arm_decode(i: u32) -> (&'static str, String) { } } 0b10 => match i.bit(25) { - F => ("BlockDataTransfer", String::from("exec_arm_ldm_stm")), + F => ( + "BlockDataTransfer", + format!( + "exec_arm_ldm_stm::<{LOAD}, {WRITEBACK}, {FLAG_S}, {ADD}, {PRE_INDEX}>", + LOAD = i.bit(20), + WRITEBACK = i.bit(21), + FLAG_S = i.bit(22), + ADD = i.bit(23), + PRE_INDEX = i.bit(24), + ), + ), T => ( "BranchLink", format!("exec_arm_b_bl::<{LINK}>", LINK = i.bit(24)), diff --git a/core/src/arm7tdmi/arm/exec.rs b/core/src/arm7tdmi/arm/exec.rs index e168b1c..6974b66 100644 --- a/core/src/arm7tdmi/arm/exec.rs +++ b/core/src/arm7tdmi/arm/exec.rs @@ -480,20 +480,27 @@ impl Core { result } - pub fn exec_arm_ldm_stm(&mut self, insn: u32) -> CpuAction { + pub fn exec_arm_ldm_stm< + const LOAD: bool, + const WRITEBACK: bool, + const FLAG_S: bool, + const ADD: bool, + const PRE_INDEX: bool, + >( + &mut self, + insn: u32, + ) -> CpuAction { let mut result = CpuAction::AdvancePC(NonSeq); - let mut full = insn.pre_index_flag(); - let ascending = insn.add_offset_flag(); - let s_flag = insn.bit(22); - let is_load = insn.load_flag(); - let mut writeback = insn.write_back_flag(); + let mut full = PRE_INDEX; + let ascending = ADD; + let mut writeback = WRITEBACK; let base_reg = insn.bit_range(16..20) as usize; let mut base_addr = self.get_reg(base_reg); let rlist = insn.register_list(); - if s_flag { + if FLAG_S { match self.cpsr.mode() { CpuMode::User | CpuMode::System => { panic!("LDM/STM with S bit in unprivileged mode") @@ -502,8 +509,8 @@ impl Core { }; } - let user_bank_transfer = if s_flag { - if is_load { + let user_bank_transfer = if FLAG_S { + if LOAD { !rlist.bit(REG_PC) } else { true @@ -517,7 +524,7 @@ impl Core { self.change_mode(old_mode, CpuMode::User); } - let psr_transfer = s_flag & is_load & rlist.bit(REG_PC); + let psr_transfer = FLAG_S & LOAD & rlist.bit(REG_PC); let rlist_count = rlist.count_ones(); @@ -535,7 +542,7 @@ impl Core { let mut addr = base_addr; if rlist != 0 { - if is_load { + if LOAD { let mut access = NonSeq; for r in 0..16 { if rlist.bit(r) { @@ -600,7 +607,7 @@ impl Core { } } } else { - if is_load { + if LOAD { let val = self.ldr_word(addr, NonSeq); self.set_reg(REG_PC, val & !3); self.reload_pipeline32();