OSDN Git Service

62f626b4ef65053cf167d04c982c1c1366a5cc98
[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 #include "target.h"
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 preceding 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 occurs.
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, 0,
1756                                            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, region->label);
1783
1784           /* We delay the generation of the _Unwind_Resume until we generate
1785              landing pads.  We emit a marker here so as to get good control
1786              flow data in the meantime.  */
1787           region->resume
1788             = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1789           emit_barrier ();
1790
1791           seq = get_insns ();
1792           end_sequence ();
1793
1794           emit_insns_before (seq, region->label);
1795           break;
1796
1797         case ERT_CLEANUP:
1798         case ERT_MUST_NOT_THROW:
1799           region->post_landing_pad = region->label;
1800           break;
1801
1802         case ERT_CATCH:
1803         case ERT_THROW:
1804           /* Nothing to do.  */
1805           break;
1806
1807         default:
1808           abort ();
1809         }
1810     }
1811 }
1812
1813 /* Replace RESX patterns with jumps to the next handler if any, or calls to
1814    _Unwind_Resume otherwise.  */
1815
1816 static void
1817 connect_post_landing_pads ()
1818 {
1819   int i;
1820
1821   for (i = cfun->eh->last_region_number; i > 0; --i)
1822     {
1823       struct eh_region *region = cfun->eh->region_array[i];
1824       struct eh_region *outer;
1825       rtx seq;
1826
1827       /* Mind we don't process a region more than once.  */
1828       if (!region || region->region_number != i)
1829         continue;
1830
1831       /* If there is no RESX, or it has been deleted by flow, there's
1832          nothing to fix up.  */
1833       if (! region->resume || INSN_DELETED_P (region->resume))
1834         continue;
1835
1836       /* Search for another landing pad in this function.  */
1837       for (outer = region->outer; outer ; outer = outer->outer)
1838         if (outer->post_landing_pad)
1839           break;
1840
1841       start_sequence ();
1842
1843       if (outer)
1844         emit_jump (outer->post_landing_pad);
1845       else
1846         emit_library_call (unwind_resume_libfunc, LCT_THROW,
1847                            VOIDmode, 1, cfun->eh->exc_ptr, Pmode);
1848
1849       seq = get_insns ();
1850       end_sequence ();
1851       emit_insns_before (seq, region->resume);
1852       delete_insn (region->resume);
1853     }
1854 }
1855
1856 \f
1857 static void
1858 dw2_build_landing_pads ()
1859 {
1860   int i;
1861   unsigned int j;
1862
1863   for (i = cfun->eh->last_region_number; i > 0; --i)
1864     {
1865       struct eh_region *region = cfun->eh->region_array[i];
1866       rtx seq;
1867       bool clobbers_hard_regs = false;
1868
1869       /* Mind we don't process a region more than once.  */
1870       if (!region || region->region_number != i)
1871         continue;
1872
1873       if (region->type != ERT_CLEANUP
1874           && region->type != ERT_TRY
1875           && region->type != ERT_ALLOWED_EXCEPTIONS)
1876         continue;
1877
1878       start_sequence ();
1879
1880       region->landing_pad = gen_label_rtx ();
1881       emit_label (region->landing_pad);
1882
1883 #ifdef HAVE_exception_receiver
1884       if (HAVE_exception_receiver)
1885         emit_insn (gen_exception_receiver ());
1886       else
1887 #endif
1888 #ifdef HAVE_nonlocal_goto_receiver
1889         if (HAVE_nonlocal_goto_receiver)
1890           emit_insn (gen_nonlocal_goto_receiver ());
1891         else
1892 #endif
1893           { /* Nothing */ }
1894
1895       /* If the eh_return data registers are call-saved, then we
1896          won't have considered them clobbered from the call that
1897          threw.  Kill them now.  */
1898       for (j = 0; ; ++j)
1899         {
1900           unsigned r = EH_RETURN_DATA_REGNO (j);
1901           if (r == INVALID_REGNUM)
1902             break;
1903           if (! call_used_regs[r])
1904             {
1905               emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, r)));
1906               clobbers_hard_regs = true;
1907             }
1908         }
1909
1910       if (clobbers_hard_regs)
1911         {
1912           /* @@@ This is a kludge.  Not all machine descriptions define a
1913              blockage insn, but we must not allow the code we just generated
1914              to be reordered by scheduling.  So emit an ASM_INPUT to act as
1915              blockage insn.  */
1916           emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
1917         }
1918
1919       emit_move_insn (cfun->eh->exc_ptr,
1920                       gen_rtx_REG (Pmode, EH_RETURN_DATA_REGNO (0)));
1921       emit_move_insn (cfun->eh->filter,
1922                       gen_rtx_REG (word_mode, EH_RETURN_DATA_REGNO (1)));
1923
1924       seq = get_insns ();
1925       end_sequence ();
1926
1927       emit_insns_before (seq, region->post_landing_pad);
1928     }
1929 }
1930
1931 \f
1932 struct sjlj_lp_info
1933 {
1934   int directly_reachable;
1935   int action_index;
1936   int dispatch_index;
1937   int call_site_index;
1938 };
1939
1940 static bool
1941 sjlj_find_directly_reachable_regions (lp_info)
1942      struct sjlj_lp_info *lp_info;
1943 {
1944   rtx insn;
1945   bool found_one = false;
1946
1947   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
1948     {
1949       struct eh_region *region;
1950       tree type_thrown;
1951       rtx note;
1952
1953       if (! INSN_P (insn))
1954         continue;
1955
1956       note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1957       if (!note || INTVAL (XEXP (note, 0)) <= 0)
1958         continue;
1959
1960       region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
1961
1962       type_thrown = NULL_TREE;
1963       if (region->type == ERT_THROW)
1964         {
1965           type_thrown = region->u.throw.type;
1966           region = region->outer;
1967         }
1968
1969       /* Find the first containing region that might handle the exception.
1970          That's the landing pad to which we will transfer control.  */
1971       for (; region; region = region->outer)
1972         if (reachable_next_level (region, type_thrown, 0) != RNL_NOT_CAUGHT)
1973           break;
1974
1975       if (region)
1976         {
1977           lp_info[region->region_number].directly_reachable = 1;
1978           found_one = true;
1979         }
1980     }
1981
1982   return found_one;
1983 }
1984
1985 static void
1986 sjlj_assign_call_site_values (dispatch_label, lp_info)
1987      rtx dispatch_label;
1988      struct sjlj_lp_info *lp_info;
1989 {
1990   htab_t ar_hash;
1991   int i, index;
1992
1993   /* First task: build the action table.  */
1994
1995   VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
1996   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
1997
1998   for (i = cfun->eh->last_region_number; i > 0; --i)
1999     if (lp_info[i].directly_reachable)
2000       {
2001         struct eh_region *r = cfun->eh->region_array[i];
2002         r->landing_pad = dispatch_label;
2003         lp_info[i].action_index = collect_one_action_chain (ar_hash, r);
2004         if (lp_info[i].action_index != -1)
2005           cfun->uses_eh_lsda = 1;
2006       }
2007
2008   htab_delete (ar_hash);
2009
2010   /* Next: assign dispatch values.  In dwarf2 terms, this would be the
2011      landing pad label for the region.  For sjlj though, there is one
2012      common landing pad from which we dispatch to the post-landing pads.
2013
2014      A region receives a dispatch index if it is directly reachable
2015      and requires in-function processing.  Regions that share post-landing
2016      pads may share dispatch indices.  */
2017   /* ??? Post-landing pad sharing doesn't actually happen at the moment
2018      (see build_post_landing_pads) so we don't bother checking for it.  */
2019
2020   index = 0;
2021   for (i = cfun->eh->last_region_number; i > 0; --i)
2022     if (lp_info[i].directly_reachable
2023         && lp_info[i].action_index >= 0)
2024       lp_info[i].dispatch_index = index++;
2025
2026   /* Finally: assign call-site values.  If dwarf2 terms, this would be
2027      the region number assigned by convert_to_eh_region_ranges, but
2028      handles no-action and must-not-throw differently.  */
2029
2030   call_site_base = 1;
2031   for (i = cfun->eh->last_region_number; i > 0; --i)
2032     if (lp_info[i].directly_reachable)
2033       {
2034         int action = lp_info[i].action_index;
2035
2036         /* Map must-not-throw to otherwise unused call-site index 0.  */
2037         if (action == -2)
2038           index = 0;
2039         /* Map no-action to otherwise unused call-site index -1.  */
2040         else if (action == -1)
2041           index = -1;
2042         /* Otherwise, look it up in the table.  */
2043         else
2044           index = add_call_site (GEN_INT (lp_info[i].dispatch_index), action);
2045
2046         lp_info[i].call_site_index = index;
2047       }
2048 }
2049
2050 static void
2051 sjlj_mark_call_sites (lp_info)
2052      struct sjlj_lp_info *lp_info;
2053 {
2054   int last_call_site = -2;
2055   rtx insn, mem;
2056
2057   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
2058     {
2059       struct eh_region *region;
2060       int this_call_site;
2061       rtx note, before, p;
2062
2063       /* Reset value tracking at extended basic block boundaries.  */
2064       if (GET_CODE (insn) == CODE_LABEL)
2065         last_call_site = -2;
2066
2067       if (! INSN_P (insn))
2068         continue;
2069
2070       note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2071       if (!note)
2072         {
2073           /* Calls (and trapping insns) without notes are outside any
2074              exception handling region in this function.  Mark them as
2075              no action.  */
2076           if (GET_CODE (insn) == CALL_INSN
2077               || (flag_non_call_exceptions
2078                   && may_trap_p (PATTERN (insn))))
2079             this_call_site = -1;
2080           else
2081             continue;
2082         }
2083       else
2084         {
2085           /* Calls that are known to not throw need not be marked.  */
2086           if (INTVAL (XEXP (note, 0)) <= 0)
2087             continue;
2088
2089           region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2090           this_call_site = lp_info[region->region_number].call_site_index;
2091         }
2092
2093       if (this_call_site == last_call_site)
2094         continue;
2095
2096       /* Don't separate a call from it's argument loads.  */
2097       before = insn;
2098       if (GET_CODE (insn) == CALL_INSN)
2099          before = find_first_parameter_load (insn, NULL_RTX);
2100
2101       start_sequence ();
2102       mem = adjust_address (cfun->eh->sjlj_fc, TYPE_MODE (integer_type_node),
2103                             sjlj_fc_call_site_ofs);
2104       emit_move_insn (mem, GEN_INT (this_call_site));
2105       p = get_insns ();
2106       end_sequence ();
2107
2108       emit_insns_before (p, before);
2109       last_call_site = this_call_site;
2110     }
2111 }
2112
2113 /* Construct the SjLj_Function_Context.  */
2114
2115 static void
2116 sjlj_emit_function_enter (dispatch_label)
2117      rtx dispatch_label;
2118 {
2119   rtx fn_begin, fc, mem, seq;
2120
2121   fc = cfun->eh->sjlj_fc;
2122
2123   start_sequence ();
2124
2125   /* We're storing this libcall's address into memory instead of
2126      calling it directly.  Thus, we must call assemble_external_libcall
2127      here, as we can not depend on emit_library_call to do it for us.  */
2128   assemble_external_libcall (eh_personality_libfunc);
2129   mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
2130   emit_move_insn (mem, eh_personality_libfunc);
2131
2132   mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
2133   if (cfun->uses_eh_lsda)
2134     {
2135       char buf[20];
2136       ASM_GENERATE_INTERNAL_LABEL (buf, "LLSDA", sjlj_funcdef_number);
2137       emit_move_insn (mem, gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)));
2138     }
2139   else
2140     emit_move_insn (mem, const0_rtx);
2141   
2142 #ifdef DONT_USE_BUILTIN_SETJMP
2143   {
2144     rtx x, note;
2145     x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
2146                                  TYPE_MODE (integer_type_node), 1,
2147                                  plus_constant (XEXP (fc, 0),
2148                                                 sjlj_fc_jbuf_ofs), Pmode);
2149
2150     note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
2151     NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, x, const0_rtx);
2152
2153     emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
2154                              TYPE_MODE (integer_type_node), 0, dispatch_label);
2155   }
2156 #else
2157   expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
2158                                dispatch_label);
2159 #endif
2160
2161   emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
2162                      1, XEXP (fc, 0), Pmode);
2163
2164   seq = get_insns ();
2165   end_sequence ();
2166
2167   /* ??? Instead of doing this at the beginning of the function,
2168      do this in a block that is at loop level 0 and dominates all
2169      can_throw_internal instructions.  */
2170
2171   for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
2172     if (GET_CODE (fn_begin) == NOTE
2173         && NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
2174       break;
2175   emit_insns_after (seq, fn_begin);
2176 }
2177
2178 /* Call back from expand_function_end to know where we should put
2179    the call to unwind_sjlj_unregister_libfunc if needed.  */
2180
2181 void
2182 sjlj_emit_function_exit_after (after)
2183      rtx after;
2184 {
2185   cfun->eh->sjlj_exit_after = after;
2186 }
2187
2188 static void
2189 sjlj_emit_function_exit ()
2190 {
2191   rtx seq;
2192
2193   start_sequence ();
2194
2195   emit_library_call (unwind_sjlj_unregister_libfunc, LCT_NORMAL, VOIDmode,
2196                      1, XEXP (cfun->eh->sjlj_fc, 0), Pmode);
2197
2198   seq = get_insns ();
2199   end_sequence ();
2200
2201   /* ??? Really this can be done in any block at loop level 0 that
2202      post-dominates all can_throw_internal instructions.  This is
2203      the last possible moment.  */
2204
2205   emit_insns_after (seq, cfun->eh->sjlj_exit_after);
2206 }
2207
2208 static void
2209 sjlj_emit_dispatch_table (dispatch_label, lp_info)
2210      rtx dispatch_label;
2211      struct sjlj_lp_info *lp_info;
2212 {
2213   int i, first_reachable;
2214   rtx mem, dispatch, seq, fc;
2215
2216   fc = cfun->eh->sjlj_fc;
2217
2218   start_sequence ();
2219
2220   emit_label (dispatch_label);
2221   
2222 #ifndef DONT_USE_BUILTIN_SETJMP
2223   expand_builtin_setjmp_receiver (dispatch_label);
2224 #endif
2225
2226   /* Load up dispatch index, exc_ptr and filter values from the
2227      function context.  */
2228   mem = adjust_address (fc, TYPE_MODE (integer_type_node),
2229                         sjlj_fc_call_site_ofs);
2230   dispatch = copy_to_reg (mem);
2231
2232   mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs);
2233   if (word_mode != Pmode)
2234     {
2235 #ifdef POINTERS_EXTEND_UNSIGNED
2236       mem = convert_memory_address (Pmode, mem);
2237 #else
2238       mem = convert_to_mode (Pmode, mem, 0);
2239 #endif
2240     }
2241   emit_move_insn (cfun->eh->exc_ptr, mem);
2242
2243   mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs + UNITS_PER_WORD);
2244   emit_move_insn (cfun->eh->filter, mem);
2245
2246   /* Jump to one of the directly reachable regions.  */
2247   /* ??? This really ought to be using a switch statement.  */
2248
2249   first_reachable = 0;
2250   for (i = cfun->eh->last_region_number; i > 0; --i)
2251     {
2252       if (! lp_info[i].directly_reachable
2253           || lp_info[i].action_index < 0)
2254         continue;
2255
2256       if (! first_reachable)
2257         {
2258           first_reachable = i;
2259           continue;
2260         }
2261
2262       emit_cmp_and_jump_insns (dispatch, GEN_INT (lp_info[i].dispatch_index),
2263                                EQ, NULL_RTX, TYPE_MODE (integer_type_node), 0,
2264                                cfun->eh->region_array[i]->post_landing_pad);
2265     }
2266
2267   seq = get_insns ();
2268   end_sequence ();
2269
2270   emit_insns_before (seq, (cfun->eh->region_array[first_reachable]
2271                            ->post_landing_pad));
2272 }
2273
2274 static void
2275 sjlj_build_landing_pads ()
2276 {
2277   struct sjlj_lp_info *lp_info;
2278
2279   lp_info = (struct sjlj_lp_info *) xcalloc (cfun->eh->last_region_number + 1,
2280                                              sizeof (struct sjlj_lp_info));
2281
2282   if (sjlj_find_directly_reachable_regions (lp_info))
2283     {
2284       rtx dispatch_label = gen_label_rtx ();
2285
2286       cfun->eh->sjlj_fc
2287         = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
2288                               int_size_in_bytes (sjlj_fc_type_node),
2289                               TYPE_ALIGN (sjlj_fc_type_node));
2290
2291       sjlj_assign_call_site_values (dispatch_label, lp_info);
2292       sjlj_mark_call_sites (lp_info);
2293
2294       sjlj_emit_function_enter (dispatch_label);
2295       sjlj_emit_dispatch_table (dispatch_label, lp_info);
2296       sjlj_emit_function_exit ();
2297     }
2298
2299   free (lp_info);
2300 }
2301
2302 void
2303 finish_eh_generation ()
2304 {
2305   /* Nothing to do if no regions created.  */
2306   if (cfun->eh->region_tree == NULL)
2307     return;
2308
2309   /* The object here is to provide find_basic_blocks with detailed
2310      information (via reachable_handlers) on how exception control
2311      flows within the function.  In this first pass, we can include
2312      type information garnered from ERT_THROW and ERT_ALLOWED_EXCEPTIONS
2313      regions, and hope that it will be useful in deleting unreachable
2314      handlers.  Subsequently, we will generate landing pads which will
2315      connect many of the handlers, and then type information will not
2316      be effective.  Still, this is a win over previous implementations.  */
2317
2318   rebuild_jump_labels (get_insns ());
2319   find_basic_blocks (get_insns (), max_reg_num (), 0);
2320   cleanup_cfg (CLEANUP_PRE_LOOP);
2321
2322   /* These registers are used by the landing pads.  Make sure they
2323      have been generated.  */
2324   get_exception_pointer (cfun);
2325   get_exception_filter (cfun);
2326
2327   /* Construct the landing pads.  */
2328
2329   assign_filter_values ();
2330   build_post_landing_pads ();
2331   connect_post_landing_pads ();
2332   if (USING_SJLJ_EXCEPTIONS)
2333     sjlj_build_landing_pads ();
2334   else
2335     dw2_build_landing_pads ();
2336
2337   cfun->eh->built_landing_pads = 1;
2338
2339   /* We've totally changed the CFG.  Start over.  */
2340   find_exception_handler_labels ();
2341   rebuild_jump_labels (get_insns ());
2342   find_basic_blocks (get_insns (), max_reg_num (), 0);
2343   cleanup_cfg (CLEANUP_PRE_LOOP);
2344 }
2345 \f
2346 /* This section handles removing dead code for flow.  */
2347
2348 /* Remove LABEL from the exception_handler_labels list.  */
2349
2350 static void
2351 remove_exception_handler_label (label)
2352      rtx label;
2353 {
2354   rtx *pl, l;
2355
2356   for (pl = &exception_handler_labels, l = *pl;
2357        XEXP (l, 0) != label;
2358        pl = &XEXP (l, 1), l = *pl)
2359     continue;
2360
2361   *pl = XEXP (l, 1);
2362   free_EXPR_LIST_node (l);
2363 }
2364
2365 /* Splice REGION from the region tree etc.  */
2366
2367 static void
2368 remove_eh_handler (region)
2369      struct eh_region *region;
2370 {
2371   struct eh_region **pp, *p;
2372   rtx lab;
2373   int i;
2374
2375   /* For the benefit of efficiently handling REG_EH_REGION notes,
2376      replace this region in the region array with its containing
2377      region.  Note that previous region deletions may result in
2378      multiple copies of this region in the array, so we have to
2379      search the whole thing.  */
2380   for (i = cfun->eh->last_region_number; i > 0; --i)
2381     if (cfun->eh->region_array[i] == region)
2382       cfun->eh->region_array[i] = region->outer;
2383
2384   if (cfun->eh->built_landing_pads)
2385     lab = region->landing_pad;
2386   else
2387     lab = region->label;
2388   if (lab)
2389     remove_exception_handler_label (lab);
2390
2391   if (region->outer)
2392     pp = &region->outer->inner;
2393   else
2394     pp = &cfun->eh->region_tree;
2395   for (p = *pp; p != region; pp = &p->next_peer, p = *pp)
2396     continue;
2397
2398   if (region->inner)
2399     {
2400       for (p = region->inner; p->next_peer ; p = p->next_peer)
2401         p->outer = region->outer;
2402       p->next_peer = region->next_peer;
2403       p->outer = region->outer;
2404       *pp = region->inner;
2405     }
2406   else
2407     *pp = region->next_peer;
2408
2409   if (region->type == ERT_CATCH)
2410     {
2411       struct eh_region *try, *next, *prev;
2412
2413       for (try = region->next_peer;
2414            try->type == ERT_CATCH;
2415            try = try->next_peer)
2416         continue;
2417       if (try->type != ERT_TRY)
2418         abort ();
2419
2420       next = region->u.catch.next_catch;
2421       prev = region->u.catch.prev_catch;
2422
2423       if (next)
2424         next->u.catch.prev_catch = prev;
2425       else
2426         try->u.try.last_catch = prev;
2427       if (prev)
2428         prev->u.catch.next_catch = next;
2429       else
2430         {
2431           try->u.try.catch = next;
2432           if (! next)
2433             remove_eh_handler (try);
2434         }
2435     }
2436
2437   free (region);
2438 }
2439
2440 /* LABEL heads a basic block that is about to be deleted.  If this
2441    label corresponds to an exception region, we may be able to
2442    delete the region.  */
2443
2444 void
2445 maybe_remove_eh_handler (label)
2446      rtx label;
2447 {
2448   int i;
2449
2450   /* ??? After generating landing pads, it's not so simple to determine
2451      if the region data is completely unused.  One must examine the
2452      landing pad and the post landing pad, and whether an inner try block
2453      is referencing the catch handlers directly.  */
2454   if (cfun->eh->built_landing_pads)
2455     return;
2456
2457   for (i = cfun->eh->last_region_number; i > 0; --i)
2458     {
2459       struct eh_region *region = cfun->eh->region_array[i];
2460       if (region && region->label == label)
2461         {
2462           /* Flow will want to remove MUST_NOT_THROW regions as unreachable
2463              because there is no path to the fallback call to terminate.
2464              But the region continues to affect call-site data until there
2465              are no more contained calls, which we don't see here.  */
2466           if (region->type == ERT_MUST_NOT_THROW)
2467             {
2468               remove_exception_handler_label (region->label);
2469               region->label = NULL_RTX;
2470             }
2471           else
2472             remove_eh_handler (region);
2473           break;
2474         }
2475     }
2476 }
2477
2478 \f
2479 /* This section describes CFG exception edges for flow.  */
2480
2481 /* For communicating between calls to reachable_next_level.  */
2482 struct reachable_info
2483 {
2484   tree types_caught;
2485   tree types_allowed;
2486   rtx handlers;
2487 };
2488
2489 /* A subroutine of reachable_next_level.  Return true if TYPE, or a
2490    base class of TYPE, is in HANDLED.  */
2491
2492 static int
2493 check_handled (handled, type)
2494      tree handled, type;
2495 {
2496   tree t;
2497
2498   /* We can check for exact matches without front-end help.  */
2499   if (! lang_eh_type_covers)
2500     {
2501       for (t = handled; t ; t = TREE_CHAIN (t))
2502         if (TREE_VALUE (t) == type)
2503           return 1;
2504     }
2505   else
2506     {
2507       for (t = handled; t ; t = TREE_CHAIN (t))
2508         if ((*lang_eh_type_covers) (TREE_VALUE (t), type))
2509           return 1;
2510     }
2511
2512   return 0;
2513 }
2514
2515 /* A subroutine of reachable_next_level.  If we are collecting a list
2516    of handlers, add one.  After landing pad generation, reference
2517    it instead of the handlers themselves.  Further, the handlers are
2518    all wired together, so by referencing one, we've got them all. 
2519    Before landing pad generation we reference each handler individually.
2520
2521    LP_REGION contains the landing pad; REGION is the handler.  */
2522
2523 static void
2524 add_reachable_handler (info, lp_region, region)
2525      struct reachable_info *info;
2526      struct eh_region *lp_region;
2527      struct eh_region *region;
2528 {
2529   if (! info)
2530     return;
2531
2532   if (cfun->eh->built_landing_pads)
2533     {
2534       if (! info->handlers)
2535         info->handlers = alloc_INSN_LIST (lp_region->landing_pad, NULL_RTX);
2536     }
2537   else
2538     info->handlers = alloc_INSN_LIST (region->label, info->handlers);
2539 }
2540
2541 /* Process one level of exception regions for reachability.  
2542    If TYPE_THROWN is non-null, then it is the *exact* type being
2543    propagated.  If INFO is non-null, then collect handler labels
2544    and caught/allowed type information between invocations.  */
2545
2546 static enum reachable_code
2547 reachable_next_level (region, type_thrown, info)
2548      struct eh_region *region;
2549      tree type_thrown;
2550      struct reachable_info *info;
2551 {
2552   switch (region->type)
2553     {
2554     case ERT_CLEANUP:
2555       /* Before landing-pad generation, we model control flow
2556          directly to the individual handlers.  In this way we can
2557          see that catch handler types may shadow one another.  */
2558       add_reachable_handler (info, region, region);
2559       return RNL_MAYBE_CAUGHT;
2560
2561     case ERT_TRY:
2562       {
2563         struct eh_region *c;
2564         enum reachable_code ret = RNL_NOT_CAUGHT;
2565
2566         for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
2567           {
2568             /* A catch-all handler ends the search.  */
2569             /* ??? _Unwind_ForcedUnwind will want outer cleanups
2570                to be run as well.  */
2571             if (c->u.catch.type == NULL)
2572               {
2573                 add_reachable_handler (info, region, c);
2574                 return RNL_CAUGHT;
2575               }
2576
2577             if (type_thrown)
2578               {
2579                 /* If we have a type match, end the search.  */
2580                 if (c->u.catch.type == type_thrown
2581                     || (lang_eh_type_covers
2582                         && (*lang_eh_type_covers) (c->u.catch.type,
2583                                                    type_thrown)))
2584                   {
2585                     add_reachable_handler (info, region, c);
2586                     return RNL_CAUGHT;
2587                   }
2588
2589                 /* If we have definitive information of a match failure,
2590                    the catch won't trigger.  */
2591                 if (lang_eh_type_covers)
2592                   return RNL_NOT_CAUGHT;
2593               }
2594
2595             if (! info)
2596               ret = RNL_MAYBE_CAUGHT;
2597
2598             /* A type must not have been previously caught.  */
2599             else if (! check_handled (info->types_caught, c->u.catch.type))
2600               {
2601                 add_reachable_handler (info, region, c);
2602                 info->types_caught = tree_cons (NULL, c->u.catch.type,
2603                                                 info->types_caught);
2604
2605                 /* ??? If the catch type is a base class of every allowed
2606                    type, then we know we can stop the search.  */
2607                 ret = RNL_MAYBE_CAUGHT;
2608               }
2609           }
2610
2611         return ret;
2612       }
2613
2614     case ERT_ALLOWED_EXCEPTIONS:
2615       /* An empty list of types definitely ends the search.  */
2616       if (region->u.allowed.type_list == NULL_TREE)
2617         {
2618           add_reachable_handler (info, region, region);
2619           return RNL_CAUGHT;
2620         }
2621
2622       /* Collect a list of lists of allowed types for use in detecting
2623          when a catch may be transformed into a catch-all.  */
2624       if (info)
2625         info->types_allowed = tree_cons (NULL_TREE,
2626                                          region->u.allowed.type_list,
2627                                          info->types_allowed);
2628             
2629       /* If we have definitive information about the type hierarchy,
2630          then we can tell if the thrown type will pass through the
2631          filter.  */
2632       if (type_thrown && lang_eh_type_covers)
2633         {
2634           if (check_handled (region->u.allowed.type_list, type_thrown))
2635             return RNL_NOT_CAUGHT;
2636           else
2637             {
2638               add_reachable_handler (info, region, region);
2639               return RNL_CAUGHT;
2640             }
2641         }
2642
2643       add_reachable_handler (info, region, region);
2644       return RNL_MAYBE_CAUGHT;
2645
2646     case ERT_CATCH:
2647       /* Catch regions are handled by their controling try region.  */
2648       return RNL_NOT_CAUGHT;
2649
2650     case ERT_MUST_NOT_THROW:
2651       /* Here we end our search, since no exceptions may propagate.
2652          If we've touched down at some landing pad previous, then the
2653          explicit function call we generated may be used.  Otherwise
2654          the call is made by the runtime.  */
2655       if (info && info->handlers)
2656         {
2657           add_reachable_handler (info, region, region);
2658           return RNL_CAUGHT;
2659         }
2660       else
2661         return RNL_BLOCKED;
2662
2663     case ERT_THROW:
2664     case ERT_FIXUP:
2665       /* Shouldn't see these here.  */
2666       break;
2667     }
2668
2669   abort ();
2670 }
2671
2672 /* Retrieve a list of labels of exception handlers which can be
2673    reached by a given insn.  */
2674
2675 rtx
2676 reachable_handlers (insn)
2677      rtx insn;
2678 {
2679   struct reachable_info info;
2680   struct eh_region *region;
2681   tree type_thrown;
2682   int region_number;
2683
2684   if (GET_CODE (insn) == JUMP_INSN
2685       && GET_CODE (PATTERN (insn)) == RESX)
2686     region_number = XINT (PATTERN (insn), 0);
2687   else
2688     {
2689       rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2690       if (!note || INTVAL (XEXP (note, 0)) <= 0)
2691         return NULL;
2692       region_number = INTVAL (XEXP (note, 0));
2693     }
2694
2695   memset (&info, 0, sizeof (info));
2696
2697   region = cfun->eh->region_array[region_number];
2698
2699   type_thrown = NULL_TREE;
2700   if (GET_CODE (insn) == JUMP_INSN
2701       && GET_CODE (PATTERN (insn)) == RESX)
2702     {
2703       /* A RESX leaves a region instead of entering it.  Thus the
2704          region itself may have been deleted out from under us.  */
2705       if (region == NULL)
2706         return NULL;
2707       region = region->outer;
2708     }
2709   else if (region->type == ERT_THROW)
2710     {
2711       type_thrown = region->u.throw.type;
2712       region = region->outer;
2713     }
2714
2715   for (; region; region = region->outer)
2716     if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT)
2717       break;
2718
2719   return info.handlers;
2720 }
2721
2722 /* Determine if the given INSN can throw an exception that is caught
2723    within the function.  */
2724
2725 bool
2726 can_throw_internal (insn)
2727      rtx insn;
2728 {
2729   struct eh_region *region;
2730   tree type_thrown;
2731   rtx note;
2732
2733   if (! INSN_P (insn))
2734     return false;
2735
2736   if (GET_CODE (insn) == INSN
2737       && GET_CODE (PATTERN (insn)) == SEQUENCE)
2738     insn = XVECEXP (PATTERN (insn), 0, 0);
2739
2740   if (GET_CODE (insn) == CALL_INSN
2741       && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
2742     {
2743       int i;
2744       for (i = 0; i < 3; ++i)
2745         {
2746           rtx sub = XEXP (PATTERN (insn), i);
2747           for (; sub ; sub = NEXT_INSN (sub))
2748             if (can_throw_internal (sub))
2749               return true;
2750         }
2751       return false;
2752     }
2753
2754   /* Every insn that might throw has an EH_REGION note.  */
2755   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2756   if (!note || INTVAL (XEXP (note, 0)) <= 0)
2757     return false;
2758
2759   region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2760
2761   type_thrown = NULL_TREE;
2762   if (region->type == ERT_THROW)
2763     {
2764       type_thrown = region->u.throw.type;
2765       region = region->outer;
2766     }
2767
2768   /* If this exception is ignored by each and every containing region,
2769      then control passes straight out.  The runtime may handle some
2770      regions, which also do not require processing internally.  */
2771   for (; region; region = region->outer)
2772     {
2773       enum reachable_code how = reachable_next_level (region, type_thrown, 0);
2774       if (how == RNL_BLOCKED)
2775         return false;
2776       if (how != RNL_NOT_CAUGHT)
2777         return true;
2778     }
2779
2780   return false;
2781 }
2782
2783 /* Determine if the given INSN can throw an exception that is
2784    visible outside the function.  */
2785
2786 bool
2787 can_throw_external (insn)
2788      rtx insn;
2789 {
2790   struct eh_region *region;
2791   tree type_thrown;
2792   rtx note;
2793
2794   if (! INSN_P (insn))
2795     return false;
2796
2797   if (GET_CODE (insn) == INSN
2798       && GET_CODE (PATTERN (insn)) == SEQUENCE)
2799     insn = XVECEXP (PATTERN (insn), 0, 0);
2800
2801   if (GET_CODE (insn) == CALL_INSN
2802       && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
2803     {
2804       int i;
2805       for (i = 0; i < 3; ++i)
2806         {
2807           rtx sub = XEXP (PATTERN (insn), i);
2808           for (; sub ; sub = NEXT_INSN (sub))
2809             if (can_throw_external (sub))
2810               return true;
2811         }
2812       return false;
2813     }
2814
2815   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2816   if (!note)
2817     {
2818       /* Calls (and trapping insns) without notes are outside any
2819          exception handling region in this function.  We have to
2820          assume it might throw.  Given that the front end and middle
2821          ends mark known NOTHROW functions, this isn't so wildly
2822          inaccurate.  */
2823       return (GET_CODE (insn) == CALL_INSN
2824               || (flag_non_call_exceptions
2825                   && may_trap_p (PATTERN (insn))));
2826     }
2827   if (INTVAL (XEXP (note, 0)) <= 0)
2828     return false;
2829
2830   region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2831
2832   type_thrown = NULL_TREE;
2833   if (region->type == ERT_THROW)
2834     {
2835       type_thrown = region->u.throw.type;
2836       region = region->outer;
2837     }
2838
2839   /* If the exception is caught or blocked by any containing region,
2840      then it is not seen by any calling function.  */
2841   for (; region ; region = region->outer)
2842     if (reachable_next_level (region, type_thrown, NULL) >= RNL_CAUGHT)
2843       return false;
2844
2845   return true;
2846 }
2847
2848 /* True if nothing in this function can throw outside this function.  */
2849
2850 bool
2851 nothrow_function_p ()
2852 {
2853   rtx insn;
2854
2855   if (! flag_exceptions)
2856     return true;
2857
2858   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2859     if (can_throw_external (insn))
2860       return false;
2861   for (insn = current_function_epilogue_delay_list; insn;
2862        insn = XEXP (insn, 1))
2863     if (can_throw_external (insn))
2864       return false;
2865
2866   return true;
2867 }
2868
2869 \f
2870 /* Various hooks for unwind library.  */
2871
2872 /* Do any necessary initialization to access arbitrary stack frames.
2873    On the SPARC, this means flushing the register windows.  */
2874
2875 void
2876 expand_builtin_unwind_init ()
2877 {
2878   /* Set this so all the registers get saved in our frame; we need to be
2879      able to copy the saved values for any registers from frames we unwind.  */
2880   current_function_has_nonlocal_label = 1;
2881
2882 #ifdef SETUP_FRAME_ADDRESSES
2883   SETUP_FRAME_ADDRESSES ();
2884 #endif
2885 }
2886
2887 rtx
2888 expand_builtin_eh_return_data_regno (arglist)
2889      tree arglist;
2890 {
2891   tree which = TREE_VALUE (arglist);
2892   unsigned HOST_WIDE_INT iwhich;
2893
2894   if (TREE_CODE (which) != INTEGER_CST)
2895     {
2896       error ("argument of `__builtin_eh_return_regno' must be constant");
2897       return constm1_rtx;
2898     }
2899
2900   iwhich = tree_low_cst (which, 1);
2901   iwhich = EH_RETURN_DATA_REGNO (iwhich);
2902   if (iwhich == INVALID_REGNUM)
2903     return constm1_rtx;
2904
2905 #ifdef DWARF_FRAME_REGNUM
2906   iwhich = DWARF_FRAME_REGNUM (iwhich);
2907 #else
2908   iwhich = DBX_REGISTER_NUMBER (iwhich);
2909 #endif
2910
2911   return GEN_INT (iwhich);      
2912 }
2913
2914 /* Given a value extracted from the return address register or stack slot,
2915    return the actual address encoded in that value.  */
2916
2917 rtx
2918 expand_builtin_extract_return_addr (addr_tree)
2919      tree addr_tree;
2920 {
2921   rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
2922
2923   /* First mask out any unwanted bits.  */
2924 #ifdef MASK_RETURN_ADDR
2925   expand_and (addr, MASK_RETURN_ADDR, addr);
2926 #endif
2927
2928   /* Then adjust to find the real return address.  */
2929 #if defined (RETURN_ADDR_OFFSET)
2930   addr = plus_constant (addr, RETURN_ADDR_OFFSET);
2931 #endif
2932
2933   return addr;
2934 }
2935
2936 /* Given an actual address in addr_tree, do any necessary encoding
2937    and return the value to be stored in the return address register or
2938    stack slot so the epilogue will return to that address.  */
2939
2940 rtx
2941 expand_builtin_frob_return_addr (addr_tree)
2942      tree addr_tree;
2943 {
2944   rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, 0);
2945
2946 #ifdef POINTERS_EXTEND_UNSIGNED
2947   if (GET_MODE (addr) != Pmode)
2948     addr = convert_memory_address (Pmode, addr);
2949 #endif
2950
2951 #ifdef RETURN_ADDR_OFFSET
2952   addr = force_reg (Pmode, addr);
2953   addr = plus_constant (addr, -RETURN_ADDR_OFFSET);
2954 #endif
2955
2956   return addr;
2957 }
2958
2959 /* Set up the epilogue with the magic bits we'll need to return to the
2960    exception handler.  */
2961
2962 void
2963 expand_builtin_eh_return (stackadj_tree, handler_tree)
2964     tree stackadj_tree, handler_tree;
2965 {
2966   rtx stackadj, handler;
2967
2968   stackadj = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj, VOIDmode, 0);
2969   handler = expand_expr (handler_tree, cfun->eh->ehr_handler, VOIDmode, 0);
2970
2971 #ifdef POINTERS_EXTEND_UNSIGNED
2972   if (GET_MODE (stackadj) != Pmode)
2973     stackadj = convert_memory_address (Pmode, stackadj);
2974
2975   if (GET_MODE (handler) != Pmode)
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 indices.  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          indices 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   (*targetm.asm_out.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 }