Impl Thumb LdrStrImmOffset
Former-commit-id: 17d6f4ae1cb5f68b9fccf35536a6346e88326e77
This commit is contained in:
parent
600bebc9d2
commit
d1ef35646f
|
@ -86,13 +86,40 @@ impl ThumbInstruction {
|
|||
f,
|
||||
"{op}{b}\t{Rd}, [{Rb}, {Ro}]",
|
||||
op = if self.is_load() { "ldr" } else { "str" },
|
||||
b = if self.is_transfering_bytes() { "b" } else { "" },
|
||||
b = if self.is_transferring_bytes() {
|
||||
"b"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
Rd = reg_string(self.rd()),
|
||||
Rb = reg_string(self.rb()),
|
||||
Ro = reg_string(self.ro()),
|
||||
)
|
||||
}
|
||||
|
||||
fn fmt_thumb_ldr_str_imm_offset(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{op}{b}\t{Rd}, [{Rb}, #{imm:#x}]",
|
||||
op = if self.is_load() { "ldr" } else { "str" },
|
||||
b = if self.is_transferring_bytes() {
|
||||
"b"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
Rd = reg_string(self.rd()),
|
||||
Rb = reg_string(self.rb()),
|
||||
imm = {
|
||||
let offset5 = self.offset5();
|
||||
if self.is_transferring_bytes() {
|
||||
offset5
|
||||
} else {
|
||||
(offset5 << 3) >> 1
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn fmt_thumb_ldr_str_halfword(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
|
@ -204,6 +231,7 @@ impl fmt::Display for ThumbInstruction {
|
|||
ThumbFormat::HiRegOpOrBranchExchange => self.fmt_thumb_high_reg_op_or_bx(f),
|
||||
ThumbFormat::LdrPc => self.fmt_thumb_ldr_pc(f),
|
||||
ThumbFormat::LdrStrRegOffset => self.fmt_thumb_ldr_str_reg_offset(f),
|
||||
ThumbFormat::LdrStrImmOffset => self.fmt_thumb_ldr_str_imm_offset(f),
|
||||
ThumbFormat::LdrStrHalfWord => self.fmt_thumb_ldr_str_halfword(f),
|
||||
ThumbFormat::LdrStrSp => self.fmt_thumb_ldr_str_sp(f),
|
||||
ThumbFormat::AddSp => self.fmt_thumb_add_sp(f),
|
||||
|
|
|
@ -153,16 +153,14 @@ impl Core {
|
|||
Ok(CpuPipelineAction::IncPC)
|
||||
}
|
||||
|
||||
fn exec_thumb_ldr_str_reg_offset(
|
||||
fn do_exec_thumb_ldr_str(
|
||||
&mut self,
|
||||
bus: &mut Bus,
|
||||
insn: ThumbInstruction,
|
||||
addr: Addr,
|
||||
) -> CpuExecResult {
|
||||
let addr = self
|
||||
.get_reg(insn.rb())
|
||||
.wrapping_add(self.get_reg(insn.ro()));
|
||||
if insn.is_load() {
|
||||
let data = if insn.is_transfering_bytes() {
|
||||
let data = if insn.is_transferring_bytes() {
|
||||
self.load_8(addr, bus) as u32
|
||||
} else {
|
||||
self.load_32(addr, bus)
|
||||
|
@ -174,7 +172,7 @@ impl Core {
|
|||
self.add_cycle();
|
||||
} else {
|
||||
let value = self.get_reg(insn.rd());
|
||||
if insn.is_transfering_bytes() {
|
||||
if insn.is_transferring_bytes() {
|
||||
self.store_8(addr, value as u8, bus);
|
||||
} else {
|
||||
self.store_32(addr, value, bus);
|
||||
|
@ -184,6 +182,31 @@ impl Core {
|
|||
Ok(CpuPipelineAction::IncPC)
|
||||
}
|
||||
|
||||
fn exec_thumb_ldr_str_reg_offset(
|
||||
&mut self,
|
||||
bus: &mut Bus,
|
||||
insn: ThumbInstruction,
|
||||
) -> CpuExecResult {
|
||||
let addr = self
|
||||
.get_reg(insn.rb())
|
||||
.wrapping_add(self.get_reg(insn.ro()));
|
||||
self.do_exec_thumb_ldr_str(bus, insn, addr)
|
||||
}
|
||||
|
||||
fn exec_thumb_ldr_str_imm_offset(
|
||||
&mut self,
|
||||
bus: &mut Bus,
|
||||
insn: ThumbInstruction,
|
||||
) -> CpuExecResult {
|
||||
let offset = if insn.is_transferring_bytes() {
|
||||
insn.offset5()
|
||||
} else {
|
||||
(insn.offset5() << 3) >> 1
|
||||
};
|
||||
let addr = self.get_reg(insn.rb()).wrapping_add(offset as u32);
|
||||
self.do_exec_thumb_ldr_str(bus, insn, addr)
|
||||
}
|
||||
|
||||
fn exec_thumb_ldr_str_halfword(
|
||||
&mut self,
|
||||
bus: &mut Bus,
|
||||
|
@ -306,6 +329,7 @@ impl Core {
|
|||
ThumbFormat::HiRegOpOrBranchExchange => self.exec_thumb_hi_reg_op_or_bx(bus, insn),
|
||||
ThumbFormat::LdrPc => self.exec_thumb_ldr_pc(bus, insn),
|
||||
ThumbFormat::LdrStrRegOffset => self.exec_thumb_ldr_str_reg_offset(bus, insn),
|
||||
ThumbFormat::LdrStrImmOffset => self.exec_thumb_ldr_str_imm_offset(bus, insn),
|
||||
ThumbFormat::LdrStrHalfWord => self.exec_thumb_ldr_str_halfword(bus, insn),
|
||||
ThumbFormat::LdrStrSp => self.exec_thumb_ldr_str_sp(bus, insn),
|
||||
ThumbFormat::AddSp => self.exec_thumb_add_sp(bus, insn),
|
||||
|
|
|
@ -261,7 +261,7 @@ impl ThumbInstruction {
|
|||
self.raw.bit_range(0..8) << 2
|
||||
}
|
||||
|
||||
pub fn is_transfering_bytes(&self) -> bool {
|
||||
pub fn is_transferring_bytes(&self) -> bool {
|
||||
self.raw.bit(10)
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue