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