1 #include <stdio.h>
2 #include <signal.h>
3 #include <setjmp.h>
4 #include <stdlib.h>
5
6 /* will be changed in signal handler */
7 volatile sig_atomic_t completed_tests;
8 static jmp_buf after_test;
9 static int nr_tests;
10
test_return(void)11 void __attribute__((naked)) test_return(void)
12 {
13 asm volatile(
14 "allocframe(#0x8)\n"
15 "r0 = #0xffffffff\n"
16 "framekey = r0\n"
17 "dealloc_return\n"
18 :
19 :
20 : "r0", "r29", "r30", "r31", "framekey");
21 }
22
test_endloop(void)23 void test_endloop(void)
24 {
25 asm volatile(
26 "loop0(1f, #2)\n"
27 "1: r0 = #0x3\n"
28 "sa0 = r0\n"
29 "{ nop }:endloop0\n"
30 :
31 :
32 : "r0", "sa0", "lc0", "usr");
33 }
34
35 asm(
36 ".pushsection .text.unaligned\n"
37 ".org 0x3\n"
38 ".global test_multi_cof_unaligned\n"
39 "test_multi_cof_unaligned:\n"
40 " jumpr r31\n"
41 ".popsection\n"
42 );
43
44 #define SYS_EXIT 94
45
test_multi_cof(void)46 void test_multi_cof(void)
47 {
48 asm volatile(
49 "p0 = cmp.eq(r0, r0)\n"
50 "{\n"
51 " if (p0) jump test_multi_cof_unaligned\n"
52 " if (!p0) jump 1f\n"
53 "}\n"
54 "1:"
55 " r0 = #1\n"
56 " r6 = #%0\n"
57 " trap0(#1)\n"
58 :
59 : "i"(SYS_EXIT)
60 : "p0", "r0", "r6");
61 }
62
sigbus_handler(int signum)63 void sigbus_handler(int signum)
64 {
65 /* retore framekey after test_return */
66 asm volatile(
67 "r0 = #0\n"
68 "framekey = r0\n"
69 :
70 :
71 : "r0", "framekey");
72 printf("Test %d complete\n", completed_tests);
73 completed_tests++;
74 siglongjmp(after_test, 1);
75 }
76
test_done(void)77 void test_done(void)
78 {
79 int err = (completed_tests != nr_tests);
80 puts(err ? "FAIL" : "PASS");
81 exit(err);
82 }
83
84 typedef void (*test_fn)(void);
85
main()86 int main()
87 {
88 test_fn tests[] = { test_return, test_endloop, test_multi_cof, test_done };
89 nr_tests = (sizeof(tests) / sizeof(tests[0])) - 1;
90
91 struct sigaction sa = {
92 .sa_sigaction = sigbus_handler,
93 .sa_flags = SA_SIGINFO
94 };
95
96 if (sigaction(SIGBUS, &sa, NULL) < 0) {
97 perror("sigaction");
98 return EXIT_FAILURE;
99 }
100
101 sigsetjmp(after_test, 1);
102 tests[completed_tests]();
103
104 /* should never get here */
105 puts("FAIL");
106 return 1;
107 }
108