1 /* Verify that unwinding can find SPE registers in signal frames. */
2 /* Origin: Joseph Myers <joseph@codesourcery.com> */
3 /* { dg-do run { target { powerpc*-*-linux* && powerpc_spe } } } */
4 /* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */
5
6 #include <unwind.h>
7 #include <stdlib.h>
8 #include <signal.h>
9 #include <string.h>
10
11 int count;
12 char *null;
13 int found_reg;
14
15 typedef int v2si __attribute__((__vector_size__(8)));
16
17 v2si v1 = { 123, 234 };
18 v2si v2 = { 345, 456 };
19
20 static _Unwind_Reason_Code
force_unwind_stop(int version,_Unwind_Action actions,_Unwind_Exception_Class exc_class,struct _Unwind_Exception * exc_obj,struct _Unwind_Context * context,void * stop_parameter)21 force_unwind_stop (int version, _Unwind_Action actions,
22 _Unwind_Exception_Class exc_class,
23 struct _Unwind_Exception *exc_obj,
24 struct _Unwind_Context *context,
25 void *stop_parameter)
26 {
27 unsigned int reg;
28 if (actions & _UA_END_OF_STACK)
29 abort ();
30 if (_Unwind_GetGR (context, 1215) == 123)
31 found_reg = 1;
32 return _URC_NO_REASON;
33 }
34
force_unwind()35 static void force_unwind ()
36 {
37 struct _Unwind_Exception *exc = malloc (sizeof (*exc));
38 memset (&exc->exception_class, 0, sizeof (exc->exception_class));
39 exc->exception_cleanup = 0;
40
41 #ifndef __USING_SJLJ_EXCEPTIONS__
42 _Unwind_ForcedUnwind (exc, force_unwind_stop, 0);
43 #else
44 _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0);
45 #endif
46
47 abort ();
48 }
49
counter(void * p)50 static void counter (void *p __attribute__((unused)))
51 {
52 ++count;
53 }
54
handler(void * p)55 static void handler (void *p __attribute__((unused)))
56 {
57 if (count != 2)
58 abort ();
59 if (!found_reg)
60 abort ();
61 exit (0);
62 }
63
fn5()64 static int __attribute__((noinline)) fn5 ()
65 {
66 char dummy __attribute__((cleanup (counter)));
67 force_unwind ();
68 return 0;
69 }
70
fn4(int sig)71 static void fn4 (int sig)
72 {
73 char dummy __attribute__((cleanup (counter)));
74 /* Clobber high part without compiler's knowledge so the only saved
75 copy is from the signal frame. */
76 asm volatile ("evmergelo 15,15,15");
77 fn5 ();
78 null = NULL;
79 }
80
fn3()81 static void fn3 ()
82 {
83 abort ();
84 }
85
fn2()86 static int __attribute__((noinline)) fn2 ()
87 {
88 register v2si r15 asm("r15");
89 r15 = v1;
90 asm volatile ("" : "+r" (r15));
91 *null = 0;
92 fn3 ();
93 return 0;
94 }
95
fn1()96 static int __attribute__((noinline)) fn1 ()
97 {
98 signal (SIGSEGV, fn4);
99 signal (SIGBUS, fn4);
100 fn2 ();
101 return 0;
102 }
103
fn0()104 static int __attribute__((noinline)) fn0 ()
105 {
106 char dummy __attribute__((cleanup (handler)));
107 fn1 ();
108 null = 0;
109 return 0;
110 }
111
main()112 int main()
113 {
114 fn0 ();
115 abort ();
116 }
117