arm: convert more instructions to use const generics
Former-commit-id: bd4c802a49a8c37e6709c2481cc73367bbadade0 Former-commit-id: f3881e4f8fee1a7110cf676c3c62b6c39db88280
This commit is contained in:
parent
7e96be21ae
commit
9e6b787536
|
@ -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",
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Reference in a new issue