aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrond <grond@grondhaus.net>2026-06-24 18:58:33 -0700
committeriximeow <me@iximeow.net>2026-07-28 02:53:24 +0000
commit485aaac0f82e6b5546ae392b6be626c4558cc26a (patch)
tree24f0717953d8b8db7c892d88727f5b60c9ce5a02
parent88db0bb355e14ba58658026df7708e62696978b2 (diff)
Decode the correct number of operands for TST/TEQ (immediate/register)
-rw-r--r--CHANGELOG4
-rw-r--r--src/armv7.rs3
-rw-r--r--tests/armv7/mod.rs16
3 files changed, 22 insertions, 1 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 1bb05d3..2c08422 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -18,7 +18,9 @@ several fixes from @Grond66:
decoded as CDP, MCR, or MRC when the bit pattern is actually undefined.
* ARMv7: fix inverted reserved bit test for some ldr*/str* (immediate) forms.
* ARMv7: fix several issues with data processing instructions:
- * CMP/CMN decoded "three operands" when they only have two.
+ * CMP/CMN decoded "three operands" in some cases when they only have two.
+ * TST/TEQ decoded "three operands" in some cases when they only have two.
+* ARMv7: do not print the "s" suffix for instructions that unconditionally set flags.
thank you for the patches!
diff --git a/src/armv7.rs b/src/armv7.rs
index f23d0c9..c2c232b 100644
--- a/src/armv7.rs
+++ b/src/armv7.rs
@@ -2606,6 +2606,7 @@ impl Decoder<ARMv7> for InstDecoder {
];
}
+ Opcode::TST | Opcode::TEQ |
Opcode::CMP | Opcode::CMN => {
if self.should_is_must {
if Rd != 0 {
@@ -2731,6 +2732,8 @@ impl Decoder<ARMv7> for InstDecoder {
inst.opcode = Opcode::ADR;
}
match opcode {
+ // TST/TEQ (immediate)
+ 0b1000 | 0b1001 |
// CMP/CMN (immediate)
0b1010 | 0b1011 => {
// According to A8-368, there are 4 bits right above the immediate that
diff --git a/tests/armv7/mod.rs b/tests/armv7/mod.rs
index 78d725b..310b3f7 100644
--- a/tests/armv7/mod.rs
+++ b/tests/armv7/mod.rs
@@ -746,6 +746,22 @@ fn test_cmp_register_decode() {
test_all([0x11, 0x03, 0x72, 0xe1], "cmns 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]
+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");
+}
+
static INSTRUCTION_BYTES: [u8; 4 * 60] = [
0x24, 0xc0, 0x9f, 0xe5,
0x00, 0xb0, 0xa0, 0xe3,