OSDN Git Service

2007-05-22 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.target / i386 / cleanup-2.c
1 /* { dg-do run { target { { i?86-*-linux* x86_64-*-linux* } && lp64 } } } */
2 /* { dg-options "-fexceptions -fnon-call-exceptions -fasynchronous-unwind-tables -O2" } */
3 /* Test complex CFA value expressions.  */
4
5 #include <unwind.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <unistd.h>
10
11 static _Unwind_Reason_Code
12 force_unwind_stop (int version, _Unwind_Action actions,
13                    _Unwind_Exception_Class exc_class,
14                    struct _Unwind_Exception *exc_obj,
15                    struct _Unwind_Context *context,
16                    void *stop_parameter)
17 {
18   if (actions & _UA_END_OF_STACK)
19     abort ();
20   return _URC_NO_REASON;
21 }
22
23 static void
24 force_unwind ()
25 {
26   struct _Unwind_Exception *exc = malloc (sizeof (*exc));
27   memset (&exc->exception_class, 0, sizeof (exc->exception_class));
28   exc->exception_cleanup = 0;
29
30   _Unwind_ForcedUnwind (exc, force_unwind_stop, 0);
31   abort ();
32 }
33
34 int count;
35
36 static void
37 counter (void *p __attribute__((unused)))
38 {
39   ++count;
40 }
41
42 static void
43 handler (void *p __attribute__((unused)))
44 {
45   if (count != 2)
46     abort ();
47   _exit (0);
48 }
49
50 static int __attribute__((noinline))
51 fn5 (void)
52 {
53   char dummy __attribute__((cleanup (counter)));
54   force_unwind ();
55   return 0;
56 }
57
58 void
59 bar (void)
60 {
61   char dummy __attribute__((cleanup (counter)));
62   fn5 ();
63 }
64
65 void __attribute__((noinline))
66 foo (int x)
67 {
68   char buf[256];
69 #ifdef __x86_64__
70   __asm (
71         "testl  %0, %0\n\t"
72         "jnz    1f\n\t"
73         ".subsection 1\n\t"
74         ".type  _L_mutex_lock_%=, @function\n"
75 "_L_mutex_lock_%=:\n"
76 "1:\t"  "leaq   %1, %%rdi\n"
77 "2:\t"  "subq   $128, %%rsp\n"
78 "3:\t"  "call   bar\n"
79 "4:\t"  "addq   $128, %%rsp\n"
80 "5:\t"  "jmp    21f\n"
81 "6:\t"  ".size _L_mutex_lock_%=, .-_L_mutex_lock_%=\n\t"
82         ".previous\n\t"
83         ".section       .eh_frame,\"a\",@progbits\n"
84 "7:\t"  ".long  9f-8f   # Length of Common Information Entry\n"
85 "8:\t"  ".long  0x0     # CIE Identifier Tag\n\t"
86         ".byte  0x1     # CIE Version\n\t"
87         ".ascii \"zR\\0\"       # CIE Augmentation\n\t"
88         ".uleb128 0x1   # CIE Code Alignment Factor\n\t"
89         ".sleb128 -8    # CIE Data Alignment Factor\n\t"
90         ".byte  0x10    # CIE RA Column\n\t"
91         ".uleb128 0x1   # Augmentation size\n\t"
92         ".byte  0x1b    # FDE Encoding (pcrel sdata4)\n\t"
93         ".byte  0xc     # DW_CFA_def_cfa\n\t"
94         ".uleb128 0x7\n\t"
95         ".uleb128 0x0\n\t"
96         ".align 8\n"
97 "9:\t"  ".long  20f-10f # FDE Length\n"
98 "10:\t" ".long  10b-7b  # FDE CIE offset\n\t"
99         ".long  1b-.    # FDE initial location\n\t"
100         ".long  6b-1b   # FDE address range\n\t"
101         ".uleb128 0x0   # Augmentation size\n\t"
102         /* This CFA expression computes the address right
103            past the jnz instruction above, from %rip somewhere
104            within the _L_mutex_lock_%= subsection.  */
105         ".byte  0x16    # DW_CFA_val_expression\n\t"
106         ".uleb128 0x10\n\t"
107         ".uleb128 19f-11f\n"
108 "11:\t" ".byte  0x80    # DW_OP_breg16\n\t"
109         ".sleb128 0\n"
110 "12:\t" ".byte  0x12    # DW_OP_dup\n\t"
111         ".byte  0x94    # DW_OP_deref_size\n\t"
112         ".byte  1\n\t"
113         ".byte  0x12    # DW_OP_dup\n\t"
114         ".byte  0x08    # DW_OP_const1u\n\t"
115         ".byte  0x48\n\t"
116         ".byte  0x2e    # DW_OP_ne\n\t"
117         ".byte  0x28    # DW_OP_bra\n\t"
118         ".2byte 16f-13f\n"
119 "13:\t" ".byte  0x13    # DW_OP_drop\n\t"
120         ".byte  0x23    # DW_OP_plus_uconst\n\t"
121         ".uleb128 1\n\t"
122         ".byte  0x12    # DW_OP_dup\n\t"
123         ".byte  0x94    # DW_OP_deref_size\n\t"
124         ".byte  1\n\t"
125         ".byte  0x08    # DW_OP_const1u\n\t"
126         ".byte  0x81\n\t"
127         ".byte  0x2e    # DW_OP_ne\n\t"
128         ".byte  0x28    # DW_OP_bra\n\t"
129         ".2byte 15f-14f\n"
130 "14:\t" ".byte  0x23    # DW_OP_plus_uconst\n\t"
131         ".uleb128 3b-2b-1\n\t"
132         ".byte  0x2f    # DW_OP_skip\n\t"
133         ".2byte 12b-15f\n"
134 "15:\t" ".byte  0x23    # DW_OP_plus_uconst\n\t"
135         ".uleb128 2b-1b-1\n\t"
136         ".byte  0x2f    # DW_OP_skip\n\t"
137         ".2byte 12b-16f\n"
138 "16:\t" ".byte  0x08    # DW_OP_const1u\n\t"
139         ".byte  0xe8\n\t"
140         ".byte  0x2e    # DW_OP_ne\n\t"
141         ".byte  0x28    # DW_OP_bra\n\t"
142         ".2byte 18f-17f\n"
143 "17:\t" ".byte  0x23    # DW_OP_plus_uconst\n\t"
144         ".uleb128 4b-3b\n\t"
145         ".byte  0x2f    # DW_OP_skip\n\t"
146         ".2byte 12b-18f\n"
147 "18:\t" ".byte  0x23    # DW_OP_plus_uconst\n\t"
148         ".uleb128 1\n\t"
149         ".byte  0x12    # DW_OP_dup\n\t"
150         ".byte  0x94    # DW_OP_deref_size\n\t"
151         ".byte  4\n\t"
152         ".byte  0x08    # DW_OP_const1u\n\t"
153         ".byte  72 - (6b-5b) * 8 # (6b-5b) == 5 ? 32 : 56\n\t"
154         ".byte  0x24    # DW_OP_shl\n\t"
155         ".byte  0x08    # DW_OP_const1u\n\t"
156         ".byte  72 - (6b-5b) * 8 # (6b-5b) == 5 ? 32 : 56\n\t"
157         ".byte  0x26    # DW_OP_shra\n\t"
158         ".byte  0x22    # DW_OP_plus\n\t"
159         ".byte  0x23    # DW_OP_plus_uconst\n\t"
160         ".uleb128 6b-5b-1\n"
161 "19:\t" ".byte  0x40 + (3b-1b) # DW_CFA_advance_loc\n\t"
162         ".byte  0xe     # DW_CFA_def_cfa_offset\n\t"
163         ".uleb128 128\n\t"
164         ".byte  0x40 + (5b-3b) # DW_CFA_advance_loc\n\t"
165         ".byte  0xe     # DW_CFA_def_cfa_offset\n\t"
166         ".uleb128 0\n\t"
167         ".align 8\n"
168 "20:\t" ".previous\n"
169 "21:"
170         : : "r" (x), "m" (x), "r" (buf)
171         : "memory", "rax", "rdx", "rcx", "rsi", "rdi",
172           "r8", "r9", "r10", "r11");
173 #else
174 # error Unsupported test architecture
175 #endif
176 }
177
178 static int __attribute__((noinline))
179 fn2 (void)
180 {
181   foo (3);
182   return 0;
183 }
184
185 static int __attribute__((noinline))
186 fn1 (void)
187 {
188   fn2 ();
189   return 0;
190 }
191
192 static void *
193 fn0 (void)
194 {
195   char dummy __attribute__((cleanup (handler)));
196   fn1 ();
197   return 0;
198 }
199
200 int
201 main (void)
202 {
203   fn0 ();
204   return 0;
205 }