aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2026-08-02 19:35:19 +0000
committeriximeow <me@iximeow.net>2026-08-02 19:35:19 +0000
commit345eacf8f1dc29cb4cd836e3d585d30497e7ea72 (patch)
treee6f1424a12ec12d59ff8ed2bcd6ef676da05bbf5
parentbc4ffbe7a8ffe1bfbf2e0785c561a339bfa25321 (diff)
pkhbt/pkhtb bitmask confusion
-rw-r--r--CHANGELOG1
-rw-r--r--src/armv7/thumb.rs2
-rw-r--r--tests/armv7/thumb.rs12
3 files changed, 14 insertions, 1 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 71aa08a..b552484 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,7 @@
* 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: pkhtb/pkhbt distinction was off by one bit
* 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`
diff --git a/src/armv7/thumb.rs b/src/armv7/thumb.rs
index 72a2ea6..439c3a6 100644
--- a/src/armv7/thumb.rs
+++ b/src/armv7/thumb.rs
@@ -1013,7 +1013,7 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d
// TODO: fix shift
// TODO: check opcode
inst.s = false;
- inst.opcode = if lower & 0b10000 != 0 {
+ inst.opcode = if lower & 0b100000 != 0 {
Opcode::PKHTB
} else {
Opcode::PKHBT
diff --git a/tests/armv7/thumb.rs b/tests/armv7/thumb.rs
index b1b9399..e6e1bfb 100644
--- a/tests/armv7/thumb.rs
+++ b/tests/armv7/thumb.rs
@@ -4573,6 +4573,18 @@ fn msr_mrs() {
}
#[test]
+fn pkh() {
+ test_display(
+ &[0xc7, 0xea, 0xe8, 0x77],
+ "pkhtb.w r7, r7, r8, asr 31"
+ );
+ test_display(
+ &[0xc7, 0xea, 0xc8, 0x77],
+ "pkhbt.w r7, r7, r8, lsl 31"
+ );
+}
+
+#[test]
fn test_target() {
// the v8 manuals list a new Test Target with some variants to it..
test_nonconforming(