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