thumb: more const-generics :)
Former-commit-id: e869dafa68973d944be3b8d88d3238451b64718c Former-commit-id: 8118d529e7a40303e4535f581ad4cf247b926b46
This commit is contained in:
parent
9e6b787536
commit
4a7eb53707
|
@ -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 {
|
||||
(
|
||||
|
|
|
@ -212,16 +212,14 @@ impl<I: MemoryInterface> Core<I> {
|
|||
|
||||
/// 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<const LOAD: bool, const BYTE: bool>(
|
||||
&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<I: MemoryInterface> Core<I> {
|
|||
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<I: MemoryInterface> Core<I> {
|
|||
|
||||
/// 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::<LOAD, BYTE>(insn, addr)
|
||||
}
|
||||
|
||||
/// Format 8 load/store sign-extended byte/halfword
|
||||
|
@ -294,16 +299,17 @@ impl<I: MemoryInterface> Core<I> {
|
|||
|
||||
/// 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::<LOAD, BYTE>(insn, addr)
|
||||
}
|
||||
|
||||
/// Format 10
|
||||
|
|
Reference in a new issue