diff options
| author | Grond <grond@grondhaus.net> | 2026-06-24 14:58:13 -0700 |
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2026-07-28 02:53:24 +0000 |
| commit | 0b4ce1210eb90aa370d286390c8566f2bee133bd (patch) | |
| tree | f4431708e688ebf81e7a726560c6f329886c5186 | |
| parent | 485aaac0f82e6b5546ae392b6be626c4558cc26a (diff) | |
Do not add an 's' when outputing opcodes that always set flags
| -rw-r--r-- | src/armv7/display.rs | 12 | ||||
| -rw-r--r-- | tests/armv7/mod.rs | 32 |
2 files changed, 27 insertions, 17 deletions
diff --git a/src/armv7/display.rs b/src/armv7/display.rs index 29d3ed6..0e909f6 100644 --- a/src/armv7/display.rs +++ b/src/armv7/display.rs @@ -55,8 +55,18 @@ impl Instruction { unsafe { f.write_lt_8(opc.name())?; } + // test/compare instructions always set flags and are consequently encoded with bit 20 set + // as most other instructions that sets flags are. because these instructions + // unconditionally set flags, though, their mnemonic skips the `s` suffix. if self.s() { - f.write_char('s')?; + let always_sets_flags = + *opc == Opcode::CMP || + *opc == Opcode::CMN || + *opc == Opcode::TST || + *opc == Opcode::TEQ; + if !always_sets_flags { + f.write_char('s')?; + } } if self.w() { f.write_fixed_size(".w")?; diff --git a/tests/armv7/mod.rs b/tests/armv7/mod.rs index 310b3f7..cebd9ba 100644 --- a/tests/armv7/mod.rs +++ b/tests/armv7/mod.rs @@ -732,34 +732,34 @@ fn test_decode_mrc2() { #[test] fn test_cmp_immediate_decode() { - test_all([0xaf, 0x00, 0x56, 0xe3], "cmps r6, 0xaf"); - test_all([0xaf, 0x00, 0x76, 0xe3], "cmns r6, 0xaf"); + test_all([0xaf, 0x00, 0x56, 0xe3], "cmp r6, 0xaf"); + test_all([0xaf, 0x00, 0x76, 0xe3], "cmn r6, 0xaf"); } #[test] fn test_cmp_register_decode() { - test_all([0x01, 0x00, 0x52, 0xe1], "cmps r2, r1"); - test_all([0x01, 0x03, 0x52, 0xe1], "cmps r2, r1, lsl 6"); - test_all([0x11, 0x03, 0x52, 0xe1], "cmps r2, r1, lsl r3"); - test_all([0x01, 0x00, 0x72, 0xe1], "cmns r2, r1"); - test_all([0x01, 0x03, 0x72, 0xe1], "cmns r2, r1, lsl 6"); - test_all([0x11, 0x03, 0x72, 0xe1], "cmns r2, r1, lsl r3"); + test_all([0x01, 0x00, 0x52, 0xe1], "cmp r2, r1"); + test_all([0x01, 0x03, 0x52, 0xe1], "cmp r2, r1, lsl 6"); + test_all([0x11, 0x03, 0x52, 0xe1], "cmp r2, r1, lsl r3"); + test_all([0x01, 0x00, 0x72, 0xe1], "cmn r2, r1"); + test_all([0x01, 0x03, 0x72, 0xe1], "cmn r2, r1, lsl 6"); + test_all([0x11, 0x03, 0x72, 0xe1], "cmn r2, r1, lsl r3"); } #[test] fn test_tst_immediate_decode() { - test_all([0xe6, 0x00, 0x18, 0xe3], "tsts r8, 0xe6"); - test_all([0xe6, 0x00, 0x38, 0xe3], "teqs r8, 0xe6"); + test_all([0xe6, 0x00, 0x18, 0xe3], "tst r8, 0xe6"); + test_all([0xe6, 0x00, 0x38, 0xe3], "teq r8, 0xe6"); } #[test] fn test_tst_register_decode() { - test_all([0x01, 0x00, 0x12, 0xe1], "tsts r2, r1"); - test_all([0x01, 0x03, 0x12, 0xe1], "tsts r2, r1, lsl 6"); - test_all([0x11, 0x03, 0x12, 0xe1], "tsts r2, r1, lsl r3"); - test_all([0x01, 0x00, 0x32, 0xe1], "teqs r2, r1"); - test_all([0x01, 0x03, 0x32, 0xe1], "teqs r2, r1, lsl 6"); - test_all([0x11, 0x03, 0x32, 0xe1], "teqs r2, r1, lsl r3"); + test_all([0x01, 0x00, 0x12, 0xe1], "tst r2, r1"); + test_all([0x01, 0x03, 0x12, 0xe1], "tst r2, r1, lsl 6"); + test_all([0x11, 0x03, 0x12, 0xe1], "tst r2, r1, lsl r3"); + test_all([0x01, 0x00, 0x32, 0xe1], "teq r2, r1"); + test_all([0x01, 0x03, 0x32, 0xe1], "teq r2, r1, lsl 6"); + test_all([0x11, 0x03, 0x32, 0xe1], "teq r2, r1, lsl r3"); } static INSTRUCTION_BYTES: [u8; 4 * 60] = [ |
