Commit 430261acac for qemu.org

commit 430261acacacad33c6a230fd5f7aa526905ae9db
Author: Brian Cain <brian.cain@oss.qualcomm.com>
Date:   Mon Jul 13 18:09:55 2026 -0700

    tests/tcg/hexagon: add unaligned scalar test

    Add unaligned_data.c to exercise unaligned memh/memw/memd accesses and
    verify SIGBUS is raised and caught.

    Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
    Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>

diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target
index 70a8ec2e7f..a2a0ffc69b 100644
--- a/tests/tcg/hexagon/Makefile.target
+++ b/tests/tcg/hexagon/Makefile.target
@@ -54,6 +54,7 @@ HEX_TESTS += invalid-slots
 HEX_TESTS += invalid-encoding
 HEX_TESTS += multiple-writes
 HEX_TESTS += unaligned_pc
+HEX_TESTS += unaligned_data

 HEX_TESTS += test_abs
 HEX_TESTS += test_bitcnt
@@ -108,6 +109,7 @@ preg_alias: preg_alias.c hex_test.h
 read_write_overlap: read_write_overlap.c hex_test.h
 reg_mut: reg_mut.c hex_test.h
 test_pnew_jump_loads: test_pnew_jump_loads.c hex_test.h
+unaligned_data: unaligned_data.c hex_test.h
 unaligned_pc: unaligned_pc.c

 # Compile for v66 so that the ELF selects a v66 CPU; the test then
diff --git a/tests/tcg/hexagon/unaligned_data.c b/tests/tcg/hexagon/unaligned_data.c
new file mode 100644
index 0000000000..e0375faafb
--- /dev/null
+++ b/tests/tcg/hexagon/unaligned_data.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/*
+ * Test that unaligned scalar loads raise SIGBUS.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <setjmp.h>
+#include <signal.h>
+
+int err;
+
+#include "hex_test.h"
+
+static bool sigbus_caught;
+static sigjmp_buf jmp_env;
+static uint64_t buf[2] = { 0, 0 };
+
+static void sigbus_handler(int sig, siginfo_t *info, void *puc)
+{
+    check32(sig, SIGBUS);
+    sigbus_caught = true;
+    siglongjmp(jmp_env, 1);
+}
+
+static void test_unaligned_load(int size, int offset)
+{
+    char *p = (char *)buf + offset;
+    uint32_t dummy32;
+    uint64_t dummy64;
+
+    sigbus_caught = false;
+    if (sigsetjmp(jmp_env, 1) == 0) {
+        switch (size) {
+        case 2:
+            asm volatile("%[dst] = memh(%[src])\n\t"
+                          : [dst] "=r"(dummy32) : [src] "r"(p) : "memory");
+            break;
+        case 4:
+            asm volatile("%[dst] = memw(%[src])\n\t"
+                          : [dst] "=r"(dummy32) : [src] "r"(p) : "memory");
+            break;
+        case 8:
+            asm volatile("%[dst] = memd(%[src])\n\t"
+                          : [dst] "=r"(dummy64) : [src] "r"(p) : "memory");
+            break;
+        default:
+            abort();
+        }
+    }
+    check32(sigbus_caught, true);
+}
+
+static void test_unaligned_store(int size, int offset)
+{
+    char *p = (char *)buf + offset;
+    uint32_t val32 = 0x11223344;
+    uint64_t val64 = 0x1122334455667788ULL;
+
+    sigbus_caught = false;
+    if (sigsetjmp(jmp_env, 1) == 0) {
+        switch (size) {
+        case 2:
+            asm volatile("memh(%[addr]) = %[val]\n\t"
+                          : : [addr] "r"(p), [val] "r"(val32) : "memory");
+            break;
+        case 4:
+            asm volatile("memw(%[addr]) = %[val]\n\t"
+                          : : [addr] "r"(p), [val] "r"(val32) : "memory");
+            break;
+        case 8:
+            asm volatile("memd(%[addr]) = %[val]\n\t"
+                          : : [addr] "r"(p), [val] "r"(val64) : "memory");
+            break;
+        default:
+            abort();
+        }
+    }
+    check32(sigbus_caught, true);
+}
+
+int main()
+{
+    struct sigaction act;
+
+    act.sa_sigaction = sigbus_handler;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_SIGINFO;
+    chk_error(sigaction(SIGBUS, &act, NULL));
+
+    test_unaligned_load(2, 1);
+    test_unaligned_load(4, 1);
+    test_unaligned_load(4, 2);
+    test_unaligned_load(4, 3);
+    test_unaligned_load(8, 1);
+    test_unaligned_load(8, 4);
+
+    test_unaligned_store(2, 1);
+    test_unaligned_store(4, 1);
+    test_unaligned_store(4, 2);
+    test_unaligned_store(4, 3);
+    test_unaligned_store(8, 1);
+    test_unaligned_store(8, 4);
+
+    act.sa_handler = SIG_DFL;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = 0;
+    chk_error(sigaction(SIGBUS, &act, NULL));
+
+    puts(err ? "FAIL" : "PASS");
+    return err ? EXIT_FAILURE : EXIT_SUCCESS;
+}