]>
Commit | Line | Data |
---|---|---|
d405059b | 1 | # DP: The Dwarf EH patch for powerpc, from Andrew Macleod, via Franz Sirl |
2 | # DP: (Revised for gcc 2.95) | |
3 | ||
4 | Index: gcc/collect2.c | |
5 | --- collect2.c 1999/05/17 22:56:24 1.72 | |
6 | +++ gcc/collect2.c 1999/06/12 18:55:22 | |
7 | @@ -2955,6 +2955,21 @@ scan_prog_file (prog_name, which_pass) | |
8 | add_to_list (&destructors, name); | |
9 | break; | |
10 | #endif | |
11 | + case 5: | |
12 | + add_to_list (&frame_tables, name); | |
13 | +#ifdef COLLECT_EXPORT_LIST | |
14 | + if (which_pass == PASS_OBJ) | |
15 | + add_to_list (&exports, name); | |
16 | + /* If this symbol was undefined and we are building | |
17 | + an import list, we should add a symbol to this | |
18 | + list. */ | |
19 | + else | |
20 | + if (import_flag | |
21 | + && is_in_list (name, undefined.first)) | |
22 | + add_to_list (&imports, name); | |
23 | +#endif | |
24 | + break; | |
25 | + | |
26 | ||
27 | default: /* not a constructor or destructor */ | |
28 | #ifdef COLLECT_EXPORT_LIST | |
29 | Index: gcc/dwarf2.h | |
30 | --- dwarf2.h 1999/01/11 13:43:21 1.11 | |
31 | +++ gcc/dwarf2.h 1999/06/12 18:55:25 | |
32 | @@ -501,7 +501,8 @@ enum dwarf_call_frame_info | |
33 | ||
34 | /* GNU extensions */ | |
35 | DW_CFA_GNU_window_save = 0x2d, | |
36 | - DW_CFA_GNU_args_size = 0x2e | |
37 | + DW_CFA_GNU_args_size = 0x2e, | |
38 | + DW_CFA_GNU_negative_offset_extended = 0x2f | |
39 | }; | |
40 | ||
41 | #define DW_CIE_ID 0xffffffff | |
42 | Index: gcc/dwarf2out.c | |
43 | --- dwarf2out.c 1999/06/03 02:30:03 1.91.4.2 | |
44 | +++ gcc/dwarf2out.c 1999/06/12 18:55:27 | |
45 | @@ -415,38 +415,54 @@ static void dwarf2out_stack_adjust PROTO | |
46 | /* We don't have unaligned support, let's hope the normal output works for | |
47 | .debug_frame. */ | |
48 | ||
49 | +#ifndef ASM_OUTPUT_DWARF_ADDR | |
50 | #define ASM_OUTPUT_DWARF_ADDR(FILE,LABEL) \ | |
51 | assemble_integer (gen_rtx_SYMBOL_REF (Pmode, LABEL), PTR_SIZE, 1) | |
52 | +#endif | |
53 | ||
54 | +#ifndef ASM_OUTPUT_DWARF_OFFSET4 | |
55 | #define ASM_OUTPUT_DWARF_OFFSET4(FILE,LABEL) \ | |
56 | assemble_integer (gen_rtx_SYMBOL_REF (SImode, LABEL), 4, 1) | |
57 | +#endif | |
58 | ||
59 | +#ifndef ASM_OUTPUT_DWARF_OFFSET | |
60 | #define ASM_OUTPUT_DWARF_OFFSET(FILE,LABEL) \ | |
61 | assemble_integer (gen_rtx_SYMBOL_REF (SImode, LABEL), 4, 1) | |
62 | +#endif | |
63 | ||
64 | +#ifndef ASM_OUTPUT_DWARF_DELTA2 | |
65 | #define ASM_OUTPUT_DWARF_DELTA2(FILE,LABEL1,LABEL2) \ | |
66 | assemble_integer (gen_rtx_MINUS (HImode, \ | |
67 | gen_rtx_SYMBOL_REF (Pmode, LABEL1), \ | |
68 | gen_rtx_SYMBOL_REF (Pmode, LABEL2)), \ | |
69 | 2, 1) | |
70 | +#endif | |
71 | ||
72 | +#ifndef ASM_OUTPUT_DWARF_DELTA4 | |
73 | #define ASM_OUTPUT_DWARF_DELTA4(FILE,LABEL1,LABEL2) \ | |
74 | assemble_integer (gen_rtx_MINUS (SImode, \ | |
75 | gen_rtx_SYMBOL_REF (Pmode, LABEL1), \ | |
76 | gen_rtx_SYMBOL_REF (Pmode, LABEL2)), \ | |
77 | 4, 1) | |
78 | +#endif | |
79 | ||
80 | +#ifndef ASM_OUTPUT_DWARF_ADDR_DELTA | |
81 | #define ASM_OUTPUT_DWARF_ADDR_DELTA(FILE,LABEL1,LABEL2) \ | |
82 | assemble_integer (gen_rtx_MINUS (Pmode, \ | |
83 | gen_rtx_SYMBOL_REF (Pmode, LABEL1), \ | |
84 | gen_rtx_SYMBOL_REF (Pmode, LABEL2)), \ | |
85 | PTR_SIZE, 1) | |
86 | +#endif | |
87 | ||
88 | +#ifndef ASM_OUTPUT_DWARF_DELTA | |
89 | #define ASM_OUTPUT_DWARF_DELTA(FILE,LABEL1,LABEL2) \ | |
90 | ASM_OUTPUT_DWARF_DELTA4 (FILE,LABEL1,LABEL2) | |
91 | +#endif | |
92 | ||
93 | +#ifndef ASM_OUTPUT_DWARF_DATA4 | |
94 | #define ASM_OUTPUT_DWARF_DATA4(FILE,VALUE) \ | |
95 | assemble_integer (GEN_INT (VALUE), 4, 1) | |
96 | +#endif | |
97 | ||
98 | #endif /* UNALIGNED_INT_ASM_OP */ | |
99 | ||
100 | @@ -719,6 +735,8 @@ dwarf_cfi_name (cfi_opc) | |
101 | return "DW_CFA_GNU_window_save"; | |
102 | case DW_CFA_GNU_args_size: | |
103 | return "DW_CFA_GNU_args_size"; | |
104 | + case DW_CFA_GNU_negative_offset_extended: | |
105 | + return "DW_CFA_GNU_negative_offset_extended"; | |
106 | ||
107 | default: | |
108 | return "DW_CFA_<unknown>"; | |
109 | @@ -948,7 +966,10 @@ reg_save (label, reg, sreg, offset) | |
110 | ||
111 | offset /= DWARF_CIE_DATA_ALIGNMENT; | |
112 | if (offset < 0) | |
113 | - abort (); | |
114 | + { | |
115 | + cfi->dw_cfi_opc = DW_CFA_GNU_negative_offset_extended; | |
116 | + offset = -offset; | |
117 | + } | |
118 | cfi->dw_cfi_oprnd2.dw_cfi_offset = offset; | |
119 | } | |
120 | else | |
121 | @@ -1421,6 +1442,10 @@ dwarf2out_frame_debug (insn) | |
122 | char *label; | |
123 | rtx src; | |
124 | ||
125 | + /* A temporary register used in adjusting SP or setting up the store_reg. */ | |
126 | + static unsigned cfa_temp_reg; | |
127 | + static long cfa_temp_value; | |
128 | + | |
129 | if (insn == NULL_RTX) | |
130 | { | |
131 | /* Set up state for generating call frame debug info. */ | |
132 | @@ -1635,6 +1660,7 @@ output_cfi (cfi, fde) | |
133 | break; | |
134 | #endif | |
135 | case DW_CFA_offset_extended: | |
136 | + case DW_CFA_GNU_negative_offset_extended: | |
137 | case DW_CFA_def_cfa: | |
138 | output_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num); | |
139 | fputc ('\n', asm_out_file); | |
140 | @@ -5862,6 +5888,14 @@ output_line_info () | |
141 | /* We used to set the address register to the first location in the text | |
142 | section here, but that didn't accomplish anything since we already | |
143 | have a line note for the opening brace of the first function. */ | |
144 | + | |
145 | + fputc ('\n', asm_out_file); | |
146 | + output_uleb128 (1 + PTR_SIZE); | |
147 | + fputc ('\n', asm_out_file); | |
148 | + ASM_OUTPUT_DWARF_DATA1 (asm_out_file, DW_LNE_set_address); | |
149 | + fputc ('\n', asm_out_file); | |
150 | + ASM_OUTPUT_DWARF_ADDR (asm_out_file, text_section_label); | |
151 | + fputc ('\n', asm_out_file); | |
152 | ||
153 | /* Generate the line number to PC correspondence table, encoded as | |
154 | a series of state machine operations. */ | |
155 | Index: gcc/dwarfout.c | |
156 | --- dwarfout.c 1999/04/18 13:09:27 1.35 | |
157 | +++ gcc/dwarfout.c 1999/06/12 18:55:29 | |
158 | @@ -864,7 +864,7 @@ static int is_redundant_typedef PROTO(( | |
159 | ASM_OUTPUT_ASCII ((FILE), P, strlen (P)+1) | |
160 | #else | |
161 | #define ASM_OUTPUT_DWARF_STRING_NEWLINE(FILE,P) \ | |
162 | - ASM_OUTPUT_DWARF_STRING (FILE,P), ASM_OUTPUT_DWARF_STRING (FILE,"\n") | |
163 | + do { ASM_OUTPUT_DWARF_STRING (FILE,P); ASM_OUTPUT_DWARF_STRING (FILE,"\n"); } while (0) | |
164 | #endif | |
165 | ||
166 | \f | |
167 | Index: gcc/except.c | |
168 | --- except.c 1999/04/15 19:54:09 1.82 | |
169 | +++ gcc/except.c 1999/06/12 18:55:30 | |
170 | @@ -2706,7 +2706,7 @@ eh_regs (pcontext, psp, pra, outgoing) | |
171 | rtx *pcontext, *psp, *pra; | |
172 | int outgoing; | |
173 | { | |
174 | - rtx rcontext, rsp, rra; | |
175 | + rtx rcontext, rsp, rra = NULL_RTX; | |
176 | int i; | |
177 | ||
178 | #ifdef FUNCTION_OUTGOING_VALUE | |
179 | @@ -2718,6 +2718,16 @@ eh_regs (pcontext, psp, pra, outgoing) | |
180 | rcontext = FUNCTION_VALUE (build_pointer_type (void_type_node), | |
181 | current_function_decl); | |
182 | ||
183 | +/* If we've specified the register to communicate the stack offset or | |
184 | + return address, use it instead of picking one */ | |
185 | + | |
186 | +#ifdef DWARF2_EH_RA_REG | |
187 | + rra = gen_rtx_REG (Pmode, DWARF2_EH_RA_REG); | |
188 | +#endif | |
189 | + | |
190 | +#ifdef DWARF2_EH_SP_REG | |
191 | + rsp = gen_rtx_REG (Pmode, DWARF2_EH_SP_REG); | |
192 | +#else | |
193 | #ifdef STATIC_CHAIN_REGNUM | |
194 | if (outgoing) | |
195 | rsp = static_chain_incoming_rtx; | |
196 | @@ -2726,6 +2736,7 @@ eh_regs (pcontext, psp, pra, outgoing) | |
197 | if (REGNO (rsp) == REGNO (rcontext)) | |
198 | #endif /* STATIC_CHAIN_REGNUM */ | |
199 | rsp = NULL_RTX; | |
200 | +#endif | |
201 | ||
202 | if (rsp == NULL_RTX) | |
203 | { | |
204 | @@ -2738,14 +2749,16 @@ eh_regs (pcontext, psp, pra, outgoing) | |
205 | rsp = gen_rtx_REG (Pmode, i); | |
206 | } | |
207 | ||
208 | - for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) | |
209 | - if (call_used_regs[i] && ! fixed_regs[i] | |
210 | - && i != REGNO (rcontext) && i != REGNO (rsp)) | |
211 | - break; | |
212 | - if (i == FIRST_PSEUDO_REGISTER) | |
213 | - abort(); | |
214 | - | |
215 | - rra = gen_rtx_REG (Pmode, i); | |
216 | + if (rra == NULL_RTX) | |
217 | + { | |
218 | + for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) | |
219 | + if (call_used_regs[i] && ! fixed_regs[i] | |
220 | + && i != REGNO (rcontext) && i != REGNO (rsp)) | |
221 | + break; | |
222 | + if (i == FIRST_PSEUDO_REGISTER) | |
223 | + abort(); | |
224 | + rra = gen_rtx_REG (Pmode, i); | |
225 | + } | |
226 | ||
227 | *pcontext = rcontext; | |
228 | *psp = rsp; | |
229 | @@ -2808,7 +2821,8 @@ expand_eh_return () | |
230 | #ifdef HAVE_eh_epilogue | |
231 | if (HAVE_eh_epilogue) | |
232 | { | |
233 | - emit_insn (gen_eh_epilogue (reg1, reg2, reg3)); | |
234 | + emit_insn (gen_eh_epilogue (eh_return_context, eh_return_stack_adjust, | |
235 | + eh_return_handler)); | |
236 | return; | |
237 | } | |
238 | #endif | |
239 | @@ -2833,6 +2847,12 @@ expand_eh_return () | |
240 | if (tmp != ra) | |
241 | emit_move_insn (ra, tmp); | |
242 | ||
243 | + eh_regs (®1, ®2, ®3, 1); | |
244 | + | |
245 | + emit_move_insn (reg1, eh_return_context); | |
246 | + emit_move_insn (reg2, eh_return_stack_adjust); | |
247 | + emit_move_insn (reg3, eh_return_handler); | |
248 | + | |
249 | /* Indicate that the registers are in fact used. */ | |
250 | emit_insn (gen_rtx_USE (VOIDmode, reg1)); | |
251 | emit_insn (gen_rtx_USE (VOIDmode, reg2)); | |
252 | Index: gcc/frame.c | |
253 | --- frame.c 1998/12/16 20:55:48 1.25 | |
254 | +++ gcc/frame.c 1999/06/12 18:55:30 | |
255 | @@ -714,6 +714,14 @@ execute_cfa_insn (void *p, struct frame_ | |
256 | state->s.args_size = offset; | |
257 | break; | |
258 | ||
259 | + case DW_CFA_GNU_negative_offset_extended: | |
260 | + p = decode_uleb128 (p, ®); | |
261 | + p = decode_uleb128 (p, &offset); | |
262 | + offset *= info->data_align; | |
263 | + state->s.saved[reg] = REG_SAVED_OFFSET; | |
264 | + state->s.reg_or_offset[reg] = -offset; | |
265 | + break; | |
266 | + | |
267 | default: | |
268 | abort (); | |
269 | } | |
270 | Index: gcc/config/rs6000/aix31.h | |
271 | --- aix31.h 1998/12/16 21:11:43 1.2 | |
272 | +++ gcc/config/rs6000/aix31.h 1999/06/12 18:55:33 | |
273 | @@ -22,6 +22,7 @@ Boston, MA 02111-1307, USA. */ | |
274 | ||
275 | ||
276 | #include "rs6000/rs6000.h" | |
277 | +#include "aix-dwarf.h" | |
278 | ||
279 | /* AIX 3.2 defined _AIX32, but older versions do not. */ | |
280 | #undef CPP_PREDEFINES | |
281 | Index: gcc/config/rs6000/aix3newas.h | |
282 | --- aix3newas.h 1998/12/16 21:11:44 1.2 | |
283 | +++ gcc/config/rs6000/aix3newas.h 1999/06/12 18:55:33 | |
284 | @@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA. */ | |
285 | {"no-xl-call", - MASK_XL_CALL}, | |
286 | ||
287 | #include "rs6000/rs6000.h" | |
288 | +#include "aix-dwarf.h" | |
289 | ||
290 | /* Tell the assembler to assume that all undefined names are external. */ | |
291 | ||
292 | Index: gcc/config/rs6000/aix41.h | |
293 | --- aix41.h 1999/03/27 18:21:29 1.6 | |
294 | +++ gcc/config/rs6000/aix41.h 1999/06/12 18:55:33 | |
295 | @@ -32,6 +32,7 @@ Boston, MA 02111-1307, USA. */ | |
296 | {"pe", 0}, | |
297 | ||
298 | #include "rs6000/rs6000.h" | |
299 | +#include "aix-dwarf.h" | |
300 | ||
301 | #undef ASM_SPEC | |
302 | #define ASM_SPEC "-u %(asm_cpu)" | |
303 | Index: gcc/config/rs6000/aix43.h | |
304 | --- aix43.h 1999/05/03 20:10:05 1.5 | |
305 | +++ gcc/config/rs6000/aix43.h 1999/06/12 18:55:33 | |
306 | @@ -58,6 +58,7 @@ do { \ | |
307 | } while (0); | |
308 | ||
309 | #include "rs6000/rs6000.h" | |
310 | +#include "aix-dwarf.h" | |
311 | ||
312 | #undef ASM_SPEC | |
313 | #define ASM_SPEC "-u %{maix64:-a64 -mppc64} %(asm_cpu)" | |
314 | Index: gcc/config/rs6000/eabi-ci.asm | |
315 | --- eabi-ci.asm 1998/12/16 21:11:50 1.2 | |
316 | +++ gcc/config/rs6000/eabi-ci.asm 1999/06/12 18:55:33 | |
317 | @@ -102,6 +102,11 @@ __SBSS2_START__: | |
318 | .type __EXCEPT_START__,@object | |
319 | __EXCEPT_START__: | |
320 | ||
321 | + .section ".eh_frame","aw" | |
322 | + .globl __EH_FRAME_BEGIN__ | |
323 | + .type __EH_FRAME_BEGIN__,@object | |
324 | +__EH_FRAME_BEGIN__: | |
325 | + | |
326 | # Head of __init function used for static constructors in Solaris | |
327 | .section ".init","ax" | |
328 | .align 2 | |
329 | Index: gcc/config/rs6000/eabi-cn.asm | |
330 | --- eabi-cn.asm 1998/12/16 21:11:51 1.2 | |
331 | +++ gcc/config/rs6000/eabi-cn.asm 1999/06/12 18:55:33 | |
332 | @@ -94,6 +94,12 @@ __SBSS2_END__: | |
333 | .type __EXCEPT_END__,@object | |
334 | __EXCEPT_END__: | |
335 | ||
336 | + .section ".eh_frame","aw" | |
337 | + .globl __EH_FRAME_END__ | |
338 | + .type __EH_FRAME_END__,@object | |
339 | +__EH_FRAME_END__: | |
340 | + .long 0 | |
341 | + | |
342 | # Tail of __init used for static constructors in Solaris | |
343 | .section ".init","ax" | |
344 | lwz 0,12(1) | |
345 | Index: gcc/config/rs6000/eabi-ctors.c | |
346 | --- eabi-ctors.c 1998/12/16 21:11:52 1.2 | |
347 | +++ gcc/config/rs6000/eabi-ctors.c 1999/06/12 18:55:33 | |
348 | @@ -40,7 +40,24 @@ extern func_ptr __CTOR_LIST__[]; | |
349 | extern func_ptr __CTOR_END__ []; | |
350 | extern func_ptr __DTOR_LIST__[]; | |
351 | extern func_ptr __DTOR_END__ []; | |
352 | +extern char __EH_FRAME_BEGIN__ []; | |
353 | ||
354 | +struct object { | |
355 | + void *pc_begin; | |
356 | + void *pc_end; | |
357 | + struct dwarf_fde *fde_begin; | |
358 | + struct dwarf_fde **fde_array; | |
359 | + long count; | |
360 | + struct object *next; | |
361 | +}; | |
362 | + | |
363 | +extern void __register_frame_info (void *, struct object *); | |
364 | +extern void __register_frame_info_table (void *, struct object *); | |
365 | +extern void __deregister_frame_info (void *); | |
366 | + | |
367 | + | |
368 | +#define EH_FRAME_SECTION_ASM_OP ".section\t.eh_frame,\"aw\"" | |
369 | + | |
370 | extern void __do_global_ctors (void); | |
371 | extern void __do_global_dtors (void); | |
372 | ||
373 | @@ -61,6 +78,11 @@ __do_global_ctors (void) | |
374 | func_ptr *ptr = &__CTOR_LIST__[0]; | |
375 | func_ptr *end = &__CTOR_END__[0]; | |
376 | ||
377 | +#ifdef EH_FRAME_SECTION_ASM_OP | |
378 | + static struct object object; | |
379 | + __register_frame_info (__EH_FRAME_BEGIN__, &object); | |
380 | +#endif | |
381 | + | |
382 | if (__atexit) | |
383 | __atexit (__do_global_dtors); | |
384 | ||
385 | @@ -88,5 +110,8 @@ __do_global_dtors (void) | |
386 | for ( ; ptr >= start; ptr--) | |
387 | if (*ptr) | |
388 | (*ptr)(); | |
389 | -} | |
390 | ||
391 | +#ifdef EH_FRAME_SECTION_ASM_OP | |
392 | + __deregister_frame_info (__EH_FRAME_BEGIN__); | |
393 | +#endif | |
394 | +} | |
395 | Index: gcc/config/rs6000/rs6000.c | |
396 | --- rs6000.c 1999/06/09 15:59:36 1.70.4.2 | |
397 | +++ gcc/config/rs6000/rs6000.c 1999/06/12 18:55:34 | |
398 | @@ -77,6 +77,11 @@ static int common_mode_defined; | |
399 | rtx rs6000_compare_op0, rs6000_compare_op1; | |
400 | int rs6000_compare_fp_p; | |
401 | ||
402 | +/* If we've defined this, we need a counter for the fixup labels */ | |
403 | +#ifdef ASM_OUTPUT_DWARF_ADDR | |
404 | +int dwarflabelno = 0; | |
405 | +#endif | |
406 | + | |
407 | #ifdef USING_SVR4_H | |
408 | /* Label number of label created for -mrelocatable, to call to so we can | |
409 | get the address of the GOT section */ | |
410 | @@ -3860,6 +3874,9 @@ rs6000_allocate_stack_space (file, size, | |
411 | } | |
412 | } | |
413 | ||
414 | +#define SET_DWARF_LABEL(X) (X = ((X == NULL) ? \ | |
415 | + (char *) dwarf2out_cfi_label () : X )) | |
416 | + | |
417 | \f | |
418 | /* Write function prologue. */ | |
419 | void | |
420 | @@ -3873,6 +3890,7 @@ output_prolog (file, size) | |
421 | const char *load_reg; | |
422 | int sp_reg = 1; | |
423 | int sp_offset = 0; | |
424 | + char *dw2_label = NULL; | |
425 | ||
426 | if (TARGET_32BIT) | |
427 | { | |
428 | @@ -3948,6 +3966,19 @@ output_prolog (file, size) | |
429 | asm_fprintf (file, "\tbl %s%d%s\n", SAVE_FP_PREFIX, | |
430 | info->first_fp_reg_save - 32, SAVE_FP_SUFFIX); | |
431 | ||
432 | + /* Regardless of whether its inlined or not, the net effect at this point | |
433 | + is that the FPRs have been saved from first to the end.*/ | |
434 | + if (dwarf2out_do_frame () && info->first_fp_reg_save != 64) | |
435 | + { | |
436 | + int regno = info->first_fp_reg_save; | |
437 | + int loc = info->fp_save_offset; | |
438 | + SET_DWARF_LABEL (dw2_label); | |
439 | + for ( ; regno < 64; regno++, loc += 8) | |
440 | + { | |
441 | + dwarf2out_reg_save (dw2_label, regno, loc); | |
442 | + } | |
443 | + } | |
444 | + | |
445 | /* Now save gpr's. */ | |
446 | if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT) | |
447 | { | |
448 | @@ -3964,6 +3995,19 @@ output_prolog (file, size) | |
449 | info->gp_save_offset + sp_offset, | |
450 | reg_names[sp_reg]); | |
451 | ||
452 | + /* Regardless of whether its inlined or not, the net effect at this point | |
453 | + is that the GPRs have been saved from first to the end.*/ | |
454 | + if (dwarf2out_do_frame () && info->first_gp_reg_save != 32) | |
455 | + { | |
456 | + int regno = info->first_gp_reg_save; | |
457 | + int loc = info->gp_save_offset; | |
458 | + SET_DWARF_LABEL (dw2_label); | |
459 | + for ( ; regno < 32; regno++, loc += reg_size) | |
460 | + { | |
461 | + dwarf2out_reg_save (dw2_label, regno, loc); | |
462 | + } | |
463 | + } | |
464 | + | |
465 | /* Save main's arguments if we need to call a function */ | |
466 | #ifdef NAME__MAIN | |
467 | if (info->main_save_p) | |
468 | @@ -3982,6 +4026,11 @@ output_prolog (file, size) | |
469 | asm_fprintf (file, store_reg, reg_names[0], info->lr_save_offset + sp_offset, | |
470 | reg_names[sp_reg]); | |
471 | ||
472 | + if (dwarf2out_do_frame () && info->lr_save_p) | |
473 | + { | |
474 | + SET_DWARF_LABEL (dw2_label); | |
475 | + dwarf2out_return_save (dw2_label, info->lr_save_offset); | |
476 | + } | |
477 | /* Save CR if we use any that must be preserved. */ | |
478 | if (info->cr_save_p) | |
479 | { | |
480 | @@ -3995,6 +4044,13 @@ output_prolog (file, size) | |
481 | else | |
482 | asm_fprintf (file, store_reg, reg_names[12], info->cr_save_offset + sp_offset, | |
483 | reg_names[sp_reg]); | |
484 | + /* we save all the condition registers as if they are a single | |
485 | + register. The are physically, so this should work fine. */ | |
486 | + if (dwarf2out_do_frame ()) | |
487 | + { | |
488 | + SET_DWARF_LABEL (dw2_label); | |
489 | + dwarf2out_reg_save (dw2_label, 70, info->cr_save_offset); | |
490 | + } | |
491 | } | |
492 | ||
493 | /* If we need PIC_OFFSET_TABLE_REGNUM, initialize it now */ | |
494 | @@ -4054,6 +4110,14 @@ output_prolog (file, size) | |
495 | if (info->push_p && DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS) | |
496 | rs6000_allocate_stack_space (file, info->total_size, FALSE); | |
497 | ||
498 | + /* Update the stack frame by size, We update it for all targets here | |
499 | + at the end since we saved everything relative to the incoming value. */ | |
500 | + | |
501 | + if (dwarf2out_do_frame () && info->push_p) | |
502 | + { | |
503 | + SET_DWARF_LABEL (dw2_label); | |
504 | + dwarf2out_def_cfa (dw2_label, 1 , info->total_size); | |
505 | + } | |
506 | /* Set frame pointer, if needed. */ | |
507 | if (frame_pointer_needed) | |
508 | asm_fprintf (file, "\tmr %s,%s\n", reg_names[31], reg_names[1]); | |
509 | Index: gcc/config/rs6000/rs6000.h | |
510 | --- rs6000.h 1999/06/09 15:59:37 1.49.4.1 | |
511 | +++ gcc/config/rs6000/rs6000.h 1999/06/12 18:55:36 | |
512 | @@ -3139,6 +3175,54 @@ do { \ | |
513 | ||
514 | #define ASM_OPEN_PAREN "(" | |
515 | #define ASM_CLOSE_PAREN ")" | |
516 | + | |
517 | +#define ASM_OUTPUT_DWARF_STRING(FILE,P) \ | |
518 | + do { \ | |
519 | + register int slen = strlen(P); \ | |
520 | + register char *p = (P); \ | |
521 | + register int i; \ | |
522 | + fprintf (FILE, "\t.asciz \""); \ | |
523 | + for (i = 0; i < slen; i++) \ | |
524 | + { \ | |
525 | + register int c = p[i]; \ | |
526 | + if (c == '\"' || c == '\\') \ | |
527 | + putc ('\\', FILE); \ | |
528 | + if (c >= ' ' && c < 0177) \ | |
529 | + putc (c, FILE); \ | |
530 | + else \ | |
531 | + { \ | |
532 | + fprintf (FILE, "\\%o", c); \ | |
533 | + } \ | |
534 | + } \ | |
535 | + fprintf (FILE, "\""); \ | |
536 | + } \ | |
537 | + while (0) | |
538 | + | |
539 | + | |
540 | +/* We can't communicate with the epilogue directly via the eh_epilogue | |
541 | + pattern, because we need to adjust the stack pointer JUST before | |
542 | + returning. If the floating point registers are restored via a | |
543 | + function call (instead of being inlined), we can't adjust the stack | |
544 | + before the callor the floating point registers will be restored from | |
545 | + the wrong address (its based of the SP.) Control never returns | |
546 | + from these routines since the return address is adjusted such that | |
547 | + when they return, they go to the target location. We leave the stub | |
548 | + mechanism in place, let the function or FP routines return to the stub | |
549 | + and do things the normal way. We have to tell the stub mechanism | |
550 | + whiuch registers to use however, since the general mechanism | |
551 | + in eh_regs (except.c) will end up choosing r0 (which is overwritten | |
552 | + by the epilogue, and R11, which is used by the epilogue for system V | |
553 | + targets. We'll just always use R4 and R5. Thats good for all targets. */ | |
554 | + | |
555 | +#define DWARF2_EH_SP_REG 4 | |
556 | +#define DWARF2_EH_RA_REG 5 | |
557 | + | |
558 | + | |
559 | +/* Pick up the return address upon entry to a procedure. Used for | |
560 | + dwarf2 unwind information. This also enables the table driven mechanism. */ | |
561 | + | |
562 | +#define INCOMING_RETURN_ADDR_RTX gen_rtx (REG, Pmode, 65) | |
563 | + | |
564 | ||
565 | /* Define results of standard character escape sequences. */ | |
566 | #define TARGET_BELL 007 | |
567 | Index: gcc/config/rs6000/rs6000.md | |
568 | --- rs6000.md 1999/06/09 15:59:39 1.55.4.1 | |
569 | +++ gcc/config/rs6000/rs6000.md 1999/06/12 18:55:37 | |
570 | @@ -7738,7 +7738,7 @@ | |
571 | ||
572 | (define_insn "nonlocal_goto_receiver" | |
573 | [(unspec_volatile [(const_int 0)] 1)] | |
574 | - "TARGET_TOC && TARGET_MINIMAL_TOC" | |
575 | + "TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0" | |
576 | "* | |
577 | { | |
578 | rs6000_output_load_toc_table (asm_out_file, 30); | |
579 | Index: gcc/config/rs6000/sysv4.h | |
580 | --- sysv4.h 1999/05/28 02:46:56 1.19.4.1 | |
581 | +++ gcc/config/rs6000/sysv4.h 1999/06/12 18:55:38 | |
582 | @@ -803,6 +803,40 @@ do { \ | |
583 | fprintf (FILE, "\t.long "); \ | |
584 | output_addr_const (FILE, (VALUE)); \ | |
585 | fprintf (FILE, "\n"); \ | |
586 | + } \ | |
587 | +} while (0) | |
588 | + | |
589 | + | |
590 | +/* This is how to output an assembler line defining an address | |
591 | + constant for the dwarf call unwinding information. | |
592 | + For -mrelocatable, we mark all addresses that need to be fixed up | |
593 | + in the .fixup section. */ | |
594 | + | |
595 | +extern int dwarflabelno; | |
596 | + | |
597 | +#undef ASM_OUTPUT_DWARF_ADDR | |
598 | +#define ASM_OUTPUT_DWARF_ADDR(FILE,LABEL) \ | |
599 | +do { \ | |
600 | + if ((TARGET_RELOCATABLE || flag_pic)) \ | |
601 | + { \ | |
602 | + char buf[256], *p; \ | |
603 | + \ | |
604 | + ASM_GENERATE_INTERNAL_LABEL (buf, "LCDW", dwarflabelno++); \ | |
605 | + STRIP_NAME_ENCODING (p, buf); \ | |
606 | + fprintf (FILE, "%s:\n", p); \ | |
607 | + fprintf (FILE, "\t.4byte\t"); \ | |
608 | + assemble_name (FILE, LABEL); \ | |
609 | + fprintf (FILE, "\n"); \ | |
610 | + fprintf (FILE, "\t.section \".fixup\",\"aw\"\n"); \ | |
611 | + ASM_OUTPUT_ALIGN (FILE, 2); \ | |
612 | + fprintf (FILE, "\t.long\t%s\n", p); \ | |
613 | + fprintf (FILE, "\t.previous\n"); \ | |
614 | + } \ | |
615 | + else \ | |
616 | + { \ | |
617 | + fprintf (FILE, "\t.4byte\t"); \ | |
618 | + assemble_name (FILE, LABEL); \ | |
619 | + fprintf (FILE, "\n"); \ | |
620 | } \ | |
621 | } while (0) | |
622 |