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