Arm: Partially implement MUL
Former-commit-id: 3b37f5cbe327e15be4cee56572c2230dbda48082
This commit is contained in:
parent
543161d6b8
commit
2864f83681
|
@ -24,6 +24,7 @@ impl Core {
|
||||||
ArmFormat::LDR_STR_HS_REG => self.exec_ldr_str_hs(bus, insn),
|
ArmFormat::LDR_STR_HS_REG => self.exec_ldr_str_hs(bus, insn),
|
||||||
ArmFormat::LDM_STM => self.exec_ldm_stm(bus, insn),
|
ArmFormat::LDM_STM => self.exec_ldm_stm(bus, insn),
|
||||||
ArmFormat::MSR_REG => self.exec_msr_reg(bus, insn),
|
ArmFormat::MSR_REG => self.exec_msr_reg(bus, insn),
|
||||||
|
ArmFormat::MUL_MLA => self.exec_mul_mla(bus, insn),
|
||||||
_ => Err(CpuError::UnimplementedCpuInstruction(
|
_ => Err(CpuError::UnimplementedCpuInstruction(
|
||||||
insn.pc,
|
insn.pc,
|
||||||
insn.raw,
|
insn.raw,
|
||||||
|
@ -335,4 +336,46 @@ impl Core {
|
||||||
|
|
||||||
Ok(pipeline_action)
|
Ok(pipeline_action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn exec_mul_mla(
|
||||||
|
&mut self,
|
||||||
|
bus: &mut Bus,
|
||||||
|
insn: ArmInstruction,
|
||||||
|
) -> CpuResult<CpuPipelineAction> {
|
||||||
|
let rd = insn.rd();
|
||||||
|
let rn = insn.rn();
|
||||||
|
let rs = insn.rs();
|
||||||
|
let rm = insn.rm();
|
||||||
|
|
||||||
|
// check validity
|
||||||
|
if REG_PC == rd || REG_PC == rn || REG_PC == rs || REG_PC == rm {
|
||||||
|
return Err(CpuError::IllegalInstruction);
|
||||||
|
}
|
||||||
|
if rd == rm {
|
||||||
|
return Err(CpuError::IllegalInstruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !insn.accumulate_flag() {
|
||||||
|
self.set_reg(insn.rn(), 0);
|
||||||
|
} else {
|
||||||
|
panic!("accumelate not implemented yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
let op1 = self.get_reg(rm) as i32;
|
||||||
|
let op2 = self.get_reg(rs) as i32;
|
||||||
|
let result = (op1 * op2) as u32;
|
||||||
|
self.set_reg(rd, result);
|
||||||
|
|
||||||
|
let m = self.get_required_multipiler_array_cycles(op2);
|
||||||
|
for _ in 0..m {
|
||||||
|
self.add_cycle();
|
||||||
|
}
|
||||||
|
|
||||||
|
if insn.set_cond_flag() {
|
||||||
|
self.cpsr.set_N(result.bit(31));
|
||||||
|
self.cpsr.set_Z(result == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(CpuPipelineAction::IncPC)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,7 +369,7 @@ impl Core {
|
||||||
self.set_reg(r, val);
|
self.set_reg(r, val);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for r in rlist.into_iter().rev() {
|
for r in rlist {
|
||||||
self.store_32(addr, self.gpr[r], bus);
|
self.store_32(addr, self.gpr[r], bus);
|
||||||
addr += 4;
|
addr += 4;
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue