OSDN Git Service

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