aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG2
-rw-r--r--src/armv7.rs6
-rw-r--r--src/armv7/display.rs10
-rw-r--r--src/armv7/thumb.rs4
-rw-r--r--tests/armv7/thumb.rs10
5 files changed, 27 insertions, 5 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 7b35eaa..61e29c0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -25,6 +25,8 @@
* thumb2: support ARMv8 hints PACBTI, BTI, ESB, PAC, and AUT
* thumb2: fix `mrc`, `mrc2` use of register number "15", which means apsr_nzcv,
rather than pc
+* thumb2: several instructions which decode an explicit rotate operand now do so
+ into a distinct Operand::Ror (sxth, uxth, stxb16, utxb16, sxtb, uxtb)
* ARMv8: support thumb2 encoding of `Test Target` instruction, `Opcode::TT`
(formatted as any of `tt`, `ttt`, `tta`, `ttat`)
* ARMv8: formerly-coprocessor instructions have been defined into SIMD extensions,
diff --git a/src/armv7.rs b/src/armv7.rs
index 87b44f5..30a8960 100644
--- a/src/armv7.rs
+++ b/src/armv7.rs
@@ -775,6 +775,10 @@ pub enum Operand {
BankedSPSR(Bank),
/// a mask of bits for the `spsr` register.
StatusRegMask(StatusRegMask),
+ /// a standalone rotate right by the specified amount.
+ ///
+ /// this typically applies equally to multiple operands; see `sxtah`, `uxtah`, etc.
+ Ror(u8),
/// the `apsr` register.
APSR,
/// the `spsr` register.
@@ -846,6 +850,8 @@ pub trait OperandVisitor {
fn visit_banked_spsr(&mut self, bank: Bank) -> Result<Self::Ok, Self::Error>;
/// process an operand that is some set of bits out of a status register.
fn visit_status_reg_mask(&mut self, mask: StatusRegMask) -> Result<Self::Ok, Self::Error>;
+ /// process an operand that is a standalone rotate of other operands in the instruction.
+ fn visit_rotate(&mut self, amt: u8) -> Result<Self::Ok, Self::Error>;
/// process an operand that is `APSR`.
fn visit_apsr(&mut self) -> Result<Self::Ok, Self::Error>;
/// process an operand that is `SPSR`.
diff --git a/src/armv7/display.rs b/src/armv7/display.rs
index 1398ce6..2d2a77c 100644
--- a/src/armv7/display.rs
+++ b/src/armv7/display.rs
@@ -357,6 +357,13 @@ impl<T: DisplaySink> crate::armv7::OperandVisitor for DisplayingOperandVisitor<'
Ok(())
}
+ fn visit_rotate(&mut self, amt: u8) -> Result<Self::Ok, Self::Error> {
+ self.emit_shift_type(ShiftStyle::ROR)?;
+ self.f.write_char(' ')?;
+ self.f.write_prefixed_u16(amt as u16)?;
+ Ok(())
+ }
+
fn visit_apsr(&mut self) -> Result<Self::Ok, Self::Error> {
self.f.span_start_register();
self.f.write_fixed_size("apsr")?;
@@ -1437,6 +1444,9 @@ impl super::Operand {
Operand::StatusRegMask(mask) => {
visitor.visit_status_reg_mask(mask)
}
+ Operand::Ror(amt) => {
+ visitor.visit_rotate(amt)
+ }
Operand::APSR => {
visitor.visit_apsr()
},
diff --git a/src/armv7/thumb.rs b/src/armv7/thumb.rs
index 4340e95..1d9d96a 100644
--- a/src/armv7/thumb.rs
+++ b/src/armv7/thumb.rs
@@ -2860,7 +2860,7 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d
Operand::Reg(Reg::from_u8(rd)),
Operand::Reg(Reg::from_u8(rm)),
if rotate != 0 {
- Operand::Imm32(rotate as u32)
+ Operand::Ror(rotate as u8)
} else {
Operand::Nothing
},
@@ -2886,7 +2886,7 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d
Operand::Reg(Reg::from_u8(rn)),
Operand::Reg(Reg::from_u8(rm)),
if rotate != 0 {
- Operand::Imm32(rotate as u32)
+ Operand::Ror(rotate as u8)
} else {
Operand::Nothing
},
diff --git a/tests/armv7/thumb.rs b/tests/armv7/thumb.rs
index 1278bd6..f03b046 100644
--- a/tests/armv7/thumb.rs
+++ b/tests/armv7/thumb.rs
@@ -4526,11 +4526,11 @@ fn test_decode_ux_sx_32b_cases() {
);
test_display(
&[0x5f, 0xfa, 0x9c, 0xfc],
- "uxtb.w ip, ip, 0x8"
+ "uxtb.w ip, ip, ror 0x8"
);
test_display(
&[0x1f, 0xfa, 0xab, 0xfb],
- "uxth.w fp, fp, 0x10"
+ "uxth.w fp, fp, ror 0x10"
);
test_display(
&[0x0f, 0xfa, 0x82, 0xf1],
@@ -4538,13 +4538,17 @@ fn test_decode_ux_sx_32b_cases() {
);
test_display(
&[0x52, 0xfa, 0x93, 0xf1],
- "uxtab.w r1, r2, r3, 0x8"
+ "uxtab.w r1, r2, r3, ror 0x8"
);
test_display(
&[0x42, 0xfa, 0x83, 0xf1],
"sxtab.w r1, r2, r3"
);
test_display(
+ &[0x2f, 0xfa, 0xfb, 0xf9],
+ "sxtb16.w sb, fp, ror 0x18"
+ );
+ test_display(
&[0x02, 0xfa, 0x83, 0xf1],
"sxtah.w r1, r2, r3"
);