diff --git a/core/build.rs b/core/build.rs index 693bb49..55df81b 100644 --- a/core/build.rs +++ b/core/build.rs @@ -62,14 +62,31 @@ fn thumb_decode(i: u16) -> (&'static str, String) { } else if i & 0xf200 == 0x5000 { ( "LdrStrRegOffset", - String::from("exec_thumb_ldr_str_reg_offset"), + format!( + "exec_thumb_ldr_str_reg_offset::<{LOAD}, {RO}, {BYTE}>", + LOAD = i.bit(11), + RO = i.bit_range(6..9) as usize, + BYTE = i.bit(10), + ), ) } else if i & 0xf200 == 0x5200 { ("LdrStrSHB", String::from("exec_thumb_ldr_str_shb")) } else if i & 0xe000 == 0x6000 { + let is_transferring_bytes = i.bit(12); + let offset5 = i.bit_range(6..11) as u8; + let offset = if is_transferring_bytes { + offset5 + } else { + (offset5 << 3) >> 1 + }; ( "LdrStrImmOffset", - String::from("exec_thumb_ldr_str_imm_offset"), + format!( + "exec_thumb_ldr_str_imm_offset::<{LOAD}, {BYTE}, {OFFSET}>", + LOAD = i.bit(11), + BYTE = is_transferring_bytes, + OFFSET = offset + ), ) } else if i & 0xf000 == 0x8000 { ( diff --git a/core/src/arm7tdmi/thumb/exec.rs b/core/src/arm7tdmi/thumb/exec.rs index b54f084..ac728b8 100644 --- a/core/src/arm7tdmi/thumb/exec.rs +++ b/core/src/arm7tdmi/thumb/exec.rs @@ -212,16 +212,14 @@ impl Core { /// Helper function for various ldr/str handler /// Execution Time: 1S+1N+1I for LDR, or 2N for STR - fn do_exec_thumb_ldr_str( + fn do_exec_thumb_ldr_str( &mut self, insn: u16, - addr: Addr, - is_transferring_bytes: bool, ) -> CpuAction { let rd = (insn & 0b111) as usize; - if insn.is_load() { - let data = if is_transferring_bytes { + if LOAD { + let data = if BYTE { self.load_8(addr, NonSeq) as u32 } else { self.ldr_word(addr, NonSeq) @@ -234,7 +232,7 @@ impl Core { CpuAction::AdvancePC(Seq) } else { let value = self.get_reg(rd); - if is_transferring_bytes { + if BYTE { self.store_8(addr, value as u8, NonSeq); } else { self.store_aligned_32(addr, value, NonSeq); @@ -245,10 +243,17 @@ impl Core { /// Format 7 load/store with register offset /// Execution Time: 1S+1N+1I for LDR, or 2N for STR - pub(in super::super) fn exec_thumb_ldr_str_reg_offset(&mut self, insn: u16) -> CpuAction { + pub(in super::super) fn exec_thumb_ldr_str_reg_offset< + const LOAD: bool, + const RO: usize, + const BYTE: bool, + >( + &mut self, + insn: u16, + ) -> CpuAction { let rb = insn.bit_range(3..6) as usize; - let addr = self.gpr[rb].wrapping_add(self.gpr[insn.ro()]); - self.do_exec_thumb_ldr_str(insn, addr, insn.bit(10)) + let addr = self.gpr[rb].wrapping_add(self.gpr[RO]); + self.do_exec_thumb_ldr_str::(insn, addr) } /// Format 8 load/store sign-extended byte/halfword @@ -294,16 +299,17 @@ impl Core { /// Format 9 /// Execution Time: 1S+1N+1I for LDR, or 2N for STR - pub(in super::super) fn exec_thumb_ldr_str_imm_offset(&mut self, insn: u16) -> CpuAction { + pub(in super::super) fn exec_thumb_ldr_str_imm_offset< + const LOAD: bool, + const BYTE: bool, + const OFFSET: u8, + >( + &mut self, + insn: u16, + ) -> CpuAction { let rb = insn.bit_range(3..6) as usize; - - let offset = if insn.bit(12) { - insn.offset5() - } else { - (insn.offset5() << 3) >> 1 - }; - let addr = self.gpr[rb].wrapping_add(offset as u32); - self.do_exec_thumb_ldr_str(insn, addr, insn.bit(12)) + let addr = self.gpr[rb].wrapping_add(OFFSET as u32); + self.do_exec_thumb_ldr_str::(insn, addr) } /// Format 10