OSDN Git Service

* cppinit.c (cpp_start_read): Free the imacros list as we
[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 GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING.  If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 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 static int
1479 t2r_eq (pentry, pdata)
1480      const PTR pentry;
1481      const PTR pdata;
1482 {
1483   tree entry = (tree) pentry;
1484   tree data = (tree) pdata;
1485
1486   return TREE_PURPOSE (entry) == data;
1487 }
1488
1489 static hashval_t
1490 t2r_hash (pentry)
1491      const PTR pentry;
1492 {
1493   tree entry = (tree) pentry;
1494   return TYPE_HASH (TREE_PURPOSE (entry));
1495 }
1496
1497 static int
1498 t2r_mark_1 (slot, data)
1499      PTR *slot;
1500      PTR data ATTRIBUTE_UNUSED;
1501 {
1502   tree contents = (tree) *slot;
1503   ggc_mark_tree (contents);
1504   return 1;
1505 }
1506
1507 static void
1508 t2r_mark (addr)
1509      PTR addr;
1510 {
1511   htab_traverse (*(htab_t *)addr, t2r_mark_1, NULL);
1512 }
1513
1514 static void
1515 add_type_for_runtime (type)
1516      tree type;
1517 {
1518   tree *slot;
1519
1520   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
1521                                             TYPE_HASH (type), INSERT);
1522   if (*slot == NULL)
1523     {
1524       tree runtime = (*lang_eh_runtime_type) (type);
1525       *slot = tree_cons (type, runtime, NULL_TREE);
1526     }
1527 }
1528   
1529 static tree
1530 lookup_type_for_runtime (type)
1531      tree type;
1532 {
1533   tree *slot;
1534
1535   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
1536                                             TYPE_HASH (type), NO_INSERT);
1537
1538   /* We should have always inserrted the data earlier.  */
1539   return TREE_VALUE (*slot);
1540 }
1541
1542 \f
1543 /* Represent an entry in @TTypes for either catch actions
1544    or exception filter actions.  */
1545 struct ttypes_filter
1546 {
1547   tree t;
1548   int filter;
1549 };
1550
1551 /* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
1552    (a tree) for a @TTypes type node we are thinking about adding.  */
1553
1554 static int
1555 ttypes_filter_eq (pentry, pdata)
1556      const PTR pentry;
1557      const PTR pdata;
1558 {
1559   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1560   tree data = (tree) pdata;
1561
1562   return entry->t == data;
1563 }
1564
1565 static hashval_t
1566 ttypes_filter_hash (pentry)
1567      const PTR pentry;
1568 {
1569   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1570   return TYPE_HASH (entry->t);
1571 }
1572
1573 /* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
1574    exception specification list we are thinking about adding.  */
1575 /* ??? Currently we use the type lists in the order given.  Someone
1576    should put these in some canonical order.  */
1577
1578 static int
1579 ehspec_filter_eq (pentry, pdata)
1580      const PTR pentry;
1581      const PTR pdata;
1582 {
1583   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1584   const struct ttypes_filter *data = (const struct ttypes_filter *) pdata;
1585
1586   return type_list_equal (entry->t, data->t);
1587 }
1588
1589 /* Hash function for exception specification lists.  */
1590
1591 static hashval_t
1592 ehspec_filter_hash (pentry)
1593      const PTR pentry;
1594 {
1595   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1596   hashval_t h = 0;
1597   tree list;
1598
1599   for (list = entry->t; list ; list = TREE_CHAIN (list))
1600     h = (h << 5) + (h >> 27) + TYPE_HASH (TREE_VALUE (list));
1601   return h;
1602 }
1603
1604 /* Add TYPE to cfun->eh->ttype_data, using TYPES_HASH to speed
1605    up the search.  Return the filter value to be used.  */
1606
1607 static int
1608 add_ttypes_entry (ttypes_hash, type)
1609      htab_t ttypes_hash;
1610      tree type;
1611 {
1612   struct ttypes_filter **slot, *n;
1613
1614   slot = (struct ttypes_filter **)
1615     htab_find_slot_with_hash (ttypes_hash, type, TYPE_HASH (type), INSERT);
1616
1617   if ((n = *slot) == NULL)
1618     {
1619       /* Filter value is a 1 based table index.  */
1620
1621       n = (struct ttypes_filter *) xmalloc (sizeof (*n));
1622       n->t = type;
1623       n->filter = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) + 1;
1624       *slot = n;
1625
1626       VARRAY_PUSH_TREE (cfun->eh->ttype_data, type);
1627     }
1628
1629   return n->filter;
1630 }
1631
1632 /* Add LIST to cfun->eh->ehspec_data, using EHSPEC_HASH and TYPES_HASH
1633    to speed up the search.  Return the filter value to be used.  */
1634
1635 static int
1636 add_ehspec_entry (ehspec_hash, ttypes_hash, list)
1637      htab_t ehspec_hash;
1638      htab_t ttypes_hash;
1639      tree list;
1640 {
1641   struct ttypes_filter **slot, *n;
1642   struct ttypes_filter dummy;
1643
1644   dummy.t = list;
1645   slot = (struct ttypes_filter **)
1646     htab_find_slot (ehspec_hash, &dummy, INSERT);
1647
1648   if ((n = *slot) == NULL)
1649     {
1650       /* Filter value is a -1 based byte index into a uleb128 buffer.  */
1651
1652       n = (struct ttypes_filter *) xmalloc (sizeof (*n));
1653       n->t = list;
1654       n->filter = -(VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) + 1);
1655       *slot = n;
1656
1657       /* Look up each type in the list and encode its filter
1658          value as a uleb128.  Terminate the list with 0.  */
1659       for (; list ; list = TREE_CHAIN (list))
1660         push_uleb128 (&cfun->eh->ehspec_data, 
1661                       add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
1662       VARRAY_PUSH_UCHAR (cfun->eh->ehspec_data, 0);
1663     }
1664
1665   return n->filter;
1666 }
1667
1668 /* Generate the action filter values to be used for CATCH and
1669    ALLOWED_EXCEPTIONS regions.  When using dwarf2 exception regions,
1670    we use lots of landing pads, and so every type or list can share
1671    the same filter value, which saves table space.  */
1672
1673 static void
1674 assign_filter_values ()
1675 {
1676   int i;
1677   htab_t ttypes, ehspec;
1678
1679   VARRAY_TREE_INIT (cfun->eh->ttype_data, 16, "ttype_data");
1680   VARRAY_UCHAR_INIT (cfun->eh->ehspec_data, 64, "ehspec_data");
1681
1682   ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free);
1683   ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free);
1684
1685   for (i = cfun->eh->last_region_number; i > 0; --i)
1686     {
1687       struct eh_region *r = cfun->eh->region_array[i];
1688
1689       /* Mind we don't process a region more than once.  */
1690       if (!r || r->region_number != i)
1691         continue;
1692
1693       switch (r->type)
1694         {
1695         case ERT_CATCH:
1696           r->u.catch.filter = add_ttypes_entry (ttypes, r->u.catch.type);
1697           break;
1698
1699         case ERT_ALLOWED_EXCEPTIONS:
1700           r->u.allowed.filter
1701             = add_ehspec_entry (ehspec, ttypes, r->u.allowed.type_list);
1702           break;
1703
1704         default:
1705           break;
1706         }
1707     }
1708
1709   htab_delete (ttypes);
1710   htab_delete (ehspec);
1711 }
1712
1713 static void
1714 build_post_landing_pads ()
1715 {
1716   int i;
1717
1718   for (i = cfun->eh->last_region_number; i > 0; --i)
1719     {
1720       struct eh_region *region = cfun->eh->region_array[i];
1721       rtx seq;
1722
1723       /* Mind we don't process a region more than once.  */
1724       if (!region || region->region_number != i)
1725         continue;
1726
1727       switch (region->type)
1728         {
1729         case ERT_TRY:
1730           /* ??? Collect the set of all non-overlapping catch handlers
1731                all the way up the chain until blocked by a cleanup.  */
1732           /* ??? Outer try regions can share landing pads with inner
1733              try regions if the types are completely non-overlapping,
1734              and there are no interveaning cleanups.  */
1735
1736           region->post_landing_pad = gen_label_rtx ();
1737
1738           start_sequence ();
1739
1740           emit_label (region->post_landing_pad);
1741
1742           /* ??? It is mighty inconvenient to call back into the
1743              switch statement generation code in expand_end_case.
1744              Rapid prototyping sez a sequence of ifs.  */
1745           {
1746             struct eh_region *c;
1747             for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
1748               {
1749                 /* ??? _Unwind_ForcedUnwind wants no match here.  */
1750                 if (c->u.catch.type == NULL)
1751                   emit_jump (c->label);
1752                 else
1753                   emit_cmp_and_jump_insns (cfun->eh->filter,
1754                                            GEN_INT (c->u.catch.filter),
1755                                            EQ, NULL_RTX, word_mode,
1756                                            0, 0, c->label);
1757               }
1758           }
1759
1760           /* We delay the generation of the _Unwind_Resume until we generate
1761              landing pads.  We emit a marker here so as to get good control
1762              flow data in the meantime.  */
1763           region->resume
1764             = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1765           emit_barrier ();
1766
1767           seq = get_insns ();
1768           end_sequence ();
1769
1770           emit_insns_before (seq, region->u.try.catch->label);
1771           break;
1772
1773         case ERT_ALLOWED_EXCEPTIONS:
1774           region->post_landing_pad = gen_label_rtx ();
1775
1776           start_sequence ();
1777
1778           emit_label (region->post_landing_pad);
1779
1780           emit_cmp_and_jump_insns (cfun->eh->filter,
1781                                    GEN_INT (region->u.allowed.filter),
1782                                    EQ, NULL_RTX, word_mode, 0, 0,
1783                                    region->label);
1784
1785           /* We delay the generation of the _Unwind_Resume until we generate
1786              landing pads.  We emit a marker here so as to get good control
1787              flow data in the meantime.  */
1788           region->resume
1789             = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1790           emit_barrier ();
1791
1792           seq = get_insns ();
1793           end_sequence ();
1794
1795           emit_insns_before (seq, region->label);
1796           break;
1797
1798         case ERT_CLEANUP:
1799         case ERT_MUST_NOT_THROW:
1800           region->post_landing_pad = region->label;
1801           break;
1802
1803         case ERT_CATCH:
1804         case ERT_THROW:
1805           /* Nothing to do.  */
1806           break;
1807
1808         default:
1809           abort ();
1810         }
1811     }
1812 }
1813
1814 /* Replace RESX patterns with jumps to the next handler if any, or calls to
1815    _Unwind_Resume otherwise.  */
1816
1817 static void
1818 connect_post_landing_pads ()
1819 {
1820   int i;
1821
1822   for (i = cfun->eh->last_region_number; i > 0; --i)
1823     {
1824       struct eh_region *region = cfun->eh->region_array[i];
1825       struct eh_region *outer;
1826       rtx seq;
1827
1828       /* Mind we don't process a region more than once.  */
1829       if (!region || region->region_number != i)
1830         continue;
1831
1832       /* If there is no RESX, or it has been deleted by flow, there's
1833          nothing to fix up.  */
1834       if (! region->resume || INSN_DELETED_P (region->resume))
1835         continue;
1836
1837       /* Search for another landing pad in this function.  */
1838       for (outer = region->outer; outer ; outer = outer->outer)
1839         if (outer->post_landing_pad)
1840           break;
1841
1842       start_sequence ();
1843
1844       if (outer)
1845         emit_jump (outer->post_landing_pad);
1846       else
1847         emit_library_call (unwind_resume_libfunc, LCT_THROW,
1848                            VOIDmode, 1, cfun->eh->exc_ptr, Pmode);
1849
1850       seq = get_insns ();
1851       end_sequence ();
1852       emit_insns_before (seq, region->resume);
1853       flow_delete_insn (region->resume);
1854     }
1855 }
1856
1857 \f
1858 static void
1859 dw2_build_landing_pads ()
1860 {
1861   int i;
1862   unsigned int j;
1863
1864   for (i = cfun->eh->last_region_number; i > 0; --i)
1865     {
1866       struct eh_region *region = cfun->eh->region_array[i];
1867       rtx seq;
1868
1869       /* Mind we don't process a region more than once.  */
1870       if (!region || region->region_number != i)
1871         continue;
1872
1873       if (region->type != ERT_CLEANUP
1874           && region->type != ERT_TRY
1875           && region->type != ERT_ALLOWED_EXCEPTIONS)
1876         continue;
1877
1878       start_sequence ();
1879
1880       region->landing_pad = gen_label_rtx ();
1881       emit_label (region->landing_pad);
1882
1883 #ifdef HAVE_exception_receiver
1884       if (HAVE_exception_receiver)
1885         emit_insn (gen_exception_receiver ());
1886       else
1887 #endif
1888 #ifdef HAVE_nonlocal_goto_receiver
1889         if (HAVE_nonlocal_goto_receiver)
1890           emit_insn (gen_nonlocal_goto_receiver ());
1891         else
1892 #endif
1893           { /* Nothing */ }
1894
1895       /* If the eh_return data registers are call-saved, then we
1896          won't have considered them clobbered from the call that
1897          threw.  Kill them now.  */
1898       for (j = 0; ; ++j)
1899         {
1900           unsigned r = EH_RETURN_DATA_REGNO (j);
1901           if (r == INVALID_REGNUM)
1902             break;
1903           if (! call_used_regs[r])
1904             emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, r)));
1905         }
1906
1907       emit_move_insn (cfun->eh->exc_ptr,
1908                       gen_rtx_REG (Pmode, EH_RETURN_DATA_REGNO (0)));
1909       emit_move_insn (cfun->eh->filter,
1910                       gen_rtx_REG (word_mode, EH_RETURN_DATA_REGNO (1)));
1911
1912       seq = get_insns ();
1913       end_sequence ();
1914
1915       emit_insns_before (seq, region->post_landing_pad);
1916     }
1917 }
1918
1919 \f
1920 struct sjlj_lp_info
1921 {
1922   int directly_reachable;
1923   int action_index;
1924   int dispatch_index;
1925   int call_site_index;
1926 };
1927
1928 static bool
1929 sjlj_find_directly_reachable_regions (lp_info)
1930      struct sjlj_lp_info *lp_info;
1931 {
1932   rtx insn;
1933   bool found_one = false;
1934
1935   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
1936     {
1937       struct eh_region *region;
1938       tree type_thrown;
1939       rtx note;
1940
1941       if (! INSN_P (insn))
1942         continue;
1943
1944       note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1945       if (!note || INTVAL (XEXP (note, 0)) <= 0)
1946         continue;
1947
1948       region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
1949
1950       type_thrown = NULL_TREE;
1951       if (region->type == ERT_THROW)
1952         {
1953           type_thrown = region->u.throw.type;
1954           region = region->outer;
1955         }
1956
1957       /* Find the first containing region that might handle the exception.
1958          That's the landing pad to which we will transfer control.  */
1959       for (; region; region = region->outer)
1960         if (reachable_next_level (region, type_thrown, 0) != RNL_NOT_CAUGHT)
1961           break;
1962
1963       if (region)
1964         {
1965           lp_info[region->region_number].directly_reachable = 1;
1966           found_one = true;
1967         }
1968     }
1969
1970   return found_one;
1971 }
1972
1973 static void
1974 sjlj_assign_call_site_values (dispatch_label, lp_info)
1975      rtx dispatch_label;
1976      struct sjlj_lp_info *lp_info;
1977 {
1978   htab_t ar_hash;
1979   int i, index;
1980
1981   /* First task: build the action table.  */
1982
1983   VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
1984   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
1985
1986   for (i = cfun->eh->last_region_number; i > 0; --i)
1987     if (lp_info[i].directly_reachable)
1988       {
1989         struct eh_region *r = cfun->eh->region_array[i];
1990         r->landing_pad = dispatch_label;
1991         lp_info[i].action_index = collect_one_action_chain (ar_hash, r);
1992         if (lp_info[i].action_index != -1)
1993           cfun->uses_eh_lsda = 1;
1994       }
1995
1996   htab_delete (ar_hash);
1997
1998   /* Next: assign dispatch values.  In dwarf2 terms, this would be the
1999      landing pad label for the region.  For sjlj though, there is one
2000      common landing pad from which we dispatch to the post-landing pads.
2001
2002      A region receives a dispatch index if it is directly reachable
2003      and requires in-function processing.  Regions that share post-landing
2004      pads may share dispatch indicies.  */
2005   /* ??? Post-landing pad sharing doesn't actually happen at the moment
2006      (see build_post_landing_pads) so we don't bother checking for it.  */
2007
2008   index = 0;
2009   for (i = cfun->eh->last_region_number; i > 0; --i)
2010     if (lp_info[i].directly_reachable
2011         && lp_info[i].action_index >= 0)
2012       lp_info[i].dispatch_index = index++;
2013
2014   /* Finally: assign call-site values.  If dwarf2 terms, this would be
2015      the region number assigned by convert_to_eh_region_ranges, but
2016      handles no-action and must-not-throw differently.  */
2017
2018   call_site_base = 1;
2019   for (i = cfun->eh->last_region_number; i > 0; --i)
2020     if (lp_info[i].directly_reachable)
2021       {
2022         int action = lp_info[i].action_index;
2023
2024         /* Map must-not-throw to otherwise unused call-site index 0.  */
2025         if (action == -2)
2026           index = 0;
2027         /* Map no-action to otherwise unused call-site index -1.  */
2028         else if (action == -1)
2029           index = -1;
2030         /* Otherwise, look it up in the table.  */
2031         else
2032           index = add_call_site (GEN_INT (lp_info[i].dispatch_index), action);
2033
2034         lp_info[i].call_site_index = index;
2035       }
2036 }
2037
2038 static void
2039 sjlj_mark_call_sites (lp_info)
2040      struct sjlj_lp_info *lp_info;
2041 {
2042   int last_call_site = -2;
2043   rtx insn, mem;
2044
2045   mem = adjust_address (cfun->eh->sjlj_fc, TYPE_MODE (integer_type_node),
2046                         sjlj_fc_call_site_ofs);
2047
2048   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
2049     {
2050       struct eh_region *region;
2051       int this_call_site;
2052       rtx note, before, p;
2053
2054       /* Reset value tracking at extended basic block boundaries.  */
2055       if (GET_CODE (insn) == CODE_LABEL)
2056         last_call_site = -2;
2057
2058       if (! INSN_P (insn))
2059         continue;
2060
2061       note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2062       if (!note)
2063         {
2064           /* Calls (and trapping insns) without notes are outside any
2065              exception handling region in this function.  Mark them as
2066              no action.  */
2067           if (GET_CODE (insn) == CALL_INSN
2068               || (flag_non_call_exceptions
2069                   && may_trap_p (PATTERN (insn))))
2070             this_call_site = -1;
2071           else
2072             continue;
2073         }
2074       else
2075         {
2076           /* Calls that are known to not throw need not be marked.  */
2077           if (INTVAL (XEXP (note, 0)) <= 0)
2078             continue;
2079
2080           region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2081           this_call_site = lp_info[region->region_number].call_site_index;
2082         }
2083
2084       if (this_call_site == last_call_site)
2085         continue;
2086
2087       /* Don't separate a call from it's argument loads.  */
2088       before = insn;
2089       if (GET_CODE (insn) == CALL_INSN)
2090          before = find_first_parameter_load (insn, NULL_RTX);
2091
2092       start_sequence ();
2093       emit_move_insn (mem, GEN_INT (this_call_site));
2094       p = get_insns ();
2095       end_sequence ();
2096
2097       emit_insns_before (p, before);
2098       last_call_site = this_call_site;
2099     }
2100 }
2101
2102 /* Construct the SjLj_Function_Context.  */
2103
2104 static void
2105 sjlj_emit_function_enter (dispatch_label)
2106      rtx dispatch_label;
2107 {
2108   rtx fn_begin, fc, mem, seq;
2109
2110   fc = cfun->eh->sjlj_fc;
2111
2112   start_sequence ();
2113
2114   /* We're storing this libcall's address into memory instead of
2115      calling it directly.  Thus, we must call assemble_external_libcall
2116      here, as we can not depend on emit_library_call to do it for us.  */
2117   assemble_external_libcall (eh_personality_libfunc);
2118   mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
2119   emit_move_insn (mem, eh_personality_libfunc);
2120
2121   mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
2122   if (cfun->uses_eh_lsda)
2123     {
2124       char buf[20];
2125       ASM_GENERATE_INTERNAL_LABEL (buf, "LLSDA", sjlj_funcdef_number);
2126       emit_move_insn (mem, gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)));
2127     }
2128   else
2129     emit_move_insn (mem, const0_rtx);
2130   
2131 #ifdef DONT_USE_BUILTIN_SETJMP
2132   {
2133     rtx x, note;
2134     x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_NORMAL,
2135                                  TYPE_MODE (integer_type_node), 1,
2136                                  plus_constant (XEXP (fc, 0),
2137                                                 sjlj_fc_jbuf_ofs), Pmode);
2138
2139     note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
2140     NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, x, const0_rtx);
2141
2142     emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
2143                              TYPE_MODE (integer_type_node), 0, 0,
2144                              dispatch_label);
2145   }
2146 #else
2147   expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
2148                                dispatch_label);
2149 #endif
2150
2151   emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
2152                      1, XEXP (fc, 0), Pmode);
2153
2154   seq = get_insns ();
2155   end_sequence ();
2156
2157   /* ??? Instead of doing this at the beginning of the function,
2158      do this in a block that is at loop level 0 and dominates all
2159      can_throw_internal instructions.  */
2160
2161   for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
2162     if (GET_CODE (fn_begin) == NOTE
2163         && NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
2164       break;
2165   emit_insns_after (seq, fn_begin);
2166 }
2167
2168 /* Call back from expand_function_end to know where we should put
2169    the call to unwind_sjlj_unregister_libfunc if needed.  */
2170
2171 void
2172 sjlj_emit_function_exit_after (after)
2173      rtx after;
2174 {
2175   cfun->eh->sjlj_exit_after = after;
2176 }
2177
2178 static void
2179 sjlj_emit_function_exit ()
2180 {
2181   rtx seq;
2182
2183   start_sequence ();
2184
2185   emit_library_call (unwind_sjlj_unregister_libfunc, LCT_NORMAL, VOIDmode,
2186                      1, XEXP (cfun->eh->sjlj_fc, 0), Pmode);
2187
2188   seq = get_insns ();
2189   end_sequence ();
2190
2191   /* ??? Really this can be done in any block at loop level 0 that
2192      post-dominates all can_throw_internal instructions.  This is
2193      the last possible moment.  */
2194
2195   emit_insns_after (seq, cfun->eh->sjlj_exit_after);
2196 }
2197
2198 static void
2199 sjlj_emit_dispatch_table (dispatch_label, lp_info)
2200      rtx dispatch_label;
2201      struct sjlj_lp_info *lp_info;
2202 {
2203   int i, first_reachable;
2204   rtx mem, dispatch, seq, fc;
2205
2206   fc = cfun->eh->sjlj_fc;
2207
2208   start_sequence ();
2209
2210   emit_label (dispatch_label);
2211   
2212 #ifndef DONT_USE_BUILTIN_SETJMP
2213   expand_builtin_setjmp_receiver (dispatch_label);
2214 #endif
2215
2216   /* Load up dispatch index, exc_ptr and filter values from the
2217      function context.  */
2218   mem = adjust_address (fc, TYPE_MODE (integer_type_node),
2219                         sjlj_fc_call_site_ofs);
2220   dispatch = copy_to_reg (mem);
2221
2222   mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs);
2223   if (word_mode != Pmode)
2224     {
2225 #ifdef POINTERS_EXTEND_UNSIGNED
2226       mem = convert_memory_address (Pmode, mem);
2227 #else
2228       mem = convert_to_mode (Pmode, mem, 0);
2229 #endif
2230     }
2231   emit_move_insn (cfun->eh->exc_ptr, mem);
2232
2233   mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs + UNITS_PER_WORD);
2234   emit_move_insn (cfun->eh->filter, mem);
2235
2236   /* Jump to one of the directly reachable regions.  */
2237   /* ??? This really ought to be using a switch statement.  */
2238
2239   first_reachable = 0;
2240   for (i = cfun->eh->last_region_number; i > 0; --i)
2241     {
2242       if (! lp_info[i].directly_reachable
2243           || lp_info[i].action_index < 0)
2244         continue;
2245
2246       if (! first_reachable)
2247         {
2248           first_reachable = i;
2249           continue;
2250         }
2251
2252       emit_cmp_and_jump_insns (dispatch,
2253                                GEN_INT (lp_info[i].dispatch_index), EQ,
2254                                NULL_RTX, TYPE_MODE (integer_type_node), 0, 0,
2255                                cfun->eh->region_array[i]->post_landing_pad);
2256     }
2257
2258   seq = get_insns ();
2259   end_sequence ();
2260
2261   emit_insns_before (seq, (cfun->eh->region_array[first_reachable]
2262                            ->post_landing_pad));
2263 }
2264
2265 static void
2266 sjlj_build_landing_pads ()
2267 {
2268   struct sjlj_lp_info *lp_info;
2269
2270   lp_info = (struct sjlj_lp_info *) xcalloc (cfun->eh->last_region_number + 1,
2271                                              sizeof (struct sjlj_lp_info));
2272
2273   if (sjlj_find_directly_reachable_regions (lp_info))
2274     {
2275       rtx dispatch_label = gen_label_rtx ();
2276
2277       cfun->eh->sjlj_fc
2278         = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
2279                               int_size_in_bytes (sjlj_fc_type_node),
2280                               TYPE_ALIGN (sjlj_fc_type_node));
2281
2282       sjlj_assign_call_site_values (dispatch_label, lp_info);
2283       sjlj_mark_call_sites (lp_info);
2284
2285       sjlj_emit_function_enter (dispatch_label);
2286       sjlj_emit_dispatch_table (dispatch_label, lp_info);
2287       sjlj_emit_function_exit ();
2288     }
2289
2290   free (lp_info);
2291 }
2292
2293 void
2294 finish_eh_generation ()
2295 {
2296   /* Nothing to do if no regions created.  */
2297   if (cfun->eh->region_tree == NULL)
2298     return;
2299
2300   /* The object here is to provide find_basic_blocks with detailed
2301      information (via reachable_handlers) on how exception control
2302      flows within the function.  In this first pass, we can include
2303      type information garnered from ERT_THROW and ERT_ALLOWED_EXCEPTIONS
2304      regions, and hope that it will be useful in deleting unreachable
2305      handlers.  Subsequently, we will generate landing pads which will
2306      connect many of the handlers, and then type information will not
2307      be effective.  Still, this is a win over previous implementations.  */
2308
2309   rebuild_jump_labels (get_insns ());
2310   find_basic_blocks (get_insns (), max_reg_num (), 0);
2311   cleanup_cfg (CLEANUP_PRE_LOOP);
2312
2313   /* These registers are used by the landing pads.  Make sure they
2314      have been generated.  */
2315   get_exception_pointer (cfun);
2316   get_exception_filter (cfun);
2317
2318   /* Construct the landing pads.  */
2319
2320   assign_filter_values ();
2321   build_post_landing_pads ();
2322   connect_post_landing_pads ();
2323   if (USING_SJLJ_EXCEPTIONS)
2324     sjlj_build_landing_pads ();
2325   else
2326     dw2_build_landing_pads ();
2327
2328   cfun->eh->built_landing_pads = 1;
2329
2330   /* We've totally changed the CFG.  Start over.  */
2331   find_exception_handler_labels ();
2332   rebuild_jump_labels (get_insns ());
2333   find_basic_blocks (get_insns (), max_reg_num (), 0);
2334   cleanup_cfg (CLEANUP_PRE_LOOP);
2335 }
2336 \f
2337 /* This section handles removing dead code for flow.  */
2338
2339 /* Remove LABEL from the exception_handler_labels list.  */
2340
2341 static void
2342 remove_exception_handler_label (label)
2343      rtx label;
2344 {
2345   rtx *pl, l;
2346
2347   for (pl = &exception_handler_labels, l = *pl;
2348        XEXP (l, 0) != label;
2349        pl = &XEXP (l, 1), l = *pl)
2350     continue;
2351
2352   *pl = XEXP (l, 1);
2353   free_EXPR_LIST_node (l);
2354 }
2355
2356 /* Splice REGION from the region tree etc.  */
2357
2358 static void
2359 remove_eh_handler (region)
2360      struct eh_region *region;
2361 {
2362   struct eh_region **pp, *p;
2363   rtx lab;
2364   int i;
2365
2366   /* For the benefit of efficiently handling REG_EH_REGION notes,
2367      replace this region in the region array with its containing
2368      region.  Note that previous region deletions may result in
2369      multiple copies of this region in the array, so we have to
2370      search the whole thing.  */
2371   for (i = cfun->eh->last_region_number; i > 0; --i)
2372     if (cfun->eh->region_array[i] == region)
2373       cfun->eh->region_array[i] = region->outer;
2374
2375   if (cfun->eh->built_landing_pads)
2376     lab = region->landing_pad;
2377   else
2378     lab = region->label;
2379   if (lab)
2380     remove_exception_handler_label (lab);
2381
2382   if (region->outer)
2383     pp = &region->outer->inner;
2384   else
2385     pp = &cfun->eh->region_tree;
2386   for (p = *pp; p != region; pp = &p->next_peer, p = *pp)
2387     continue;
2388
2389   if (region->inner)
2390     {
2391       for (p = region->inner; p->next_peer ; p = p->next_peer)
2392         p->outer = region->outer;
2393       p->next_peer = region->next_peer;
2394       p->outer = region->outer;
2395       *pp = region->inner;
2396     }
2397   else
2398     *pp = region->next_peer;
2399
2400   if (region->type == ERT_CATCH)
2401     {
2402       struct eh_region *try, *next, *prev;
2403
2404       for (try = region->next_peer;
2405            try->type == ERT_CATCH;
2406            try = try->next_peer)
2407         continue;
2408       if (try->type != ERT_TRY)
2409         abort ();
2410
2411       next = region->u.catch.next_catch;
2412       prev = region->u.catch.prev_catch;
2413
2414       if (next)
2415         next->u.catch.prev_catch = prev;
2416       else
2417         try->u.try.last_catch = prev;
2418       if (prev)
2419         prev->u.catch.next_catch = next;
2420       else
2421         {
2422           try->u.try.catch = next;
2423           if (! next)
2424             remove_eh_handler (try);
2425         }
2426     }
2427
2428   free (region);
2429 }
2430
2431 /* LABEL heads a basic block that is about to be deleted.  If this
2432    label corresponds to an exception region, we may be able to
2433    delete the region.  */
2434
2435 void
2436 maybe_remove_eh_handler (label)
2437      rtx label;
2438 {
2439   int i;
2440
2441   /* ??? After generating landing pads, it's not so simple to determine
2442      if the region data is completely unused.  One must examine the
2443      landing pad and the post landing pad, and whether an inner try block
2444      is referencing the catch handlers directly.  */
2445   if (cfun->eh->built_landing_pads)
2446     return;
2447
2448   for (i = cfun->eh->last_region_number; i > 0; --i)
2449     {
2450       struct eh_region *region = cfun->eh->region_array[i];
2451       if (region && region->label == label)
2452         {
2453           /* Flow will want to remove MUST_NOT_THROW regions as unreachable
2454              because there is no path to the fallback call to terminate.
2455              But the region continues to affect call-site data until there
2456              are no more contained calls, which we don't see here.  */
2457           if (region->type == ERT_MUST_NOT_THROW)
2458             {
2459               remove_exception_handler_label (region->label);
2460               region->label = NULL_RTX;
2461             }
2462           else
2463             remove_eh_handler (region);
2464           break;
2465         }
2466     }
2467 }
2468
2469 \f
2470 /* This section describes CFG exception edges for flow.  */
2471
2472 /* For communicating between calls to reachable_next_level.  */
2473 struct reachable_info
2474 {
2475   tree types_caught;
2476   tree types_allowed;
2477   rtx handlers;
2478 };
2479
2480 /* A subroutine of reachable_next_level.  Return true if TYPE, or a
2481    base class of TYPE, is in HANDLED.  */
2482
2483 static int
2484 check_handled (handled, type)
2485      tree handled, type;
2486 {
2487   tree t;
2488
2489   /* We can check for exact matches without front-end help.  */
2490   if (! lang_eh_type_covers)
2491     {
2492       for (t = handled; t ; t = TREE_CHAIN (t))
2493         if (TREE_VALUE (t) == type)
2494           return 1;
2495     }
2496   else
2497     {
2498       for (t = handled; t ; t = TREE_CHAIN (t))
2499         if ((*lang_eh_type_covers) (TREE_VALUE (t), type))
2500           return 1;
2501     }
2502
2503   return 0;
2504 }
2505
2506 /* A subroutine of reachable_next_level.  If we are collecting a list
2507    of handlers, add one.  After landing pad generation, reference
2508    it instead of the handlers themselves.  Further, the handlers are
2509    all wired together, so by referencing one, we've got them all. 
2510    Before landing pad generation we reference each handler individually.
2511
2512    LP_REGION contains the landing pad; REGION is the handler.  */
2513
2514 static void
2515 add_reachable_handler (info, lp_region, region)
2516      struct reachable_info *info;
2517      struct eh_region *lp_region;
2518      struct eh_region *region;
2519 {
2520   if (! info)
2521     return;
2522
2523   if (cfun->eh->built_landing_pads)
2524     {
2525       if (! info->handlers)
2526         info->handlers = alloc_INSN_LIST (lp_region->landing_pad, NULL_RTX);
2527     }
2528   else
2529     info->handlers = alloc_INSN_LIST (region->label, info->handlers);
2530 }
2531
2532 /* Process one level of exception regions for reachability.  
2533    If TYPE_THROWN is non-null, then it is the *exact* type being
2534    propagated.  If INFO is non-null, then collect handler labels
2535    and caught/allowed type information between invocations.  */
2536
2537 static enum reachable_code
2538 reachable_next_level (region, type_thrown, info)
2539      struct eh_region *region;
2540      tree type_thrown;
2541      struct reachable_info *info;
2542 {
2543   switch (region->type)
2544     {
2545     case ERT_CLEANUP:
2546       /* Before landing-pad generation, we model control flow
2547          directly to the individual handlers.  In this way we can
2548          see that catch handler types may shadow one another.  */
2549       add_reachable_handler (info, region, region);
2550       return RNL_MAYBE_CAUGHT;
2551
2552     case ERT_TRY:
2553       {
2554         struct eh_region *c;
2555         enum reachable_code ret = RNL_NOT_CAUGHT;
2556
2557         for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
2558           {
2559             /* A catch-all handler ends the search.  */
2560             /* ??? _Unwind_ForcedUnwind will want outer cleanups
2561                to be run as well.  */
2562             if (c->u.catch.type == NULL)
2563               {
2564                 add_reachable_handler (info, region, c);
2565                 return RNL_CAUGHT;
2566               }
2567
2568             if (type_thrown)
2569               {
2570                 /* If we have a type match, end the search.  */
2571                 if (c->u.catch.type == type_thrown
2572                     || (lang_eh_type_covers
2573                         && (*lang_eh_type_covers) (c->u.catch.type,
2574                                                    type_thrown)))
2575                   {
2576                     add_reachable_handler (info, region, c);
2577                     return RNL_CAUGHT;
2578                   }
2579
2580                 /* If we have definitive information of a match failure,
2581                    the catch won't trigger.  */
2582                 if (lang_eh_type_covers)
2583                   return RNL_NOT_CAUGHT;
2584               }
2585
2586             if (! info)
2587               ret = RNL_MAYBE_CAUGHT;
2588
2589             /* A type must not have been previously caught.  */
2590             else if (! check_handled (info->types_caught, c->u.catch.type))
2591               {
2592                 add_reachable_handler (info, region, c);
2593                 info->types_caught = tree_cons (NULL, c->u.catch.type,
2594                                                 info->types_caught);
2595
2596                 /* ??? If the catch type is a base class of every allowed
2597                    type, then we know we can stop the search.  */
2598                 ret = RNL_MAYBE_CAUGHT;
2599               }
2600           }
2601
2602         return ret;
2603       }
2604
2605     case ERT_ALLOWED_EXCEPTIONS:
2606       /* An empty list of types definitely ends the search.  */
2607       if (region->u.allowed.type_list == NULL_TREE)
2608         {
2609           add_reachable_handler (info, region, region);
2610           return RNL_CAUGHT;
2611         }
2612
2613       /* Collect a list of lists of allowed types for use in detecting
2614          when a catch may be transformed into a catch-all.  */
2615       if (info)
2616         info->types_allowed = tree_cons (NULL_TREE,
2617                                          region->u.allowed.type_list,
2618                                          info->types_allowed);
2619             
2620       /* If we have definitive information about the type heirarchy,
2621          then we can tell if the thrown type will pass through the
2622          filter.  */
2623       if (type_thrown && lang_eh_type_covers)
2624         {
2625           if (check_handled (region->u.allowed.type_list, type_thrown))
2626             return RNL_NOT_CAUGHT;
2627           else
2628             {
2629               add_reachable_handler (info, region, region);
2630               return RNL_CAUGHT;
2631             }
2632         }
2633
2634       add_reachable_handler (info, region, region);
2635       return RNL_MAYBE_CAUGHT;
2636
2637     case ERT_CATCH:
2638       /* Catch regions are handled by their controling try region.  */
2639       return RNL_NOT_CAUGHT;
2640
2641     case ERT_MUST_NOT_THROW:
2642       /* Here we end our search, since no exceptions may propagate.
2643          If we've touched down at some landing pad previous, then the
2644          explicit function call we generated may be used.  Otherwise
2645          the call is made by the runtime.  */
2646       if (info && info->handlers)
2647         {
2648           add_reachable_handler (info, region, region);
2649           return RNL_CAUGHT;
2650         }
2651       else
2652         return RNL_BLOCKED;
2653
2654     case ERT_THROW:
2655     case ERT_FIXUP:
2656       /* Shouldn't see these here.  */
2657       break;
2658     }
2659
2660   abort ();
2661 }
2662
2663 /* Retrieve a list of labels of exception handlers which can be
2664    reached by a given insn.  */
2665
2666 rtx
2667 reachable_handlers (insn)
2668      rtx insn;
2669 {
2670   struct reachable_info info;
2671   struct eh_region *region;
2672   tree type_thrown;
2673   int region_number;
2674
2675   if (GET_CODE (insn) == JUMP_INSN
2676       && GET_CODE (PATTERN (insn)) == RESX)
2677     region_number = XINT (PATTERN (insn), 0);
2678   else
2679     {
2680       rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2681       if (!note || INTVAL (XEXP (note, 0)) <= 0)
2682         return NULL;
2683       region_number = INTVAL (XEXP (note, 0));
2684     }
2685
2686   memset (&info, 0, sizeof (info));
2687
2688   region = cfun->eh->region_array[region_number];
2689
2690   type_thrown = NULL_TREE;
2691   if (GET_CODE (insn) == JUMP_INSN
2692       && GET_CODE (PATTERN (insn)) == RESX)
2693     {
2694       /* A RESX leaves a region instead of entering it.  Thus the
2695          region itself may have been deleted out from under us.  */
2696       if (region == NULL)
2697         return NULL;
2698       region = region->outer;
2699     }
2700   else if (region->type == ERT_THROW)
2701     {
2702       type_thrown = region->u.throw.type;
2703       region = region->outer;
2704     }
2705
2706   for (; region; region = region->outer)
2707     if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT)
2708       break;
2709
2710   return info.handlers;
2711 }
2712
2713 /* Determine if the given INSN can throw an exception that is caught
2714    within the function.  */
2715
2716 bool
2717 can_throw_internal (insn)
2718      rtx insn;
2719 {
2720   struct eh_region *region;
2721   tree type_thrown;
2722   rtx note;
2723
2724   if (! INSN_P (insn))
2725     return false;
2726
2727   if (GET_CODE (insn) == INSN
2728       && GET_CODE (PATTERN (insn)) == SEQUENCE)
2729     insn = XVECEXP (PATTERN (insn), 0, 0);
2730
2731   if (GET_CODE (insn) == CALL_INSN
2732       && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
2733     {
2734       int i;
2735       for (i = 0; i < 3; ++i)
2736         {
2737           rtx sub = XEXP (PATTERN (insn), i);
2738           for (; sub ; sub = NEXT_INSN (sub))
2739             if (can_throw_internal (sub))
2740               return true;
2741         }
2742       return false;
2743     }
2744
2745   /* Every insn that might throw has an EH_REGION note.  */
2746   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2747   if (!note || INTVAL (XEXP (note, 0)) <= 0)
2748     return false;
2749
2750   region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2751
2752   type_thrown = NULL_TREE;
2753   if (region->type == ERT_THROW)
2754     {
2755       type_thrown = region->u.throw.type;
2756       region = region->outer;
2757     }
2758
2759   /* If this exception is ignored by each and every containing region,
2760      then control passes straight out.  The runtime may handle some
2761      regions, which also do not require processing internally.  */
2762   for (; region; region = region->outer)
2763     {
2764       enum reachable_code how = reachable_next_level (region, type_thrown, 0);
2765       if (how == RNL_BLOCKED)
2766         return false;
2767       if (how != RNL_NOT_CAUGHT)
2768         return true;
2769     }
2770
2771   return false;
2772 }
2773
2774 /* Determine if the given INSN can throw an exception that is
2775    visible outside the function.  */
2776
2777 bool
2778 can_throw_external (insn)
2779      rtx insn;
2780 {
2781   struct eh_region *region;
2782   tree type_thrown;
2783   rtx note;
2784
2785   if (! INSN_P (insn))
2786     return false;
2787
2788   if (GET_CODE (insn) == INSN
2789       && GET_CODE (PATTERN (insn)) == SEQUENCE)
2790     insn = XVECEXP (PATTERN (insn), 0, 0);
2791
2792   if (GET_CODE (insn) == CALL_INSN
2793       && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
2794     {
2795       int i;
2796       for (i = 0; i < 3; ++i)
2797         {
2798           rtx sub = XEXP (PATTERN (insn), i);
2799           for (; sub ; sub = NEXT_INSN (sub))
2800             if (can_throw_external (sub))
2801               return true;
2802         }
2803       return false;
2804     }
2805
2806   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2807   if (!note)
2808     {
2809       /* Calls (and trapping insns) without notes are outside any
2810          exception handling region in this function.  We have to
2811          assume it might throw.  Given that the front end and middle
2812          ends mark known NOTHROW functions, this isn't so wildly
2813          inaccurate.  */
2814       return (GET_CODE (insn) == CALL_INSN
2815               || (flag_non_call_exceptions
2816                   && may_trap_p (PATTERN (insn))));
2817     }
2818   if (INTVAL (XEXP (note, 0)) <= 0)
2819     return false;
2820
2821   region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2822
2823   type_thrown = NULL_TREE;
2824   if (region->type == ERT_THROW)
2825     {
2826       type_thrown = region->u.throw.type;
2827       region = region->outer;
2828     }
2829
2830   /* If the exception is caught or blocked by any containing region,
2831      then it is not seen by any calling function.  */
2832   for (; region ; region = region->outer)
2833     if (reachable_next_level (region, type_thrown, NULL) >= RNL_CAUGHT)
2834       return false;
2835
2836   return true;
2837 }
2838
2839 /* True if nothing in this function can throw outside this function.  */
2840
2841 bool
2842 nothrow_function_p ()
2843 {
2844   rtx insn;
2845
2846   if (! flag_exceptions)
2847     return true;
2848
2849   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2850     if (can_throw_external (insn))
2851       return false;
2852   for (insn = current_function_epilogue_delay_list; insn;
2853        insn = XEXP (insn, 1))
2854     if (can_throw_external (insn))
2855       return false;
2856
2857   return true;
2858 }
2859
2860 \f
2861 /* Various hooks for unwind library.  */
2862
2863 /* Do any necessary initialization to access arbitrary stack frames.
2864    On the SPARC, this means flushing the register windows.  */
2865
2866 void
2867 expand_builtin_unwind_init ()
2868 {
2869   /* Set this so all the registers get saved in our frame; we need to be
2870      able to copy the saved values for any registers from frames we unwind.  */
2871   current_function_has_nonlocal_label = 1;
2872
2873 #ifdef SETUP_FRAME_ADDRESSES
2874   SETUP_FRAME_ADDRESSES ();
2875 #endif
2876 }
2877
2878 rtx
2879 expand_builtin_eh_return_data_regno (arglist)
2880      tree arglist;
2881 {
2882   tree which = TREE_VALUE (arglist);
2883   unsigned HOST_WIDE_INT iwhich;
2884
2885   if (TREE_CODE (which) != INTEGER_CST)
2886     {
2887       error ("argument of `__builtin_eh_return_regno' must be constant");
2888       return constm1_rtx;
2889     }
2890
2891   iwhich = tree_low_cst (which, 1);
2892   iwhich = EH_RETURN_DATA_REGNO (iwhich);
2893   if (iwhich == INVALID_REGNUM)
2894     return constm1_rtx;
2895
2896 #ifdef DWARF_FRAME_REGNUM
2897   iwhich = DWARF_FRAME_REGNUM (iwhich);
2898 #else
2899   iwhich = DBX_REGISTER_NUMBER (iwhich);
2900 #endif
2901
2902   return GEN_INT (iwhich);      
2903 }
2904
2905 /* Given a value extracted from the return address register or stack slot,
2906    return the actual address encoded in that value.  */
2907
2908 rtx
2909 expand_builtin_extract_return_addr (addr_tree)
2910      tree addr_tree;
2911 {
2912   rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
2913
2914   /* First mask out any unwanted bits.  */
2915 #ifdef MASK_RETURN_ADDR
2916   expand_and (addr, MASK_RETURN_ADDR, addr);
2917 #endif
2918
2919   /* Then adjust to find the real return address.  */
2920 #if defined (RETURN_ADDR_OFFSET)
2921   addr = plus_constant (addr, RETURN_ADDR_OFFSET);
2922 #endif
2923
2924   return addr;
2925 }
2926
2927 /* Given an actual address in addr_tree, do any necessary encoding
2928    and return the value to be stored in the return address register or
2929    stack slot so the epilogue will return to that address.  */
2930
2931 rtx
2932 expand_builtin_frob_return_addr (addr_tree)
2933      tree addr_tree;
2934 {
2935   rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
2936
2937 #ifdef POINTERS_EXTEND_UNSIGNED
2938   addr = convert_memory_address (Pmode, addr);
2939 #endif
2940
2941 #ifdef RETURN_ADDR_OFFSET
2942   addr = force_reg (Pmode, addr);
2943   addr = plus_constant (addr, -RETURN_ADDR_OFFSET);
2944 #endif
2945
2946   return addr;
2947 }
2948
2949 /* Set up the epilogue with the magic bits we'll need to return to the
2950    exception handler.  */
2951
2952 void
2953 expand_builtin_eh_return (stackadj_tree, handler_tree)
2954     tree stackadj_tree, handler_tree;
2955 {
2956   rtx stackadj, handler;
2957
2958   stackadj = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj, VOIDmode, 0);
2959   handler = expand_expr (handler_tree, cfun->eh->ehr_handler, VOIDmode, 0);
2960
2961 #ifdef POINTERS_EXTEND_UNSIGNED
2962   stackadj = convert_memory_address (Pmode, stackadj);
2963   handler = convert_memory_address (Pmode, handler);
2964 #endif
2965
2966   if (! cfun->eh->ehr_label)
2967     {
2968       cfun->eh->ehr_stackadj = copy_to_reg (stackadj);
2969       cfun->eh->ehr_handler = copy_to_reg (handler);
2970       cfun->eh->ehr_label = gen_label_rtx ();
2971     }
2972   else
2973     {
2974       if (stackadj != cfun->eh->ehr_stackadj)
2975         emit_move_insn (cfun->eh->ehr_stackadj, stackadj);
2976       if (handler != cfun->eh->ehr_handler)
2977         emit_move_insn (cfun->eh->ehr_handler, handler);
2978     }
2979
2980   emit_jump (cfun->eh->ehr_label);
2981 }
2982
2983 void
2984 expand_eh_return ()
2985 {
2986   rtx sa, ra, around_label;
2987
2988   if (! cfun->eh->ehr_label)
2989     return;
2990
2991   sa = EH_RETURN_STACKADJ_RTX;
2992   if (! sa)
2993     {
2994       error ("__builtin_eh_return not supported on this target");
2995       return;
2996     }
2997
2998   current_function_calls_eh_return = 1;
2999
3000   around_label = gen_label_rtx ();
3001   emit_move_insn (sa, const0_rtx);
3002   emit_jump (around_label);
3003
3004   emit_label (cfun->eh->ehr_label);
3005   clobber_return_register ();
3006
3007 #ifdef HAVE_eh_return
3008   if (HAVE_eh_return)
3009     emit_insn (gen_eh_return (cfun->eh->ehr_stackadj, cfun->eh->ehr_handler));
3010   else
3011 #endif
3012     {
3013       ra = EH_RETURN_HANDLER_RTX;
3014       if (! ra)
3015         {
3016           error ("__builtin_eh_return not supported on this target");
3017           ra = gen_reg_rtx (Pmode);
3018         }
3019
3020       emit_move_insn (sa, cfun->eh->ehr_stackadj);
3021       emit_move_insn (ra, cfun->eh->ehr_handler);
3022     }
3023
3024   emit_label (around_label);
3025 }
3026 \f
3027 /* In the following functions, we represent entries in the action table
3028    as 1-based indicies.  Special cases are:
3029
3030          0:     null action record, non-null landing pad; implies cleanups
3031         -1:     null action record, null landing pad; implies no action
3032         -2:     no call-site entry; implies must_not_throw
3033         -3:     we have yet to process outer regions
3034
3035    Further, no special cases apply to the "next" field of the record.
3036    For next, 0 means end of list.  */
3037
3038 struct action_record
3039 {
3040   int offset;
3041   int filter;
3042   int next;
3043 };
3044
3045 static int
3046 action_record_eq (pentry, pdata)
3047      const PTR pentry;
3048      const PTR pdata;
3049 {
3050   const struct action_record *entry = (const struct action_record *) pentry;
3051   const struct action_record *data = (const struct action_record *) pdata;
3052   return entry->filter == data->filter && entry->next == data->next;
3053 }
3054
3055 static hashval_t
3056 action_record_hash (pentry)
3057      const PTR pentry;
3058 {
3059   const struct action_record *entry = (const struct action_record *) pentry;
3060   return entry->next * 1009 + entry->filter;
3061 }
3062
3063 static int
3064 add_action_record (ar_hash, filter, next)
3065      htab_t ar_hash;
3066      int filter, next;
3067 {
3068   struct action_record **slot, *new, tmp;
3069
3070   tmp.filter = filter;
3071   tmp.next = next;
3072   slot = (struct action_record **) htab_find_slot (ar_hash, &tmp, INSERT);
3073
3074   if ((new = *slot) == NULL)
3075     {
3076       new = (struct action_record *) xmalloc (sizeof (*new));
3077       new->offset = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
3078       new->filter = filter;
3079       new->next = next;
3080       *slot = new;
3081
3082       /* The filter value goes in untouched.  The link to the next
3083          record is a "self-relative" byte offset, or zero to indicate
3084          that there is no next record.  So convert the absolute 1 based
3085          indicies we've been carrying around into a displacement.  */
3086
3087       push_sleb128 (&cfun->eh->action_record_data, filter);
3088       if (next)
3089         next -= VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
3090       push_sleb128 (&cfun->eh->action_record_data, next);
3091     }
3092
3093   return new->offset;
3094 }
3095
3096 static int
3097 collect_one_action_chain (ar_hash, region)
3098      htab_t ar_hash;
3099      struct eh_region *region;
3100 {
3101   struct eh_region *c;
3102   int next;
3103
3104   /* If we've reached the top of the region chain, then we have
3105      no actions, and require no landing pad.  */
3106   if (region == NULL)
3107     return -1;
3108
3109   switch (region->type)
3110     {
3111     case ERT_CLEANUP:
3112       /* A cleanup adds a zero filter to the beginning of the chain, but
3113          there are special cases to look out for.  If there are *only*
3114          cleanups along a path, then it compresses to a zero action.
3115          Further, if there are multiple cleanups along a path, we only
3116          need to represent one of them, as that is enough to trigger
3117          entry to the landing pad at runtime.  */
3118       next = collect_one_action_chain (ar_hash, region->outer);
3119       if (next <= 0)
3120         return 0;
3121       for (c = region->outer; c ; c = c->outer)
3122         if (c->type == ERT_CLEANUP)
3123           return next;
3124       return add_action_record (ar_hash, 0, next);
3125
3126     case ERT_TRY:
3127       /* Process the associated catch regions in reverse order.
3128          If there's a catch-all handler, then we don't need to
3129          search outer regions.  Use a magic -3 value to record
3130          that we havn't done the outer search.  */
3131       next = -3;
3132       for (c = region->u.try.last_catch; c ; c = c->u.catch.prev_catch)
3133         {
3134           if (c->u.catch.type == NULL)
3135             next = add_action_record (ar_hash, c->u.catch.filter, 0);
3136           else
3137             {
3138               if (next == -3)
3139                 {
3140                   next = collect_one_action_chain (ar_hash, region->outer);
3141
3142                   /* If there is no next action, terminate the chain.  */
3143                   if (next == -1)
3144                     next = 0;
3145                   /* If all outer actions are cleanups or must_not_throw,
3146                      we'll have no action record for it, since we had wanted
3147                      to encode these states in the call-site record directly.
3148                      Add a cleanup action to the chain to catch these.  */
3149                   else if (next <= 0)
3150                     next = add_action_record (ar_hash, 0, 0);
3151                 }
3152               next = add_action_record (ar_hash, c->u.catch.filter, next);
3153             }
3154         }
3155       return next;
3156
3157     case ERT_ALLOWED_EXCEPTIONS:
3158       /* An exception specification adds its filter to the
3159          beginning of the chain.  */
3160       next = collect_one_action_chain (ar_hash, region->outer);
3161       return add_action_record (ar_hash, region->u.allowed.filter,
3162                                 next < 0 ? 0 : next);
3163
3164     case ERT_MUST_NOT_THROW:
3165       /* A must-not-throw region with no inner handlers or cleanups
3166          requires no call-site entry.  Note that this differs from
3167          the no handler or cleanup case in that we do require an lsda
3168          to be generated.  Return a magic -2 value to record this.  */
3169       return -2;
3170
3171     case ERT_CATCH:
3172     case ERT_THROW:
3173       /* CATCH regions are handled in TRY above.  THROW regions are
3174          for optimization information only and produce no output.  */
3175       return collect_one_action_chain (ar_hash, region->outer);
3176
3177     default:
3178       abort ();
3179     }
3180 }
3181
3182 static int
3183 add_call_site (landing_pad, action)
3184      rtx landing_pad;
3185      int action;
3186 {
3187   struct call_site_record *data = cfun->eh->call_site_data;
3188   int used = cfun->eh->call_site_data_used;
3189   int size = cfun->eh->call_site_data_size;
3190
3191   if (used >= size)
3192     {
3193       size = (size ? size * 2 : 64);
3194       data = (struct call_site_record *)
3195         xrealloc (data, sizeof (*data) * size);
3196       cfun->eh->call_site_data = data;
3197       cfun->eh->call_site_data_size = size;
3198     }
3199
3200   data[used].landing_pad = landing_pad;
3201   data[used].action = action;
3202
3203   cfun->eh->call_site_data_used = used + 1;
3204
3205   return used + call_site_base;
3206 }
3207
3208 /* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
3209    The new note numbers will not refer to region numbers, but
3210    instead to call site entries.  */
3211
3212 void
3213 convert_to_eh_region_ranges ()
3214 {
3215   rtx insn, iter, note;
3216   htab_t ar_hash;
3217   int last_action = -3;
3218   rtx last_action_insn = NULL_RTX;
3219   rtx last_landing_pad = NULL_RTX;
3220   rtx first_no_action_insn = NULL_RTX;
3221   int call_site = 0;
3222
3223   if (USING_SJLJ_EXCEPTIONS || cfun->eh->region_tree == NULL)
3224     return;
3225
3226   VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
3227
3228   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
3229
3230   for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
3231     if (INSN_P (iter))
3232       {
3233         struct eh_region *region;
3234         int this_action;
3235         rtx this_landing_pad;
3236
3237         insn = iter;
3238         if (GET_CODE (insn) == INSN
3239             && GET_CODE (PATTERN (insn)) == SEQUENCE)
3240           insn = XVECEXP (PATTERN (insn), 0, 0);
3241
3242         note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3243         if (!note)
3244           {
3245             if (! (GET_CODE (insn) == CALL_INSN
3246                    || (flag_non_call_exceptions
3247                        && may_trap_p (PATTERN (insn)))))
3248               continue;
3249             this_action = -1;
3250             region = NULL;
3251           }
3252         else
3253           {
3254             if (INTVAL (XEXP (note, 0)) <= 0)
3255               continue;
3256             region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
3257             this_action = collect_one_action_chain (ar_hash, region);
3258           }
3259
3260         /* Existence of catch handlers, or must-not-throw regions
3261            implies that an lsda is needed (even if empty).  */
3262         if (this_action != -1)
3263           cfun->uses_eh_lsda = 1;
3264
3265         /* Delay creation of region notes for no-action regions
3266            until we're sure that an lsda will be required.  */
3267         else if (last_action == -3)
3268           {
3269             first_no_action_insn = iter;
3270             last_action = -1;
3271           }
3272
3273         /* Cleanups and handlers may share action chains but not
3274            landing pads.  Collect the landing pad for this region.  */
3275         if (this_action >= 0)
3276           {
3277             struct eh_region *o;
3278             for (o = region; ! o->landing_pad ; o = o->outer)
3279               continue;
3280             this_landing_pad = o->landing_pad;
3281           }
3282         else
3283           this_landing_pad = NULL_RTX;
3284
3285         /* Differing actions or landing pads implies a change in call-site
3286            info, which implies some EH_REGION note should be emitted.  */
3287         if (last_action != this_action
3288             || last_landing_pad != this_landing_pad)
3289           {
3290             /* If we'd not seen a previous action (-3) or the previous
3291                action was must-not-throw (-2), then we do not need an
3292                end note.  */
3293             if (last_action >= -1)
3294               {
3295                 /* If we delayed the creation of the begin, do it now.  */
3296                 if (first_no_action_insn)
3297                   {
3298                     call_site = add_call_site (NULL_RTX, 0);
3299                     note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
3300                                              first_no_action_insn);
3301                     NOTE_EH_HANDLER (note) = call_site;
3302                     first_no_action_insn = NULL_RTX;
3303                   }
3304
3305                 note = emit_note_after (NOTE_INSN_EH_REGION_END,
3306                                         last_action_insn);
3307                 NOTE_EH_HANDLER (note) = call_site;
3308               }
3309
3310             /* If the new action is must-not-throw, then no region notes
3311                are created.  */
3312             if (this_action >= -1)
3313               {
3314                 call_site = add_call_site (this_landing_pad, 
3315                                            this_action < 0 ? 0 : this_action);
3316                 note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter);
3317                 NOTE_EH_HANDLER (note) = call_site;
3318               }
3319
3320             last_action = this_action;
3321             last_landing_pad = this_landing_pad;
3322           }
3323         last_action_insn = iter;
3324       }
3325
3326   if (last_action >= -1 && ! first_no_action_insn)
3327     {
3328       note = emit_note_after (NOTE_INSN_EH_REGION_END, last_action_insn);
3329       NOTE_EH_HANDLER (note) = call_site;
3330     }
3331
3332   htab_delete (ar_hash);
3333 }
3334
3335 \f
3336 static void
3337 push_uleb128 (data_area, value)
3338      varray_type *data_area;
3339      unsigned int value;
3340 {
3341   do
3342     {
3343       unsigned char byte = value & 0x7f;
3344       value >>= 7;
3345       if (value)
3346         byte |= 0x80;
3347       VARRAY_PUSH_UCHAR (*data_area, byte);
3348     }
3349   while (value);
3350 }
3351
3352 static void
3353 push_sleb128 (data_area, value)
3354      varray_type *data_area;
3355      int value;
3356 {
3357   unsigned char byte;
3358   int more;
3359
3360   do
3361     {
3362       byte = value & 0x7f;
3363       value >>= 7;
3364       more = ! ((value == 0 && (byte & 0x40) == 0)
3365                 || (value == -1 && (byte & 0x40) != 0));
3366       if (more)
3367         byte |= 0x80;
3368       VARRAY_PUSH_UCHAR (*data_area, byte);
3369     }
3370   while (more);
3371 }
3372
3373 \f
3374 #ifndef HAVE_AS_LEB128
3375 static int
3376 dw2_size_of_call_site_table ()
3377 {
3378   int n = cfun->eh->call_site_data_used;
3379   int size = n * (4 + 4 + 4);
3380   int i;
3381
3382   for (i = 0; i < n; ++i)
3383     {
3384       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3385       size += size_of_uleb128 (cs->action);
3386     }
3387
3388   return size;
3389 }
3390
3391 static int
3392 sjlj_size_of_call_site_table ()
3393 {
3394   int n = cfun->eh->call_site_data_used;
3395   int size = 0;
3396   int i;
3397
3398   for (i = 0; i < n; ++i)
3399     {
3400       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3401       size += size_of_uleb128 (INTVAL (cs->landing_pad));
3402       size += size_of_uleb128 (cs->action);
3403     }
3404
3405   return size;
3406 }
3407 #endif
3408
3409 static void
3410 dw2_output_call_site_table ()
3411 {
3412   const char *function_start_lab
3413     = IDENTIFIER_POINTER (current_function_func_begin_label);
3414   int n = cfun->eh->call_site_data_used;
3415   int i;
3416
3417   for (i = 0; i < n; ++i)
3418     {
3419       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3420       char reg_start_lab[32];
3421       char reg_end_lab[32];
3422       char landing_pad_lab[32];
3423
3424       ASM_GENERATE_INTERNAL_LABEL (reg_start_lab, "LEHB", call_site_base + i);
3425       ASM_GENERATE_INTERNAL_LABEL (reg_end_lab, "LEHE", call_site_base + i);
3426
3427       if (cs->landing_pad)
3428         ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab, "L",
3429                                      CODE_LABEL_NUMBER (cs->landing_pad));
3430
3431       /* ??? Perhaps use insn length scaling if the assembler supports
3432          generic arithmetic.  */
3433       /* ??? Perhaps use attr_length to choose data1 or data2 instead of
3434          data4 if the function is small enough.  */
3435 #ifdef HAVE_AS_LEB128
3436       dw2_asm_output_delta_uleb128 (reg_start_lab, function_start_lab,
3437                                     "region %d start", i);
3438       dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab,
3439                                     "length");
3440       if (cs->landing_pad)
3441         dw2_asm_output_delta_uleb128 (landing_pad_lab, function_start_lab,
3442                                       "landing pad");
3443       else
3444         dw2_asm_output_data_uleb128 (0, "landing pad");
3445 #else
3446       dw2_asm_output_delta (4, reg_start_lab, function_start_lab,
3447                             "region %d start", i);
3448       dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length");
3449       if (cs->landing_pad)
3450         dw2_asm_output_delta (4, landing_pad_lab, function_start_lab,
3451                               "landing pad");
3452       else
3453         dw2_asm_output_data (4, 0, "landing pad");
3454 #endif
3455       dw2_asm_output_data_uleb128 (cs->action, "action");
3456     }
3457
3458   call_site_base += n;
3459 }
3460
3461 static void
3462 sjlj_output_call_site_table ()
3463 {
3464   int n = cfun->eh->call_site_data_used;
3465   int i;
3466
3467   for (i = 0; i < n; ++i)
3468     {
3469       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3470
3471       dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad),
3472                                    "region %d landing pad", i);
3473       dw2_asm_output_data_uleb128 (cs->action, "action");
3474     }
3475
3476   call_site_base += n;
3477 }
3478
3479 void
3480 output_function_exception_table ()
3481 {
3482   int tt_format, cs_format, lp_format, i, n;
3483 #ifdef HAVE_AS_LEB128
3484   char ttype_label[32];
3485   char cs_after_size_label[32];
3486   char cs_end_label[32];
3487 #else
3488   int call_site_len;
3489 #endif
3490   int have_tt_data;
3491   int funcdef_number;
3492   int tt_format_size = 0;
3493
3494   /* Not all functions need anything.  */
3495   if (! cfun->uses_eh_lsda)
3496     return;
3497
3498   funcdef_number = (USING_SJLJ_EXCEPTIONS
3499                     ? sjlj_funcdef_number
3500                     : current_funcdef_number);
3501
3502 #ifdef IA64_UNWIND_INFO
3503   fputs ("\t.personality\t", asm_out_file);
3504   output_addr_const (asm_out_file, eh_personality_libfunc);
3505   fputs ("\n\t.handlerdata\n", asm_out_file);
3506   /* Note that varasm still thinks we're in the function's code section.
3507      The ".endp" directive that will immediately follow will take us back.  */
3508 #else
3509   exception_section ();
3510 #endif
3511
3512   have_tt_data = (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) > 0
3513                   || VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) > 0);
3514
3515   /* Indicate the format of the @TType entries.  */
3516   if (! have_tt_data)
3517     tt_format = DW_EH_PE_omit;
3518   else
3519     {
3520       tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
3521 #ifdef HAVE_AS_LEB128
3522       ASM_GENERATE_INTERNAL_LABEL (ttype_label, "LLSDATT", funcdef_number);
3523 #endif
3524       tt_format_size = size_of_encoded_value (tt_format);
3525
3526       assemble_align (tt_format_size * BITS_PER_UNIT);
3527     }
3528
3529   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LLSDA", funcdef_number);
3530
3531   /* The LSDA header.  */
3532
3533   /* Indicate the format of the landing pad start pointer.  An omitted
3534      field implies @LPStart == @Start.  */
3535   /* Currently we always put @LPStart == @Start.  This field would
3536      be most useful in moving the landing pads completely out of
3537      line to another section, but it could also be used to minimize
3538      the size of uleb128 landing pad offsets.  */
3539   lp_format = DW_EH_PE_omit;
3540   dw2_asm_output_data (1, lp_format, "@LPStart format (%s)",
3541                        eh_data_format_name (lp_format));
3542
3543   /* @LPStart pointer would go here.  */
3544
3545   dw2_asm_output_data (1, tt_format, "@TType format (%s)",
3546                        eh_data_format_name (tt_format));
3547
3548 #ifndef HAVE_AS_LEB128
3549   if (USING_SJLJ_EXCEPTIONS)
3550     call_site_len = sjlj_size_of_call_site_table ();
3551   else
3552     call_site_len = dw2_size_of_call_site_table ();
3553 #endif
3554
3555   /* A pc-relative 4-byte displacement to the @TType data.  */
3556   if (have_tt_data)
3557     {
3558 #ifdef HAVE_AS_LEB128
3559       char ttype_after_disp_label[32];
3560       ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label, "LLSDATTD", 
3561                                    funcdef_number);
3562       dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label,
3563                                     "@TType base offset");
3564       ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label);
3565 #else
3566       /* Ug.  Alignment queers things.  */
3567       unsigned int before_disp, after_disp, last_disp, disp;
3568
3569       before_disp = 1 + 1;
3570       after_disp = (1 + size_of_uleb128 (call_site_len)
3571                     + call_site_len
3572                     + VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data)
3573                     + (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data)
3574                        * tt_format_size));
3575
3576       disp = after_disp;
3577       do
3578         {
3579           unsigned int disp_size, pad;
3580
3581           last_disp = disp;
3582           disp_size = size_of_uleb128 (disp);
3583           pad = before_disp + disp_size + after_disp;
3584           if (pad % tt_format_size)
3585             pad = tt_format_size - (pad % tt_format_size);
3586           else
3587             pad = 0;
3588           disp = after_disp + pad;
3589         }
3590       while (disp != last_disp);
3591
3592       dw2_asm_output_data_uleb128 (disp, "@TType base offset");
3593 #endif
3594     }
3595
3596   /* Indicate the format of the call-site offsets.  */
3597 #ifdef HAVE_AS_LEB128
3598   cs_format = DW_EH_PE_uleb128;
3599 #else
3600   cs_format = DW_EH_PE_udata4;
3601 #endif
3602   dw2_asm_output_data (1, cs_format, "call-site format (%s)",
3603                        eh_data_format_name (cs_format));
3604
3605 #ifdef HAVE_AS_LEB128
3606   ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label, "LLSDACSB",
3607                                funcdef_number);
3608   ASM_GENERATE_INTERNAL_LABEL (cs_end_label, "LLSDACSE",
3609                                funcdef_number);
3610   dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label,
3611                                 "Call-site table length");
3612   ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label);
3613   if (USING_SJLJ_EXCEPTIONS)
3614     sjlj_output_call_site_table ();
3615   else
3616     dw2_output_call_site_table ();
3617   ASM_OUTPUT_LABEL (asm_out_file, cs_end_label);
3618 #else
3619   dw2_asm_output_data_uleb128 (call_site_len,"Call-site table length");
3620   if (USING_SJLJ_EXCEPTIONS)
3621     sjlj_output_call_site_table ();
3622   else
3623     dw2_output_call_site_table ();
3624 #endif
3625
3626   /* ??? Decode and interpret the data for flag_debug_asm.  */
3627   n = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data);
3628   for (i = 0; i < n; ++i)
3629     dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->action_record_data, i),
3630                          (i ? NULL : "Action record table"));
3631
3632   if (have_tt_data)
3633     assemble_align (tt_format_size * BITS_PER_UNIT);
3634
3635   i = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data);
3636   while (i-- > 0)
3637     {
3638       tree type = VARRAY_TREE (cfun->eh->ttype_data, i);
3639       rtx value;
3640
3641       if (type == NULL_TREE)
3642         type = integer_zero_node;
3643       else
3644         type = lookup_type_for_runtime (type);
3645
3646       value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
3647       if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)
3648         assemble_integer (value, tt_format_size,
3649                           tt_format_size * BITS_PER_UNIT, 1);
3650       else
3651         dw2_asm_output_encoded_addr_rtx (tt_format, value, 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 }