OSDN Git Service

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