diff options
| author | iximeow <me@iximeow.net> | 2026-08-03 00:25:39 +0000 |
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2026-08-03 00:25:39 +0000 |
| commit | ee19aba4c34f495d29c87b6d2c9d32614ba62cf8 (patch) | |
| tree | 0a8b685c4dfe3328cf3a58e5c83ca32b9a69b8c9 | |
| parent | 1158b671a39d01ce3de822c814d4d3bae3466918 (diff) | |
decode unknown wide hints like any other hints
| -rw-r--r-- | CHANGELOG | 2 | ||||
| -rw-r--r-- | src/armv7.rs | 10 | ||||
| -rw-r--r-- | src/armv7/thumb.rs | 21 | ||||
| -rw-r--r-- | tests/armv7/thumb.rs | 5 |
4 files changed, 36 insertions, 2 deletions
@@ -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() { |
