arm: convert more instructions to use const generics

Former-commit-id: bd4c802a49a8c37e6709c2481cc73367bbadade0
Former-commit-id: f3881e4f8fee1a7110cf676c3c62b6c39db88280
This commit is contained in:
Michel Heily 2021-07-02 12:45:11 +03:00 committed by MichelOS
parent 7e96be21ae
commit 9e6b787536
3 changed files with 33 additions and 19 deletions

View file

@ -44,10 +44,21 @@ fn thumb_decode(i: u16) -> (&'static str, String) {
} else if i & 0xfc00 == 0x4400 { } else if i & 0xfc00 == 0x4400 {
( (
"HiRegOpOrBranchExchange", "HiRegOpOrBranchExchange",
String::from("exec_thumb_hi_reg_op_or_bx"), format!(
"exec_thumb_hi_reg_op_or_bx::<{OP}, {FLAG_H1}, {FLAG_H2}>",
OP = i.bit_range(8..10) as u8,
FLAG_H1 = i.bit(7),
FLAG_H2 = i.bit(6),
),
) )
} else if i & 0xf800 == 0x4800 { } else if i & 0xf800 == 0x4800 {
("LdrPc", String::from("exec_thumb_ldr_pc")) (
"LdrPc",
format!(
"exec_thumb_ldr_pc::<{RD}>",
RD = i.bit_range(8..11) as usize
),
)
} else if i & 0xf200 == 0x5000 { } else if i & 0xf200 == 0x5000 {
( (
"LdrStrRegOffset", "LdrStrRegOffset",

View file

@ -62,7 +62,10 @@ impl<I: MemoryInterface> Core<I> {
/// Format 3 /// Format 3
/// Execution Time: 1S /// Execution Time: 1S
pub(in super::super) fn exec_thumb_data_process_imm<const OP: u8, const RD: usize>(&mut self, insn: u16) -> CpuAction { pub(in super::super) fn exec_thumb_data_process_imm<const OP: u8, const RD: usize>(
&mut self,
insn: u16,
) -> CpuAction {
use OpFormat3::*; use OpFormat3::*;
let op = OpFormat3::from_u8(OP).unwrap(); let op = OpFormat3::from_u8(OP).unwrap();
let op1 = self.gpr[RD]; let op1 = self.gpr[RD];
@ -147,19 +150,19 @@ impl<I: MemoryInterface> Core<I> {
/// Execution Time: /// Execution Time:
/// 1S for ADD/MOV/CMP /// 1S for ADD/MOV/CMP
/// 2S+1N for ADD/MOV with Rd=R15, and for BX /// 2S+1N for ADD/MOV with Rd=R15, and for BX
pub(in super::super) fn exec_thumb_hi_reg_op_or_bx(&mut self, insn: u16) -> CpuAction { pub(in super::super) fn exec_thumb_hi_reg_op_or_bx<
let op = insn.format5_op(); const OP: u8,
const FLAG_H1: bool,
const FLAG_H2: bool,
>(
&mut self,
insn: u16,
) -> CpuAction {
let op = OpFormat5::from_u8(OP).unwrap();
let rd = (insn & 0b111) as usize; let rd = (insn & 0b111) as usize;
let dst_reg = if insn.bit(consts::flags::FLAG_H1) { let rs = insn.rs();
rd + 8 let dst_reg = if FLAG_H1 { rd + 8 } else { rd };
} else { let src_reg = if FLAG_H2 { rs + 8 } else { rs };
rd
};
let src_reg = if insn.bit(consts::flags::FLAG_H2) {
insn.rs() + 8
} else {
insn.rs()
};
let op1 = self.get_reg(dst_reg); let op1 = self.get_reg(dst_reg);
let op2 = self.get_reg(src_reg); let op2 = self.get_reg(src_reg);
@ -195,13 +198,11 @@ impl<I: MemoryInterface> Core<I> {
/// Format 6 load PC-relative (for loading immediates from literal pool) /// Format 6 load PC-relative (for loading immediates from literal pool)
/// Execution Time: 1S+1N+1I /// Execution Time: 1S+1N+1I
pub(in super::super) fn exec_thumb_ldr_pc(&mut self, insn: u16) -> CpuAction { pub(in super::super) fn exec_thumb_ldr_pc<const RD: usize>(&mut self, insn: u16) -> CpuAction {
let rd = insn.bit_range(8..11) as usize;
let ofs = insn.word8() as Addr; let ofs = insn.word8() as Addr;
let addr = (self.pc & !3) + ofs; let addr = (self.pc & !3) + ofs;
self.gpr[rd] = self.load_32(addr, NonSeq); self.gpr[RD] = self.load_32(addr, NonSeq);
// +1I // +1I
self.idle_cycle(); self.idle_cycle();

View file

@ -210,7 +210,9 @@ impl From<OpFormat5> for AluOpCode {
pub(super) mod consts { pub(super) mod consts {
pub(super) mod flags { pub(super) mod flags {
#[cfg(feature = "debugger")]
pub const FLAG_H1: usize = 7; pub const FLAG_H1: usize = 7;
#[cfg(feature = "debugger")]
pub const FLAG_H2: usize = 6; pub const FLAG_H2: usize = 6;
pub const FLAG_R: usize = 8; pub const FLAG_R: usize = 8;
pub const FLAG_S: usize = 7; pub const FLAG_S: usize = 7;