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 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 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 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 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 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 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