OSDN Git Service

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