arm: do const-generics for BlockDataTransfer
Former-commit-id: d4be9648b334891de5a2daf3c2931cf8e31b337a Former-commit-id: 6e7e54efd9fa3901008d2fab21dab4560d597763
This commit is contained in:
parent
416cc2937b
commit
86c35a2eb3
|
@ -338,7 +338,17 @@ fn arm_decode(i: u32) -> (&'static str, String) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0b10 => match i.bit(25) {
|
0b10 => match i.bit(25) {
|
||||||
F => ("BlockDataTransfer", String::from("exec_arm_ldm_stm")),
|
F => (
|
||||||
|
"BlockDataTransfer",
|
||||||
|
format!(
|
||||||
|
"exec_arm_ldm_stm::<{LOAD}, {WRITEBACK}, {FLAG_S}, {ADD}, {PRE_INDEX}>",
|
||||||
|
LOAD = i.bit(20),
|
||||||
|
WRITEBACK = i.bit(21),
|
||||||
|
FLAG_S = i.bit(22),
|
||||||
|
ADD = i.bit(23),
|
||||||
|
PRE_INDEX = i.bit(24),
|
||||||
|
),
|
||||||
|
),
|
||||||
T => (
|
T => (
|
||||||
"BranchLink",
|
"BranchLink",
|
||||||
format!("exec_arm_b_bl::<{LINK}>", LINK = i.bit(24)),
|
format!("exec_arm_b_bl::<{LINK}>", LINK = i.bit(24)),
|
||||||
|
|
|
@ -480,20 +480,27 @@ impl<I: MemoryInterface> Core<I> {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec_arm_ldm_stm(&mut self, insn: u32) -> CpuAction {
|
pub fn exec_arm_ldm_stm<
|
||||||
|
const LOAD: bool,
|
||||||
|
const WRITEBACK: bool,
|
||||||
|
const FLAG_S: bool,
|
||||||
|
const ADD: bool,
|
||||||
|
const PRE_INDEX: bool,
|
||||||
|
>(
|
||||||
|
&mut self,
|
||||||
|
insn: u32,
|
||||||
|
) -> CpuAction {
|
||||||
let mut result = CpuAction::AdvancePC(NonSeq);
|
let mut result = CpuAction::AdvancePC(NonSeq);
|
||||||
|
|
||||||
let mut full = insn.pre_index_flag();
|
let mut full = PRE_INDEX;
|
||||||
let ascending = insn.add_offset_flag();
|
let ascending = ADD;
|
||||||
let s_flag = insn.bit(22);
|
let mut writeback = WRITEBACK;
|
||||||
let is_load = insn.load_flag();
|
|
||||||
let mut writeback = insn.write_back_flag();
|
|
||||||
let base_reg = insn.bit_range(16..20) as usize;
|
let base_reg = insn.bit_range(16..20) as usize;
|
||||||
let mut base_addr = self.get_reg(base_reg);
|
let mut base_addr = self.get_reg(base_reg);
|
||||||
|
|
||||||
let rlist = insn.register_list();
|
let rlist = insn.register_list();
|
||||||
|
|
||||||
if s_flag {
|
if FLAG_S {
|
||||||
match self.cpsr.mode() {
|
match self.cpsr.mode() {
|
||||||
CpuMode::User | CpuMode::System => {
|
CpuMode::User | CpuMode::System => {
|
||||||
panic!("LDM/STM with S bit in unprivileged mode")
|
panic!("LDM/STM with S bit in unprivileged mode")
|
||||||
|
@ -502,8 +509,8 @@ impl<I: MemoryInterface> Core<I> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let user_bank_transfer = if s_flag {
|
let user_bank_transfer = if FLAG_S {
|
||||||
if is_load {
|
if LOAD {
|
||||||
!rlist.bit(REG_PC)
|
!rlist.bit(REG_PC)
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
|
@ -517,7 +524,7 @@ impl<I: MemoryInterface> Core<I> {
|
||||||
self.change_mode(old_mode, CpuMode::User);
|
self.change_mode(old_mode, CpuMode::User);
|
||||||
}
|
}
|
||||||
|
|
||||||
let psr_transfer = s_flag & is_load & rlist.bit(REG_PC);
|
let psr_transfer = FLAG_S & LOAD & rlist.bit(REG_PC);
|
||||||
|
|
||||||
let rlist_count = rlist.count_ones();
|
let rlist_count = rlist.count_ones();
|
||||||
|
|
||||||
|
@ -535,7 +542,7 @@ impl<I: MemoryInterface> Core<I> {
|
||||||
let mut addr = base_addr;
|
let mut addr = base_addr;
|
||||||
|
|
||||||
if rlist != 0 {
|
if rlist != 0 {
|
||||||
if is_load {
|
if LOAD {
|
||||||
let mut access = NonSeq;
|
let mut access = NonSeq;
|
||||||
for r in 0..16 {
|
for r in 0..16 {
|
||||||
if rlist.bit(r) {
|
if rlist.bit(r) {
|
||||||
|
@ -600,7 +607,7 @@ impl<I: MemoryInterface> Core<I> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if is_load {
|
if LOAD {
|
||||||
let val = self.ldr_word(addr, NonSeq);
|
let val = self.ldr_word(addr, NonSeq);
|
||||||
self.set_reg(REG_PC, val & !3);
|
self.set_reg(REG_PC, val & !3);
|
||||||
self.reload_pipeline32();
|
self.reload_pipeline32();
|
||||||
|
|
Reference in a new issue