aboutsummaryrefslogtreecommitdiff
path: root/tests/armv7/thumb.rs
diff options
context:
space:
mode:
authorBrandon Ros <brandonros1@gmail.com>2026-07-03 00:14:45 -0400
committeriximeow <me@iximeow.net>2026-07-28 02:53:24 +0000
commit9e9c7b2663fa52881bf6883e74f4cd8610c38570 (patch)
tree9646b1250f2f2bea921a582192932eda40ed3ab0 /tests/armv7/thumb.rs
parenteea7a08447871114c86ad3c42945847336960d2c (diff)
fix more thumb2 register data-processing decode bugs
- register-controlled shifts (lsl/lsr/asr/ror by register) all decoded as lsl: the shift type was read from hw1[6:5] (always 0 for this form) instead of hw0[6:5] - 32-bit uxt*/sxt* extends read the ror amount from the wrong field (hw1[2:1] scaled by 4 instead of hw1[5:4] scaled by 8), so a no-rotation extend came back as ror #4; rotation of 0 is now omitted - sxtab was decoded as sxtah (wrong opcode table entry) all cases verified against binutils objdump
Diffstat (limited to 'tests/armv7/thumb.rs')
-rw-r--r--tests/armv7/thumb.rs78
1 files changed, 78 insertions, 0 deletions
diff --git a/tests/armv7/thumb.rs b/tests/armv7/thumb.rs
index 473f17c..8c1885d 100644
--- a/tests/armv7/thumb.rs
+++ b/tests/armv7/thumb.rs
@@ -4247,3 +4247,81 @@ fn test_decode_mov_reg_shift_cases() {
"rrx r3, r2"
);
}
+
+#[test]
+fn test_decode_ux_sx_32b_cases() {
+ // rotation is hw1[5:4] scaled by 8, and omitted when zero
+ test_display(
+ &[0x1f, 0xfa, 0x8b, 0xfb],
+ "uxth.w fp, fp"
+ );
+ test_display(
+ &[0x5f, 0xfa, 0x8c, 0xfc],
+ "uxtb.w ip, ip"
+ );
+ test_display(
+ &[0x5f, 0xfa, 0x9c, 0xfc],
+ "uxtb.w ip, ip, 0x8"
+ );
+ test_display(
+ &[0x1f, 0xfa, 0xab, 0xfb],
+ "uxth.w fp, fp, 0x10"
+ );
+ test_display(
+ &[0x0f, 0xfa, 0x82, 0xf1],
+ "sxth.w r1, r2"
+ );
+ test_display(
+ &[0x52, 0xfa, 0x93, 0xf1],
+ "uxtab.w r1, r2, r3, 0x8"
+ );
+ test_display(
+ &[0x42, 0xfa, 0x83, 0xf1],
+ "sxtab.w r1, r2, r3"
+ );
+ test_display(
+ &[0x02, 0xfa, 0x83, 0xf1],
+ "sxtah.w r1, r2, r3"
+ );
+}
+
+#[test]
+fn test_decode_ux_sx_b16_32b_cases() {
+ test_display(
+ &[0x2f, 0xfa, 0x82, 0xf1],
+ "sxtb16.w r1, r2"
+ );
+ test_display(
+ &[0x3f, 0xfa, 0x82, 0xf1],
+ "uxtb16.w r1, r2"
+ );
+ test_display(
+ &[0x22, 0xfa, 0x83, 0xf1],
+ "sxtab16.w r1, r2, r3"
+ );
+ test_display(
+ &[0x32, 0xfa, 0x83, 0xf1],
+ "uxtab16.w r1, r2, r3"
+ );
+}
+
+#[test]
+fn test_decode_shift_reg_32b_cases() {
+ // register-controlled shift: type is in hw0[6:5]
+ test_display(
+ &[0x02, 0xfa, 0x03, 0xf1],
+ "lsl.w r1, r2, r3"
+ );
+ test_display(
+ &[0x22, 0xfa, 0x03, 0xf1],
+ "lsr.w r1, r2, r3"
+ );
+ test_display(
+ &[0x42, 0xfa, 0x03, 0xf1],
+ "asr.w r1, r2, r3"
+ );
+ test_display(
+ &[0x62, 0xfa, 0x03, 0xf1],
+ "ror.w r1, r2, r3"
+ );
+}