Impl Thumb LdrStrImmOffset

Former-commit-id: 17d6f4ae1cb5f68b9fccf35536a6346e88326e77
This commit is contained in:
Michel Heily 2019-07-06 15:51:58 +03:00
parent 600bebc9d2
commit d1ef35646f
3 changed files with 60 additions and 8 deletions

View file

@ -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),

View file

@ -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),

View file

@ -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)
}