arm: finish converting all instructions to const-generics
Former-commit-id: 4557ecffb89d563357f5bd769515254533a404ac Former-commit-id: 8ce461f1b48ff5e7c72cdcd3069dcee0960dbc8e
This commit is contained in:
parent
86c35a2eb3
commit
a7cc770be8
|
@ -305,10 +305,10 @@ fn arm_decode(i: u32) -> (&'static str, String) {
|
||||||
let is_op_not_touching_rd = i.bit_range(21..25) & 0b1100 == 0b1000;
|
let is_op_not_touching_rd = i.bit_range(21..25) & 0b1100 == 0b1000;
|
||||||
if !set_cond_flags && is_op_not_touching_rd {
|
if !set_cond_flags && is_op_not_touching_rd {
|
||||||
if i.bit(21) {
|
if i.bit(21) {
|
||||||
// Since bit-16 is ignored and we can't know statically if this is a exec_arm_transfer_to_status or exec_arm_transfer_to_status
|
("MoveToStatus", format!("exec_arm_transfer_to_status::<{IMM}, {SPSR_FLAG}>",
|
||||||
("MoveToStatus", String::from("exec_arm_transfer_to_status"))
|
IMM = i.bit(25), SPSR_FLAG = i.bit(22)))
|
||||||
} else {
|
} else {
|
||||||
("MoveFromStatus", String::from("exec_arm_mrs"))
|
("MoveFromStatus", format!("exec_arm_mrs::<{SPSR_FLAG}>", SPSR_FLAG = i.bit(22)))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
("DataProcessing", format!("exec_arm_data_processing::<{OP}, {IMM}, {SET_FLAGS}, {SHIFT_BY_REG}>",
|
("DataProcessing", format!("exec_arm_data_processing::<{OP}, {IMM}, {SET_FLAGS}, {SHIFT_BY_REG}>",
|
||||||
|
|
|
@ -75,9 +75,9 @@ impl<I: MemoryInterface> Core<I> {
|
||||||
|
|
||||||
/// Move from status register
|
/// Move from status register
|
||||||
/// 1S
|
/// 1S
|
||||||
pub fn exec_arm_mrs(&mut self, insn: u32) -> CpuAction {
|
pub fn exec_arm_mrs<const SPSR_FLAG: bool>(&mut self, insn: u32) -> CpuAction {
|
||||||
let rd = insn.bit_range(12..16) as usize;
|
let rd = insn.bit_range(12..16) as usize;
|
||||||
let result = if insn.spsr_flag() {
|
let result = if SPSR_FLAG {
|
||||||
self.spsr.get()
|
self.spsr.get()
|
||||||
} else {
|
} else {
|
||||||
self.cpsr.get()
|
self.cpsr.get()
|
||||||
|
@ -87,9 +87,13 @@ impl<I: MemoryInterface> Core<I> {
|
||||||
CpuAction::AdvancePC(Seq)
|
CpuAction::AdvancePC(Seq)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
/// Move to status register
|
||||||
fn decode_msr_param(&mut self, insn: u32) -> u32 {
|
/// 1S
|
||||||
if insn.bit(25) {
|
pub fn exec_arm_transfer_to_status<const IMM: bool, const SPSR_FLAG: bool>(
|
||||||
|
&mut self,
|
||||||
|
insn: u32,
|
||||||
|
) -> CpuAction {
|
||||||
|
let value = if IMM {
|
||||||
let immediate = insn & 0xff;
|
let immediate = insn & 0xff;
|
||||||
let rotate = 2 * insn.bit_range(8..12);
|
let rotate = 2 * insn.bit_range(8..12);
|
||||||
let mut carry = self.cpsr.C();
|
let mut carry = self.cpsr.C();
|
||||||
|
@ -98,13 +102,7 @@ impl<I: MemoryInterface> Core<I> {
|
||||||
v
|
v
|
||||||
} else {
|
} else {
|
||||||
self.get_reg((insn & 0b1111) as usize)
|
self.get_reg((insn & 0b1111) as usize)
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
/// Move to status register
|
|
||||||
/// 1S
|
|
||||||
pub fn exec_arm_transfer_to_status(&mut self, insn: u32) -> CpuAction {
|
|
||||||
let value = self.decode_msr_param(insn);
|
|
||||||
|
|
||||||
let f = insn.bit(19);
|
let f = insn.bit(19);
|
||||||
let s = insn.bit(18);
|
let s = insn.bit(18);
|
||||||
|
@ -125,17 +123,15 @@ impl<I: MemoryInterface> Core<I> {
|
||||||
mask |= 0xff << 0;
|
mask |= 0xff << 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_spsr = insn.spsr_flag();
|
|
||||||
|
|
||||||
match self.cpsr.mode() {
|
match self.cpsr.mode() {
|
||||||
CpuMode::User => {
|
CpuMode::User => {
|
||||||
if is_spsr {
|
if SPSR_FLAG {
|
||||||
panic!("User mode can't access SPSR")
|
panic!("User mode can't access SPSR")
|
||||||
}
|
}
|
||||||
self.cpsr.set_flag_bits(value);
|
self.cpsr.set_flag_bits(value);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if is_spsr {
|
if SPSR_FLAG {
|
||||||
self.spsr.set(value);
|
self.spsr.set(value);
|
||||||
} else {
|
} else {
|
||||||
let old_mode = self.cpsr.mode();
|
let old_mode = self.cpsr.mode();
|
||||||
|
|
Reference in a new issue