aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG4
-rw-r--r--src/armv7.rs3
-rw-r--r--src/armv7/display.rs6
-rw-r--r--src/armv7/thumb.rs27
-rw-r--r--tests/armv7/thumb.rs37
5 files changed, 77 insertions, 0 deletions
diff --git a/CHANGELOG b/CHANGELOG
index a580cc9..71aa08a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,10 @@
* the decoder reused the non-thumb encoding table, but thumb opcode/sizes are
encoded in a different order.
* thumb2: `ldrexd` was off by one in looking up an opcode
+* thumb2: `mrs` destinations, which should have been a mask of the current (or
+ saved) program status register, was reported as a banked GPR.
+* ARMv8: support thumb2 encoding of `Test Target` instruction, `Opcode::TT`
+ (formatted as any of `tt`, `ttt`, `tta`, `ttat`)
several fixes from @Grond66:
* ARMv7: support the RRX rotate mode.
diff --git a/src/armv7.rs b/src/armv7.rs
index 54bb998..a67067f 100644
--- a/src/armv7.rs
+++ b/src/armv7.rs
@@ -277,6 +277,9 @@ pub enum Opcode {
LDAEXH,
LDAEX,
LDAEXD,
+
+ /// ARMv8 `Test Target`
+ TT { alternate: bool, unprivileged: bool },
}
static DATA_PROCESSING_OPCODES: [Opcode; 16] = [
diff --git a/src/armv7/display.rs b/src/armv7/display.rs
index 6673fcd..91affeb 100644
--- a/src/armv7/display.rs
+++ b/src/armv7/display.rs
@@ -964,6 +964,7 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for ConditionedOpcode {
Opcode::DSB |
Opcode::CSDB |
Opcode::SRS(_, _) |
+ Opcode::TT { .. } |
Opcode::BKPT => { write!(out, "{}", colors.misc_op(self)) },
Opcode::DBG |
@@ -1262,6 +1263,11 @@ impl Opcode {
Opcode::USUB8 => { "usub8" },
Opcode::UQSUB8 => { "uqsub8" },
Opcode::UHSUB8 => { "uhsub8" },
+
+ Opcode::TT { alternate: false, unprivileged: false } => "tt",
+ Opcode::TT { alternate: true, unprivileged: false } => "tta",
+ Opcode::TT { alternate: false, unprivileged: true } => "ttt",
+ Opcode::TT { alternate: true, unprivileged: true } => "ttat",
}
}
}
diff --git a/src/armv7/thumb.rs b/src/armv7/thumb.rs
index 16d671a..72a2ea6 100644
--- a/src/armv7/thumb.rs
+++ b/src/armv7/thumb.rs
@@ -147,6 +147,33 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d
match op1op2 {
0b0000 => {
// `STREX` (`A8-691`)
+ // v8.something
+
+ // TODO: isa version flags
+ if rt == 15 /* && decoder.armv8 */ {
+ if imm8 & 0b0011_1111 != 0 {
+ if decoder.should_is_must {
+ return Err(DecodeError::Nonconforming);
+ }
+ }
+ let at = imm8 >> 6;
+ inst.opcode = Opcode::TT {
+ alternate: (at >> 1) != 0,
+ unprivileged: (at & 1) != 0,
+ };
+ if rd == 13 || rd == 15 || rn == 15 {
+ decoder.unpredictable()?;
+ }
+ inst.operands = [
+ Operand::Reg(Reg::from_u8(rd)),
+ Operand::Reg(Reg::from_u8(rn)),
+ Operand::Nothing,
+ Operand::Nothing,
+ ];
+
+ return Ok(());
+ }
+
// v6T2
if rd == 13 || rd == 15 || rt == 13 || rt == 15 || rn == 15 {
decoder.unpredictable()?;
diff --git a/tests/armv7/thumb.rs b/tests/armv7/thumb.rs
index 59dafaa..b1b9399 100644
--- a/tests/armv7/thumb.rs
+++ b/tests/armv7/thumb.rs
@@ -4573,6 +4573,43 @@ fn msr_mrs() {
}
#[test]
+fn test_target() {
+ // the v8 manuals list a new Test Target with some variants to it..
+ test_nonconforming(
+ &[0x44, 0xe8, 0x3f, 0xfc],
+ "tt ip, r4"
+ );
+ test_nonconforming(
+ &[0x44, 0xe8, 0x7f, 0xfc],
+ "ttt ip, r4"
+ );
+ test_nonconforming(
+ &[0x44, 0xe8, 0xbf, 0xfc],
+ "tta ip, r4"
+ );
+ test_nonconforming(
+ &[0x4d, 0xe8, 0xff, 0xf8],
+ "ttat r8, sp"
+ );
+ test_display(
+ &[0x44, 0xe8, 0x00, 0xfc],
+ "tt ip, r4"
+ );
+ test_display(
+ &[0x44, 0xe8, 0x40, 0xfc],
+ "ttt ip, r4"
+ );
+ test_display(
+ &[0x44, 0xe8, 0x80, 0xfc],
+ "tta ip, r4"
+ );
+ test_display(
+ &[0x4d, 0xe8, 0xc0, 0xf8],
+ "ttat r8, sp"
+ );
+}
+
+#[test]
fn test_decode_tbh_operand_shape() {
use yaxpeax_arm::armv7::{Opcode, Operand, RegShiftStyle, ShiftStyle};