Impl Thumb 18 (Branch)
Former-commit-id: 152dab739a1fa1b9d324084fc810b8540af9c3d7
This commit is contained in:
parent
74329c2a0b
commit
638e449421
|
@ -170,6 +170,17 @@ impl ThumbInstruction {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fmt_thumb_branch(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"b\t{addr:#x}",
|
||||||
|
addr = {
|
||||||
|
let offset = (self.offset11() << 21) >> 20;
|
||||||
|
(self.pc as i32 + 4).wrapping_add(offset) as Addr
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn fmt_thumb_branch_long_with_link(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt_thumb_branch_long_with_link(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "bl\t#0x{:08x}", {
|
write!(f, "bl\t#0x{:08x}", {
|
||||||
let offset11 = self.offset11();
|
let offset11 = self.offset11();
|
||||||
|
@ -198,6 +209,7 @@ impl fmt::Display for ThumbInstruction {
|
||||||
ThumbFormat::AddSp => self.fmt_thumb_add_sp(f),
|
ThumbFormat::AddSp => self.fmt_thumb_add_sp(f),
|
||||||
ThumbFormat::PushPop => self.fmt_thumb_push_pop(f),
|
ThumbFormat::PushPop => self.fmt_thumb_push_pop(f),
|
||||||
ThumbFormat::BranchConditional => self.fmt_thumb_branch_with_cond(f),
|
ThumbFormat::BranchConditional => self.fmt_thumb_branch_with_cond(f),
|
||||||
|
ThumbFormat::Branch => self.fmt_thumb_branch(f),
|
||||||
ThumbFormat::BranchLongWithLink => self.fmt_thumb_branch_long_with_link(f),
|
ThumbFormat::BranchLongWithLink => self.fmt_thumb_branch_long_with_link(f),
|
||||||
_ => write!(f, "({:?})", self),
|
_ => write!(f, "({:?})", self),
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,11 +132,11 @@ impl Core {
|
||||||
insn.rs()
|
insn.rs()
|
||||||
};
|
};
|
||||||
let arm_alu_op: ArmOpCode = insn.format5_op().into();
|
let arm_alu_op: ArmOpCode = insn.format5_op().into();
|
||||||
let op1 = self.gpr[dst_reg] as i32;
|
let op1 = self.get_reg(dst_reg) as i32;
|
||||||
let op2 = self.gpr[src_reg] as i32;
|
let op2 = self.get_reg(src_reg) as i32;
|
||||||
let result = self.alu(arm_alu_op, op1, op2, true);
|
let result = self.alu(arm_alu_op, op1, op2, true);
|
||||||
if let Some(result) = result {
|
if let Some(result) = result {
|
||||||
self.gpr[dst_reg] = result as u32;
|
self.set_reg(dst_reg, result as u32);
|
||||||
}
|
}
|
||||||
Ok(CpuPipelineAction::IncPC)
|
Ok(CpuPipelineAction::IncPC)
|
||||||
}
|
}
|
||||||
|
@ -269,6 +269,16 @@ impl Core {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn exec_thumb_branch(
|
||||||
|
&mut self,
|
||||||
|
_bus: &mut Bus,
|
||||||
|
insn: ThumbInstruction,
|
||||||
|
) -> CpuExecResult {
|
||||||
|
let offset = ((insn.offset11() << 21) >> 20) as i32;
|
||||||
|
self.pc = (self.pc as i32).wrapping_add(offset) as u32;
|
||||||
|
Ok(CpuPipelineAction::Flush)
|
||||||
|
}
|
||||||
|
|
||||||
fn exec_thumb_branch_long_with_link(
|
fn exec_thumb_branch_long_with_link(
|
||||||
&mut self,
|
&mut self,
|
||||||
_bus: &mut Bus,
|
_bus: &mut Bus,
|
||||||
|
@ -305,6 +315,7 @@ impl Core {
|
||||||
ThumbFormat::AddSp => self.exec_thumb_add_sp(bus, insn),
|
ThumbFormat::AddSp => self.exec_thumb_add_sp(bus, insn),
|
||||||
ThumbFormat::PushPop => self.exec_thumb_push_pop(bus, insn),
|
ThumbFormat::PushPop => self.exec_thumb_push_pop(bus, insn),
|
||||||
ThumbFormat::BranchConditional => self.exec_thumb_branch_with_cond(bus, insn),
|
ThumbFormat::BranchConditional => self.exec_thumb_branch_with_cond(bus, insn),
|
||||||
|
ThumbFormat::Branch => self.exec_thumb_branch(bus, insn),
|
||||||
ThumbFormat::BranchLongWithLink => self.exec_thumb_branch_long_with_link(bus, insn),
|
ThumbFormat::BranchLongWithLink => self.exec_thumb_branch_long_with_link(bus, insn),
|
||||||
_ => unimplemented!("thumb not implemented {:#x?}", insn),
|
_ => unimplemented!("thumb not implemented {:#x?}", insn),
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue