aboutsummaryrefslogtreecommitdiff
path: root/src/armv7.rs
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-12-06 11:37:19 -0800
committeriximeow <me@iximeow.net>2020-12-06 11:58:57 -0800
commit72109c2385c7b0940072f31fc3bcbeed68006060 (patch)
tree0f35249a5672b2369faf67ca501341f6b65bcaf9 /src/armv7.rs
parentf483afc2654391962a821ae41f4a50b484ad9bae (diff)
fix more incomplete cases, report arm instruction length properly
Diffstat (limited to 'src/armv7.rs')
-rw-r--r--src/armv7.rs27
1 files changed, 25 insertions, 2 deletions
diff --git a/src/armv7.rs b/src/armv7.rs
index 91b65bd..73530fb 100644
--- a/src/armv7.rs
+++ b/src/armv7.rs
@@ -1313,8 +1313,14 @@ pub struct Instruction {
pub condition: ConditionCode,
pub opcode: Opcode,
pub operands: [Operand; 4],
+ /// does this instruction update flags, while variants that do not update flags exist?
pub s: bool,
+ /// is this a 32-bit thumb instruction?
+ pub wide: bool,
+ /// and if it is a 32-bit thumb instruction, should the .w suffix be shown?
pub thumb_w: bool,
+ /// and generally speaking, was this just a thumb-encoded instruction?
+ pub thumb: bool,
}
#[derive(Debug, PartialEq)]
@@ -1363,6 +1369,8 @@ impl Default for Instruction {
operands: [Operand::Nothing, Operand::Nothing, Operand::Nothing, Operand::Nothing],
s: false,
thumb_w: false,
+ wide: false,
+ thumb: false,
}
}
}
@@ -1376,6 +1384,14 @@ impl Instruction {
self.thumb_w = value;
}
pub fn w(&self) -> bool { self.thumb_w }
+ pub(crate) fn set_wide(&mut self, value: bool) {
+ self.wide = value;
+ }
+ pub fn wide(&self) -> bool { self.wide }
+ pub(crate) fn set_thumb(&mut self, value: bool) {
+ self.thumb = value;
+ }
+ pub fn thumb(&self) -> bool { self.thumb }
}
fn format_reg_list<T: fmt::Write, C: fmt::Display, Y: YaxColors<C>>(f: &mut T, mut list: u16, colors: &Y) -> Result<(), fmt::Error> {
@@ -1485,10 +1501,15 @@ impl Display for Instruction {
impl LengthedInstruction for Instruction {
type Unit = AddressDiff<<ARMv7 as Arch>::Address>;
fn min_size() -> Self::Unit {
+ // TODO: this is contingent on the decoder mode...
AddressDiff::from_const(4)
}
fn len(&self) -> Self::Unit {
- AddressDiff::from_const(4)
+ if self.thumb && !self.wide {
+ AddressDiff::from_const(2)
+ } else {
+ AddressDiff::from_const(4)
+ }
}
}
@@ -1777,10 +1798,12 @@ impl Decoder<Instruction> for InstDecoder {
type Error = DecodeError;
fn decode_into<T: IntoIterator<Item=u8>>(&self, inst: &mut Instruction, bytes: T) -> Result<(), Self::Error> {
+ inst.set_w(false);
+ inst.set_wide(false);
if self.thumb {
return thumb::decode_into(&self, inst, bytes);
} else {
- inst.set_w(false);
+ inst.set_thumb(false);
}
fn read_word<T: IntoIterator<Item=u8>>(bytes: T) -> Result<u32, DecodeError> {