OSDN Git Service

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