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