From bc4ffbe7a8ffe1bfbf2e0785c561a339bfa25321 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 2 Aug 2026 19:23:45 +0000 Subject: Test Target, fix bogus MRS destinations --- CHANGELOG | 4 ++++ src/armv7.rs | 3 +++ src/armv7/display.rs | 6 ++++++ src/armv7/thumb.rs | 27 +++++++++++++++++++++++++++ tests/armv7/thumb.rs | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 77 insertions(+) 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 Colorize 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::Address, ::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}; -- cgit v1.1