except.c (remove_fixup_regions): Adjust REG_EH_REGION notes to the parent of the...
[platform/upstream/gcc.git] / gcc / except.c
1 /* Implements exception handling.
2    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 
3    1999, 2000, 2001 Free Software Foundation, Inc.
4    Contributed by Mike Stump <mrs@cygnus.com>.
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING.  If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23
24 /* An exception is an event that can be signaled from within a
25    function. This event can then be "caught" or "trapped" by the
26    callers of this function. This potentially allows program flow to
27    be transferred to any arbitrary code associated with a function call
28    several levels up the stack.
29
30    The intended use for this mechanism is for signaling "exceptional
31    events" in an out-of-band fashion, hence its name. The C++ language
32    (and many other OO-styled or functional languages) practically
33    requires such a mechanism, as otherwise it becomes very difficult
34    or even impossible to signal failure conditions in complex
35    situations.  The traditional C++ example is when an error occurs in
36    the process of constructing an object; without such a mechanism, it
37    is impossible to signal that the error occurs without adding global
38    state variables and error checks around every object construction.
39
40    The act of causing this event to occur is referred to as "throwing
41    an exception". (Alternate terms include "raising an exception" or
42    "signaling an exception".) The term "throw" is used because control
43    is returned to the callers of the function that is signaling the
44    exception, and thus there is the concept of "throwing" the
45    exception up the call stack.
46
47    [ Add updated documentation on how to use this.  ]  */
48
49
50 #include "config.h"
51 #include "system.h"
52 #include "rtl.h"
53 #include "tree.h"
54 #include "flags.h"
55 #include "function.h"
56 #include "expr.h"
57 #include "insn-config.h"
58 #include "except.h"
59 #include "integrate.h"
60 #include "hard-reg-set.h"
61 #include "basic-block.h"
62 #include "output.h"
63 #include "dwarf2asm.h"
64 #include "dwarf2out.h"
65 #include "toplev.h"
66 #include "hashtab.h"
67 #include "intl.h"
68 #include "ggc.h"
69 #include "tm_p.h"
70
71
72 /* Provide defaults for stuff that may not be defined when using
73    sjlj exceptions.  */
74 #ifndef EH_RETURN_STACKADJ_RTX
75 #define EH_RETURN_STACKADJ_RTX 0
76 #endif
77 #ifndef EH_RETURN_HANDLER_RTX
78 #define EH_RETURN_HANDLER_RTX 0
79 #endif
80 #ifndef EH_RETURN_DATA_REGNO
81 #define EH_RETURN_DATA_REGNO(N) INVALID_REGNUM
82 #endif
83
84
85 /* Nonzero means enable synchronous exceptions for non-call instructions.  */
86 int flag_non_call_exceptions;
87
88 /* Protect cleanup actions with must-not-throw regions, with a call
89    to the given failure handler.  */
90 tree protect_cleanup_actions;
91
92 /* Return true if type A catches type B.  */
93 int (*lang_eh_type_covers) PARAMS ((tree a, tree b));
94
95 /* Map a type to a runtime object to match type.  */
96 tree (*lang_eh_runtime_type) PARAMS ((tree));
97
98 /* A list of labels used for exception handlers.  */
99 rtx exception_handler_labels;
100
101 static int call_site_base;
102 static int sjlj_funcdef_number;
103 static htab_t type_to_runtime_map;
104
105 /* Describe the SjLj_Function_Context structure.  */
106 static tree sjlj_fc_type_node;
107 static int sjlj_fc_call_site_ofs;
108 static int sjlj_fc_data_ofs;
109 static int sjlj_fc_personality_ofs;
110 static int sjlj_fc_lsda_ofs;
111 static int sjlj_fc_jbuf_ofs;
112 \f
113 /* Describes one exception region.  */
114 struct eh_region
115 {
116   /* The immediately surrounding region.  */
117   struct eh_region *outer;
118
119   /* The list of immediately contained regions.  */
120   struct eh_region *inner;
121   struct eh_region *next_peer;
122
123   /* An identifier for this region.  */
124   int region_number;
125
126   /* Each region does exactly one thing.  */
127   enum eh_region_type
128   {
129     ERT_CLEANUP = 1,
130     ERT_TRY,
131     ERT_CATCH,
132     ERT_ALLOWED_EXCEPTIONS,
133     ERT_MUST_NOT_THROW,
134     ERT_THROW,
135     ERT_FIXUP
136   } type;
137
138   /* Holds the action to perform based on the preceeding type.  */
139   union {
140     /* A list of catch blocks, a surrounding try block,
141        and the label for continuing after a catch.  */
142     struct {
143       struct eh_region *catch;
144       struct eh_region *last_catch;
145       struct eh_region *prev_try;
146       rtx continue_label;
147     } try;
148
149     /* The list through the catch handlers, the type object
150        matched, and a pointer to the generated code.  */
151     struct {
152       struct eh_region *next_catch;
153       struct eh_region *prev_catch;
154       tree type;
155       int filter;
156     } catch;
157
158     /* A tree_list of allowed types.  */
159     struct {
160       tree type_list;
161       int filter;
162     } allowed;
163
164     /* The type given by a call to "throw foo();", or discovered 
165        for a throw.  */
166     struct {
167       tree type;
168     } throw;
169
170     /* Retain the cleanup expression even after expansion so that
171        we can match up fixup regions.  */
172     struct {
173       tree exp;
174     } cleanup;
175
176     /* The real region (by expression and by pointer) that fixup code
177        should live in.  */
178     struct {
179       tree cleanup_exp;
180       struct eh_region *real_region;
181     } fixup;
182   } u;
183
184   /* Entry point for this region's handler before landing pads are built.  */
185   rtx label;
186
187   /* Entry point for this region's handler from the runtime eh library.  */
188   rtx landing_pad;
189
190   /* Entry point for this region's handler from an inner region.  */
191   rtx post_landing_pad;
192
193   /* The RESX insn for handing off control to the next outermost handler,
194      if appropriate.  */
195   rtx resume;
196 };
197
198 /* Used to save exception status for each function.  */
199 struct eh_status
200 {
201   /* The tree of all regions for this function.  */
202   struct eh_region *region_tree;
203
204   /* The same information as an indexable array.  */
205   struct eh_region **region_array;
206
207   /* The most recently open region.  */
208   struct eh_region *cur_region;
209
210   /* This is the region for which we are processing catch blocks.  */
211   struct eh_region *try_region;
212
213   /* A stack (TREE_LIST) of lists of handlers.  The TREE_VALUE of each
214      node is itself a TREE_CHAINed list of handlers for regions that
215      are not yet closed. The TREE_VALUE of each entry contains the
216      handler for the corresponding entry on the ehstack.  */
217   tree protect_list;
218
219   rtx filter;
220   rtx exc_ptr;
221
222   int built_landing_pads;
223   int last_region_number;
224
225   varray_type ttype_data;
226   varray_type ehspec_data;
227   varray_type action_record_data;
228
229   struct call_site_record
230   {
231     rtx landing_pad;
232     int action;
233   } *call_site_data;
234   int call_site_data_used;
235   int call_site_data_size;
236
237   rtx ehr_stackadj;
238   rtx ehr_handler;
239   rtx ehr_label;
240
241   rtx sjlj_fc;
242   rtx sjlj_exit_after;
243 };
244
245 \f
246 static void mark_eh_region                      PARAMS ((struct eh_region *));
247
248 static int t2r_eq                               PARAMS ((const PTR,
249                                                          const PTR));
250 static hashval_t t2r_hash                       PARAMS ((const PTR));
251 static int t2r_mark_1                           PARAMS ((PTR *, PTR));
252 static void t2r_mark                            PARAMS ((PTR));
253 static void add_type_for_runtime                PARAMS ((tree));
254 static tree lookup_type_for_runtime             PARAMS ((tree));
255
256 static struct eh_region *expand_eh_region_end   PARAMS ((void));
257
258 static rtx get_exception_filter                 PARAMS ((void));
259
260 static void collect_eh_region_array             PARAMS ((void));
261 static void resolve_fixup_regions               PARAMS ((void));
262 static void remove_fixup_regions                PARAMS ((void));
263 static void convert_from_eh_region_ranges_1     PARAMS ((rtx *, int *, int));
264
265 static struct eh_region *duplicate_eh_region_1  PARAMS ((struct eh_region *,
266                                                      struct inline_remap *));
267 static void duplicate_eh_region_2               PARAMS ((struct eh_region *,
268                                                          struct eh_region **));
269 static int ttypes_filter_eq                     PARAMS ((const PTR,
270                                                          const PTR));
271 static hashval_t ttypes_filter_hash             PARAMS ((const PTR));
272 static int ehspec_filter_eq                     PARAMS ((const PTR,
273                                                          const PTR));
274 static hashval_t ehspec_filter_hash             PARAMS ((const PTR));
275 static int add_ttypes_entry                     PARAMS ((htab_t, tree));
276 static int add_ehspec_entry                     PARAMS ((htab_t, htab_t,
277                                                          tree));
278 static void assign_filter_values                PARAMS ((void));
279 static void build_post_landing_pads             PARAMS ((void));
280 static void connect_post_landing_pads           PARAMS ((void));
281 static void dw2_build_landing_pads              PARAMS ((void));
282
283 struct sjlj_lp_info;
284 static bool sjlj_find_directly_reachable_regions
285      PARAMS ((struct sjlj_lp_info *));
286 static void sjlj_assign_call_site_values
287      PARAMS ((rtx, struct sjlj_lp_info *));
288 static void sjlj_mark_call_sites
289      PARAMS ((struct sjlj_lp_info *));
290 static void sjlj_emit_function_enter            PARAMS ((rtx));
291 static void sjlj_emit_function_exit             PARAMS ((void));
292 static void sjlj_emit_dispatch_table
293      PARAMS ((rtx, struct sjlj_lp_info *));
294 static void sjlj_build_landing_pads             PARAMS ((void));
295
296 static void remove_exception_handler_label      PARAMS ((rtx));
297 static void remove_eh_handler                   PARAMS ((struct eh_region *));
298
299 struct reachable_info;
300
301 /* The return value of reachable_next_level.  */
302 enum reachable_code
303 {
304   /* The given exception is not processed by the given region.  */
305   RNL_NOT_CAUGHT,
306   /* The given exception may need processing by the given region.  */
307   RNL_MAYBE_CAUGHT,
308   /* The given exception is completely processed by the given region.  */
309   RNL_CAUGHT,
310   /* The given exception is completely processed by the runtime.  */
311   RNL_BLOCKED
312 };
313
314 static int check_handled                        PARAMS ((tree, tree));
315 static void add_reachable_handler
316      PARAMS ((struct reachable_info *, struct eh_region *,
317               struct eh_region *));
318 static enum reachable_code reachable_next_level
319      PARAMS ((struct eh_region *, tree, struct reachable_info *));
320
321 static int action_record_eq                     PARAMS ((const PTR,
322                                                          const PTR));
323 static hashval_t action_record_hash             PARAMS ((const PTR));
324 static int add_action_record                    PARAMS ((htab_t, int, int));
325 static int collect_one_action_chain             PARAMS ((htab_t,
326                                                          struct eh_region *));
327 static int add_call_site                        PARAMS ((rtx, int));
328
329 static void push_uleb128                        PARAMS ((varray_type *,
330                                                          unsigned int));
331 static void push_sleb128                        PARAMS ((varray_type *, int));
332 static const char *eh_data_format_name          PARAMS ((int));
333 #ifndef HAVE_AS_LEB128
334 static int dw2_size_of_call_site_table          PARAMS ((void));
335 static int sjlj_size_of_call_site_table         PARAMS ((void));
336 #endif
337 static void dw2_output_call_site_table          PARAMS ((void));
338 static void sjlj_output_call_site_table         PARAMS ((void));
339
340 \f
341 /* Routine to see if exception handling is turned on.
342    DO_WARN is non-zero if we want to inform the user that exception
343    handling is turned off. 
344
345    This is used to ensure that -fexceptions has been specified if the
346    compiler tries to use any exception-specific functions.  */
347
348 int
349 doing_eh (do_warn)
350      int do_warn;
351 {
352   if (! flag_exceptions)
353     {
354       static int warned = 0;
355       if (! warned && do_warn)
356         {
357           error ("exception handling disabled, use -fexceptions to enable");
358           warned = 1;
359         }
360       return 0;
361     }
362   return 1;
363 }
364
365 \f
366 void
367 init_eh ()
368 {
369   ggc_add_rtx_root (&exception_handler_labels, 1);
370   ggc_add_tree_root (&protect_cleanup_actions, 1);
371
372   if (! flag_exceptions)
373     return;
374
375   type_to_runtime_map = htab_create (31, t2r_hash, t2r_eq, NULL);
376   ggc_add_root (&type_to_runtime_map, 1, sizeof (htab_t), t2r_mark);
377
378   /* Create the SjLj_Function_Context structure.  This should match
379      the definition in unwind-sjlj.c.  */
380   if (USING_SJLJ_EXCEPTIONS)
381     {
382       tree f_jbuf, f_per, f_lsda, f_prev, f_cs, f_data, tmp;
383
384       sjlj_fc_type_node = make_lang_type (RECORD_TYPE);
385       ggc_add_tree_root (&sjlj_fc_type_node, 1);
386
387       f_prev = build_decl (FIELD_DECL, get_identifier ("__prev"),
388                            build_pointer_type (sjlj_fc_type_node));
389       DECL_FIELD_CONTEXT (f_prev) = sjlj_fc_type_node;
390
391       f_cs = build_decl (FIELD_DECL, get_identifier ("__call_site"),
392                          integer_type_node);
393       DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node;
394
395       tmp = build_index_type (build_int_2 (4 - 1, 0));
396       tmp = build_array_type (type_for_mode (word_mode, 1), tmp);
397       f_data = build_decl (FIELD_DECL, get_identifier ("__data"), tmp);
398       DECL_FIELD_CONTEXT (f_data) = sjlj_fc_type_node;
399
400       f_per = build_decl (FIELD_DECL, get_identifier ("__personality"),
401                           ptr_type_node);
402       DECL_FIELD_CONTEXT (f_per) = sjlj_fc_type_node;
403
404       f_lsda = build_decl (FIELD_DECL, get_identifier ("__lsda"),
405                            ptr_type_node);
406       DECL_FIELD_CONTEXT (f_lsda) = sjlj_fc_type_node;
407
408 #ifdef DONT_USE_BUILTIN_SETJMP
409 #ifdef JMP_BUF_SIZE
410       tmp = build_int_2 (JMP_BUF_SIZE - 1, 0);
411 #else
412       /* Should be large enough for most systems, if it is not,
413          JMP_BUF_SIZE should be defined with the proper value.  It will
414          also tend to be larger than necessary for most systems, a more
415          optimal port will define JMP_BUF_SIZE.  */
416       tmp = build_int_2 (FIRST_PSEUDO_REGISTER + 2 - 1, 0);
417 #endif
418 #else
419       /* This is 2 for builtin_setjmp, plus whatever the target requires
420          via STACK_SAVEAREA_MODE (SAVE_NONLOCAL).  */
421       tmp = build_int_2 ((GET_MODE_SIZE (STACK_SAVEAREA_MODE (SAVE_NONLOCAL))
422                           / GET_MODE_SIZE (Pmode)) + 2 - 1, 0);
423 #endif
424       tmp = build_index_type (tmp);
425       tmp = build_array_type (ptr_type_node, tmp);
426       f_jbuf = build_decl (FIELD_DECL, get_identifier ("__jbuf"), tmp);
427 #ifdef DONT_USE_BUILTIN_SETJMP
428       /* We don't know what the alignment requirements of the
429          runtime's jmp_buf has.  Overestimate.  */
430       DECL_ALIGN (f_jbuf) = BIGGEST_ALIGNMENT;
431       DECL_USER_ALIGN (f_jbuf) = 1;
432 #endif
433       DECL_FIELD_CONTEXT (f_jbuf) = sjlj_fc_type_node;
434
435       TYPE_FIELDS (sjlj_fc_type_node) = f_prev;
436       TREE_CHAIN (f_prev) = f_cs;
437       TREE_CHAIN (f_cs) = f_data;
438       TREE_CHAIN (f_data) = f_per;
439       TREE_CHAIN (f_per) = f_lsda;
440       TREE_CHAIN (f_lsda) = f_jbuf;
441
442       layout_type (sjlj_fc_type_node);
443
444       /* Cache the interesting field offsets so that we have
445          easy access from rtl.  */
446       sjlj_fc_call_site_ofs
447         = (tree_low_cst (DECL_FIELD_OFFSET (f_cs), 1)
448            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_cs), 1) / BITS_PER_UNIT);
449       sjlj_fc_data_ofs
450         = (tree_low_cst (DECL_FIELD_OFFSET (f_data), 1)
451            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_data), 1) / BITS_PER_UNIT);
452       sjlj_fc_personality_ofs
453         = (tree_low_cst (DECL_FIELD_OFFSET (f_per), 1)
454            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_per), 1) / BITS_PER_UNIT);
455       sjlj_fc_lsda_ofs
456         = (tree_low_cst (DECL_FIELD_OFFSET (f_lsda), 1)
457            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_lsda), 1) / BITS_PER_UNIT);
458       sjlj_fc_jbuf_ofs
459         = (tree_low_cst (DECL_FIELD_OFFSET (f_jbuf), 1)
460            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_jbuf), 1) / BITS_PER_UNIT);
461     }
462 }
463
464 void
465 init_eh_for_function ()
466 {
467   cfun->eh = (struct eh_status *) xcalloc (1, sizeof (struct eh_status));
468 }
469
470 /* Mark EH for GC.  */
471
472 static void
473 mark_eh_region (region)
474      struct eh_region *region;
475 {
476   if (! region)
477     return;
478
479   switch (region->type)
480     {
481     case ERT_CLEANUP:
482       ggc_mark_tree (region->u.cleanup.exp);
483       break;
484     case ERT_TRY:
485       ggc_mark_rtx (region->u.try.continue_label);
486       break;
487     case ERT_CATCH:
488       ggc_mark_tree (region->u.catch.type);
489       break;
490     case ERT_ALLOWED_EXCEPTIONS:
491       ggc_mark_tree (region->u.allowed.type_list);
492       break;
493     case ERT_MUST_NOT_THROW:
494       break;
495     case ERT_THROW:
496       ggc_mark_tree (region->u.throw.type);
497       break;
498     case ERT_FIXUP:
499       ggc_mark_tree (region->u.fixup.cleanup_exp);
500       break;
501     default:
502       abort ();
503     }
504
505   ggc_mark_rtx (region->label);
506   ggc_mark_rtx (region->resume);
507   ggc_mark_rtx (region->landing_pad);
508   ggc_mark_rtx (region->post_landing_pad);
509 }
510
511 void
512 mark_eh_status (eh)
513      struct eh_status *eh;
514 {
515   int i;
516
517   if (eh == 0)
518     return;
519
520   /* If we've called collect_eh_region_array, use it.  Otherwise walk
521      the tree non-recursively.  */
522   if (eh->region_array)
523     {
524       for (i = eh->last_region_number; i > 0; --i)
525         {
526           struct eh_region *r = eh->region_array[i];
527           if (r && r->region_number == i)
528             mark_eh_region (r);
529         }
530     }
531   else if (eh->region_tree)
532     {
533       struct eh_region *r = eh->region_tree;
534       while (1)
535         {
536           mark_eh_region (r);
537           if (r->inner)
538             r = r->inner;
539           else if (r->next_peer)
540             r = r->next_peer;
541           else
542             {
543               do {
544                 r = r->outer;
545                 if (r == NULL)
546                   goto tree_done;
547               } while (r->next_peer == NULL);
548               r = r->next_peer;
549             }
550         }
551     tree_done:;
552     }
553
554   ggc_mark_tree (eh->protect_list);
555   ggc_mark_rtx (eh->filter);
556   ggc_mark_rtx (eh->exc_ptr);
557   ggc_mark_tree_varray (eh->ttype_data);
558
559   if (eh->call_site_data)
560     {
561       for (i = eh->call_site_data_used - 1; i >= 0; --i)
562         ggc_mark_rtx (eh->call_site_data[i].landing_pad);
563     }
564
565   ggc_mark_rtx (eh->ehr_stackadj);
566   ggc_mark_rtx (eh->ehr_handler);
567   ggc_mark_rtx (eh->ehr_label);
568
569   ggc_mark_rtx (eh->sjlj_fc);
570   ggc_mark_rtx (eh->sjlj_exit_after);
571 }
572
573 void
574 free_eh_status (f)
575      struct function *f;
576 {
577   struct eh_status *eh = f->eh;
578
579   if (eh->region_array)
580     {
581       int i;
582       for (i = eh->last_region_number; i > 0; --i)
583         {
584           struct eh_region *r = eh->region_array[i];
585           /* Mind we don't free a region struct more than once.  */
586           if (r && r->region_number == i)
587             free (r);
588         }
589       free (eh->region_array);
590     }
591   else if (eh->region_tree)
592     {
593       struct eh_region *next, *r = eh->region_tree;
594       while (1)
595         {
596           if (r->inner)
597             r = r->inner;
598           else if (r->next_peer)
599             {
600               next = r->next_peer;
601               free (r);
602               r = next;
603             }
604           else
605             {
606               do {
607                 next = r->outer;
608                 free (r);
609                 r = next;
610                 if (r == NULL)
611                   goto tree_done;
612               } while (r->next_peer == NULL);
613               next = r->next_peer;
614               free (r);
615               r = next;
616             }
617         }
618     tree_done:;
619     }
620
621   VARRAY_FREE (eh->ttype_data);
622   VARRAY_FREE (eh->ehspec_data);
623   VARRAY_FREE (eh->action_record_data);
624   if (eh->call_site_data)
625     free (eh->call_site_data);
626
627   free (eh);
628   f->eh = NULL;
629 }
630
631 \f
632 /* Start an exception handling region.  All instructions emitted
633    after this point are considered to be part of the region until
634    expand_eh_region_end is invoked.  */
635
636 void
637 expand_eh_region_start ()
638 {
639   struct eh_region *new_region;
640   struct eh_region *cur_region;
641   rtx note;
642
643   if (! doing_eh (0))
644     return;
645
646   /* Insert a new blank region as a leaf in the tree.  */
647   new_region = (struct eh_region *) xcalloc (1, sizeof (*new_region));
648   cur_region = cfun->eh->cur_region;
649   new_region->outer = cur_region;
650   if (cur_region)
651     {
652       new_region->next_peer = cur_region->inner;
653       cur_region->inner = new_region;
654     }
655   else
656     {
657       new_region->next_peer = cfun->eh->region_tree;
658       cfun->eh->region_tree = new_region;
659     }
660   cfun->eh->cur_region = new_region;
661
662   /* Create a note marking the start of this region.  */
663   new_region->region_number = ++cfun->eh->last_region_number;
664   note = emit_note (NULL, NOTE_INSN_EH_REGION_BEG);
665   NOTE_EH_HANDLER (note) = new_region->region_number;
666 }
667
668 /* Common code to end a region.  Returns the region just ended.  */
669
670 static struct eh_region *
671 expand_eh_region_end ()
672 {
673   struct eh_region *cur_region = cfun->eh->cur_region;
674   rtx note;
675
676   /* Create a nute marking the end of this region.  */
677   note = emit_note (NULL, NOTE_INSN_EH_REGION_END);
678   NOTE_EH_HANDLER (note) = cur_region->region_number;
679
680   /* Pop.  */
681   cfun->eh->cur_region = cur_region->outer;
682
683   return cur_region;
684 }
685
686 /* End an exception handling region for a cleanup.  HANDLER is an
687    expression to expand for the cleanup.  */
688
689 void
690 expand_eh_region_end_cleanup (handler)
691      tree handler;
692 {
693   struct eh_region *region;
694   rtx around_label;
695   rtx data_save[2];
696
697   if (! doing_eh (0))
698     return;
699
700   region = expand_eh_region_end ();
701   region->type = ERT_CLEANUP;
702   region->label = gen_label_rtx ();
703   region->u.cleanup.exp = handler;
704
705   around_label = gen_label_rtx ();
706   emit_jump (around_label);
707
708   emit_label (region->label);
709
710   if (protect_cleanup_actions)
711     expand_eh_region_start ();
712
713   /* In case this cleanup involves an inline destructor with a try block in
714      it, we need to save the EH return data registers around it.  */
715   data_save[0] = gen_reg_rtx (Pmode);
716   emit_move_insn (data_save[0], get_exception_pointer ());
717   data_save[1] = gen_reg_rtx (word_mode);
718   emit_move_insn (data_save[1], get_exception_filter ());
719
720   expand_expr (handler, const0_rtx, VOIDmode, 0);
721
722   emit_move_insn (cfun->eh->exc_ptr, data_save[0]);
723   emit_move_insn (cfun->eh->filter, data_save[1]);
724
725   if (protect_cleanup_actions)
726     expand_eh_region_end_must_not_throw (protect_cleanup_actions);
727
728   /* We need any stack adjustment complete before the around_label.  */
729   do_pending_stack_adjust ();
730
731   /* We delay the generation of the _Unwind_Resume until we generate
732      landing pads.  We emit a marker here so as to get good control
733      flow data in the meantime.  */
734   region->resume
735     = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
736   emit_barrier ();
737
738   emit_label (around_label);
739 }
740
741 /* End an exception handling region for a try block, and prepares
742    for subsequent calls to expand_start_catch.  */
743
744 void
745 expand_start_all_catch ()
746 {
747   struct eh_region *region;
748
749   if (! doing_eh (1))
750     return;
751
752   region = expand_eh_region_end ();
753   region->type = ERT_TRY;
754   region->u.try.prev_try = cfun->eh->try_region;
755   region->u.try.continue_label = gen_label_rtx ();
756
757   cfun->eh->try_region = region;
758
759   emit_jump (region->u.try.continue_label);
760 }
761
762 /* Begin a catch clause.  TYPE is the type caught, or null if this is
763    a catch-all clause.  */
764
765 void
766 expand_start_catch (type)
767      tree type;
768 {
769   struct eh_region *t, *c, *l;
770
771   if (! doing_eh (0))
772     return;
773
774   if (type)
775     add_type_for_runtime (type);
776   expand_eh_region_start ();
777
778   t = cfun->eh->try_region;
779   c = cfun->eh->cur_region;
780   c->type = ERT_CATCH;
781   c->u.catch.type = type;
782   c->label = gen_label_rtx ();
783
784   l = t->u.try.last_catch;
785   c->u.catch.prev_catch = l;
786   if (l)
787     l->u.catch.next_catch = c;
788   else
789     t->u.try.catch = c;
790   t->u.try.last_catch = c;
791
792   emit_label (c->label);
793 }
794
795 /* End a catch clause.  Control will resume after the try/catch block.  */
796
797 void
798 expand_end_catch ()
799 {
800   struct eh_region *try_region, *catch_region;
801
802   if (! doing_eh (0))
803     return;
804
805   catch_region = expand_eh_region_end ();
806   try_region = cfun->eh->try_region;
807
808   emit_jump (try_region->u.try.continue_label);
809 }
810
811 /* End a sequence of catch handlers for a try block.  */
812
813 void
814 expand_end_all_catch ()
815 {
816   struct eh_region *try_region;
817
818   if (! doing_eh (0))
819     return;
820
821   try_region = cfun->eh->try_region;
822   cfun->eh->try_region = try_region->u.try.prev_try;
823
824   emit_label (try_region->u.try.continue_label);
825 }
826
827 /* End an exception region for an exception type filter.  ALLOWED is a
828    TREE_LIST of types to be matched by the runtime.  FAILURE is an
829    expression to invoke if a mismatch ocurrs.  */
830
831 void
832 expand_eh_region_end_allowed (allowed, failure)
833      tree allowed, failure;
834 {
835   struct eh_region *region;
836   rtx around_label;
837
838   if (! doing_eh (0))
839     return;
840
841   region = expand_eh_region_end ();
842   region->type = ERT_ALLOWED_EXCEPTIONS;
843   region->u.allowed.type_list = allowed;
844   region->label = gen_label_rtx ();
845
846   for (; allowed ; allowed = TREE_CHAIN (allowed))
847     add_type_for_runtime (TREE_VALUE (allowed));
848
849   /* We must emit the call to FAILURE here, so that if this function
850      throws a different exception, that it will be processed by the
851      correct region.  */
852
853   around_label = gen_label_rtx ();
854   emit_jump (around_label);
855
856   emit_label (region->label);
857   expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL);
858
859   emit_label (around_label);
860 }
861
862 /* End an exception region for a must-not-throw filter.  FAILURE is an
863    expression invoke if an uncaught exception propagates this far.
864
865    This is conceptually identical to expand_eh_region_end_allowed with
866    an empty allowed list (if you passed "std::terminate" instead of
867    "__cxa_call_unexpected"), but they are represented differently in
868    the C++ LSDA.  */
869
870 void
871 expand_eh_region_end_must_not_throw (failure)
872      tree failure;
873 {
874   struct eh_region *region;
875   rtx around_label;
876
877   if (! doing_eh (0))
878     return;
879
880   region = expand_eh_region_end ();
881   region->type = ERT_MUST_NOT_THROW;
882   region->label = gen_label_rtx ();
883
884   /* We must emit the call to FAILURE here, so that if this function
885      throws a different exception, that it will be processed by the
886      correct region.  */
887
888   around_label = gen_label_rtx ();
889   emit_jump (around_label);
890
891   emit_label (region->label);
892   expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL);
893
894   emit_label (around_label);
895 }
896
897 /* End an exception region for a throw.  No handling goes on here,
898    but it's the easiest way for the front-end to indicate what type
899    is being thrown.  */
900
901 void
902 expand_eh_region_end_throw (type)
903      tree type;
904 {
905   struct eh_region *region;
906
907   if (! doing_eh (0))
908     return;
909
910   region = expand_eh_region_end ();
911   region->type = ERT_THROW;
912   region->u.throw.type = type;
913 }
914
915 /* End a fixup region.  Within this region the cleanups for the immediately
916    enclosing region are _not_ run.  This is used for goto cleanup to avoid
917    destroying an object twice.
918
919    This would be an extraordinarily simple prospect, were it not for the
920    fact that we don't actually know what the immediately enclosing region
921    is.  This surprising fact is because expand_cleanups is currently
922    generating a sequence that it will insert somewhere else.  We collect
923    the proper notion of "enclosing" in convert_from_eh_region_ranges.  */
924
925 void
926 expand_eh_region_end_fixup (handler)
927      tree handler;
928 {
929   struct eh_region *fixup;
930
931   if (! doing_eh (0))
932     return;
933
934   fixup = expand_eh_region_end ();
935   fixup->type = ERT_FIXUP;
936   fixup->u.fixup.cleanup_exp = handler;
937 }
938
939 /* Return an rtl expression for a pointer to the exception object
940    within a handler.  */
941
942 rtx
943 get_exception_pointer ()
944 {
945   rtx exc_ptr = cfun->eh->exc_ptr;
946   if (! exc_ptr)
947     {
948       exc_ptr = gen_reg_rtx (Pmode);
949       cfun->eh->exc_ptr = exc_ptr;
950     }
951   return exc_ptr;
952 }
953
954 /* Return an rtl expression for the exception dispatch filter
955    within a handler.  */
956
957 static rtx
958 get_exception_filter ()
959 {
960   rtx filter = cfun->eh->filter;
961   if (! filter)
962     {
963       filter = gen_reg_rtx (word_mode);
964       cfun->eh->filter = filter;
965     }
966   return filter;
967 }
968 \f
969 /* Begin a region that will contain entries created with
970    add_partial_entry.  */
971
972 void
973 begin_protect_partials ()
974 {
975   /* Push room for a new list.  */
976   cfun->eh->protect_list
977     = tree_cons (NULL_TREE, NULL_TREE, cfun->eh->protect_list);
978 }
979
980 /* Start a new exception region for a region of code that has a
981    cleanup action and push the HANDLER for the region onto
982    protect_list. All of the regions created with add_partial_entry
983    will be ended when end_protect_partials is invoked.  */
984
985 void
986 add_partial_entry (handler)
987      tree handler;
988 {
989   expand_eh_region_start ();
990
991   /* ??? This comment was old before the most recent rewrite.  We
992      really ought to fix the callers at some point.  */
993   /* For backwards compatibility, we allow callers to omit calls to
994      begin_protect_partials for the outermost region.  So, we must
995      explicitly do so here.  */
996   if (!cfun->eh->protect_list)
997     begin_protect_partials ();
998
999   /* Add this entry to the front of the list.  */
1000   TREE_VALUE (cfun->eh->protect_list) 
1001     = tree_cons (NULL_TREE, handler, TREE_VALUE (cfun->eh->protect_list));
1002 }
1003
1004 /* End all the pending exception regions on protect_list.  */
1005
1006 void
1007 end_protect_partials ()
1008 {
1009   tree t;
1010
1011   /* ??? This comment was old before the most recent rewrite.  We
1012      really ought to fix the callers at some point.  */
1013   /* For backwards compatibility, we allow callers to omit the call to
1014      begin_protect_partials for the outermost region.  So,
1015      PROTECT_LIST may be NULL.  */
1016   if (!cfun->eh->protect_list)
1017     return;
1018
1019   /* Pop the topmost entry.  */
1020   t = TREE_VALUE (cfun->eh->protect_list);
1021   cfun->eh->protect_list = TREE_CHAIN (cfun->eh->protect_list);
1022
1023   /* End all the exception regions.  */
1024   for (; t; t = TREE_CHAIN (t))
1025     expand_eh_region_end_cleanup (TREE_VALUE (t));
1026 }
1027
1028 \f
1029 /* This section is for the exception handling specific optimization pass.  */
1030
1031 /* Random access the exception region tree.  It's just as simple to
1032    collect the regions this way as in expand_eh_region_start, but
1033    without having to realloc memory.  */
1034
1035 static void
1036 collect_eh_region_array ()
1037 {
1038   struct eh_region **array, *i;
1039
1040   i = cfun->eh->region_tree;
1041   if (! i)
1042     return;
1043
1044   array = xcalloc (cfun->eh->last_region_number + 1, sizeof (*array));
1045   cfun->eh->region_array = array;
1046
1047   while (1)
1048     {
1049       array[i->region_number] = i;
1050
1051       /* If there are sub-regions, process them.  */
1052       if (i->inner)
1053         i = i->inner;
1054       /* If there are peers, process them.  */
1055       else if (i->next_peer)
1056         i = i->next_peer;
1057       /* Otherwise, step back up the tree to the next peer.  */
1058       else
1059         {
1060           do {
1061             i = i->outer;
1062             if (i == NULL)
1063               return;
1064           } while (i->next_peer == NULL);
1065           i = i->next_peer;
1066         }
1067     }
1068 }
1069
1070 static void
1071 resolve_fixup_regions ()
1072 {
1073   int i, j, n = cfun->eh->last_region_number;
1074
1075   for (i = 1; i <= n; ++i)
1076     {
1077       struct eh_region *fixup = cfun->eh->region_array[i];
1078       struct eh_region *cleanup;
1079
1080       if (! fixup || fixup->type != ERT_FIXUP)
1081         continue;
1082
1083       for (j = 1; j <= n; ++j)
1084         {
1085           cleanup = cfun->eh->region_array[j];
1086           if (cleanup->type == ERT_CLEANUP
1087               && cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp)
1088             break;
1089         }
1090       if (j > n)
1091         abort ();
1092
1093       fixup->u.fixup.real_region = cleanup->outer;
1094     }
1095 }
1096
1097 /* Now that we've discovered what region actually encloses a fixup,
1098    we can shuffle pointers and remove them from the tree.  */
1099
1100 static void
1101 remove_fixup_regions ()
1102 {
1103   int i;
1104   rtx insn, note;
1105   struct eh_region *fixup;
1106
1107   /* Walk the insn chain and adjust the REG_EH_REGION numbers
1108      for instructions referencing fixup regions.  This is only
1109      strictly necessary for fixup regions with no parent, but
1110      doesn't hurt to do it for all regions.  */
1111   for (insn = get_insns(); insn ; insn = NEXT_INSN (insn))
1112     if (INSN_P (insn)
1113         && (note = find_reg_note (insn, REG_EH_REGION, NULL))
1114         && INTVAL (XEXP (note, 0)) > 0
1115         && (fixup = cfun->eh->region_array[INTVAL (XEXP (note, 0))])
1116         && fixup->type == ERT_FIXUP)
1117       {
1118         if (fixup->u.fixup.real_region)
1119           XEXP (note, 1) = GEN_INT (fixup->u.fixup.real_region->region_number);
1120         else
1121           remove_note (insn, note);
1122       }
1123
1124   /* Remove the fixup regions from the tree.  */
1125   for (i = cfun->eh->last_region_number; i > 0; --i)
1126     {
1127       fixup = cfun->eh->region_array[i];
1128       if (! fixup)
1129         continue;
1130
1131       /* Allow GC to maybe free some memory.  */
1132       if (fixup->type == ERT_CLEANUP)
1133         fixup->u.cleanup.exp = NULL_TREE;
1134
1135       if (fixup->type != ERT_FIXUP)
1136         continue;
1137
1138       if (fixup->inner)
1139         {
1140           struct eh_region *parent, *p, **pp;
1141
1142           parent = fixup->u.fixup.real_region;
1143
1144           /* Fix up the children's parent pointers; find the end of
1145              the list.  */
1146           for (p = fixup->inner; ; p = p->next_peer)
1147             {
1148               p->outer = parent;
1149               if (! p->next_peer)
1150                 break;
1151             }
1152
1153           /* In the tree of cleanups, only outer-inner ordering matters.
1154              So link the children back in anywhere at the correct level.  */
1155           if (parent)
1156             pp = &parent->inner;
1157           else
1158             pp = &cfun->eh->region_tree;
1159           p->next_peer = *pp;
1160           *pp = fixup->inner;
1161           fixup->inner = NULL;
1162         }
1163
1164       remove_eh_handler (fixup);
1165     }
1166 }
1167
1168 /* Turn NOTE_INSN_EH_REGION notes into REG_EH_REGION notes for each
1169    can_throw instruction in the region.  */
1170
1171 static void
1172 convert_from_eh_region_ranges_1 (pinsns, orig_sp, cur)
1173      rtx *pinsns;
1174      int *orig_sp;
1175      int cur;
1176 {
1177   int *sp = orig_sp;
1178   rtx insn, next;
1179
1180   for (insn = *pinsns; insn ; insn = next)
1181     {
1182       next = NEXT_INSN (insn);
1183       if (GET_CODE (insn) == NOTE)
1184         {
1185           int kind = NOTE_LINE_NUMBER (insn);
1186           if (kind == NOTE_INSN_EH_REGION_BEG
1187               || kind == NOTE_INSN_EH_REGION_END)
1188             {
1189               if (kind == NOTE_INSN_EH_REGION_BEG)
1190                 {
1191                   struct eh_region *r;
1192
1193                   *sp++ = cur;
1194                   cur = NOTE_EH_HANDLER (insn);
1195
1196                   r = cfun->eh->region_array[cur];
1197                   if (r->type == ERT_FIXUP)
1198                     {
1199                       r = r->u.fixup.real_region;
1200                       cur = r ? r->region_number : 0;
1201                     }
1202                   else if (r->type == ERT_CATCH)
1203                     {
1204                       r = r->outer;
1205                       cur = r ? r->region_number : 0;
1206                     }
1207                 }
1208               else
1209                 cur = *--sp;
1210
1211               /* Removing the first insn of a CALL_PLACEHOLDER sequence
1212                  requires extra care to adjust sequence start.  */
1213               if (insn == *pinsns)
1214                 *pinsns = next;
1215               remove_insn (insn);
1216               continue;
1217             }
1218         }
1219       else if (INSN_P (insn))
1220         {
1221           if (cur > 0
1222               && ! find_reg_note (insn, REG_EH_REGION, NULL_RTX)
1223               /* Calls can always potentially throw exceptions, unless
1224                  they have a REG_EH_REGION note with a value of 0 or less.
1225                  Which should be the only possible kind so far.  */
1226               && (GET_CODE (insn) == CALL_INSN
1227                   /* If we wanted exceptions for non-call insns, then
1228                      any may_trap_p instruction could throw.  */
1229                   || (flag_non_call_exceptions
1230                       && may_trap_p (PATTERN (insn)))))
1231             {
1232               REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, GEN_INT (cur),
1233                                                   REG_NOTES (insn));
1234             }
1235
1236           if (GET_CODE (insn) == CALL_INSN
1237               && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
1238             {
1239               convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 0),
1240                                                sp, cur);
1241               convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 1),
1242                                                sp, cur);
1243               convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 2),
1244                                                sp, cur);
1245             }
1246         }
1247     }
1248
1249   if (sp != orig_sp)
1250     abort ();
1251 }
1252
1253 void
1254 convert_from_eh_region_ranges ()
1255 {
1256   int *stack;
1257   rtx insns;
1258
1259   collect_eh_region_array ();
1260   resolve_fixup_regions ();
1261
1262   stack = xmalloc (sizeof (int) * (cfun->eh->last_region_number + 1));
1263   insns = get_insns ();
1264   convert_from_eh_region_ranges_1 (&insns, stack, 0);
1265   free (stack);
1266
1267   remove_fixup_regions ();
1268 }
1269
1270 void
1271 find_exception_handler_labels ()
1272 {
1273   rtx list = NULL_RTX;
1274   int i;
1275
1276   free_EXPR_LIST_list (&exception_handler_labels);
1277
1278   if (cfun->eh->region_tree == NULL)
1279     return;
1280
1281   for (i = cfun->eh->last_region_number; i > 0; --i)
1282     {
1283       struct eh_region *region = cfun->eh->region_array[i];
1284       rtx lab;
1285
1286       if (! region)
1287         continue;
1288       if (cfun->eh->built_landing_pads)
1289         lab = region->landing_pad;
1290       else
1291         lab = region->label;
1292
1293       if (lab)
1294         list = alloc_EXPR_LIST (0, lab, list);
1295     }
1296
1297   /* For sjlj exceptions, need the return label to remain live until
1298      after landing pad generation.  */
1299   if (USING_SJLJ_EXCEPTIONS && ! cfun->eh->built_landing_pads)
1300     list = alloc_EXPR_LIST (0, return_label, list);
1301
1302   exception_handler_labels = list;
1303 }
1304
1305 \f
1306 static struct eh_region *
1307 duplicate_eh_region_1 (o, map)
1308      struct eh_region *o;
1309      struct inline_remap *map;
1310 {
1311   struct eh_region *n
1312     = (struct eh_region *) xcalloc (1, sizeof (struct eh_region));
1313
1314   n->region_number = o->region_number + cfun->eh->last_region_number;
1315   n->type = o->type;
1316
1317   switch (n->type)
1318     {
1319     case ERT_CLEANUP:
1320     case ERT_MUST_NOT_THROW:
1321       break;
1322
1323     case ERT_TRY:
1324       if (o->u.try.continue_label)
1325         n->u.try.continue_label
1326           = get_label_from_map (map,
1327                                 CODE_LABEL_NUMBER (o->u.try.continue_label));
1328       break;
1329
1330     case ERT_CATCH:
1331       n->u.catch.type = o->u.catch.type;
1332       break;
1333
1334     case ERT_ALLOWED_EXCEPTIONS:
1335       n->u.allowed.type_list = o->u.allowed.type_list;
1336       break;
1337
1338     case ERT_THROW:
1339       n->u.throw.type = o->u.throw.type;
1340       
1341     default:
1342       abort ();
1343     }
1344
1345   if (o->label)
1346     n->label = get_label_from_map (map, CODE_LABEL_NUMBER (o->label));
1347   if (o->resume)
1348     {
1349       n->resume = map->insn_map[INSN_UID (o->resume)];
1350       if (n->resume == NULL)
1351         abort ();
1352     }
1353
1354   return n;
1355 }
1356
1357 static void
1358 duplicate_eh_region_2 (o, n_array)
1359      struct eh_region *o;
1360      struct eh_region **n_array;
1361 {
1362   struct eh_region *n = n_array[o->region_number];
1363
1364   switch (n->type)
1365     {
1366     case ERT_TRY:
1367       n->u.try.catch = n_array[o->u.try.catch->region_number];
1368       n->u.try.last_catch = n_array[o->u.try.last_catch->region_number];
1369       break;
1370
1371     case ERT_CATCH:
1372       if (o->u.catch.next_catch)
1373         n->u.catch.next_catch = n_array[o->u.catch.next_catch->region_number];
1374       if (o->u.catch.prev_catch)
1375         n->u.catch.prev_catch = n_array[o->u.catch.prev_catch->region_number];
1376       break;
1377
1378     default:
1379       break;
1380     }
1381
1382   if (o->outer)
1383     n->outer = n_array[o->outer->region_number];
1384   if (o->inner)
1385     n->inner = n_array[o->inner->region_number];
1386   if (o->next_peer)
1387     n->next_peer = n_array[o->next_peer->region_number];
1388 }    
1389
1390 int
1391 duplicate_eh_regions (ifun, map)
1392      struct function *ifun;
1393      struct inline_remap *map;
1394 {
1395   int ifun_last_region_number = ifun->eh->last_region_number;
1396   struct eh_region **n_array, *root, *cur;
1397   int i;
1398
1399   if (ifun_last_region_number == 0)
1400     return 0;
1401
1402   n_array = xcalloc (ifun_last_region_number + 1, sizeof (*n_array));
1403
1404   for (i = 1; i <= ifun_last_region_number; ++i)
1405     {
1406       cur = ifun->eh->region_array[i];
1407       if (!cur || cur->region_number != i)
1408         continue;
1409       n_array[i] = duplicate_eh_region_1 (cur, map);
1410     }
1411   for (i = 1; i <= ifun_last_region_number; ++i)
1412     {
1413       cur = ifun->eh->region_array[i];
1414       if (!cur || cur->region_number != i)
1415         continue;
1416       duplicate_eh_region_2 (cur, n_array);
1417     }
1418
1419   root = n_array[ifun->eh->region_tree->region_number];
1420   cur = cfun->eh->cur_region;
1421   if (cur)
1422     {
1423       struct eh_region *p = cur->inner;
1424       if (p)
1425         {
1426           while (p->next_peer)
1427             p = p->next_peer;
1428           p->next_peer = root;
1429         }
1430       else
1431         cur->inner = root;
1432
1433       for (i = 1; i <= ifun_last_region_number; ++i)
1434         if (n_array[i]->outer == NULL)
1435           n_array[i]->outer = cur;
1436     }
1437   else
1438     {
1439       struct eh_region *p = cfun->eh->region_tree;
1440       if (p)
1441         {
1442           while (p->next_peer)
1443             p = p->next_peer;
1444           p->next_peer = root;
1445         }
1446       else
1447         cfun->eh->region_tree = root;
1448     }
1449
1450   free (n_array);
1451
1452   i = cfun->eh->last_region_number;
1453   cfun->eh->last_region_number = i + ifun_last_region_number;
1454   return i;
1455 }
1456
1457 \f
1458 /* ??? Move from tree.c to tree.h.  */
1459 #define TYPE_HASH(TYPE) ((HOST_WIDE_INT) (TYPE) & 0777777)
1460
1461 static int
1462 t2r_eq (pentry, pdata)
1463      const PTR pentry;
1464      const PTR pdata;
1465 {
1466   tree entry = (tree) pentry;
1467   tree data = (tree) pdata;
1468
1469   return TREE_PURPOSE (entry) == data;
1470 }
1471
1472 static hashval_t
1473 t2r_hash (pentry)
1474      const PTR pentry;
1475 {
1476   tree entry = (tree) pentry;
1477   return TYPE_HASH (TREE_PURPOSE (entry));
1478 }
1479
1480 static int
1481 t2r_mark_1 (slot, data)
1482      PTR *slot;
1483      PTR data ATTRIBUTE_UNUSED;
1484 {
1485   tree contents = (tree) *slot;
1486   ggc_mark_tree (contents);
1487   return 1;
1488 }
1489
1490 static void
1491 t2r_mark (addr)
1492      PTR addr;
1493 {
1494   htab_traverse (*(htab_t *)addr, t2r_mark_1, NULL);
1495 }
1496
1497 static void
1498 add_type_for_runtime (type)
1499      tree type;
1500 {
1501   tree *slot;
1502
1503   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
1504                                             TYPE_HASH (type), INSERT);
1505   if (*slot == NULL)
1506     {
1507       tree runtime = (*lang_eh_runtime_type) (type);
1508       *slot = tree_cons (type, runtime, NULL_TREE);
1509     }
1510 }
1511   
1512 static tree
1513 lookup_type_for_runtime (type)
1514      tree type;
1515 {
1516   tree *slot;
1517
1518   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
1519                                             TYPE_HASH (type), NO_INSERT);
1520
1521   /* We should have always inserrted the data earlier.  */
1522   return TREE_VALUE (*slot);
1523 }
1524
1525 \f
1526 /* Represent an entry in @TTypes for either catch actions
1527    or exception filter actions.  */
1528 struct ttypes_filter
1529 {
1530   tree t;
1531   int filter;
1532 };
1533
1534 /* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
1535    (a tree) for a @TTypes type node we are thinking about adding.  */
1536
1537 static int
1538 ttypes_filter_eq (pentry, pdata)
1539      const PTR pentry;
1540      const PTR pdata;
1541 {
1542   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1543   tree data = (tree) pdata;
1544
1545   return entry->t == data;
1546 }
1547
1548 static hashval_t
1549 ttypes_filter_hash (pentry)
1550      const PTR pentry;
1551 {
1552   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1553   return TYPE_HASH (entry->t);
1554 }
1555
1556 /* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
1557    exception specification list we are thinking about adding.  */
1558 /* ??? Currently we use the type lists in the order given.  Someone
1559    should put these in some canonical order.  */
1560
1561 static int
1562 ehspec_filter_eq (pentry, pdata)
1563      const PTR pentry;
1564      const PTR pdata;
1565 {
1566   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1567   const struct ttypes_filter *data = (const struct ttypes_filter *) pdata;
1568
1569   return type_list_equal (entry->t, data->t);
1570 }
1571
1572 /* Hash function for exception specification lists.  */
1573
1574 static hashval_t
1575 ehspec_filter_hash (pentry)
1576      const PTR pentry;
1577 {
1578   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1579   hashval_t h = 0;
1580   tree list;
1581
1582   for (list = entry->t; list ; list = TREE_CHAIN (list))
1583     h = (h << 5) + (h >> 27) + TYPE_HASH (TREE_VALUE (list));
1584   return h;
1585 }
1586
1587 /* Add TYPE to cfun->eh->ttype_data, using TYPES_HASH to speed
1588    up the search.  Return the filter value to be used.  */
1589
1590 static int
1591 add_ttypes_entry (ttypes_hash, type)
1592      htab_t ttypes_hash;
1593      tree type;
1594 {
1595   struct ttypes_filter **slot, *n;
1596
1597   slot = (struct ttypes_filter **)
1598     htab_find_slot_with_hash (ttypes_hash, type, TYPE_HASH (type), INSERT);
1599
1600   if ((n = *slot) == NULL)
1601     {
1602       /* Filter value is a 1 based table index.  */
1603
1604       n = (struct ttypes_filter *) xmalloc (sizeof (*n));
1605       n->t = type;
1606       n->filter = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) + 1;
1607       *slot = n;
1608
1609       VARRAY_PUSH_TREE (cfun->eh->ttype_data, type);
1610     }
1611
1612   return n->filter;
1613 }
1614
1615 /* Add LIST to cfun->eh->ehspec_data, using EHSPEC_HASH and TYPES_HASH
1616    to speed up the search.  Return the filter value to be used.  */
1617
1618 static int
1619 add_ehspec_entry (ehspec_hash, ttypes_hash, list)
1620      htab_t ehspec_hash;
1621      htab_t ttypes_hash;
1622      tree list;
1623 {
1624   struct ttypes_filter **slot, *n;
1625   struct ttypes_filter dummy;
1626
1627   dummy.t = list;
1628   slot = (struct ttypes_filter **)
1629     htab_find_slot (ehspec_hash, &dummy, INSERT);
1630
1631   if ((n = *slot) == NULL)
1632     {
1633       /* Filter value is a -1 based byte index into a uleb128 buffer.  */
1634
1635       n = (struct ttypes_filter *) xmalloc (sizeof (*n));
1636       n->t = list;
1637       n->filter = -(VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) + 1);
1638       *slot = n;
1639
1640       /* Look up each type in the list and encode its filter
1641          value as a uleb128.  Terminate the list with 0.  */
1642       for (; list ; list = TREE_CHAIN (list))
1643         push_uleb128 (&cfun->eh->ehspec_data, 
1644                       add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
1645       VARRAY_PUSH_UCHAR (cfun->eh->ehspec_data, 0);
1646     }
1647
1648   return n->filter;
1649 }
1650
1651 /* Generate the action filter values to be used for CATCH and
1652    ALLOWED_EXCEPTIONS regions.  When using dwarf2 exception regions,
1653    we use lots of landing pads, and so every type or list can share
1654    the same filter value, which saves table space.  */
1655
1656 static void
1657 assign_filter_values ()
1658 {
1659   int i;
1660   htab_t ttypes, ehspec;
1661
1662   VARRAY_TREE_INIT (cfun->eh->ttype_data, 16, "ttype_data");
1663   VARRAY_UCHAR_INIT (cfun->eh->ehspec_data, 64, "ehspec_data");
1664
1665   ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free);
1666   ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free);
1667
1668   for (i = cfun->eh->last_region_number; i > 0; --i)
1669     {
1670       struct eh_region *r = cfun->eh->region_array[i];
1671
1672       /* Mind we don't process a region more than once.  */
1673       if (!r || r->region_number != i)
1674         continue;
1675
1676       switch (r->type)
1677         {
1678         case ERT_CATCH:
1679           r->u.catch.filter = add_ttypes_entry (ttypes, r->u.catch.type);
1680           break;
1681
1682         case ERT_ALLOWED_EXCEPTIONS:
1683           r->u.allowed.filter
1684             = add_ehspec_entry (ehspec, ttypes, r->u.allowed.type_list);
1685           break;
1686
1687         default:
1688           break;
1689         }
1690     }
1691
1692   htab_delete (ttypes);
1693   htab_delete (ehspec);
1694 }
1695
1696 static void
1697 build_post_landing_pads ()
1698 {
1699   int i;
1700
1701   for (i = cfun->eh->last_region_number; i > 0; --i)
1702     {
1703       struct eh_region *region = cfun->eh->region_array[i];
1704       rtx seq;
1705
1706       /* Mind we don't process a region more than once.  */
1707       if (!region || region->region_number != i)
1708         continue;
1709
1710       switch (region->type)
1711         {
1712         case ERT_TRY:
1713           /* ??? Collect the set of all non-overlapping catch handlers
1714                all the way up the chain until blocked by a cleanup.  */
1715           /* ??? Outer try regions can share landing pads with inner
1716              try regions if the types are completely non-overlapping,
1717              and there are no interveaning cleanups.  */
1718
1719           region->post_landing_pad = gen_label_rtx ();
1720
1721           start_sequence ();
1722
1723           emit_label (region->post_landing_pad);
1724
1725           /* ??? It is mighty inconvenient to call back into the
1726              switch statement generation code in expand_end_case.
1727              Rapid prototyping sez a sequence of ifs.  */
1728           {
1729             struct eh_region *c;
1730             for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
1731               {
1732                 /* ??? _Unwind_ForcedUnwind wants no match here.  */
1733                 if (c->u.catch.type == NULL)
1734                   emit_jump (c->label);
1735                 else
1736                   emit_cmp_and_jump_insns (cfun->eh->filter,
1737                                            GEN_INT (c->u.catch.filter),
1738                                            EQ, NULL_RTX, word_mode,
1739                                            0, 0, c->label);
1740               }
1741           }
1742
1743           /* We delay the generation of the _Unwind_Resume until we generate
1744              landing pads.  We emit a marker here so as to get good control
1745              flow data in the meantime.  */
1746           region->resume
1747             = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1748           emit_barrier ();
1749
1750           seq = get_insns ();
1751           end_sequence ();
1752
1753           emit_insns_before (seq, region->u.try.catch->label);
1754           break;
1755
1756         case ERT_ALLOWED_EXCEPTIONS:
1757           region->post_landing_pad = gen_label_rtx ();
1758
1759           start_sequence ();
1760
1761           emit_label (region->post_landing_pad);
1762
1763           emit_cmp_and_jump_insns (cfun->eh->filter,
1764                                    GEN_INT (region->u.allowed.filter),
1765                                    EQ, NULL_RTX, word_mode, 0, 0,
1766                                    region->label);
1767
1768           /* We delay the generation of the _Unwind_Resume until we generate
1769              landing pads.  We emit a marker here so as to get good control
1770              flow data in the meantime.  */
1771           region->resume
1772             = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1773           emit_barrier ();
1774
1775           seq = get_insns ();
1776           end_sequence ();
1777
1778           emit_insns_before (seq, region->label);
1779           break;
1780
1781         case ERT_CLEANUP:
1782         case ERT_MUST_NOT_THROW:
1783           region->post_landing_pad = region->label;
1784           break;
1785
1786         case ERT_CATCH:
1787         case ERT_THROW:
1788           /* Nothing to do.  */
1789           break;
1790
1791         default:
1792           abort ();
1793         }
1794     }
1795 }
1796
1797 /* Replace RESX patterns with jumps to the next handler if any, or calls to
1798    _Unwind_Resume otherwise.  */
1799
1800 static void
1801 connect_post_landing_pads ()
1802 {
1803   int i;
1804
1805   for (i = cfun->eh->last_region_number; i > 0; --i)
1806     {
1807       struct eh_region *region = cfun->eh->region_array[i];
1808       struct eh_region *outer;
1809       rtx seq;
1810
1811       /* Mind we don't process a region more than once.  */
1812       if (!region || region->region_number != i)
1813         continue;
1814
1815       /* If there is no RESX, or it has been deleted by flow, there's
1816          nothing to fix up.  */
1817       if (! region->resume || INSN_DELETED_P (region->resume))
1818         continue;
1819
1820       /* Search for another landing pad in this function.  */
1821       for (outer = region->outer; outer ; outer = outer->outer)
1822         if (outer->post_landing_pad)
1823           break;
1824
1825       start_sequence ();
1826
1827       if (outer)
1828         emit_jump (outer->post_landing_pad);
1829       else
1830         emit_library_call (unwind_resume_libfunc, LCT_THROW,
1831                            VOIDmode, 1, cfun->eh->exc_ptr, Pmode);
1832
1833       seq = get_insns ();
1834       end_sequence ();
1835       emit_insns_before (seq, region->resume);
1836
1837       /* Leave the RESX to be deleted by flow.  */
1838     }
1839 }
1840
1841 \f
1842 static void
1843 dw2_build_landing_pads ()
1844 {
1845   int i, j;
1846
1847   for (i = cfun->eh->last_region_number; i > 0; --i)
1848     {
1849       struct eh_region *region = cfun->eh->region_array[i];
1850       rtx seq;
1851
1852       /* Mind we don't process a region more than once.  */
1853       if (!region || region->region_number != i)
1854         continue;
1855
1856       if (region->type != ERT_CLEANUP
1857           && region->type != ERT_TRY
1858           && region->type != ERT_ALLOWED_EXCEPTIONS)
1859         continue;
1860
1861       start_sequence ();
1862
1863       region->landing_pad = gen_label_rtx ();
1864       emit_label (region->landing_pad);
1865
1866 #ifdef HAVE_exception_receiver
1867       if (HAVE_exception_receiver)
1868         emit_insn (gen_exception_receiver ());
1869       else
1870 #endif
1871 #ifdef HAVE_nonlocal_goto_receiver
1872         if (HAVE_nonlocal_goto_receiver)
1873           emit_insn (gen_nonlocal_goto_receiver ());
1874         else
1875 #endif
1876           { /* Nothing */ }
1877
1878       /* If the eh_return data registers are call-saved, then we
1879          won't have considered them clobbered from the call that
1880          threw.  Kill them now.  */
1881       for (j = 0; ; ++j)
1882         {
1883           unsigned r = EH_RETURN_DATA_REGNO (j);
1884           if (r == INVALID_REGNUM)
1885             break;
1886           if (! call_used_regs[r])
1887             emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, r)));
1888         }
1889
1890       emit_move_insn (cfun->eh->exc_ptr,
1891                       gen_rtx_REG (Pmode, EH_RETURN_DATA_REGNO (0)));
1892       emit_move_insn (cfun->eh->filter,
1893                       gen_rtx_REG (Pmode, EH_RETURN_DATA_REGNO (1)));
1894
1895       seq = get_insns ();
1896       end_sequence ();
1897
1898       emit_insns_before (seq, region->post_landing_pad);
1899     }
1900 }
1901
1902 \f
1903 struct sjlj_lp_info
1904 {
1905   int directly_reachable;
1906   int action_index;
1907   int dispatch_index;
1908   int call_site_index;
1909 };
1910
1911 static bool
1912 sjlj_find_directly_reachable_regions (lp_info)
1913      struct sjlj_lp_info *lp_info;
1914 {
1915   rtx insn;
1916   bool found_one = false;
1917
1918   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
1919     {
1920       struct eh_region *region;
1921       tree type_thrown;
1922       rtx note;
1923
1924       if (! INSN_P (insn))
1925         continue;
1926
1927       note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1928       if (!note || INTVAL (XEXP (note, 0)) <= 0)
1929         continue;
1930
1931       region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
1932
1933       type_thrown = NULL_TREE;
1934       if (region->type == ERT_THROW)
1935         {
1936           type_thrown = region->u.throw.type;
1937           region = region->outer;
1938         }
1939
1940       /* Find the first containing region that might handle the exception.
1941          That's the landing pad to which we will transfer control.  */
1942       for (; region; region = region->outer)
1943         if (reachable_next_level (region, type_thrown, 0) != RNL_NOT_CAUGHT)
1944           break;
1945
1946       if (region)
1947         {
1948           lp_info[region->region_number].directly_reachable = 1;
1949           found_one = true;
1950         }
1951     }
1952
1953   return found_one;
1954 }
1955
1956 static void
1957 sjlj_assign_call_site_values (dispatch_label, lp_info)
1958      rtx dispatch_label;
1959      struct sjlj_lp_info *lp_info;
1960 {
1961   htab_t ar_hash;
1962   int i, index;
1963
1964   /* First task: build the action table.  */
1965
1966   VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
1967   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
1968
1969   for (i = cfun->eh->last_region_number; i > 0; --i)
1970     if (lp_info[i].directly_reachable)
1971       {
1972         struct eh_region *r = cfun->eh->region_array[i];
1973         r->landing_pad = dispatch_label;
1974         lp_info[i].action_index = collect_one_action_chain (ar_hash, r);
1975         if (lp_info[i].action_index != -1)
1976           cfun->uses_eh_lsda = 1;
1977       }
1978
1979   htab_delete (ar_hash);
1980
1981   /* Next: assign dispatch values.  In dwarf2 terms, this would be the
1982      landing pad label for the region.  For sjlj though, there is one
1983      common landing pad from which we dispatch to the post-landing pads.
1984
1985      A region receives a dispatch index if it is directly reachable
1986      and requires in-function processing.  Regions that share post-landing
1987      pads may share dispatch indicies.  */
1988   /* ??? Post-landing pad sharing doesn't actually happen at the moment
1989      (see build_post_landing_pads) so we don't bother checking for it.  */
1990
1991   index = 0;
1992   for (i = cfun->eh->last_region_number; i > 0; --i)
1993     if (lp_info[i].directly_reachable
1994         && lp_info[i].action_index >= 0)
1995       lp_info[i].dispatch_index = index++;
1996
1997   /* Finally: assign call-site values.  If dwarf2 terms, this would be
1998      the region number assigned by convert_to_eh_region_ranges, but
1999      handles no-action and must-not-throw differently.  */
2000
2001   call_site_base = 1;
2002   for (i = cfun->eh->last_region_number; i > 0; --i)
2003     if (lp_info[i].directly_reachable)
2004       {
2005         int action = lp_info[i].action_index;
2006
2007         /* Map must-not-throw to otherwise unused call-site index 0.  */
2008         if (action == -2)
2009           index = 0;
2010         /* Map no-action to otherwise unused call-site index -1.  */
2011         else if (action == -1)
2012           index = -1;
2013         /* Otherwise, look it up in the table.  */
2014         else
2015           index = add_call_site (GEN_INT (lp_info[i].dispatch_index), action);
2016
2017         lp_info[i].call_site_index = index;
2018       }
2019 }
2020
2021 static void
2022 sjlj_mark_call_sites (lp_info)
2023      struct sjlj_lp_info *lp_info;
2024 {
2025   int last_call_site = -2;
2026   rtx insn, mem;
2027
2028   mem = change_address (cfun->eh->sjlj_fc, TYPE_MODE (integer_type_node),
2029                         plus_constant (XEXP (cfun->eh->sjlj_fc, 0),
2030                                        sjlj_fc_call_site_ofs));
2031
2032   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
2033     {
2034       struct eh_region *region;
2035       int this_call_site;
2036       rtx note, before, p;
2037
2038       /* Reset value tracking at extended basic block boundaries.  */
2039       if (GET_CODE (insn) == CODE_LABEL)
2040         last_call_site = -2;
2041
2042       if (! INSN_P (insn))
2043         continue;
2044
2045       note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2046       if (!note)
2047         {
2048           /* Calls (and trapping insns) without notes are outside any
2049              exception handling region in this function.  Mark them as
2050              no action.  */
2051           if (GET_CODE (insn) == CALL_INSN
2052               || (flag_non_call_exceptions
2053                   && may_trap_p (PATTERN (insn))))
2054             this_call_site = -1;
2055           else
2056             continue;
2057         }
2058       else
2059         {
2060           /* Calls that are known to not throw need not be marked.  */
2061           if (INTVAL (XEXP (note, 0)) <= 0)
2062             continue;
2063
2064           region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2065           this_call_site = lp_info[region->region_number].call_site_index;
2066         }
2067
2068       if (this_call_site == last_call_site)
2069         continue;
2070
2071       /* Don't separate a call from it's argument loads.  */
2072       before = insn;
2073       if (GET_CODE (insn) == CALL_INSN)
2074         {
2075           HARD_REG_SET parm_regs;
2076           int nparm_regs;
2077           
2078           /* Since different machines initialize their parameter registers
2079              in different orders, assume nothing.  Collect the set of all
2080              parameter registers.  */
2081           CLEAR_HARD_REG_SET (parm_regs);
2082           nparm_regs = 0;
2083           for (p = CALL_INSN_FUNCTION_USAGE (insn); p ; p = XEXP (p, 1))
2084             if (GET_CODE (XEXP (p, 0)) == USE
2085                 && GET_CODE (XEXP (XEXP (p, 0), 0)) == REG)
2086               {
2087                 if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER)
2088                   abort ();
2089
2090                 SET_HARD_REG_BIT (parm_regs, REGNO (XEXP (XEXP (p, 0), 0)));
2091                 nparm_regs++;
2092               }
2093
2094           /* Search backward for the first set of a register in this set.  */
2095           while (nparm_regs)
2096             {
2097               before = PREV_INSN (before);
2098
2099               /* Given that we've done no other optimizations yet,
2100                  the arguments should be immediately available.  */
2101               if (GET_CODE (before) == CODE_LABEL)
2102                 abort ();
2103
2104               p = single_set (before);
2105               if (p && GET_CODE (SET_DEST (p)) == REG
2106                   && REGNO (SET_DEST (p)) < FIRST_PSEUDO_REGISTER
2107                   && TEST_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p))))
2108                 {
2109                   CLEAR_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p)));
2110                   nparm_regs--;
2111                 }
2112             }
2113         }
2114
2115       start_sequence ();
2116       emit_move_insn (mem, GEN_INT (this_call_site));
2117       p = get_insns ();
2118       end_sequence ();
2119
2120       emit_insns_before (p, before);
2121       last_call_site = this_call_site;
2122     }
2123 }
2124
2125 /* Construct the SjLj_Function_Context.  */
2126
2127 static void
2128 sjlj_emit_function_enter (dispatch_label)
2129      rtx dispatch_label;
2130 {
2131   rtx fn_begin, fc, mem, seq;
2132
2133   fc = cfun->eh->sjlj_fc;
2134
2135   start_sequence ();
2136
2137   mem = change_address (fc, Pmode,
2138                         plus_constant (XEXP (fc, 0), sjlj_fc_personality_ofs));
2139   emit_move_insn (mem, eh_personality_libfunc);
2140
2141   mem = change_address (fc, Pmode,
2142                         plus_constant (XEXP (fc, 0), sjlj_fc_lsda_ofs));
2143   if (cfun->uses_eh_lsda)
2144     {
2145       char buf[20];
2146       ASM_GENERATE_INTERNAL_LABEL (buf, "LLSDA", sjlj_funcdef_number);
2147       emit_move_insn (mem, gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)));
2148     }
2149   else
2150     emit_move_insn (mem, const0_rtx);
2151   
2152 #ifdef DONT_USE_BUILTIN_SETJMP
2153   {
2154     rtx x, note;
2155     x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_NORMAL,
2156                                  TYPE_MODE (integer_type_node), 1,
2157                                  plus_constant (XEXP (fc, 0),
2158                                                 sjlj_fc_jbuf_ofs), Pmode);
2159
2160     note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
2161     NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, x, const0_rtx);
2162
2163     emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
2164                              TYPE_MODE (integer_type_node), 0, 0,
2165                              dispatch_label);
2166   }
2167 #else
2168   expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
2169                                dispatch_label);
2170 #endif
2171
2172   emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
2173                      1, XEXP (fc, 0), Pmode);
2174
2175   seq = get_insns ();
2176   end_sequence ();
2177
2178   /* ??? Instead of doing this at the beginning of the function,
2179      do this in a block that is at loop level 0 and dominates all
2180      can_throw_internal instructions.  */
2181
2182   for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
2183     if (GET_CODE (fn_begin) == NOTE
2184         && NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
2185       break;
2186   emit_insns_after (seq, fn_begin);
2187 }
2188
2189 /* Call back from expand_function_end to know where we should put
2190    the call to unwind_sjlj_unregister_libfunc if needed.  */
2191
2192 void
2193 sjlj_emit_function_exit_after (after)
2194      rtx after;
2195 {
2196   cfun->eh->sjlj_exit_after = after;
2197 }
2198
2199 static void
2200 sjlj_emit_function_exit ()
2201 {
2202   rtx seq;
2203
2204   start_sequence ();
2205
2206   emit_library_call (unwind_sjlj_unregister_libfunc, LCT_NORMAL, VOIDmode,
2207                      1, XEXP (cfun->eh->sjlj_fc, 0), Pmode);
2208
2209   seq = get_insns ();
2210   end_sequence ();
2211
2212   /* ??? Really this can be done in any block at loop level 0 that
2213      post-dominates all can_throw_internal instructions.  This is
2214      the last possible moment.  */
2215
2216   emit_insns_after (seq, cfun->eh->sjlj_exit_after);
2217 }
2218
2219 static void
2220 sjlj_emit_dispatch_table (dispatch_label, lp_info)
2221      rtx dispatch_label;
2222      struct sjlj_lp_info *lp_info;
2223 {
2224   int i, first_reachable;
2225   rtx mem, dispatch, seq, fc;
2226
2227   fc = cfun->eh->sjlj_fc;
2228
2229   start_sequence ();
2230
2231   emit_label (dispatch_label);
2232   
2233 #ifndef DONT_USE_BUILTIN_SETJMP
2234   expand_builtin_setjmp_receiver (dispatch_label);
2235 #endif
2236
2237   /* Load up dispatch index, exc_ptr and filter values from the
2238      function context.  */
2239   mem = change_address (fc, TYPE_MODE (integer_type_node),
2240                         plus_constant (XEXP (fc, 0), sjlj_fc_call_site_ofs));
2241   dispatch = copy_to_reg (mem);
2242
2243   mem = change_address (fc, word_mode,
2244                         plus_constant (XEXP (fc, 0), sjlj_fc_data_ofs));
2245   if (word_mode != Pmode)
2246     {
2247 #ifdef POINTERS_EXTEND_UNSIGNED
2248       mem = convert_memory_address (Pmode, mem);
2249 #else
2250       mem = convert_to_mode (Pmode, mem, 0);
2251 #endif
2252     }
2253   emit_move_insn (cfun->eh->exc_ptr, mem);
2254
2255   mem = change_address (fc, word_mode,
2256                         plus_constant (XEXP (fc, 0),
2257                                        sjlj_fc_data_ofs + UNITS_PER_WORD));
2258   emit_move_insn (cfun->eh->filter, mem);
2259
2260   /* Jump to one of the directly reachable regions.  */
2261   /* ??? This really ought to be using a switch statement.  */
2262
2263   first_reachable = 0;
2264   for (i = cfun->eh->last_region_number; i > 0; --i)
2265     {
2266       if (! lp_info[i].directly_reachable
2267           || lp_info[i].action_index < 0)
2268         continue;
2269
2270       if (! first_reachable)
2271         {
2272           first_reachable = i;
2273           continue;
2274         }
2275
2276       emit_cmp_and_jump_insns (dispatch,
2277                                GEN_INT (lp_info[i].dispatch_index), EQ,
2278                                NULL_RTX, TYPE_MODE (integer_type_node), 0, 0,
2279                                cfun->eh->region_array[i]->post_landing_pad);
2280     }
2281
2282   seq = get_insns ();
2283   end_sequence ();
2284
2285   emit_insns_before (seq, (cfun->eh->region_array[first_reachable]
2286                            ->post_landing_pad));
2287 }
2288
2289 static void
2290 sjlj_build_landing_pads ()
2291 {
2292   struct sjlj_lp_info *lp_info;
2293
2294   lp_info = (struct sjlj_lp_info *) xcalloc (cfun->eh->last_region_number + 1,
2295                                              sizeof (struct sjlj_lp_info));
2296
2297   if (sjlj_find_directly_reachable_regions (lp_info))
2298     {
2299       rtx dispatch_label = gen_label_rtx ();
2300
2301       cfun->eh->sjlj_fc
2302         = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
2303                               int_size_in_bytes (sjlj_fc_type_node),
2304                               TYPE_ALIGN (sjlj_fc_type_node));
2305
2306       sjlj_assign_call_site_values (dispatch_label, lp_info);
2307       sjlj_mark_call_sites (lp_info);
2308
2309       sjlj_emit_function_enter (dispatch_label);
2310       sjlj_emit_dispatch_table (dispatch_label, lp_info);
2311       sjlj_emit_function_exit ();
2312     }
2313
2314   free (lp_info);
2315 }
2316
2317 void
2318 finish_eh_generation ()
2319 {
2320   /* Nothing to do if no regions created.  */
2321   if (cfun->eh->region_tree == NULL)
2322     return;
2323
2324   /* The object here is to provide find_basic_blocks with detailed
2325      information (via reachable_handlers) on how exception control
2326      flows within the function.  In this first pass, we can include
2327      type information garnered from ERT_THROW and ERT_ALLOWED_EXCEPTIONS
2328      regions, and hope that it will be useful in deleting unreachable
2329      handlers.  Subsequently, we will generate landing pads which will
2330      connect many of the handlers, and then type information will not
2331      be effective.  Still, this is a win over previous implementations.  */
2332
2333   jump_optimize_minimal (get_insns ());
2334   find_basic_blocks (get_insns (), max_reg_num (), 0);
2335   cleanup_cfg ();
2336
2337   /* These registers are used by the landing pads.  Make sure they
2338      have been generated.  */
2339   get_exception_pointer ();
2340   get_exception_filter ();
2341
2342   /* Construct the landing pads.  */
2343
2344   assign_filter_values ();
2345   build_post_landing_pads ();
2346   connect_post_landing_pads ();
2347   if (USING_SJLJ_EXCEPTIONS)
2348     sjlj_build_landing_pads ();
2349   else
2350     dw2_build_landing_pads ();
2351
2352   cfun->eh->built_landing_pads = 1;
2353
2354   /* We've totally changed the CFG.  Start over.  */
2355   find_exception_handler_labels ();
2356   jump_optimize_minimal (get_insns ());
2357   find_basic_blocks (get_insns (), max_reg_num (), 0);
2358   cleanup_cfg ();
2359 }
2360 \f
2361 /* This section handles removing dead code for flow.  */
2362
2363 /* Remove LABEL from the exception_handler_labels list.  */
2364
2365 static void
2366 remove_exception_handler_label (label)
2367      rtx label;
2368 {
2369   rtx *pl, l;
2370
2371   for (pl = &exception_handler_labels, l = *pl;
2372        XEXP (l, 0) != label;
2373        pl = &XEXP (l, 1), l = *pl)
2374     continue;
2375
2376   *pl = XEXP (l, 1);
2377   free_EXPR_LIST_node (l);
2378 }
2379
2380 /* Splice REGION from the region tree etc.  */
2381
2382 static void
2383 remove_eh_handler (region)
2384      struct eh_region *region;
2385 {
2386   struct eh_region **pp, *p;
2387   rtx lab;
2388   int i;
2389
2390   /* For the benefit of efficiently handling REG_EH_REGION notes,
2391      replace this region in the region array with its containing
2392      region.  Note that previous region deletions may result in
2393      multiple copies of this region in the array, so we have to
2394      search the whole thing.  */
2395   for (i = cfun->eh->last_region_number; i > 0; --i)
2396     if (cfun->eh->region_array[i] == region)
2397       cfun->eh->region_array[i] = region->outer;
2398
2399   if (cfun->eh->built_landing_pads)
2400     lab = region->landing_pad;
2401   else
2402     lab = region->label;
2403   if (lab)
2404     remove_exception_handler_label (lab);
2405
2406   if (region->outer)
2407     pp = &region->outer->inner;
2408   else
2409     pp = &cfun->eh->region_tree;
2410   for (p = *pp; p != region; pp = &p->next_peer, p = *pp)
2411     continue;
2412
2413   if (region->inner)
2414     {
2415       for (p = region->inner; p->next_peer ; p = p->next_peer)
2416         p->outer = region->outer;
2417       p->next_peer = region->next_peer;
2418       p->outer = region->outer;
2419       *pp = region->inner;
2420     }
2421   else
2422     *pp = region->next_peer;
2423
2424   if (region->type == ERT_CATCH)
2425     {
2426       struct eh_region *try, *next, *prev;
2427
2428       for (try = region->next_peer;
2429            try->type == ERT_CATCH;
2430            try = try->next_peer)
2431         continue;
2432       if (try->type != ERT_TRY)
2433         abort ();
2434
2435       next = region->u.catch.next_catch;
2436       prev = region->u.catch.prev_catch;
2437
2438       if (next)
2439         next->u.catch.prev_catch = prev;
2440       else
2441         try->u.try.last_catch = prev;
2442       if (prev)
2443         prev->u.catch.next_catch = next;
2444       else
2445         {
2446           try->u.try.catch = next;
2447           if (! next)
2448             remove_eh_handler (try);
2449         }
2450     }
2451
2452   free (region);
2453 }
2454
2455 /* LABEL heads a basic block that is about to be deleted.  If this
2456    label corresponds to an exception region, we may be able to
2457    delete the region.  */
2458
2459 void
2460 maybe_remove_eh_handler (label)
2461      rtx label;
2462 {
2463   int i;
2464
2465   /* ??? After generating landing pads, it's not so simple to determine
2466      if the region data is completely unused.  One must examine the
2467      landing pad and the post landing pad, and whether an inner try block
2468      is referencing the catch handlers directly.  */
2469   if (cfun->eh->built_landing_pads)
2470     return;
2471
2472   for (i = cfun->eh->last_region_number; i > 0; --i)
2473     {
2474       struct eh_region *region = cfun->eh->region_array[i];
2475       if (region && region->label == label)
2476         {
2477           /* Flow will want to remove MUST_NOT_THROW regions as unreachable
2478              because there is no path to the fallback call to terminate.
2479              But the region continues to affect call-site data until there
2480              are no more contained calls, which we don't see here.  */
2481           if (region->type == ERT_MUST_NOT_THROW)
2482             {
2483               remove_exception_handler_label (region->label);
2484               region->label = NULL_RTX;
2485             }
2486           else
2487             remove_eh_handler (region);
2488           break;
2489         }
2490     }
2491 }
2492
2493 \f
2494 /* This section describes CFG exception edges for flow.  */
2495
2496 /* For communicating between calls to reachable_next_level.  */
2497 struct reachable_info
2498 {
2499   tree types_caught;
2500   tree types_allowed;
2501   rtx handlers;
2502 };
2503
2504 /* A subroutine of reachable_next_level.  Return true if TYPE, or a
2505    base class of TYPE, is in HANDLED.  */
2506
2507 static int
2508 check_handled (handled, type)
2509      tree handled, type;
2510 {
2511   tree t;
2512
2513   /* We can check for exact matches without front-end help.  */
2514   if (! lang_eh_type_covers)
2515     {
2516       for (t = handled; t ; t = TREE_CHAIN (t))
2517         if (TREE_VALUE (t) == type)
2518           return 1;
2519     }
2520   else
2521     {
2522       for (t = handled; t ; t = TREE_CHAIN (t))
2523         if ((*lang_eh_type_covers) (TREE_VALUE (t), type))
2524           return 1;
2525     }
2526
2527   return 0;
2528 }
2529
2530 /* A subroutine of reachable_next_level.  If we are collecting a list
2531    of handlers, add one.  After landing pad generation, reference
2532    it instead of the handlers themselves.  Further, the handlers are
2533    all wired together, so by referencing one, we've got them all. 
2534    Before landing pad generation we reference each handler individually.
2535
2536    LP_REGION contains the landing pad; REGION is the handler.  */
2537
2538 static void
2539 add_reachable_handler (info, lp_region, region)
2540      struct reachable_info *info;
2541      struct eh_region *lp_region;
2542      struct eh_region *region;
2543 {
2544   if (! info)
2545     return;
2546
2547   if (cfun->eh->built_landing_pads)
2548     {
2549       if (! info->handlers)
2550         info->handlers = alloc_INSN_LIST (lp_region->landing_pad, NULL_RTX);
2551     }
2552   else
2553     info->handlers = alloc_INSN_LIST (region->label, info->handlers);
2554 }
2555
2556 /* Process one level of exception regions for reachability.  
2557    If TYPE_THROWN is non-null, then it is the *exact* type being
2558    propagated.  If INFO is non-null, then collect handler labels
2559    and caught/allowed type information between invocations.  */
2560
2561 static enum reachable_code
2562 reachable_next_level (region, type_thrown, info)
2563      struct eh_region *region;
2564      tree type_thrown;
2565      struct reachable_info *info;
2566 {
2567   switch (region->type)
2568     {
2569     case ERT_CLEANUP:
2570       /* Before landing-pad generation, we model control flow
2571          directly to the individual handlers.  In this way we can
2572          see that catch handler types may shadow one another.  */
2573       add_reachable_handler (info, region, region);
2574       return RNL_MAYBE_CAUGHT;
2575
2576     case ERT_TRY:
2577       {
2578         struct eh_region *c;
2579         enum reachable_code ret = RNL_NOT_CAUGHT;
2580
2581         for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
2582           {
2583             /* A catch-all handler ends the search.  */
2584             /* ??? _Unwind_ForcedUnwind will want outer cleanups
2585                to be run as well.  */
2586             if (c->u.catch.type == NULL)
2587               {
2588                 add_reachable_handler (info, region, c);
2589                 return RNL_CAUGHT;
2590               }
2591
2592             if (type_thrown)
2593               {
2594                 /* If we have a type match, end the search.  */
2595                 if (c->u.catch.type == type_thrown
2596                     || (lang_eh_type_covers
2597                         && (*lang_eh_type_covers) (c->u.catch.type,
2598                                                    type_thrown)))
2599                   {
2600                     add_reachable_handler (info, region, c);
2601                     return RNL_CAUGHT;
2602                   }
2603
2604                 /* If we have definitive information of a match failure,
2605                    the catch won't trigger.  */
2606                 if (lang_eh_type_covers)
2607                   return RNL_NOT_CAUGHT;
2608               }
2609
2610             if (! info)
2611               ret = RNL_MAYBE_CAUGHT;
2612
2613             /* A type must not have been previously caught.  */
2614             else if (! check_handled (info->types_caught, c->u.catch.type))
2615               {
2616                 add_reachable_handler (info, region, c);
2617                 info->types_caught = tree_cons (NULL, c->u.catch.type,
2618                                                 info->types_caught);
2619
2620                 /* ??? If the catch type is a base class of every allowed
2621                    type, then we know we can stop the search.  */
2622                 ret = RNL_MAYBE_CAUGHT;
2623               }
2624           }
2625
2626         return ret;
2627       }
2628
2629     case ERT_ALLOWED_EXCEPTIONS:
2630       /* An empty list of types definitely ends the search.  */
2631       if (region->u.allowed.type_list == NULL_TREE)
2632         {
2633           add_reachable_handler (info, region, region);
2634           return RNL_CAUGHT;
2635         }
2636
2637       /* Collect a list of lists of allowed types for use in detecting
2638          when a catch may be transformed into a catch-all.  */
2639       if (info)
2640         info->types_allowed = tree_cons (NULL_TREE,
2641                                          region->u.allowed.type_list,
2642                                          info->types_allowed);
2643             
2644       /* If we have definitive information about the type heirarchy,
2645          then we can tell if the thrown type will pass through the
2646          filter.  */
2647       if (type_thrown && lang_eh_type_covers)
2648         {
2649           if (check_handled (region->u.allowed.type_list, type_thrown))
2650             return RNL_NOT_CAUGHT;
2651           else
2652             {
2653               add_reachable_handler (info, region, region);
2654               return RNL_CAUGHT;
2655             }
2656         }
2657
2658       add_reachable_handler (info, region, region);
2659       return RNL_MAYBE_CAUGHT;
2660
2661     case ERT_CATCH:
2662       /* Catch regions are handled by their controling try region.  */
2663       return RNL_NOT_CAUGHT;
2664
2665     case ERT_MUST_NOT_THROW:
2666       /* Here we end our search, since no exceptions may propagate.
2667          If we've touched down at some landing pad previous, then the
2668          explicit function call we generated may be used.  Otherwise
2669          the call is made by the runtime.  */
2670       if (info && info->handlers)
2671         {
2672           add_reachable_handler (info, region, region);
2673           return RNL_CAUGHT;
2674         }
2675       else
2676         return RNL_BLOCKED;
2677
2678     case ERT_THROW:
2679     case ERT_FIXUP:
2680       /* Shouldn't see these here.  */
2681       break;
2682     }
2683
2684   abort ();
2685 }
2686
2687 /* Retrieve a list of labels of exception handlers which can be
2688    reached by a given insn.  */
2689
2690 rtx
2691 reachable_handlers (insn)
2692      rtx insn;
2693 {
2694   struct reachable_info info;
2695   struct eh_region *region;
2696   tree type_thrown;
2697   int region_number;
2698
2699   if (GET_CODE (insn) == JUMP_INSN
2700       && GET_CODE (PATTERN (insn)) == RESX)
2701     region_number = XINT (PATTERN (insn), 0);
2702   else
2703     {
2704       rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2705       if (!note || INTVAL (XEXP (note, 0)) <= 0)
2706         return NULL;
2707       region_number = INTVAL (XEXP (note, 0));
2708     }
2709
2710   memset (&info, 0, sizeof (info));
2711
2712   region = cfun->eh->region_array[region_number];
2713
2714   type_thrown = NULL_TREE;
2715   if (region->type == ERT_THROW)
2716     {
2717       type_thrown = region->u.throw.type;
2718       region = region->outer;
2719     }
2720   else if (GET_CODE (insn) == JUMP_INSN
2721            && GET_CODE (PATTERN (insn)) == RESX)
2722     region = region->outer;
2723
2724   for (; region; region = region->outer)
2725     if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT)
2726       break;
2727
2728   return info.handlers;
2729 }
2730
2731 /* Determine if the given INSN can throw an exception that is caught
2732    within the function.  */
2733
2734 bool
2735 can_throw_internal (insn)
2736      rtx insn;
2737 {
2738   struct eh_region *region;
2739   tree type_thrown;
2740   rtx note;
2741
2742   if (! INSN_P (insn))
2743     return false;
2744
2745   if (GET_CODE (insn) == INSN
2746       && GET_CODE (PATTERN (insn)) == SEQUENCE)
2747     insn = XVECEXP (PATTERN (insn), 0, 0);
2748
2749   if (GET_CODE (insn) == CALL_INSN
2750       && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
2751     {
2752       int i;
2753       for (i = 0; i < 3; ++i)
2754         {
2755           rtx sub = XEXP (PATTERN (insn), i);
2756           for (; sub ; sub = NEXT_INSN (sub))
2757             if (can_throw_internal (sub))
2758               return true;
2759         }
2760       return false;
2761     }
2762
2763   /* Every insn that might throw has an EH_REGION note.  */
2764   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2765   if (!note || INTVAL (XEXP (note, 0)) <= 0)
2766     return false;
2767
2768   region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2769
2770   type_thrown = NULL_TREE;
2771   if (region->type == ERT_THROW)
2772     {
2773       type_thrown = region->u.throw.type;
2774       region = region->outer;
2775     }
2776
2777   /* If this exception is ignored by each and every containing region,
2778      then control passes straight out.  The runtime may handle some
2779      regions, which also do not require processing internally.  */
2780   for (; region; region = region->outer)
2781     {
2782       enum reachable_code how = reachable_next_level (region, type_thrown, 0);
2783       if (how == RNL_BLOCKED)
2784         return false;
2785       if (how != RNL_NOT_CAUGHT)
2786         return true;
2787     }
2788
2789   return false;
2790 }
2791
2792 /* Determine if the given INSN can throw an exception that is
2793    visible outside the function.  */
2794
2795 bool
2796 can_throw_external (insn)
2797      rtx insn;
2798 {
2799   struct eh_region *region;
2800   tree type_thrown;
2801   rtx note;
2802
2803   if (! INSN_P (insn))
2804     return false;
2805
2806   if (GET_CODE (insn) == INSN
2807       && GET_CODE (PATTERN (insn)) == SEQUENCE)
2808     insn = XVECEXP (PATTERN (insn), 0, 0);
2809
2810   if (GET_CODE (insn) == CALL_INSN
2811       && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
2812     {
2813       int i;
2814       for (i = 0; i < 3; ++i)
2815         {
2816           rtx sub = XEXP (PATTERN (insn), i);
2817           for (; sub ; sub = NEXT_INSN (sub))
2818             if (can_throw_external (sub))
2819               return true;
2820         }
2821       return false;
2822     }
2823
2824   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2825   if (!note)
2826     {
2827       /* Calls (and trapping insns) without notes are outside any
2828          exception handling region in this function.  We have to
2829          assume it might throw.  Given that the front end and middle
2830          ends mark known NOTHROW functions, this isn't so wildly
2831          inaccurate.  */
2832       return (GET_CODE (insn) == CALL_INSN
2833               || (flag_non_call_exceptions
2834                   && may_trap_p (PATTERN (insn))));
2835     }
2836   if (INTVAL (XEXP (note, 0)) <= 0)
2837     return false;
2838
2839   region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2840
2841   type_thrown = NULL_TREE;
2842   if (region->type == ERT_THROW)
2843     {
2844       type_thrown = region->u.throw.type;
2845       region = region->outer;
2846     }
2847
2848   /* If the exception is caught or blocked by any containing region,
2849      then it is not seen by any calling function.  */
2850   for (; region ; region = region->outer)
2851     if (reachable_next_level (region, type_thrown, NULL) >= RNL_CAUGHT)
2852       return false;
2853
2854   return true;
2855 }
2856
2857 /* True if nothing in this function can throw outside this function.  */
2858
2859 bool
2860 nothrow_function_p ()
2861 {
2862   rtx insn;
2863
2864   if (! flag_exceptions)
2865     return true;
2866
2867   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2868     if (can_throw_external (insn))
2869       return false;
2870   for (insn = current_function_epilogue_delay_list; insn;
2871        insn = XEXP (insn, 1))
2872     if (can_throw_external (insn))
2873       return false;
2874
2875   return true;
2876 }
2877
2878 \f
2879 /* Various hooks for unwind library.  */
2880
2881 /* Do any necessary initialization to access arbitrary stack frames.
2882    On the SPARC, this means flushing the register windows.  */
2883
2884 void
2885 expand_builtin_unwind_init ()
2886 {
2887   /* Set this so all the registers get saved in our frame; we need to be
2888      able to copy the saved values for any registers from frames we unwind. */
2889   current_function_has_nonlocal_label = 1;
2890
2891 #ifdef SETUP_FRAME_ADDRESSES
2892   SETUP_FRAME_ADDRESSES ();
2893 #endif
2894 }
2895
2896 rtx
2897 expand_builtin_eh_return_data_regno (arglist)
2898      tree arglist;
2899 {
2900   tree which = TREE_VALUE (arglist);
2901   unsigned HOST_WIDE_INT iwhich;
2902
2903   if (TREE_CODE (which) != INTEGER_CST)
2904     {
2905       error ("argument of `__builtin_eh_return_regno' must be constant");
2906       return constm1_rtx;
2907     }
2908
2909   iwhich = tree_low_cst (which, 1);
2910   iwhich = EH_RETURN_DATA_REGNO (iwhich);
2911   if (iwhich == INVALID_REGNUM)
2912     return constm1_rtx;
2913
2914 #ifdef DWARF_FRAME_REGNUM
2915   iwhich = DWARF_FRAME_REGNUM (iwhich);
2916 #else
2917   iwhich = DBX_REGISTER_NUMBER (iwhich);
2918 #endif
2919
2920   return GEN_INT (iwhich);      
2921 }
2922
2923 /* Given a value extracted from the return address register or stack slot,
2924    return the actual address encoded in that value.  */
2925
2926 rtx
2927 expand_builtin_extract_return_addr (addr_tree)
2928      tree addr_tree;
2929 {
2930   rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
2931
2932   /* First mask out any unwanted bits.  */
2933 #ifdef MASK_RETURN_ADDR
2934   expand_and (addr, MASK_RETURN_ADDR, addr);
2935 #endif
2936
2937   /* Then adjust to find the real return address.  */
2938 #if defined (RETURN_ADDR_OFFSET)
2939   addr = plus_constant (addr, RETURN_ADDR_OFFSET);
2940 #endif
2941
2942   return addr;
2943 }
2944
2945 /* Given an actual address in addr_tree, do any necessary encoding
2946    and return the value to be stored in the return address register or
2947    stack slot so the epilogue will return to that address.  */
2948
2949 rtx
2950 expand_builtin_frob_return_addr (addr_tree)
2951      tree addr_tree;
2952 {
2953   rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
2954
2955 #ifdef RETURN_ADDR_OFFSET
2956   addr = force_reg (Pmode, addr);
2957   addr = plus_constant (addr, -RETURN_ADDR_OFFSET);
2958 #endif
2959
2960   return addr;
2961 }
2962
2963 /* Set up the epilogue with the magic bits we'll need to return to the
2964    exception handler.  */
2965
2966 void
2967 expand_builtin_eh_return (stackadj_tree, handler_tree)
2968     tree stackadj_tree, handler_tree;
2969 {
2970   rtx stackadj, handler;
2971
2972   stackadj = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj, VOIDmode, 0);
2973   handler = expand_expr (handler_tree, cfun->eh->ehr_handler, VOIDmode, 0);
2974
2975   if (! cfun->eh->ehr_label)
2976     {
2977       cfun->eh->ehr_stackadj = copy_to_reg (stackadj);
2978       cfun->eh->ehr_handler = copy_to_reg (handler);
2979       cfun->eh->ehr_label = gen_label_rtx ();
2980     }
2981   else
2982     {
2983       if (stackadj != cfun->eh->ehr_stackadj)
2984         emit_move_insn (cfun->eh->ehr_stackadj, stackadj);
2985       if (handler != cfun->eh->ehr_handler)
2986         emit_move_insn (cfun->eh->ehr_handler, handler);
2987     }
2988
2989   emit_jump (cfun->eh->ehr_label);
2990 }
2991
2992 void
2993 expand_eh_return ()
2994 {
2995   rtx sa, ra, around_label;
2996
2997   if (! cfun->eh->ehr_label)
2998     return;
2999
3000   sa = EH_RETURN_STACKADJ_RTX;
3001   if (! sa)
3002     {
3003       error ("__builtin_eh_return not supported on this target");
3004       return;
3005     }
3006
3007   current_function_calls_eh_return = 1;
3008
3009   around_label = gen_label_rtx ();
3010   emit_move_insn (sa, const0_rtx);
3011   emit_jump (around_label);
3012
3013   emit_label (cfun->eh->ehr_label);
3014   clobber_return_register ();
3015
3016 #ifdef HAVE_eh_return
3017   if (HAVE_eh_return)
3018     emit_insn (gen_eh_return (cfun->eh->ehr_stackadj, cfun->eh->ehr_handler));
3019   else
3020 #endif
3021     {
3022       ra = EH_RETURN_HANDLER_RTX;
3023       if (! ra)
3024         {
3025           error ("__builtin_eh_return not supported on this target");
3026           ra = gen_reg_rtx (Pmode);
3027         }
3028
3029       emit_move_insn (sa, cfun->eh->ehr_stackadj);
3030       emit_move_insn (ra, cfun->eh->ehr_handler);
3031     }
3032
3033   emit_label (around_label);
3034 }
3035 \f
3036 struct action_record
3037 {
3038   int offset;
3039   int filter;
3040   int next;
3041 };
3042
3043 static int
3044 action_record_eq (pentry, pdata)
3045      const PTR pentry;
3046      const PTR pdata;
3047 {
3048   const struct action_record *entry = (const struct action_record *) pentry;
3049   const struct action_record *data = (const struct action_record *) pdata;
3050   return entry->filter == data->filter && entry->next == data->next;
3051 }
3052
3053 static hashval_t
3054 action_record_hash (pentry)
3055      const PTR pentry;
3056 {
3057   const struct action_record *entry = (const struct action_record *) pentry;
3058   return entry->next * 1009 + entry->filter;
3059 }
3060
3061 static int
3062 add_action_record (ar_hash, filter, next)
3063      htab_t ar_hash;
3064      int filter, next;
3065 {
3066   struct action_record **slot, *new, tmp;
3067
3068   tmp.filter = filter;
3069   tmp.next = next;
3070   slot = (struct action_record **) htab_find_slot (ar_hash, &tmp, INSERT);
3071
3072   if ((new = *slot) == NULL)
3073     {
3074       new = (struct action_record *) xmalloc (sizeof (*new));
3075       new->offset = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
3076       new->filter = filter;
3077       new->next = next;
3078       *slot = new;
3079
3080       /* The filter value goes in untouched.  The link to the next
3081          record is a "self-relative" byte offset, or zero to indicate
3082          that there is no next record.  So convert the absolute 1 based
3083          indicies we've been carrying around into a displacement.  */
3084
3085       push_sleb128 (&cfun->eh->action_record_data, filter);
3086       if (next)
3087         next -= VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
3088       push_sleb128 (&cfun->eh->action_record_data, next);
3089     }
3090
3091   return new->offset;
3092 }
3093
3094 static int
3095 collect_one_action_chain (ar_hash, region)
3096      htab_t ar_hash;
3097      struct eh_region *region;
3098 {
3099   struct eh_region *c;
3100   int next;
3101
3102   /* If we've reached the top of the region chain, then we have
3103      no actions, and require no landing pad.  */
3104   if (region == NULL)
3105     return -1;
3106
3107   switch (region->type)
3108     {
3109     case ERT_CLEANUP:
3110       /* A cleanup adds a zero filter to the beginning of the chain, but
3111          there are special cases to look out for.  If there are *only*
3112          cleanups along a path, then it compresses to a zero action.
3113          Further, if there are multiple cleanups along a path, we only
3114          need to represent one of them, as that is enough to trigger
3115          entry to the landing pad at runtime.  */
3116       next = collect_one_action_chain (ar_hash, region->outer);
3117       if (next <= 0)
3118         return 0;
3119       for (c = region->outer; c ; c = c->outer)
3120         if (c->type == ERT_CLEANUP)
3121           return next;
3122       return add_action_record (ar_hash, 0, next);
3123
3124     case ERT_TRY:
3125       /* Process the associated catch regions in reverse order.
3126          If there's a catch-all handler, then we don't need to
3127          search outer regions.  Use a magic -3 value to record
3128          that we havn't done the outer search.  */
3129       next = -3;
3130       for (c = region->u.try.last_catch; c ; c = c->u.catch.prev_catch)
3131         {
3132           if (c->u.catch.type == NULL)
3133             next = add_action_record (ar_hash, c->u.catch.filter, 0);
3134           else
3135             {
3136               if (next == -3)
3137                 {
3138                   next = collect_one_action_chain (ar_hash, region->outer);
3139                   if (next < 0)
3140                     next = 0;
3141                 }
3142               next = add_action_record (ar_hash, c->u.catch.filter, next);
3143             }
3144         }
3145       return next;
3146
3147     case ERT_ALLOWED_EXCEPTIONS:
3148       /* An exception specification adds its filter to the
3149          beginning of the chain.  */
3150       next = collect_one_action_chain (ar_hash, region->outer);
3151       return add_action_record (ar_hash, region->u.allowed.filter,
3152                                 next < 0 ? 0 : next);
3153
3154     case ERT_MUST_NOT_THROW:
3155       /* A must-not-throw region with no inner handlers or cleanups
3156          requires no call-site entry.  Note that this differs from
3157          the no handler or cleanup case in that we do require an lsda
3158          to be generated.  Return a magic -2 value to record this.  */
3159       return -2;
3160
3161     case ERT_CATCH:
3162     case ERT_THROW:
3163       /* CATCH regions are handled in TRY above.  THROW regions are
3164          for optimization information only and produce no output.  */
3165       return collect_one_action_chain (ar_hash, region->outer);
3166
3167     default:
3168       abort ();
3169     }
3170 }
3171
3172 static int
3173 add_call_site (landing_pad, action)
3174      rtx landing_pad;
3175      int action;
3176 {
3177   struct call_site_record *data = cfun->eh->call_site_data;
3178   int used = cfun->eh->call_site_data_used;
3179   int size = cfun->eh->call_site_data_size;
3180
3181   if (used >= size)
3182     {
3183       size = (size ? size * 2 : 64);
3184       data = (struct call_site_record *)
3185         xrealloc (data, sizeof (*data) * size);
3186       cfun->eh->call_site_data = data;
3187       cfun->eh->call_site_data_size = size;
3188     }
3189
3190   data[used].landing_pad = landing_pad;
3191   data[used].action = action;
3192
3193   cfun->eh->call_site_data_used = used + 1;
3194
3195   return used + call_site_base;
3196 }
3197
3198 /* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
3199    The new note numbers will not refer to region numbers, but
3200    instead to call site entries.  */
3201
3202 void
3203 convert_to_eh_region_ranges ()
3204 {
3205   rtx insn, iter, note;
3206   htab_t ar_hash;
3207   int last_action = -3;
3208   rtx last_action_insn = NULL_RTX;
3209   rtx last_landing_pad = NULL_RTX;
3210   rtx first_no_action_insn = NULL_RTX;
3211   int call_site;
3212
3213   if (USING_SJLJ_EXCEPTIONS || cfun->eh->region_tree == NULL)
3214     return;
3215
3216   VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
3217
3218   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
3219
3220   for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
3221     if (INSN_P (iter))
3222       {
3223         struct eh_region *region;
3224         int this_action;
3225         rtx this_landing_pad;
3226
3227         insn = iter;
3228         if (GET_CODE (insn) == INSN
3229             && GET_CODE (PATTERN (insn)) == SEQUENCE)
3230           insn = XVECEXP (PATTERN (insn), 0, 0);
3231
3232         note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3233         if (!note)
3234           {
3235             if (! (GET_CODE (insn) == CALL_INSN
3236                    || (flag_non_call_exceptions
3237                        && may_trap_p (PATTERN (insn)))))
3238               continue;
3239             this_action = -1;
3240             region = NULL;
3241           }
3242         else
3243           {
3244             if (INTVAL (XEXP (note, 0)) <= 0)
3245               continue;
3246             region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
3247             this_action = collect_one_action_chain (ar_hash, region);
3248           }
3249
3250         /* Existence of catch handlers, or must-not-throw regions
3251            implies that an lsda is needed (even if empty).  */
3252         if (this_action != -1)
3253           cfun->uses_eh_lsda = 1;
3254
3255         /* Delay creation of region notes for no-action regions
3256            until we're sure that an lsda will be required.  */
3257         else if (last_action == -3)
3258           {
3259             first_no_action_insn = iter;
3260             last_action = -1;
3261           }
3262
3263         /* Cleanups and handlers may share action chains but not
3264            landing pads.  Collect the landing pad for this region.  */
3265         if (this_action >= 0)
3266           {
3267             struct eh_region *o;
3268             for (o = region; ! o->landing_pad ; o = o->outer)
3269               continue;
3270             this_landing_pad = o->landing_pad;
3271           }
3272         else
3273           this_landing_pad = NULL_RTX;
3274
3275         /* Differing actions or landing pads implies a change in call-site
3276            info, which implies some EH_REGION note should be emitted.  */
3277         if (last_action != this_action
3278             || last_landing_pad != this_landing_pad)
3279           {
3280             /* If we'd not seen a previous action (-3) or the previous
3281                action was must-not-throw (-2), then we do not need an
3282                end note.  */
3283             if (last_action >= -1)
3284               {
3285                 /* If we delayed the creation of the begin, do it now.  */
3286                 if (first_no_action_insn)
3287                   {
3288                     call_site = add_call_site (NULL_RTX, 0);
3289                     note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
3290                                              first_no_action_insn);
3291                     NOTE_EH_HANDLER (note) = call_site;
3292                     first_no_action_insn = NULL_RTX;
3293                   }
3294
3295                 note = emit_note_after (NOTE_INSN_EH_REGION_END,
3296                                         last_action_insn);
3297                 NOTE_EH_HANDLER (note) = call_site;
3298               }
3299
3300             /* If the new action is must-not-throw, then no region notes
3301                are created.  */
3302             if (this_action >= -1)
3303               {
3304                 call_site = add_call_site (this_landing_pad, 
3305                                            this_action < 0 ? 0 : this_action);
3306                 note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter);
3307                 NOTE_EH_HANDLER (note) = call_site;
3308               }
3309
3310             last_action = this_action;
3311             last_landing_pad = this_landing_pad;
3312           }
3313         last_action_insn = iter;
3314       }
3315
3316   if (last_action >= -1 && ! first_no_action_insn)
3317     {
3318       note = emit_note_after (NOTE_INSN_EH_REGION_END, last_action_insn);
3319       NOTE_EH_HANDLER (note) = call_site;
3320     }
3321
3322   htab_delete (ar_hash);
3323 }
3324
3325 \f
3326 static void
3327 push_uleb128 (data_area, value)
3328      varray_type *data_area;
3329      unsigned int value;
3330 {
3331   do
3332     {
3333       unsigned char byte = value & 0x7f;
3334       value >>= 7;
3335       if (value)
3336         byte |= 0x80;
3337       VARRAY_PUSH_UCHAR (*data_area, byte);
3338     }
3339   while (value);
3340 }
3341
3342 static void
3343 push_sleb128 (data_area, value)
3344      varray_type *data_area;
3345      int value;
3346 {
3347   unsigned char byte;
3348   int more;
3349
3350   do
3351     {
3352       byte = value & 0x7f;
3353       value >>= 7;
3354       more = ! ((value == 0 && (byte & 0x40) == 0)
3355                 || (value == -1 && (byte & 0x40) != 0));
3356       if (more)
3357         byte |= 0x80;
3358       VARRAY_PUSH_UCHAR (*data_area, byte);
3359     }
3360   while (more);
3361 }
3362
3363 \f
3364 #define DW_EH_PE_absptr         0x00
3365 #define DW_EH_PE_omit           0xff
3366
3367 #define DW_EH_PE_uleb128        0x01
3368 #define DW_EH_PE_udata2         0x02
3369 #define DW_EH_PE_udata4         0x03
3370 #define DW_EH_PE_udata8         0x04
3371 #define DW_EH_PE_sleb128        0x09
3372 #define DW_EH_PE_sdata2         0x0A
3373 #define DW_EH_PE_sdata4         0x0B
3374 #define DW_EH_PE_sdata8         0x0C
3375 #define DW_EH_PE_signed         0x08
3376
3377 #define DW_EH_PE_pcrel          0x10
3378 #define DW_EH_PE_textrel        0x20
3379 #define DW_EH_PE_datarel        0x30
3380 #define DW_EH_PE_funcrel        0x40
3381
3382 static const char *
3383 eh_data_format_name (format)
3384      int format;
3385 {
3386   switch (format)
3387     {
3388     case DW_EH_PE_absptr:       return "absolute";
3389     case DW_EH_PE_omit:         return "omit";
3390
3391     case DW_EH_PE_uleb128:      return "uleb128";
3392     case DW_EH_PE_udata2:       return "udata2";
3393     case DW_EH_PE_udata4:       return "udata4";
3394     case DW_EH_PE_udata8:       return "udata8";
3395     case DW_EH_PE_sleb128:      return "sleb128";
3396     case DW_EH_PE_sdata2:       return "sdata2";
3397     case DW_EH_PE_sdata4:       return "sdata4";
3398     case DW_EH_PE_sdata8:       return "sdata8";
3399
3400     case DW_EH_PE_uleb128 | DW_EH_PE_pcrel:     return "pcrel uleb128";
3401     case DW_EH_PE_udata2 | DW_EH_PE_pcrel:      return "pcrel udata2";
3402     case DW_EH_PE_udata4 | DW_EH_PE_pcrel:      return "pcrel udata4";
3403     case DW_EH_PE_udata8 | DW_EH_PE_pcrel:      return "pcrel udata8";
3404     case DW_EH_PE_sleb128 | DW_EH_PE_pcrel:     return "pcrel sleb128";
3405     case DW_EH_PE_sdata2 | DW_EH_PE_pcrel:      return "pcrel sdata2";
3406     case DW_EH_PE_sdata4 | DW_EH_PE_pcrel:      return "pcrel sdata4";
3407     case DW_EH_PE_sdata8 | DW_EH_PE_pcrel:      return "pcrel sdata8";
3408
3409     case DW_EH_PE_uleb128 | DW_EH_PE_textrel:   return "textrel uleb128";
3410     case DW_EH_PE_udata2 | DW_EH_PE_textrel:    return "textrel udata2";
3411     case DW_EH_PE_udata4 | DW_EH_PE_textrel:    return "textrel udata4";
3412     case DW_EH_PE_udata8 | DW_EH_PE_textrel:    return "textrel udata8";
3413     case DW_EH_PE_sleb128 | DW_EH_PE_textrel:   return "textrel sleb128";
3414     case DW_EH_PE_sdata2 | DW_EH_PE_textrel:    return "textrel sdata2";
3415     case DW_EH_PE_sdata4 | DW_EH_PE_textrel:    return "textrel sdata4";
3416     case DW_EH_PE_sdata8 | DW_EH_PE_textrel:    return "textrel sdata8";
3417
3418     case DW_EH_PE_uleb128 | DW_EH_PE_datarel:   return "datarel uleb128";
3419     case DW_EH_PE_udata2 | DW_EH_PE_datarel:    return "datarel udata2";
3420     case DW_EH_PE_udata4 | DW_EH_PE_datarel:    return "datarel udata4";
3421     case DW_EH_PE_udata8 | DW_EH_PE_datarel:    return "datarel udata8";
3422     case DW_EH_PE_sleb128 | DW_EH_PE_datarel:   return "datarel sleb128";
3423     case DW_EH_PE_sdata2 | DW_EH_PE_datarel:    return "datarel sdata2";
3424     case DW_EH_PE_sdata4 | DW_EH_PE_datarel:    return "datarel sdata4";
3425     case DW_EH_PE_sdata8 | DW_EH_PE_datarel:    return "datarel sdata8";
3426
3427     case DW_EH_PE_uleb128 | DW_EH_PE_funcrel:   return "funcrel uleb128";
3428     case DW_EH_PE_udata2 | DW_EH_PE_funcrel:    return "funcrel udata2";
3429     case DW_EH_PE_udata4 | DW_EH_PE_funcrel:    return "funcrel udata4";
3430     case DW_EH_PE_udata8 | DW_EH_PE_funcrel:    return "funcrel udata8";
3431     case DW_EH_PE_sleb128 | DW_EH_PE_funcrel:   return "funcrel sleb128";
3432     case DW_EH_PE_sdata2 | DW_EH_PE_funcrel:    return "funcrel sdata2";
3433     case DW_EH_PE_sdata4 | DW_EH_PE_funcrel:    return "funcrel sdata4";
3434     case DW_EH_PE_sdata8 | DW_EH_PE_funcrel:    return "funcrel sdata8";
3435
3436     default:
3437       abort ();
3438     }
3439 }
3440
3441 #ifndef HAVE_AS_LEB128
3442 static int
3443 dw2_size_of_call_site_table ()
3444 {
3445   int n = cfun->eh->call_site_data_used;
3446   int size = n * (4 + 4 + 4);
3447   int i;
3448
3449   for (i = 0; i < n; ++i)
3450     {
3451       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3452       size += size_of_uleb128 (cs->action);
3453     }
3454
3455   return size;
3456 }
3457
3458 static int
3459 sjlj_size_of_call_site_table ()
3460 {
3461   int n = cfun->eh->call_site_data_used;
3462   int size = 0;
3463   int i;
3464
3465   for (i = 0; i < n; ++i)
3466     {
3467       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3468       size += size_of_uleb128 (INTVAL (cs->landing_pad));
3469       size += size_of_uleb128 (cs->action);
3470     }
3471
3472   return size;
3473 }
3474 #endif
3475
3476 static void
3477 dw2_output_call_site_table ()
3478 {
3479   const char *function_start_lab
3480     = IDENTIFIER_POINTER (current_function_func_begin_label);
3481   int n = cfun->eh->call_site_data_used;
3482   int i;
3483
3484   for (i = 0; i < n; ++i)
3485     {
3486       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3487       char reg_start_lab[32];
3488       char reg_end_lab[32];
3489       char landing_pad_lab[32];
3490
3491       ASM_GENERATE_INTERNAL_LABEL (reg_start_lab, "LEHB", call_site_base + i);
3492       ASM_GENERATE_INTERNAL_LABEL (reg_end_lab, "LEHE", call_site_base + i);
3493
3494       if (cs->landing_pad)
3495         ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab, "L",
3496                                      CODE_LABEL_NUMBER (cs->landing_pad));
3497
3498       /* ??? Perhaps use insn length scaling if the assembler supports
3499          generic arithmetic.  */
3500       /* ??? Perhaps use attr_length to choose data1 or data2 instead of
3501          data4 if the function is small enough.  */
3502 #ifdef HAVE_AS_LEB128
3503       dw2_asm_output_delta_uleb128 (reg_start_lab, function_start_lab,
3504                                     "region %d start", i);
3505       dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab,
3506                                     "length");
3507       if (cs->landing_pad)
3508         dw2_asm_output_delta_uleb128 (landing_pad_lab, function_start_lab,
3509                                       "landing pad");
3510       else
3511         dw2_asm_output_data_uleb128 (0, "landing pad");
3512 #else
3513       dw2_asm_output_delta (4, reg_start_lab, function_start_lab,
3514                             "region %d start", i);
3515       dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length");
3516       if (cs->landing_pad)
3517         dw2_asm_output_delta (4, landing_pad_lab, function_start_lab,
3518                               "landing pad");
3519       else
3520         dw2_asm_output_data (4, 0, "landing pad");
3521 #endif
3522       dw2_asm_output_data_uleb128 (cs->action, "action");
3523     }
3524
3525   call_site_base += n;
3526 }
3527
3528 static void
3529 sjlj_output_call_site_table ()
3530 {
3531   int n = cfun->eh->call_site_data_used;
3532   int i;
3533
3534   for (i = 0; i < n; ++i)
3535     {
3536       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3537
3538       dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad),
3539                                    "region %d landing pad", i);
3540       dw2_asm_output_data_uleb128 (cs->action, "action");
3541     }
3542
3543   call_site_base += n;
3544 }
3545
3546 void
3547 output_function_exception_table ()
3548 {
3549   int format, i, n;
3550 #ifdef HAVE_AS_LEB128
3551   char ttype_label[32];
3552   char cs_after_size_label[32];
3553   char cs_end_label[32];
3554 #else
3555   int call_site_len;
3556 #endif
3557   int have_tt_data;
3558   int funcdef_number;
3559
3560   /* Not all functions need anything.  */
3561   if (! cfun->uses_eh_lsda)
3562     return;
3563
3564   funcdef_number = (USING_SJLJ_EXCEPTIONS
3565                     ? sjlj_funcdef_number
3566                     : current_funcdef_number);
3567
3568   exception_section ();
3569
3570   have_tt_data = (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) > 0
3571                   || VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) > 0);
3572
3573   if (have_tt_data)
3574     assemble_eh_align (GET_MODE_ALIGNMENT (ptr_mode));
3575
3576   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LLSDA", funcdef_number);
3577
3578   /* The LSDA header.  */
3579
3580   /* Indicate the format of the landing pad start pointer.  An omitted
3581      field implies @LPStart == @Start.  */
3582   /* Currently we always put @LPStart == @Start.  This field would
3583      be most useful in moving the landing pads completely out of
3584      line to another section, but it could also be used to minimize
3585      the size of uleb128 landing pad offsets.  */
3586   format = DW_EH_PE_omit;
3587   dw2_asm_output_data (1, format, "@LPStart format (%s)",
3588                        eh_data_format_name (format));
3589
3590   /* @LPStart pointer would go here.  */
3591
3592   /* Indicate the format of the @TType entries.  */
3593   if (! have_tt_data)
3594     format = DW_EH_PE_omit;
3595   else
3596     {
3597       /* ??? Define a ASM_PREFERRED_DATA_FORMAT to say what 
3598          sort of dynamic-relocation-free reference to emit.  */
3599       format = 0;
3600 #ifdef HAVE_AS_LEB128
3601       ASM_GENERATE_INTERNAL_LABEL (ttype_label, "LLSDATT", funcdef_number);
3602 #endif
3603     }
3604   dw2_asm_output_data (1, format, "@TType format (%s)",
3605                        eh_data_format_name (format));
3606
3607 #ifndef HAVE_AS_LEB128
3608   if (USING_SJLJ_EXCEPTIONS)
3609     call_site_len = sjlj_size_of_call_site_table ();
3610   else
3611     call_site_len = dw2_size_of_call_site_table ();
3612 #endif
3613
3614   /* A pc-relative 4-byte displacement to the @TType data.  */
3615   if (have_tt_data)
3616     {
3617 #ifdef HAVE_AS_LEB128
3618       char ttype_after_disp_label[32];
3619       ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label, "LLSDATTD", 
3620                                    funcdef_number);
3621       dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label,
3622                                     "@TType base offset");
3623       ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label);
3624 #else
3625       /* Ug.  Alignment queers things.  */
3626       unsigned int before_disp, after_disp, last_disp, disp, align;
3627
3628       align = POINTER_SIZE / BITS_PER_UNIT;
3629       before_disp = 1 + 1;
3630       after_disp = (1 + size_of_uleb128 (call_site_len)
3631                     + call_site_len
3632                     + VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data)
3633                     + VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) * align);
3634
3635       disp = after_disp;
3636       do
3637         {
3638           unsigned int disp_size, pad;
3639
3640           last_disp = disp;
3641           disp_size = size_of_uleb128 (disp);
3642           pad = before_disp + disp_size + after_disp;
3643           if (pad % align)
3644             pad = align - (pad % align);
3645           else
3646             pad = 0;
3647           disp = after_disp + pad;
3648         }
3649       while (disp != last_disp);
3650
3651       dw2_asm_output_data_uleb128 (disp, "@TType base offset");
3652 #endif
3653     }
3654
3655   /* Indicate the format of the call-site offsets.  */
3656 #ifdef HAVE_AS_LEB128
3657   format = DW_EH_PE_uleb128;
3658 #else
3659   format = DW_EH_PE_udata4;
3660 #endif
3661   dw2_asm_output_data (1, format, "call-site format (%s)",
3662                        eh_data_format_name (format));
3663
3664 #ifdef HAVE_AS_LEB128
3665   ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label, "LLSDACSB",
3666                                funcdef_number);
3667   ASM_GENERATE_INTERNAL_LABEL (cs_end_label, "LLSDACSE",
3668                                funcdef_number);
3669   dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label,
3670                                 "Call-site table length");
3671   ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label);
3672   if (USING_SJLJ_EXCEPTIONS)
3673     sjlj_output_call_site_table ();
3674   else
3675     dw2_output_call_site_table ();
3676   ASM_OUTPUT_LABEL (asm_out_file, cs_end_label);
3677 #else
3678   dw2_asm_output_data_uleb128 (call_site_len,"Call-site table length");
3679   if (USING_SJLJ_EXCEPTIONS)
3680     sjlj_output_call_site_table ();
3681   else
3682     dw2_output_call_site_table ();
3683 #endif
3684
3685   /* ??? Decode and interpret the data for flag_debug_asm.  */
3686   n = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data);
3687   for (i = 0; i < n; ++i)
3688     dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->action_record_data, i),
3689                          (i ? NULL : "Action record table"));
3690
3691   if (have_tt_data)
3692     assemble_eh_align (GET_MODE_ALIGNMENT (ptr_mode));
3693
3694   i = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data);
3695   while (i-- > 0)
3696     {
3697       tree type = VARRAY_TREE (cfun->eh->ttype_data, i);
3698
3699       if (type == NULL_TREE)
3700         type = integer_zero_node;
3701       else
3702         type = lookup_type_for_runtime (type);
3703
3704       /* ??? Handle ASM_PREFERRED_DATA_FORMAT.  */
3705       output_constant (type, GET_MODE_SIZE (ptr_mode));
3706     }
3707
3708 #ifdef HAVE_AS_LEB128
3709   if (have_tt_data)
3710       ASM_OUTPUT_LABEL (asm_out_file, ttype_label);
3711 #endif
3712
3713   /* ??? Decode and interpret the data for flag_debug_asm.  */
3714   n = VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data);
3715   for (i = 0; i < n; ++i)
3716     dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->ehspec_data, i),
3717                          (i ? NULL : "Exception specification table"));
3718
3719   function_section (current_function_decl);
3720
3721   if (USING_SJLJ_EXCEPTIONS)
3722     sjlj_funcdef_number += 1;
3723 }