aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2026-08-03 00:25:39 +0000
committeriximeow <me@iximeow.net>2026-08-03 00:25:39 +0000
commitee19aba4c34f495d29c87b6d2c9d32614ba62cf8 (patch)
tree0a8b685c4dfe3328cf3a58e5c83ca32b9a69b8c9
parent1158b671a39d01ce3de822c814d4d3bae3466918 (diff)
decode unknown wide hints like any other hints
-rw-r--r--CHANGELOG2
-rw-r--r--src/armv7.rs10
-rw-r--r--src/armv7/thumb.rs21
-rw-r--r--tests/armv7/thumb.rs5
4 files changed, 36 insertions, 2 deletions
diff --git a/CHANGELOG b/CHANGELOG
index c534c70..17cfc5b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,6 +17,8 @@
* thumb2: some coprocessor instructions were incorrectly decoded as `ldc*/stc*`
* thumb2: fix missing decode of `s` bit for wide lsl/lsr/asr/ror (register)
* thumb2: rfeia and rfedb were decoded backwards. likewise for srsia and srsdb
+* thumb2: unknown wide hints are decoded as `hint` like other cases in ARM,
+ rather than rejected as invalid
* 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 a67067f..01c1827 100644
--- a/src/armv7.rs
+++ b/src/armv7.rs
@@ -161,6 +161,16 @@ pub enum Opcode {
SEV,
CSDB,
YIELD,
+ /// ARM generally does not have a blanket `hint #123` instruction, but does have a section of
+ /// opcode space reserved for architectural hinting. this is where `nop`, `yield`, `wfe`, etc
+ /// are defined. those "hints" have defined architectural (non-)effects and have their own
+ /// Opcode variants. for the bit patterns not yet defined to a specific hint, the ARM reference
+ /// manual says the execution on historical processors is as if `op2 is set to 0b00000000`
+ /// (that is, `nop`), but that software must not use these unallocated encodings.
+ ///
+ /// so, `hint` exists to describe these "execute-as-nop" instructions which have at least one
+ /// operand describing possible future behavior. instructions that are defined in this space
+ /// are expected to be decoded as distinct opcodes.
HINT,
NOP,
LEAVEX,
diff --git a/src/armv7/thumb.rs b/src/armv7/thumb.rs
index ab3f94b..cba18a4 100644
--- a/src/armv7/thumb.rs
+++ b/src/armv7/thumb.rs
@@ -1808,8 +1808,25 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d
Operand::Nothing,
];
}
- _ => {
- return Err(DecodeError::Undefined);
+ hint => {
+ // from DDI0406 C.d (v7):
+ // > Encodings with op1 set to 0b000 and a value of
+ // > op2 that is not shown in the table are
+ // > unallocated hints, and behave as if op2 is set
+ // > to 0b00000000. These unallocated hint encodings
+ // > are reserved and software must not use them.
+ //
+ // so.. it would be "right" to report these as
+ // "nop", but the hint operand is interesting for
+ // forward compatibility. guess that means we
+ // invent a "hint" instruction too?
+ inst.opcode = Opcode::HINT;
+ inst.operands = [
+ Operand::Imm12(hint as u16),
+ Operand::Nothing,
+ Operand::Nothing,
+ Operand::Nothing,
+ ];
}
}
}
diff --git a/tests/armv7/thumb.rs b/tests/armv7/thumb.rs
index b7b43d3..7fb2d90 100644
--- a/tests/armv7/thumb.rs
+++ b/tests/armv7/thumb.rs
@@ -2590,6 +2590,11 @@ fn test_decode_misc_cases() {
&[0xfe, 0xde],
"udf 0xfe"
);
+
+ test_display(
+ &[0xaf, 0xf3, 0x6e, 0x80],
+ "hint.w 0x6e"
+ );
}
#[test]
fn test_decode_mov_cases() {