OSDN Git Service

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