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>
Brian Cain committed
Jul 13, 2026 at 18:09 UTC
430261acacacad33c6a230fd5f7aa526905ae9db
2 files changed
+120
tests/tcg/hexagon/Makefile.target
+2
@@ -54,6 +54,7 @@ HEX_TESTS += invalid-slots
54
HEX_TESTS += invalid-encoding
55
HEX_TESTS += multiple-writes
56
HEX_TESTS += unaligned_pc
57
+HEX_TESTS += unaligned_data
58
59
HEX_TESTS += test_abs
60
HEX_TESTS += test_bitcnt
@@ -108,6 +109,7 @@ preg_alias: preg_alias.c hex_test.h
109
read_write_overlap: read_write_overlap.c hex_test.h
110
reg_mut: reg_mut.c hex_test.h
111
test_pnew_jump_loads: test_pnew_jump_loads.c hex_test.h
112
+unaligned_data: unaligned_data.c hex_test.h
113
unaligned_pc: unaligned_pc.c
114
115
# Compile for v66 so that the ELF selects a v66 CPU; the test then
tests/tcg/hexagon/unaligned_data.c
new
+118
@@ -0,0 +1,118 @@
1
+/*
2
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
3
+ * SPDX-License-Identifier: GPL-2.0-or-later
4
+ */
5
+
6
+/*
7
+ * Test that unaligned scalar loads raise SIGBUS.
8
+ */
9
+
10
+#include <stdlib.h>
11
+#include <stdio.h>
12
+#include <stdint.h>
13
+#include <stdbool.h>
14
+#include <setjmp.h>
15
+#include <signal.h>
16
+
17
+int err;
18
+
19
+#include "hex_test.h"
20
+
21
+static bool sigbus_caught;
22
+static sigjmp_buf jmp_env;
23
+static uint64_t buf[2] = { 0, 0 };
24
+
25
+static void sigbus_handler(int sig, siginfo_t *info, void *puc)
26
+{
27
+ check32(sig, SIGBUS);
28
+ sigbus_caught = true;
29
+ siglongjmp(jmp_env, 1);
30
+}
31
+
32
+static void test_unaligned_load(int size, int offset)
33
+{
34
+ char *p = (char *)buf + offset;
35
+ uint32_t dummy32;
36
+ uint64_t dummy64;
37
+
38
+ sigbus_caught = false;
39
+ if (sigsetjmp(jmp_env, 1) == 0) {
40
+ switch (size) {
41
+ case 2:
42
+ asm volatile("%[dst] = memh(%[src])\n\t"
43
+ : [dst] "=r"(dummy32) : [src] "r"(p) : "memory");
44
+ break;
45
+ case 4:
46
+ asm volatile("%[dst] = memw(%[src])\n\t"
47
+ : [dst] "=r"(dummy32) : [src] "r"(p) : "memory");
48
+ break;
49
+ case 8:
50
+ asm volatile("%[dst] = memd(%[src])\n\t"
51
+ : [dst] "=r"(dummy64) : [src] "r"(p) : "memory");
52
+ break;
53
+ default:
54
+ abort();
55
+ }
56
+ }
57
+ check32(sigbus_caught, true);
58
+}
59
+
60
+static void test_unaligned_store(int size, int offset)
61
+{
62
+ char *p = (char *)buf + offset;
63
+ uint32_t val32 = 0x11223344;
64
+ uint64_t val64 = 0x1122334455667788ULL;
65
+
66
+ sigbus_caught = false;
67
+ if (sigsetjmp(jmp_env, 1) == 0) {
68
+ switch (size) {
69
+ case 2:
70
+ asm volatile("memh(%[addr]) = %[val]\n\t"
71
+ : : [addr] "r"(p), [val] "r"(val32) : "memory");
72
+ break;
73
+ case 4:
74
+ asm volatile("memw(%[addr]) = %[val]\n\t"
75
+ : : [addr] "r"(p), [val] "r"(val32) : "memory");
76
+ break;
77
+ case 8:
78
+ asm volatile("memd(%[addr]) = %[val]\n\t"
79
+ : : [addr] "r"(p), [val] "r"(val64) : "memory");
80
+ break;
81
+ default:
82
+ abort();
83
+ }
84
+ }
85
+ check32(sigbus_caught, true);
86
+}
87
+
88
+int main()
89
+{
90
+ struct sigaction act;
91
+
92
+ act.sa_sigaction = sigbus_handler;
93
+ sigemptyset(&act.sa_mask);
94
+ act.sa_flags = SA_SIGINFO;
95
+ chk_error(sigaction(SIGBUS, &act, NULL));
96
+
97
+ test_unaligned_load(2, 1);
98
+ test_unaligned_load(4, 1);
99
+ test_unaligned_load(4, 2);
100
+ test_unaligned_load(4, 3);
101
+ test_unaligned_load(8, 1);
102
+ test_unaligned_load(8, 4);
103
+
104
+ test_unaligned_store(2, 1);
105
+ test_unaligned_store(4, 1);
106
+ test_unaligned_store(4, 2);
107
+ test_unaligned_store(4, 3);
108
+ test_unaligned_store(8, 1);
109
+ test_unaligned_store(8, 4);
110
+
111
+ act.sa_handler = SIG_DFL;
112
+ sigemptyset(&act.sa_mask);
113
+ act.sa_flags = 0;
114
+ chk_error(sigaction(SIGBUS, &act, NULL));
115
+
116
+ puts(err ? "FAIL" : "PASS");
117
+ return err ? EXIT_FAILURE : EXIT_SUCCESS;
118
+}