thumb: more const-generics :)

Former-commit-id: e869dafa68973d944be3b8d88d3238451b64718c
Former-commit-id: 8118d529e7a40303e4535f581ad4cf247b926b46
This commit is contained in:
Michel Heily 2021-07-02 13:00:00 +03:00 committed by MichelOS
parent 9e6b787536
commit 4a7eb53707
2 changed files with 43 additions and 20 deletions

View file

@ -62,14 +62,31 @@ fn thumb_decode(i: u16) -> (&'static str, String) {
} else if i & 0xf200 == 0x5000 { } else if i & 0xf200 == 0x5000 {
( (
"LdrStrRegOffset", "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 { } else if i & 0xf200 == 0x5200 {
("LdrStrSHB", String::from("exec_thumb_ldr_str_shb")) ("LdrStrSHB", String::from("exec_thumb_ldr_str_shb"))
} else if i & 0xe000 == 0x6000 { } 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", "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 { } else if i & 0xf000 == 0x8000 {
( (

View file

@ -212,16 +212,14 @@ impl<I: MemoryInterface> Core<I> {
/// Helper function for various ldr/str handler /// Helper function for various ldr/str handler
/// Execution Time: 1S+1N+1I for LDR, or 2N for STR /// Execution Time: 1S+1N+1I for LDR, or 2N for STR
fn do_exec_thumb_ldr_str( fn do_exec_thumb_ldr_str<const LOAD: bool, const BYTE: bool>(
&mut self, &mut self,
insn: u16, insn: u16,
addr: Addr, addr: Addr,
is_transferring_bytes: bool,
) -> CpuAction { ) -> CpuAction {
let rd = (insn & 0b111) as usize; let rd = (insn & 0b111) as usize;
if insn.is_load() { if LOAD {
let data = if is_transferring_bytes { let data = if BYTE {
self.load_8(addr, NonSeq) as u32 self.load_8(addr, NonSeq) as u32
} else { } else {
self.ldr_word(addr, NonSeq) self.ldr_word(addr, NonSeq)
@ -234,7 +232,7 @@ impl<I: MemoryInterface> Core<I> {
CpuAction::AdvancePC(Seq) CpuAction::AdvancePC(Seq)
} else { } else {
let value = self.get_reg(rd); let value = self.get_reg(rd);
if is_transferring_bytes { if BYTE {
self.store_8(addr, value as u8, NonSeq); self.store_8(addr, value as u8, NonSeq);
} else { } else {
self.store_aligned_32(addr, value, NonSeq); self.store_aligned_32(addr, value, NonSeq);
@ -245,10 +243,17 @@ impl<I: MemoryInterface> Core<I> {
/// Format 7 load/store with register offset /// Format 7 load/store with register offset
/// Execution Time: 1S+1N+1I for LDR, or 2N for STR /// 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 rb = insn.bit_range(3..6) as usize;
let addr = self.gpr[rb].wrapping_add(self.gpr[insn.ro()]); let addr = self.gpr[rb].wrapping_add(self.gpr[RO]);
self.do_exec_thumb_ldr_str(insn, addr, insn.bit(10)) self.do_exec_thumb_ldr_str::<LOAD, BYTE>(insn, addr)
} }
/// Format 8 load/store sign-extended byte/halfword /// Format 8 load/store sign-extended byte/halfword
@ -294,16 +299,17 @@ impl<I: MemoryInterface> Core<I> {
/// Format 9 /// Format 9
/// Execution Time: 1S+1N+1I for LDR, or 2N for STR /// 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 rb = insn.bit_range(3..6) as usize;
let addr = self.gpr[rb].wrapping_add(OFFSET as u32);
let offset = if insn.bit(12) { self.do_exec_thumb_ldr_str::<LOAD, BYTE>(insn, addr)
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))
} }
/// Format 10 /// Format 10