except.c revision 50397
1/* Implements exception handling.
2   Copyright (C) 1989, 92-97, 1998 Free Software Foundation, Inc.
3   Contributed by Mike Stump <mrs@cygnus.com>.
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING.  If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA.  */
21
22
23/* An exception is an event that can be signaled from within a
24   function. This event can then be "caught" or "trapped" by the
25   callers of this function. This potentially allows program flow to
26   be transferred to any arbitrary code associated with a function call
27   several levels up the stack.
28
29   The intended use for this mechanism is for signaling "exceptional
30   events" in an out-of-band fashion, hence its name. The C++ language
31   (and many other OO-styled or functional languages) practically
32   requires such a mechanism, as otherwise it becomes very difficult
33   or even impossible to signal failure conditions in complex
34   situations.  The traditional C++ example is when an error occurs in
35   the process of constructing an object; without such a mechanism, it
36   is impossible to signal that the error occurs without adding global
37   state variables and error checks around every object construction.
38
39   The act of causing this event to occur is referred to as "throwing
40   an exception". (Alternate terms include "raising an exception" or
41   "signaling an exception".) The term "throw" is used because control
42   is returned to the callers of the function that is signaling the
43   exception, and thus there is the concept of "throwing" the
44   exception up the call stack.
45
46   There are two major codegen options for exception handling.  The
47   flag -fsjlj-exceptions can be used to select the setjmp/longjmp
48   approach, which is the default.  -fno-sjlj-exceptions can be used to
49   get the PC range table approach.  While this is a compile time
50   flag, an entire application must be compiled with the same codegen
51   option.  The first is a PC range table approach, the second is a
52   setjmp/longjmp based scheme.  We will first discuss the PC range
53   table approach, after that, we will discuss the setjmp/longjmp
54   based approach.
55
56   It is appropriate to speak of the "context of a throw". This
57   context refers to the address where the exception is thrown from,
58   and is used to determine which exception region will handle the
59   exception.
60
61   Regions of code within a function can be marked such that if it
62   contains the context of a throw, control will be passed to a
63   designated "exception handler". These areas are known as "exception
64   regions".  Exception regions cannot overlap, but they can be nested
65   to any arbitrary depth. Also, exception regions cannot cross
66   function boundaries.
67
68   Exception handlers can either be specified by the user (which we
69   will call a "user-defined handler") or generated by the compiler
70   (which we will designate as a "cleanup"). Cleanups are used to
71   perform tasks such as destruction of objects allocated on the
72   stack.
73
74   In the current implementation, cleanups are handled by allocating an
75   exception region for the area that the cleanup is designated for,
76   and the handler for the region performs the cleanup and then
77   rethrows the exception to the outer exception region. From the
78   standpoint of the current implementation, there is little
79   distinction made between a cleanup and a user-defined handler, and
80   the phrase "exception handler" can be used to refer to either one
81   equally well. (The section "Future Directions" below discusses how
82   this will change).
83
84   Each object file that is compiled with exception handling contains
85   a static array of exception handlers named __EXCEPTION_TABLE__.
86   Each entry contains the starting and ending addresses of the
87   exception region, and the address of the handler designated for
88   that region.
89
90   If the target does not use the DWARF 2 frame unwind information, at
91   program startup each object file invokes a function named
92   __register_exceptions with the address of its local
93   __EXCEPTION_TABLE__. __register_exceptions is defined in libgcc2.c, and
94   is responsible for recording all of the exception regions into one list
95   (which is kept in a static variable named exception_table_list).
96
97   On targets that support crtstuff.c, the unwind information
98   is stored in a section named .eh_frame and the information for the
99   entire shared object or program is registered with a call to
100   __register_frame_info.  On other targets, the information for each
101   translation unit is registered from the file generated by collect2.
102   __register_frame_info is defined in frame.c, and is responsible for
103   recording all of the unwind regions into one list (which is kept in a
104   static variable named unwind_table_list).
105
106   The function __throw is actually responsible for doing the
107   throw. On machines that have unwind info support, __throw is generated
108   by code in libgcc2.c, otherwise __throw is generated on a
109   per-object-file basis for each source file compiled with
110   -fexceptions by the C++ frontend.  Before __throw is invoked,
111   the current context of the throw needs to be placed in the global
112   variable __eh_pc.
113
114   __throw attempts to find the appropriate exception handler for the
115   PC value stored in __eh_pc by calling __find_first_exception_table_match
116   (which is defined in libgcc2.c). If __find_first_exception_table_match
117   finds a relevant handler, __throw transfers control directly to it.
118
119   If a handler for the context being thrown from can't be found, __throw
120   walks (see Walking the stack below) the stack up the dynamic call chain to
121   continue searching for an appropriate exception handler based upon the
122   caller of the function it last sought a exception handler for.  It stops
123   then either an exception handler is found, or when the top of the
124   call chain is reached.
125
126   If no handler is found, an external library function named
127   __terminate is called.  If a handler is found, then we restart
128   our search for a handler at the end of the call chain, and repeat
129   the search process, but instead of just walking up the call chain,
130   we unwind the call chain as we walk up it.
131
132   Internal implementation details:
133
134   To associate a user-defined handler with a block of statements, the
135   function expand_start_try_stmts is used to mark the start of the
136   block of statements with which the handler is to be associated
137   (which is known as a "try block"). All statements that appear
138   afterwards will be associated with the try block.
139
140   A call to expand_start_all_catch marks the end of the try block,
141   and also marks the start of the "catch block" (the user-defined
142   handler) associated with the try block.
143
144   This user-defined handler will be invoked for *every* exception
145   thrown with the context of the try block. It is up to the handler
146   to decide whether or not it wishes to handle any given exception,
147   as there is currently no mechanism in this implementation for doing
148   this. (There are plans for conditionally processing an exception
149   based on its "type", which will provide a language-independent
150   mechanism).
151
152   If the handler chooses not to process the exception (perhaps by
153   looking at an "exception type" or some other additional data
154   supplied with the exception), it can fall through to the end of the
155   handler. expand_end_all_catch and expand_leftover_cleanups
156   add additional code to the end of each handler to take care of
157   rethrowing to the outer exception handler.
158
159   The handler also has the option to continue with "normal flow of
160   code", or in other words to resume executing at the statement
161   immediately after the end of the exception region. The variable
162   caught_return_label_stack contains a stack of labels, and jumping
163   to the topmost entry's label via expand_goto will resume normal
164   flow to the statement immediately after the end of the exception
165   region. If the handler falls through to the end, the exception will
166   be rethrown to the outer exception region.
167
168   The instructions for the catch block are kept as a separate
169   sequence, and will be emitted at the end of the function along with
170   the handlers specified via expand_eh_region_end. The end of the
171   catch block is marked with expand_end_all_catch.
172
173   Any data associated with the exception must currently be handled by
174   some external mechanism maintained in the frontend.  For example,
175   the C++ exception mechanism passes an arbitrary value along with
176   the exception, and this is handled in the C++ frontend by using a
177   global variable to hold the value. (This will be changing in the
178   future.)
179
180   The mechanism in C++ for handling data associated with the
181   exception is clearly not thread-safe. For a thread-based
182   environment, another mechanism must be used (possibly using a
183   per-thread allocation mechanism if the size of the area that needs
184   to be allocated isn't known at compile time.)
185
186   Internally-generated exception regions (cleanups) are marked by
187   calling expand_eh_region_start to mark the start of the region,
188   and expand_eh_region_end (handler) is used to both designate the
189   end of the region and to associate a specified handler/cleanup with
190   the region. The rtl code in HANDLER will be invoked whenever an
191   exception occurs in the region between the calls to
192   expand_eh_region_start and expand_eh_region_end. After HANDLER is
193   executed, additional code is emitted to handle rethrowing the
194   exception to the outer exception handler. The code for HANDLER will
195   be emitted at the end of the function.
196
197   TARGET_EXPRs can also be used to designate exception regions. A
198   TARGET_EXPR gives an unwind-protect style interface commonly used
199   in functional languages such as LISP. The associated expression is
200   evaluated, and whether or not it (or any of the functions that it
201   calls) throws an exception, the protect expression is always
202   invoked. This implementation takes care of the details of
203   associating an exception table entry with the expression and
204   generating the necessary code (it actually emits the protect
205   expression twice, once for normal flow and once for the exception
206   case). As for the other handlers, the code for the exception case
207   will be emitted at the end of the function.
208
209   Cleanups can also be specified by using add_partial_entry (handler)
210   and end_protect_partials. add_partial_entry creates the start of
211   a new exception region; HANDLER will be invoked if an exception is
212   thrown with the context of the region between the calls to
213   add_partial_entry and end_protect_partials. end_protect_partials is
214   used to mark the end of these regions. add_partial_entry can be
215   called as many times as needed before calling end_protect_partials.
216   However, end_protect_partials should only be invoked once for each
217   group of calls to add_partial_entry as the entries are queued
218   and all of the outstanding entries are processed simultaneously
219   when end_protect_partials is invoked. Similarly to the other
220   handlers, the code for HANDLER will be emitted at the end of the
221   function.
222
223   The generated RTL for an exception region includes
224   NOTE_INSN_EH_REGION_BEG and NOTE_INSN_EH_REGION_END notes that mark
225   the start and end of the exception region. A unique label is also
226   generated at the start of the exception region, which is available
227   by looking at the ehstack variable. The topmost entry corresponds
228   to the current region.
229
230   In the current implementation, an exception can only be thrown from
231   a function call (since the mechanism used to actually throw an
232   exception involves calling __throw).  If an exception region is
233   created but no function calls occur within that region, the region
234   can be safely optimized away (along with its exception handlers)
235   since no exceptions can ever be caught in that region.  This
236   optimization is performed unless -fasynchronous-exceptions is
237   given.  If the user wishes to throw from a signal handler, or other
238   asynchronous place, -fasynchronous-exceptions should be used when
239   compiling for maximally correct code, at the cost of additional
240   exception regions.  Using -fasynchronous-exceptions only produces
241   code that is reasonably safe in such situations, but a correct
242   program cannot rely upon this working.  It can be used in failsafe
243   code, where trying to continue on, and proceeding with potentially
244   incorrect results is better than halting the program.
245
246
247   Walking the stack:
248
249   The stack is walked by starting with a pointer to the current
250   frame, and finding the pointer to the callers frame.  The unwind info
251   tells __throw how to find it.
252
253   Unwinding the stack:
254
255   When we use the term unwinding the stack, we mean undoing the
256   effects of the function prologue in a controlled fashion so that we
257   still have the flow of control.  Otherwise, we could just return
258   (jump to the normal end of function epilogue).
259
260   This is done in __throw in libgcc2.c when we know that a handler exists
261   in a frame higher up the call stack than its immediate caller.
262
263   To unwind, we find the unwind data associated with the frame, if any.
264   If we don't find any, we call the library routine __terminate.  If we do
265   find it, we use the information to copy the saved register values from
266   that frame into the register save area in the frame for __throw, return
267   into a stub which updates the stack pointer, and jump to the handler.
268   The normal function epilogue for __throw handles restoring the saved
269   values into registers.
270
271   When unwinding, we use this method if we know it will
272   work (if DWARF2_UNWIND_INFO is defined).  Otherwise, we know that
273   an inline unwinder will have been emitted for any function that
274   __unwind_function cannot unwind.  The inline unwinder appears as a
275   normal exception handler for the entire function, for any function
276   that we know cannot be unwound by __unwind_function.  We inform the
277   compiler of whether a function can be unwound with
278   __unwind_function by having DOESNT_NEED_UNWINDER evaluate to true
279   when the unwinder isn't needed.  __unwind_function is used as an
280   action of last resort.  If no other method can be used for
281   unwinding, __unwind_function is used.  If it cannot unwind, it
282   should call __terminate.
283
284   By default, if the target-specific backend doesn't supply a definition
285   for __unwind_function and doesn't support DWARF2_UNWIND_INFO, inlined
286   unwinders will be used instead. The main tradeoff here is in text space
287   utilization.  Obviously, if inline unwinders have to be generated
288   repeatedly, this uses much more space than if a single routine is used.
289
290   However, it is simply not possible on some platforms to write a
291   generalized routine for doing stack unwinding without having some
292   form of additional data associated with each function.  The current
293   implementation can encode this data in the form of additional
294   machine instructions or as static data in tabular form.  The later
295   is called the unwind data.
296
297   The backend macro DOESNT_NEED_UNWINDER is used to conditionalize whether
298   or not per-function unwinders are needed. If DOESNT_NEED_UNWINDER is
299   defined and has a non-zero value, a per-function unwinder is not emitted
300   for the current function.  If the static unwind data is supported, then
301   a per-function unwinder is not emitted.
302
303   On some platforms it is possible that neither __unwind_function
304   nor inlined unwinders are available. For these platforms it is not
305   possible to throw through a function call, and abort will be
306   invoked instead of performing the throw.
307
308   The reason the unwind data may be needed is that on some platforms
309   the order and types of data stored on the stack can vary depending
310   on the type of function, its arguments and returned values, and the
311   compilation options used (optimization versus non-optimization,
312   -fomit-frame-pointer, processor variations, etc).
313
314   Unfortunately, this also means that throwing through functions that
315   aren't compiled with exception handling support will still not be
316   possible on some platforms. This problem is currently being
317   investigated, but no solutions have been found that do not imply
318   some unacceptable performance penalties.
319
320   Future directions:
321
322   Currently __throw makes no differentiation between cleanups and
323   user-defined exception regions. While this makes the implementation
324   simple, it also implies that it is impossible to determine if a
325   user-defined exception handler exists for a given exception without
326   completely unwinding the stack in the process. This is undesirable
327   from the standpoint of debugging, as ideally it would be possible
328   to trap unhandled exceptions in the debugger before the process of
329   unwinding has even started.
330
331   This problem can be solved by marking user-defined handlers in a
332   special way (probably by adding additional bits to exception_table_list).
333   A two-pass scheme could then be used by __throw to iterate
334   through the table. The first pass would search for a relevant
335   user-defined handler for the current context of the throw, and if
336   one is found, the second pass would then invoke all needed cleanups
337   before jumping to the user-defined handler.
338
339   Many languages (including C++ and Ada) make execution of a
340   user-defined handler conditional on the "type" of the exception
341   thrown. (The type of the exception is actually the type of the data
342   that is thrown with the exception.) It will thus be necessary for
343   __throw to be able to determine if a given user-defined
344   exception handler will actually be executed, given the type of
345   exception.
346
347   One scheme is to add additional information to exception_table_list
348   as to the types of exceptions accepted by each handler. __throw
349   can do the type comparisons and then determine if the handler is
350   actually going to be executed.
351
352   There is currently no significant level of debugging support
353   available, other than to place a breakpoint on __throw. While
354   this is sufficient in most cases, it would be helpful to be able to
355   know where a given exception was going to be thrown to before it is
356   actually thrown, and to be able to choose between stopping before
357   every exception region (including cleanups), or just user-defined
358   exception regions. This should be possible to do in the two-pass
359   scheme by adding additional labels to __throw for appropriate
360   breakpoints, and additional debugger commands could be added to
361   query various state variables to determine what actions are to be
362   performed next.
363
364   Another major problem that is being worked on is the issue with stack
365   unwinding on various platforms. Currently the only platforms that have
366   support for the generation of a generic unwinder are the SPARC and MIPS.
367   All other ports require per-function unwinders, which produce large
368   amounts of code bloat.
369
370   For setjmp/longjmp based exception handling, some of the details
371   are as above, but there are some additional details.  This section
372   discusses the details.
373
374   We don't use NOTE_INSN_EH_REGION_{BEG,END} pairs.  We don't
375   optimize EH regions yet.  We don't have to worry about machine
376   specific issues with unwinding the stack, as we rely upon longjmp
377   for all the machine specific details.  There is no variable context
378   of a throw, just the one implied by the dynamic handler stack
379   pointed to by the dynamic handler chain.  There is no exception
380   table, and no calls to __register_exceptions.  __sjthrow is used
381   instead of __throw, and it works by using the dynamic handler
382   chain, and longjmp.  -fasynchronous-exceptions has no effect, as
383   the elimination of trivial exception regions is not yet performed.
384
385   A frontend can set protect_cleanup_actions_with_terminate when all
386   the cleanup actions should be protected with an EH region that
387   calls terminate when an unhandled exception is throw.  C++ does
388   this, Ada does not.  */
389
390
391#include "config.h"
392#include "defaults.h"
393#include "eh-common.h"
394#include "system.h"
395#include "rtl.h"
396#include "tree.h"
397#include "flags.h"
398#include "except.h"
399#include "function.h"
400#include "insn-flags.h"
401#include "expr.h"
402#include "insn-codes.h"
403#include "regs.h"
404#include "hard-reg-set.h"
405#include "insn-config.h"
406#include "recog.h"
407#include "output.h"
408#include "toplev.h"
409
410/* One to use setjmp/longjmp method of generating code for exception
411   handling.  */
412
413int exceptions_via_longjmp = 2;
414
415/* One to enable asynchronous exception support.  */
416
417int asynchronous_exceptions = 0;
418
419/* One to protect cleanup actions with a handler that calls
420   __terminate, zero otherwise.  */
421
422int protect_cleanup_actions_with_terminate;
423
424/* A list of labels used for exception handlers.  Created by
425   find_exception_handler_labels for the optimization passes.  */
426
427rtx exception_handler_labels;
428
429/* The EH context.  Nonzero if the function has already
430   fetched a pointer to the EH context  for exception handling.  */
431
432rtx current_function_ehc;
433
434/* A stack used for keeping track of the currently active exception
435   handling region.  As each exception region is started, an entry
436   describing the region is pushed onto this stack.  The current
437   region can be found by looking at the top of the stack, and as we
438   exit regions, the corresponding entries are popped.
439
440   Entries cannot overlap; they can be nested. So there is only one
441   entry at most that corresponds to the current instruction, and that
442   is the entry on the top of the stack.  */
443
444static struct eh_stack ehstack;
445
446
447/* This stack is used to represent what the current eh region is
448   for the catch blocks beings processed */
449
450static struct eh_stack catchstack;
451
452/* A queue used for tracking which exception regions have closed but
453   whose handlers have not yet been expanded. Regions are emitted in
454   groups in an attempt to improve paging performance.
455
456   As we exit a region, we enqueue a new entry. The entries are then
457   dequeued during expand_leftover_cleanups and expand_start_all_catch,
458
459   We should redo things so that we either take RTL for the handler,
460   or we expand the handler expressed as a tree immediately at region
461   end time.  */
462
463static struct eh_queue ehqueue;
464
465/* Insns for all of the exception handlers for the current function.
466   They are currently emitted by the frontend code.  */
467
468rtx catch_clauses;
469
470/* A TREE_CHAINed list of handlers for regions that are not yet
471   closed. The TREE_VALUE of each entry contains the handler for the
472   corresponding entry on the ehstack.  */
473
474static tree protect_list;
475
476/* Stacks to keep track of various labels.  */
477
478/* Keeps track of the label to resume to should one want to resume
479   normal control flow out of a handler (instead of, say, returning to
480   the caller of the current function or exiting the program).  */
481
482struct label_node *caught_return_label_stack = NULL;
483
484/* Keeps track of the label used as the context of a throw to rethrow an
485   exception to the outer exception region.  */
486
487struct label_node *outer_context_label_stack = NULL;
488
489/* A random data area for the front end's own use.  */
490
491struct label_node *false_label_stack = NULL;
492
493static void push_eh_entry	PROTO((struct eh_stack *));
494static struct eh_entry * pop_eh_entry		PROTO((struct eh_stack *));
495static void enqueue_eh_entry	PROTO((struct eh_queue *, struct eh_entry *));
496static struct eh_entry * dequeue_eh_entry	PROTO((struct eh_queue *));
497static rtx call_get_eh_context	PROTO((void));
498static void start_dynamic_cleanup		PROTO((tree, tree));
499static void start_dynamic_handler		PROTO((void));
500static void expand_rethrow	PROTO((rtx));
501static void output_exception_table_entry	PROTO((FILE *, int));
502static int can_throw		PROTO((rtx));
503static rtx scan_region		PROTO((rtx, int, int *));
504static void eh_regs		PROTO((rtx *, rtx *, int));
505static void set_insn_eh_region	PROTO((rtx *, int));
506#ifdef DONT_USE_BUILTIN_SETJMP
507static void jumpif_rtx		PROTO((rtx, rtx));
508#endif
509
510
511rtx expand_builtin_return_addr	PROTO((enum built_in_function, int, rtx));
512
513/* Various support routines to manipulate the various data structures
514   used by the exception handling code.  */
515
516/* Push a label entry onto the given STACK.  */
517
518void
519push_label_entry (stack, rlabel, tlabel)
520     struct label_node **stack;
521     rtx rlabel;
522     tree tlabel;
523{
524  struct label_node *newnode
525    = (struct label_node *) xmalloc (sizeof (struct label_node));
526
527  if (rlabel)
528    newnode->u.rlabel = rlabel;
529  else
530    newnode->u.tlabel = tlabel;
531  newnode->chain = *stack;
532  *stack = newnode;
533}
534
535/* Pop a label entry from the given STACK.  */
536
537rtx
538pop_label_entry (stack)
539     struct label_node **stack;
540{
541  rtx label;
542  struct label_node *tempnode;
543
544  if (! *stack)
545    return NULL_RTX;
546
547  tempnode = *stack;
548  label = tempnode->u.rlabel;
549  *stack = (*stack)->chain;
550  free (tempnode);
551
552  return label;
553}
554
555/* Return the top element of the given STACK.  */
556
557tree
558top_label_entry (stack)
559     struct label_node **stack;
560{
561  if (! *stack)
562    return NULL_TREE;
563
564  return (*stack)->u.tlabel;
565}
566
567/* get an exception label. These must be on the permanent obstack */
568
569rtx
570gen_exception_label ()
571{
572  rtx lab;
573
574  push_obstacks_nochange ();
575  end_temporary_allocation ();
576  lab = gen_label_rtx ();
577  pop_obstacks ();
578  return lab;
579}
580
581/* Push a new eh_node entry onto STACK.  */
582
583static void
584push_eh_entry (stack)
585     struct eh_stack *stack;
586{
587  struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
588  struct eh_entry *entry = (struct eh_entry *) xmalloc (sizeof (struct eh_entry));
589
590  entry->outer_context = gen_label_rtx ();
591  entry->finalization = NULL_TREE;
592  entry->label_used = 0;
593  entry->exception_handler_label = gen_exception_label ();
594
595  node->entry = entry;
596  node->chain = stack->top;
597  stack->top = node;
598}
599
600/* push an existing entry onto a stack. */
601static void
602push_entry (stack, entry)
603     struct eh_stack *stack;
604     struct eh_entry *entry;
605{
606  struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
607  node->entry = entry;
608  node->chain = stack->top;
609  stack->top = node;
610}
611
612/* Pop an entry from the given STACK.  */
613
614static struct eh_entry *
615pop_eh_entry (stack)
616     struct eh_stack *stack;
617{
618  struct eh_node *tempnode;
619  struct eh_entry *tempentry;
620
621  tempnode = stack->top;
622  tempentry = tempnode->entry;
623  stack->top = stack->top->chain;
624  free (tempnode);
625
626  return tempentry;
627}
628
629/* Enqueue an ENTRY onto the given QUEUE.  */
630
631static void
632enqueue_eh_entry (queue, entry)
633     struct eh_queue *queue;
634     struct eh_entry *entry;
635{
636  struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
637
638  node->entry = entry;
639  node->chain = NULL;
640
641  if (queue->head == NULL)
642    {
643      queue->head = node;
644    }
645  else
646    {
647      queue->tail->chain = node;
648    }
649  queue->tail = node;
650}
651
652/* Dequeue an entry from the given QUEUE.  */
653
654static struct eh_entry *
655dequeue_eh_entry (queue)
656     struct eh_queue *queue;
657{
658  struct eh_node *tempnode;
659  struct eh_entry *tempentry;
660
661  if (queue->head == NULL)
662    return NULL;
663
664  tempnode = queue->head;
665  queue->head = queue->head->chain;
666
667  tempentry = tempnode->entry;
668  free (tempnode);
669
670  return tempentry;
671}
672
673static void
674receive_exception_label (handler_label)
675     rtx handler_label;
676{
677  emit_label (handler_label);
678
679#ifdef HAVE_exception_receiver
680  if (! exceptions_via_longjmp)
681    if (HAVE_exception_receiver)
682      emit_insn (gen_exception_receiver ());
683#endif
684
685#ifdef HAVE_nonlocal_goto_receiver
686  if (! exceptions_via_longjmp)
687    if (HAVE_nonlocal_goto_receiver)
688      emit_insn (gen_nonlocal_goto_receiver ());
689#endif
690}
691
692
693struct func_eh_entry
694{
695  int range_number;   /* EH region number from EH NOTE insn's */
696  struct handler_info *handlers;
697};
698
699
700/* table of function eh regions */
701static struct func_eh_entry *function_eh_regions = NULL;
702static int num_func_eh_entries = 0;
703static int current_func_eh_entry = 0;
704
705#define SIZE_FUNC_EH(X)   (sizeof (struct func_eh_entry) * X)
706
707/* Add a new eh_entry for this function, and base it off of the information
708   in the EH_ENTRY parameter. A NULL parameter is invalid. The number
709   returned is an number which uniquely identifies this exception range. */
710
711int
712new_eh_region_entry (note_eh_region)
713     int note_eh_region;
714{
715  if (current_func_eh_entry == num_func_eh_entries)
716    {
717      if (num_func_eh_entries == 0)
718        {
719          function_eh_regions =
720                        (struct func_eh_entry *) malloc (SIZE_FUNC_EH (50));
721          num_func_eh_entries = 50;
722        }
723      else
724        {
725          num_func_eh_entries  = num_func_eh_entries * 3 / 2;
726          function_eh_regions = (struct func_eh_entry *)
727            realloc (function_eh_regions, SIZE_FUNC_EH (num_func_eh_entries));
728        }
729    }
730  function_eh_regions[current_func_eh_entry].range_number = note_eh_region;
731  function_eh_regions[current_func_eh_entry].handlers = NULL;
732
733  return current_func_eh_entry++;
734}
735
736/* Add new handler information to an exception range. The  first parameter
737   specifies the range number (returned from new_eh_entry()). The second
738   parameter specifies the handler.  By default the handler is inserted at
739   the end of the list. A handler list may contain only ONE NULL_TREE
740   typeinfo entry. Regardless where it is positioned, a NULL_TREE entry
741   is always output as the LAST handler in the exception table for a region. */
742
743void
744add_new_handler (region, newhandler)
745     int region;
746     struct handler_info *newhandler;
747{
748  struct handler_info *last;
749
750  newhandler->next = NULL;
751  last = function_eh_regions[region].handlers;
752  if (last == NULL)
753    function_eh_regions[region].handlers = newhandler;
754  else
755    {
756      for ( ; last->next != NULL; last = last->next)
757        ;
758      last->next = newhandler;
759    }
760}
761
762/* Remove a handler label. The handler label is being deleted, so all
763   regions which reference this handler should have it removed from their
764   list of possible handlers. Any region which has the final handler
765   removed can be deleted. */
766
767void remove_handler (removing_label)
768     rtx removing_label;
769{
770  struct handler_info *handler, *last;
771  int x;
772  for (x = 0 ; x < current_func_eh_entry; ++x)
773    {
774      last = NULL;
775      handler = function_eh_regions[x].handlers;
776      for ( ; handler; last = handler, handler = handler->next)
777        if (handler->handler_label == removing_label)
778          {
779            if (last)
780              {
781                last->next = handler->next;
782                handler = last;
783              }
784            else
785              function_eh_regions[x].handlers = handler->next;
786          }
787    }
788}
789
790/* This function will return a malloc'd pointer to an array of
791   void pointer representing the runtime match values that
792   currently exist in all regions. */
793
794int
795find_all_handler_type_matches (array)
796  void ***array;
797{
798  struct handler_info *handler, *last;
799  int x,y;
800  void *val;
801  void **ptr;
802  int max_ptr;
803  int n_ptr = 0;
804
805  *array = NULL;
806
807  if (!doing_eh (0) || ! flag_new_exceptions)
808    return 0;
809
810  max_ptr = 100;
811  ptr = (void **)malloc (max_ptr * sizeof (void *));
812
813  if (ptr == NULL)
814    return 0;
815
816  for (x = 0 ; x < current_func_eh_entry; x++)
817    {
818      last = NULL;
819      handler = function_eh_regions[x].handlers;
820      for ( ; handler; last = handler, handler = handler->next)
821        {
822          val = handler->type_info;
823          if (val != NULL && val != CATCH_ALL_TYPE)
824            {
825              /* See if this match value has already been found. */
826              for (y = 0; y < n_ptr; y++)
827                if (ptr[y] == val)
828                  break;
829
830              /* If we break early, we already found this value. */
831              if (y < n_ptr)
832                continue;
833
834              /* Do we need to allocate more space? */
835              if (n_ptr >= max_ptr)
836                {
837                  max_ptr += max_ptr / 2;
838                  ptr = (void **)realloc (ptr, max_ptr * sizeof (void *));
839                  if (ptr == NULL)
840                    return 0;
841                }
842              ptr[n_ptr] = val;
843              n_ptr++;
844            }
845        }
846    }
847  *array = ptr;
848  return n_ptr;
849}
850
851/* Create a new handler structure initialized with the handler label and
852   typeinfo fields passed in. */
853
854struct handler_info *
855get_new_handler (handler, typeinfo)
856     rtx handler;
857     void *typeinfo;
858{
859  struct handler_info* ptr;
860  ptr = (struct handler_info *) malloc (sizeof (struct handler_info));
861  ptr->handler_label = handler;
862  ptr->type_info = typeinfo;
863  ptr->next = NULL;
864
865  return ptr;
866}
867
868
869
870/* Find the index in function_eh_regions associated with a NOTE region. If
871   the region cannot be found, a -1 is returned. This should never happen! */
872
873int
874find_func_region (insn_region)
875     int insn_region;
876{
877  int x;
878  for (x = 0; x < current_func_eh_entry; x++)
879    if (function_eh_regions[x].range_number == insn_region)
880      return x;
881
882  return -1;
883}
884
885/* Get a pointer to the first handler in an exception region's list. */
886
887struct handler_info *
888get_first_handler (region)
889     int region;
890{
891  return function_eh_regions[find_func_region (region)].handlers;
892}
893
894/* Clean out the function_eh_region table and free all memory */
895
896static void
897clear_function_eh_region ()
898{
899  int x;
900  struct handler_info *ptr, *next;
901  for (x = 0; x < current_func_eh_entry; x++)
902    for (ptr = function_eh_regions[x].handlers; ptr != NULL; ptr = next)
903      {
904        next = ptr->next;
905        free (ptr);
906      }
907  free (function_eh_regions);
908  num_func_eh_entries  = 0;
909  current_func_eh_entry = 0;
910}
911
912/* Make a duplicate of an exception region by copying all the handlers
913   for an exception region. Return the new handler index. */
914
915int
916duplicate_handlers (old_note_eh_region, new_note_eh_region)
917     int old_note_eh_region, new_note_eh_region;
918{
919  struct handler_info *ptr, *new_ptr;
920  int new_region, region;
921
922  region = find_func_region (old_note_eh_region);
923  if (region == -1)
924    error ("Cannot duplicate non-existant exception region.");
925
926  if (find_func_region (new_note_eh_region) != -1)
927    error ("Cannot duplicate EH region because new note region already exists");
928
929  new_region = new_eh_region_entry (new_note_eh_region);
930  ptr = function_eh_regions[region].handlers;
931
932  for ( ; ptr; ptr = ptr->next)
933    {
934      new_ptr = get_new_handler (ptr->handler_label, ptr->type_info);
935      add_new_handler (new_region, new_ptr);
936    }
937
938  return new_region;
939}
940
941
942/* Routine to see if exception handling is turned on.
943   DO_WARN is non-zero if we want to inform the user that exception
944   handling is turned off.
945
946   This is used to ensure that -fexceptions has been specified if the
947   compiler tries to use any exception-specific functions.  */
948
949int
950doing_eh (do_warn)
951     int do_warn;
952{
953  if (! flag_exceptions)
954    {
955      static int warned = 0;
956      if (! warned && do_warn)
957	{
958	  error ("exception handling disabled, use -fexceptions to enable");
959	  warned = 1;
960	}
961      return 0;
962    }
963  return 1;
964}
965
966/* Given a return address in ADDR, determine the address we should use
967   to find the corresponding EH region.  */
968
969rtx
970eh_outer_context (addr)
971     rtx addr;
972{
973  /* First mask out any unwanted bits.  */
974#ifdef MASK_RETURN_ADDR
975  expand_and (addr, MASK_RETURN_ADDR, addr);
976#endif
977
978  /* Then adjust to find the real return address.  */
979#if defined (RETURN_ADDR_OFFSET)
980  addr = plus_constant (addr, RETURN_ADDR_OFFSET);
981#endif
982
983  return addr;
984}
985
986/* Start a new exception region for a region of code that has a
987   cleanup action and push the HANDLER for the region onto
988   protect_list. All of the regions created with add_partial_entry
989   will be ended when end_protect_partials is invoked.  */
990
991void
992add_partial_entry (handler)
993     tree handler;
994{
995  expand_eh_region_start ();
996
997  /* Make sure the entry is on the correct obstack.  */
998  push_obstacks_nochange ();
999  resume_temporary_allocation ();
1000
1001  /* Because this is a cleanup action, we may have to protect the handler
1002     with __terminate.  */
1003  handler = protect_with_terminate (handler);
1004
1005  protect_list = tree_cons (NULL_TREE, handler, protect_list);
1006  pop_obstacks ();
1007}
1008
1009/* Emit code to get EH context to current function.  */
1010
1011static rtx
1012call_get_eh_context ()
1013{
1014  static tree fn;
1015  tree expr;
1016
1017  if (fn == NULL_TREE)
1018    {
1019      tree fntype;
1020      fn = get_identifier ("__get_eh_context");
1021      push_obstacks_nochange ();
1022      end_temporary_allocation ();
1023      fntype = build_pointer_type (build_pointer_type
1024				   (build_pointer_type (void_type_node)));
1025      fntype = build_function_type (fntype, NULL_TREE);
1026      fn = build_decl (FUNCTION_DECL, fn, fntype);
1027      DECL_EXTERNAL (fn) = 1;
1028      TREE_PUBLIC (fn) = 1;
1029      DECL_ARTIFICIAL (fn) = 1;
1030      TREE_READONLY (fn) = 1;
1031      make_decl_rtl (fn, NULL_PTR, 1);
1032      assemble_external (fn);
1033      pop_obstacks ();
1034    }
1035
1036  expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
1037  expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
1038		expr, NULL_TREE, NULL_TREE);
1039  TREE_SIDE_EFFECTS (expr) = 1;
1040
1041  return copy_to_reg (expand_expr (expr, NULL_RTX, VOIDmode, 0));
1042}
1043
1044/* Get a reference to the EH context.
1045   We will only generate a register for the current function EH context here,
1046   and emit a USE insn to mark that this is a EH context register.
1047
1048   Later, emit_eh_context will emit needed call to __get_eh_context
1049   in libgcc2, and copy the value to the register we have generated. */
1050
1051rtx
1052get_eh_context ()
1053{
1054  if (current_function_ehc == 0)
1055    {
1056      rtx insn;
1057
1058      current_function_ehc = gen_reg_rtx (Pmode);
1059
1060      insn = gen_rtx_USE (GET_MODE (current_function_ehc),
1061			  current_function_ehc);
1062      insn = emit_insn_before (insn, get_first_nonparm_insn ());
1063
1064      REG_NOTES (insn)
1065	= gen_rtx_EXPR_LIST (REG_EH_CONTEXT, current_function_ehc,
1066			     REG_NOTES (insn));
1067    }
1068  return current_function_ehc;
1069}
1070
1071/* Get a reference to the dynamic handler chain.  It points to the
1072   pointer to the next element in the dynamic handler chain.  It ends
1073   when there are no more elements in the dynamic handler chain, when
1074   the value is &top_elt from libgcc2.c.  Immediately after the
1075   pointer, is an area suitable for setjmp/longjmp when
1076   DONT_USE_BUILTIN_SETJMP is defined, and an area suitable for
1077   __builtin_setjmp/__builtin_longjmp when DONT_USE_BUILTIN_SETJMP
1078   isn't defined. */
1079
1080rtx
1081get_dynamic_handler_chain ()
1082{
1083  rtx ehc, dhc, result;
1084
1085  ehc = get_eh_context ();
1086
1087  /* This is the offset of dynamic_handler_chain in the eh_context struct
1088     declared in eh-common.h. If its location is change, change this offset */
1089  dhc = plus_constant (ehc, POINTER_SIZE / BITS_PER_UNIT);
1090
1091  result = copy_to_reg (dhc);
1092
1093  /* We don't want a copy of the dcc, but rather, the single dcc.  */
1094  return gen_rtx_MEM (Pmode, result);
1095}
1096
1097/* Get a reference to the dynamic cleanup chain.  It points to the
1098   pointer to the next element in the dynamic cleanup chain.
1099   Immediately after the pointer, are two Pmode variables, one for a
1100   pointer to a function that performs the cleanup action, and the
1101   second, the argument to pass to that function.  */
1102
1103rtx
1104get_dynamic_cleanup_chain ()
1105{
1106  rtx dhc, dcc, result;
1107
1108  dhc = get_dynamic_handler_chain ();
1109  dcc = plus_constant (dhc, POINTER_SIZE / BITS_PER_UNIT);
1110
1111  result = copy_to_reg (dcc);
1112
1113  /* We don't want a copy of the dcc, but rather, the single dcc.  */
1114  return gen_rtx_MEM (Pmode, result);
1115}
1116
1117#ifdef DONT_USE_BUILTIN_SETJMP
1118/* Generate code to evaluate X and jump to LABEL if the value is nonzero.
1119   LABEL is an rtx of code CODE_LABEL, in this function.  */
1120
1121static void
1122jumpif_rtx (x, label)
1123     rtx x;
1124     rtx label;
1125{
1126  jumpif (make_tree (type_for_mode (GET_MODE (x), 0), x), label);
1127}
1128#endif
1129
1130/* Start a dynamic cleanup on the EH runtime dynamic cleanup stack.
1131   We just need to create an element for the cleanup list, and push it
1132   into the chain.
1133
1134   A dynamic cleanup is a cleanup action implied by the presence of an
1135   element on the EH runtime dynamic cleanup stack that is to be
1136   performed when an exception is thrown.  The cleanup action is
1137   performed by __sjthrow when an exception is thrown.  Only certain
1138   actions can be optimized into dynamic cleanup actions.  For the
1139   restrictions on what actions can be performed using this routine,
1140   see expand_eh_region_start_tree.  */
1141
1142static void
1143start_dynamic_cleanup (func, arg)
1144     tree func;
1145     tree arg;
1146{
1147  rtx dcc;
1148  rtx new_func, new_arg;
1149  rtx x, buf;
1150  int size;
1151
1152  /* We allocate enough room for a pointer to the function, and
1153     one argument.  */
1154  size = 2;
1155
1156  /* XXX, FIXME: The stack space allocated this way is too long lived,
1157     but there is no allocation routine that allocates at the level of
1158     the last binding contour.  */
1159  buf = assign_stack_local (BLKmode,
1160			    GET_MODE_SIZE (Pmode)*(size+1),
1161			    0);
1162
1163  buf = change_address (buf, Pmode, NULL_RTX);
1164
1165  /* Store dcc into the first word of the newly allocated buffer.  */
1166
1167  dcc = get_dynamic_cleanup_chain ();
1168  emit_move_insn (buf, dcc);
1169
1170  /* Store func and arg into the cleanup list element.  */
1171
1172  new_func = gen_rtx_MEM (Pmode, plus_constant (XEXP (buf, 0),
1173						GET_MODE_SIZE (Pmode)));
1174  new_arg = gen_rtx_MEM (Pmode, plus_constant (XEXP (buf, 0),
1175					       GET_MODE_SIZE (Pmode)*2));
1176  x = expand_expr (func, new_func, Pmode, 0);
1177  if (x != new_func)
1178    emit_move_insn (new_func, x);
1179
1180  x = expand_expr (arg, new_arg, Pmode, 0);
1181  if (x != new_arg)
1182    emit_move_insn (new_arg, x);
1183
1184  /* Update the cleanup chain.  */
1185
1186  emit_move_insn (dcc, XEXP (buf, 0));
1187}
1188
1189/* Emit RTL to start a dynamic handler on the EH runtime dynamic
1190   handler stack.  This should only be used by expand_eh_region_start
1191   or expand_eh_region_start_tree.  */
1192
1193static void
1194start_dynamic_handler ()
1195{
1196  rtx dhc, dcc;
1197  rtx x, arg, buf;
1198  int size;
1199
1200#ifndef DONT_USE_BUILTIN_SETJMP
1201  /* The number of Pmode words for the setjmp buffer, when using the
1202     builtin setjmp/longjmp, see expand_builtin, case
1203     BUILT_IN_LONGJMP.  */
1204  size = 5;
1205#else
1206#ifdef JMP_BUF_SIZE
1207  size = JMP_BUF_SIZE;
1208#else
1209  /* Should be large enough for most systems, if it is not,
1210     JMP_BUF_SIZE should be defined with the proper value.  It will
1211     also tend to be larger than necessary for most systems, a more
1212     optimal port will define JMP_BUF_SIZE.  */
1213  size = FIRST_PSEUDO_REGISTER+2;
1214#endif
1215#endif
1216  /* XXX, FIXME: The stack space allocated this way is too long lived,
1217     but there is no allocation routine that allocates at the level of
1218     the last binding contour.  */
1219  arg = assign_stack_local (BLKmode,
1220			    GET_MODE_SIZE (Pmode)*(size+1),
1221			    0);
1222
1223  arg = change_address (arg, Pmode, NULL_RTX);
1224
1225  /* Store dhc into the first word of the newly allocated buffer.  */
1226
1227  dhc = get_dynamic_handler_chain ();
1228  dcc = gen_rtx_MEM (Pmode, plus_constant (XEXP (arg, 0),
1229					   GET_MODE_SIZE (Pmode)));
1230  emit_move_insn (arg, dhc);
1231
1232  /* Zero out the start of the cleanup chain.  */
1233  emit_move_insn (dcc, const0_rtx);
1234
1235  /* The jmpbuf starts two words into the area allocated.  */
1236  buf = plus_constant (XEXP (arg, 0), GET_MODE_SIZE (Pmode)*2);
1237
1238#ifdef DONT_USE_BUILTIN_SETJMP
1239  x = emit_library_call_value (setjmp_libfunc, NULL_RTX, 1, SImode, 1,
1240			       buf, Pmode);
1241  /* If we come back here for a catch, transfer control to the handler.  */
1242  jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
1243#else
1244  {
1245    /* A label to continue execution for the no exception case.  */
1246    rtx noex = gen_label_rtx();
1247    x = expand_builtin_setjmp (buf, NULL_RTX, noex,
1248			       ehstack.top->entry->exception_handler_label);
1249    emit_label (noex);
1250  }
1251#endif
1252
1253  /* We are committed to this, so update the handler chain.  */
1254
1255  emit_move_insn (dhc, XEXP (arg, 0));
1256}
1257
1258/* Start an exception handling region for the given cleanup action.
1259   All instructions emitted after this point are considered to be part
1260   of the region until expand_eh_region_end is invoked.  CLEANUP is
1261   the cleanup action to perform.  The return value is true if the
1262   exception region was optimized away.  If that case,
1263   expand_eh_region_end does not need to be called for this cleanup,
1264   nor should it be.
1265
1266   This routine notices one particular common case in C++ code
1267   generation, and optimizes it so as to not need the exception
1268   region.  It works by creating a dynamic cleanup action, instead of
1269   a using an exception region.  */
1270
1271int
1272expand_eh_region_start_tree (decl, cleanup)
1273     tree decl;
1274     tree cleanup;
1275{
1276  /* This is the old code.  */
1277  if (! doing_eh (0))
1278    return 0;
1279
1280  /* The optimization only applies to actions protected with
1281     terminate, and only applies if we are using the setjmp/longjmp
1282     codegen method.  */
1283  if (exceptions_via_longjmp
1284      && protect_cleanup_actions_with_terminate)
1285    {
1286      tree func, arg;
1287      tree args;
1288
1289      /* Ignore any UNSAVE_EXPR.  */
1290      if (TREE_CODE (cleanup) == UNSAVE_EXPR)
1291	cleanup = TREE_OPERAND (cleanup, 0);
1292
1293      /* Further, it only applies if the action is a call, if there
1294	 are 2 arguments, and if the second argument is 2.  */
1295
1296      if (TREE_CODE (cleanup) == CALL_EXPR
1297	  && (args = TREE_OPERAND (cleanup, 1))
1298	  && (func = TREE_OPERAND (cleanup, 0))
1299	  && (arg = TREE_VALUE (args))
1300	  && (args = TREE_CHAIN (args))
1301
1302	  /* is the second argument 2?  */
1303	  && TREE_CODE (TREE_VALUE (args)) == INTEGER_CST
1304	  && TREE_INT_CST_LOW (TREE_VALUE (args)) == 2
1305	  && TREE_INT_CST_HIGH (TREE_VALUE (args)) == 0
1306
1307	  /* Make sure there are no other arguments.  */
1308	  && TREE_CHAIN (args) == NULL_TREE)
1309	{
1310	  /* Arrange for returns and gotos to pop the entry we make on the
1311	     dynamic cleanup stack.  */
1312	  expand_dcc_cleanup (decl);
1313	  start_dynamic_cleanup (func, arg);
1314	  return 1;
1315	}
1316    }
1317
1318  expand_eh_region_start_for_decl (decl);
1319  ehstack.top->entry->finalization = cleanup;
1320
1321  return 0;
1322}
1323
1324/* Just like expand_eh_region_start, except if a cleanup action is
1325   entered on the cleanup chain, the TREE_PURPOSE of the element put
1326   on the chain is DECL.  DECL should be the associated VAR_DECL, if
1327   any, otherwise it should be NULL_TREE.  */
1328
1329void
1330expand_eh_region_start_for_decl (decl)
1331     tree decl;
1332{
1333  rtx note;
1334
1335  /* This is the old code.  */
1336  if (! doing_eh (0))
1337    return;
1338
1339  if (exceptions_via_longjmp)
1340    {
1341      /* We need a new block to record the start and end of the
1342	 dynamic handler chain.  We could always do this, but we
1343	 really want to permit jumping into such a block, and we want
1344	 to avoid any errors or performance impact in the SJ EH code
1345	 for now.  */
1346      expand_start_bindings (0);
1347
1348      /* But we don't need or want a new temporary level.  */
1349      pop_temp_slots ();
1350
1351      /* Mark this block as created by expand_eh_region_start.  This
1352	 is so that we can pop the block with expand_end_bindings
1353	 automatically.  */
1354      mark_block_as_eh_region ();
1355
1356      /* Arrange for returns and gotos to pop the entry we make on the
1357	 dynamic handler stack.  */
1358      expand_dhc_cleanup (decl);
1359    }
1360
1361  push_eh_entry (&ehstack);
1362  note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_BEG);
1363  NOTE_BLOCK_NUMBER (note)
1364    = CODE_LABEL_NUMBER (ehstack.top->entry->exception_handler_label);
1365  if (exceptions_via_longjmp)
1366    start_dynamic_handler ();
1367}
1368
1369/* Start an exception handling region.  All instructions emitted after
1370   this point are considered to be part of the region until
1371   expand_eh_region_end is invoked.  */
1372
1373void
1374expand_eh_region_start ()
1375{
1376  expand_eh_region_start_for_decl (NULL_TREE);
1377}
1378
1379/* End an exception handling region.  The information about the region
1380   is found on the top of ehstack.
1381
1382   HANDLER is either the cleanup for the exception region, or if we're
1383   marking the end of a try block, HANDLER is integer_zero_node.
1384
1385   HANDLER will be transformed to rtl when expand_leftover_cleanups
1386   is invoked.  */
1387
1388void
1389expand_eh_region_end (handler)
1390     tree handler;
1391{
1392  struct eh_entry *entry;
1393  rtx note;
1394
1395  if (! doing_eh (0))
1396    return;
1397
1398  entry = pop_eh_entry (&ehstack);
1399
1400  note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END);
1401  NOTE_BLOCK_NUMBER (note)
1402    = CODE_LABEL_NUMBER (entry->exception_handler_label);
1403  if (exceptions_via_longjmp == 0
1404      /* We share outer_context between regions; only emit it once.  */
1405      && INSN_UID (entry->outer_context) == 0)
1406    {
1407      rtx label;
1408
1409      label = gen_label_rtx ();
1410      emit_jump (label);
1411
1412      /* Emit a label marking the end of this exception region that
1413	 is used for rethrowing into the outer context.  */
1414      emit_label (entry->outer_context);
1415      expand_internal_throw ();
1416
1417      emit_label (label);
1418    }
1419
1420  entry->finalization = handler;
1421
1422  /* create region entry in final exception table */
1423  new_eh_region_entry (NOTE_BLOCK_NUMBER (note));
1424
1425  enqueue_eh_entry (&ehqueue, entry);
1426
1427  /* If we have already started ending the bindings, don't recurse.
1428     This only happens when exceptions_via_longjmp is true.  */
1429  if (is_eh_region ())
1430    {
1431      /* Because we don't need or want a new temporary level and
1432	 because we didn't create one in expand_eh_region_start,
1433	 create a fake one now to avoid removing one in
1434	 expand_end_bindings.  */
1435      push_temp_slots ();
1436
1437      mark_block_as_not_eh_region ();
1438
1439      /* Maybe do this to prevent jumping in and so on...  */
1440      expand_end_bindings (NULL_TREE, 0, 0);
1441    }
1442}
1443
1444/* End the EH region for a goto fixup.  We only need them in the region-based
1445   EH scheme.  */
1446
1447void
1448expand_fixup_region_start ()
1449{
1450  if (! doing_eh (0) || exceptions_via_longjmp)
1451    return;
1452
1453  expand_eh_region_start ();
1454}
1455
1456/* End the EH region for a goto fixup.  CLEANUP is the cleanup we just
1457   expanded; to avoid running it twice if it throws, we look through the
1458   ehqueue for a matching region and rethrow from its outer_context.  */
1459
1460void
1461expand_fixup_region_end (cleanup)
1462     tree cleanup;
1463{
1464  struct eh_node *node;
1465  int dont_issue;
1466
1467  if (! doing_eh (0) || exceptions_via_longjmp)
1468    return;
1469
1470  for (node = ehstack.top; node && node->entry->finalization != cleanup; )
1471    node = node->chain;
1472  if (node == 0)
1473    for (node = ehqueue.head; node && node->entry->finalization != cleanup; )
1474      node = node->chain;
1475  if (node == 0)
1476    abort ();
1477
1478  /* If the outer context label has not been issued yet, we don't want
1479     to issue it as a part of this region, unless this is the
1480     correct region for the outer context. If we did, then the label for
1481     the outer context will be WITHIN the begin/end labels,
1482     and we could get an infinte loop when it tried to rethrow, or just
1483     generally incorrect execution following a throw. */
1484
1485  dont_issue = ((INSN_UID (node->entry->outer_context) == 0)
1486            && (ehstack.top->entry != node->entry));
1487
1488  ehstack.top->entry->outer_context = node->entry->outer_context;
1489
1490  /* Since we are rethrowing to the OUTER region, we know we don't need
1491     a jump around sequence for this region, so we'll pretend the outer
1492     context label has been issued by setting INSN_UID to 1, then clearing
1493     it again afterwards. */
1494
1495  if (dont_issue)
1496    INSN_UID (node->entry->outer_context) = 1;
1497
1498  /* Just rethrow.  size_zero_node is just a NOP.  */
1499  expand_eh_region_end (size_zero_node);
1500
1501  if (dont_issue)
1502    INSN_UID (node->entry->outer_context) = 0;
1503}
1504
1505/* If we are using the setjmp/longjmp EH codegen method, we emit a
1506   call to __sjthrow.
1507
1508   Otherwise, we emit a call to __throw and note that we threw
1509   something, so we know we need to generate the necessary code for
1510   __throw.
1511
1512   Before invoking throw, the __eh_pc variable must have been set up
1513   to contain the PC being thrown from. This address is used by
1514   __throw to determine which exception region (if any) is
1515   responsible for handling the exception.  */
1516
1517void
1518emit_throw ()
1519{
1520  if (exceptions_via_longjmp)
1521    {
1522      emit_library_call (sjthrow_libfunc, 0, VOIDmode, 0);
1523    }
1524  else
1525    {
1526#ifdef JUMP_TO_THROW
1527      emit_indirect_jump (throw_libfunc);
1528#else
1529      emit_library_call (throw_libfunc, 0, VOIDmode, 0);
1530#endif
1531    }
1532  emit_barrier ();
1533}
1534
1535/* Throw the current exception.  If appropriate, this is done by jumping
1536   to the next handler.  */
1537
1538void
1539expand_internal_throw ()
1540{
1541  emit_throw ();
1542}
1543
1544/* Called from expand_exception_blocks and expand_end_catch_block to
1545   emit any pending handlers/cleanups queued from expand_eh_region_end.  */
1546
1547void
1548expand_leftover_cleanups ()
1549{
1550  struct eh_entry *entry;
1551
1552  while ((entry = dequeue_eh_entry (&ehqueue)) != 0)
1553    {
1554      rtx prev;
1555
1556      /* A leftover try block. Shouldn't be one here.  */
1557      if (entry->finalization == integer_zero_node)
1558	abort ();
1559
1560      /* Output the label for the start of the exception handler.  */
1561
1562      receive_exception_label (entry->exception_handler_label);
1563
1564      /* register a handler for this cleanup region */
1565      add_new_handler (
1566        find_func_region (CODE_LABEL_NUMBER (entry->exception_handler_label)),
1567        get_new_handler (entry->exception_handler_label, NULL));
1568
1569      /* And now generate the insns for the handler.  */
1570      expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
1571
1572      prev = get_last_insn ();
1573      if (prev == NULL || GET_CODE (prev) != BARRIER)
1574	/* Emit code to throw to the outer context if we fall off
1575	   the end of the handler.  */
1576	expand_rethrow (entry->outer_context);
1577
1578      do_pending_stack_adjust ();
1579      free (entry);
1580    }
1581}
1582
1583/* Called at the start of a block of try statements.  */
1584void
1585expand_start_try_stmts ()
1586{
1587  if (! doing_eh (1))
1588    return;
1589
1590  expand_eh_region_start ();
1591}
1592
1593/* Called to begin a catch clause. The parameter is the object which
1594   will be passed to the runtime type check routine. */
1595void
1596start_catch_handler (rtime)
1597     tree rtime;
1598{
1599  rtx handler_label;
1600  int insn_region_num;
1601  int eh_region_entry;
1602
1603  if (! doing_eh (1))
1604    return;
1605
1606  handler_label = catchstack.top->entry->exception_handler_label;
1607  insn_region_num = CODE_LABEL_NUMBER (handler_label);
1608  eh_region_entry = find_func_region (insn_region_num);
1609
1610  /* If we've already issued this label, pick a new one */
1611  if (catchstack.top->entry->label_used)
1612    handler_label = gen_exception_label ();
1613  else
1614    catchstack.top->entry->label_used = 1;
1615
1616  receive_exception_label (handler_label);
1617
1618  add_new_handler (eh_region_entry, get_new_handler (handler_label, rtime));
1619}
1620
1621/* Generate RTL for the start of a group of catch clauses.
1622
1623   It is responsible for starting a new instruction sequence for the
1624   instructions in the catch block, and expanding the handlers for the
1625   internally-generated exception regions nested within the try block
1626   corresponding to this catch block.  */
1627
1628void
1629expand_start_all_catch ()
1630{
1631  struct eh_entry *entry;
1632  tree label;
1633  rtx outer_context;
1634
1635  if (! doing_eh (1))
1636    return;
1637
1638  outer_context = ehstack.top->entry->outer_context;
1639
1640  /* End the try block.  */
1641  expand_eh_region_end (integer_zero_node);
1642
1643  emit_line_note (input_filename, lineno);
1644  label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1645
1646  /* The label for the exception handling block that we will save.
1647     This is Lresume in the documentation.  */
1648  expand_label (label);
1649
1650  /* Push the label that points to where normal flow is resumed onto
1651     the top of the label stack.  */
1652  push_label_entry (&caught_return_label_stack, NULL_RTX, label);
1653
1654  /* Start a new sequence for all the catch blocks.  We will add this
1655     to the global sequence catch_clauses when we have completed all
1656     the handlers in this handler-seq.  */
1657  start_sequence ();
1658
1659  entry = dequeue_eh_entry (&ehqueue);
1660  for ( ; entry->finalization != integer_zero_node;
1661                                 entry = dequeue_eh_entry (&ehqueue))
1662    {
1663      rtx prev;
1664
1665      /* Emit the label for the cleanup handler for this region, and
1666	 expand the code for the handler.
1667
1668	 Note that a catch region is handled as a side-effect here;
1669	 for a try block, entry->finalization will contain
1670	 integer_zero_node, so no code will be generated in the
1671	 expand_expr call below. But, the label for the handler will
1672	 still be emitted, so any code emitted after this point will
1673	 end up being the handler.  */
1674
1675      receive_exception_label (entry->exception_handler_label);
1676
1677      /* register a handler for this cleanup region */
1678      add_new_handler (
1679        find_func_region (CODE_LABEL_NUMBER (entry->exception_handler_label)),
1680        get_new_handler (entry->exception_handler_label, NULL));
1681
1682      /* And now generate the insns for the cleanup handler.  */
1683      expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
1684
1685      prev = get_last_insn ();
1686      if (prev == NULL || GET_CODE (prev) != BARRIER)
1687	/* Code to throw out to outer context when we fall off end
1688	   of the handler. We can't do this here for catch blocks,
1689	   so it's done in expand_end_all_catch instead.  */
1690	expand_rethrow (entry->outer_context);
1691
1692      do_pending_stack_adjust ();
1693      free (entry);
1694    }
1695
1696  /* At this point, all the cleanups are done, and the ehqueue now has
1697     the current exception region at its head. We dequeue it, and put it
1698     on the catch stack. */
1699
1700    push_entry (&catchstack, entry);
1701
1702  /* If we are not doing setjmp/longjmp EH, because we are reordered
1703     out of line, we arrange to rethrow in the outer context.  We need to
1704     do this because we are not physically within the region, if any, that
1705     logically contains this catch block.  */
1706  if (! exceptions_via_longjmp)
1707    {
1708      expand_eh_region_start ();
1709      ehstack.top->entry->outer_context = outer_context;
1710    }
1711
1712  /* We also have to start the handler if we aren't using the new model. */
1713  if (! flag_new_exceptions)
1714    start_catch_handler (NULL);
1715}
1716
1717/* Finish up the catch block.  At this point all the insns for the
1718   catch clauses have already been generated, so we only have to add
1719   them to the catch_clauses list. We also want to make sure that if
1720   we fall off the end of the catch clauses that we rethrow to the
1721   outer EH region.  */
1722
1723void
1724expand_end_all_catch ()
1725{
1726  rtx new_catch_clause, outer_context = NULL_RTX;
1727  struct eh_entry *entry;
1728
1729  if (! doing_eh (1))
1730    return;
1731
1732  /* Dequeue the current catch clause region. */
1733  entry = pop_eh_entry (&catchstack);
1734  free (entry);
1735
1736  if (! exceptions_via_longjmp)
1737    {
1738      outer_context = ehstack.top->entry->outer_context;
1739
1740      /* Finish the rethrow region.  size_zero_node is just a NOP.  */
1741      expand_eh_region_end (size_zero_node);
1742    }
1743
1744  /* Code to throw out to outer context, if we fall off end of catch
1745     handlers.  This is rethrow (Lresume, same id, same obj) in the
1746     documentation. We use Lresume because we know that it will throw
1747     to the correct context.
1748
1749     In other words, if the catch handler doesn't exit or return, we
1750     do a "throw" (using the address of Lresume as the point being
1751     thrown from) so that the outer EH region can then try to process
1752     the exception.  */
1753  expand_rethrow (outer_context);
1754
1755  /* Now we have the complete catch sequence.  */
1756  new_catch_clause = get_insns ();
1757  end_sequence ();
1758
1759  /* This level of catch blocks is done, so set up the successful
1760     catch jump label for the next layer of catch blocks.  */
1761  pop_label_entry (&caught_return_label_stack);
1762  pop_label_entry (&outer_context_label_stack);
1763
1764  /* Add the new sequence of catches to the main one for this function.  */
1765  push_to_sequence (catch_clauses);
1766  emit_insns (new_catch_clause);
1767  catch_clauses = get_insns ();
1768  end_sequence ();
1769
1770  /* Here we fall through into the continuation code.  */
1771}
1772
1773/* Rethrow from the outer context LABEL.  */
1774
1775static void
1776expand_rethrow (label)
1777     rtx label;
1778{
1779  if (exceptions_via_longjmp)
1780    emit_throw ();
1781  else
1782    emit_jump (label);
1783}
1784
1785/* End all the pending exception regions on protect_list. The handlers
1786   will be emitted when expand_leftover_cleanups is invoked.  */
1787
1788void
1789end_protect_partials ()
1790{
1791  while (protect_list)
1792    {
1793      expand_eh_region_end (TREE_VALUE (protect_list));
1794      protect_list = TREE_CHAIN (protect_list);
1795    }
1796}
1797
1798/* Arrange for __terminate to be called if there is an unhandled throw
1799   from within E.  */
1800
1801tree
1802protect_with_terminate (e)
1803     tree e;
1804{
1805  /* We only need to do this when using setjmp/longjmp EH and the
1806     language requires it, as otherwise we protect all of the handlers
1807     at once, if we need to.  */
1808  if (exceptions_via_longjmp && protect_cleanup_actions_with_terminate)
1809    {
1810      tree handler, result;
1811
1812      /* All cleanups must be on the function_obstack.  */
1813      push_obstacks_nochange ();
1814      resume_temporary_allocation ();
1815
1816      handler = make_node (RTL_EXPR);
1817      TREE_TYPE (handler) = void_type_node;
1818      RTL_EXPR_RTL (handler) = const0_rtx;
1819      TREE_SIDE_EFFECTS (handler) = 1;
1820      start_sequence_for_rtl_expr (handler);
1821
1822      emit_library_call (terminate_libfunc, 0, VOIDmode, 0);
1823      emit_barrier ();
1824
1825      RTL_EXPR_SEQUENCE (handler) = get_insns ();
1826      end_sequence ();
1827
1828      result = build (TRY_CATCH_EXPR, TREE_TYPE (e), e, handler);
1829      TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e);
1830      TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
1831      TREE_READONLY (result) = TREE_READONLY (e);
1832
1833      pop_obstacks ();
1834
1835      e = result;
1836    }
1837
1838  return e;
1839}
1840
1841/* The exception table that we build that is used for looking up and
1842   dispatching exceptions, the current number of entries, and its
1843   maximum size before we have to extend it.
1844
1845   The number in eh_table is the code label number of the exception
1846   handler for the region. This is added by add_eh_table_entry and
1847   used by output_exception_table_entry.  */
1848
1849static int *eh_table = NULL;
1850static int eh_table_size = 0;
1851static int eh_table_max_size = 0;
1852
1853/* Note the need for an exception table entry for region N.  If we
1854   don't need to output an explicit exception table, avoid all of the
1855   extra work.
1856
1857   Called from final_scan_insn when a NOTE_INSN_EH_REGION_BEG is seen.
1858   (Or NOTE_INSN_EH_REGION_END sometimes)
1859   N is the NOTE_BLOCK_NUMBER of the note, which comes from the code
1860   label number of the exception handler for the region.  */
1861
1862void
1863add_eh_table_entry (n)
1864     int n;
1865{
1866#ifndef OMIT_EH_TABLE
1867  if (eh_table_size >= eh_table_max_size)
1868    {
1869      if (eh_table)
1870	{
1871	  eh_table_max_size += eh_table_max_size>>1;
1872
1873	  if (eh_table_max_size < 0)
1874	    abort ();
1875
1876	  eh_table = (int *) xrealloc (eh_table,
1877				       eh_table_max_size * sizeof (int));
1878	}
1879      else
1880	{
1881	  eh_table_max_size = 252;
1882	  eh_table = (int *) xmalloc (eh_table_max_size * sizeof (int));
1883	}
1884    }
1885  eh_table[eh_table_size++] = n;
1886#endif
1887}
1888
1889/* Return a non-zero value if we need to output an exception table.
1890
1891   On some platforms, we don't have to output a table explicitly.
1892   This routine doesn't mean we don't have one.  */
1893
1894int
1895exception_table_p ()
1896{
1897  if (eh_table)
1898    return 1;
1899
1900  return 0;
1901}
1902
1903/* Output the entry of the exception table corresponding to the
1904   exception region numbered N to file FILE.
1905
1906   N is the code label number corresponding to the handler of the
1907   region.  */
1908
1909static void
1910output_exception_table_entry (file, n)
1911     FILE *file;
1912     int n;
1913{
1914  char buf[256];
1915  rtx sym;
1916  struct handler_info *handler;
1917
1918  handler = get_first_handler (n);
1919
1920  for ( ; handler != NULL; handler = handler->next)
1921    {
1922      ASM_GENERATE_INTERNAL_LABEL (buf, "LEHB", n);
1923      sym = gen_rtx_SYMBOL_REF (Pmode, buf);
1924      assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
1925
1926      ASM_GENERATE_INTERNAL_LABEL (buf, "LEHE", n);
1927      sym = gen_rtx_SYMBOL_REF (Pmode, buf);
1928      assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
1929
1930      assemble_integer (handler->handler_label,
1931                                         POINTER_SIZE / BITS_PER_UNIT, 1);
1932
1933      if (flag_new_exceptions)
1934        {
1935          if (handler->type_info == NULL)
1936            assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1937          else
1938            if (handler->type_info == CATCH_ALL_TYPE)
1939              assemble_integer (GEN_INT (CATCH_ALL_TYPE),
1940                                             POINTER_SIZE / BITS_PER_UNIT, 1);
1941            else
1942              output_constant ((tree)(handler->type_info),
1943                                                POINTER_SIZE / BITS_PER_UNIT);
1944        }
1945      putc ('\n', file);		/* blank line */
1946    }
1947}
1948
1949/* Output the exception table if we have and need one.  */
1950
1951static short language_code = 0;
1952static short version_code = 0;
1953
1954/* This routine will set the language code for exceptions. */
1955void set_exception_lang_code (code)
1956     short code;
1957{
1958  language_code = code;
1959}
1960
1961/* This routine will set the language version code for exceptions. */
1962void set_exception_version_code (code)
1963     short code;
1964{
1965  version_code = code;
1966}
1967
1968
1969void
1970output_exception_table ()
1971{
1972  int i;
1973  extern FILE *asm_out_file;
1974
1975  if (! doing_eh (0) || ! eh_table)
1976    return;
1977
1978  exception_section ();
1979
1980  /* Beginning marker for table.  */
1981  assemble_align (GET_MODE_ALIGNMENT (ptr_mode));
1982  assemble_label ("__EXCEPTION_TABLE__");
1983
1984  if (flag_new_exceptions)
1985    {
1986      assemble_integer (GEN_INT (NEW_EH_RUNTIME),
1987                                        POINTER_SIZE / BITS_PER_UNIT, 1);
1988      assemble_integer (GEN_INT (language_code), 2 , 1);
1989      assemble_integer (GEN_INT (version_code), 2 , 1);
1990
1991      /* Add enough padding to make sure table aligns on a pointer boundry. */
1992      i = GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT - 4;
1993      for ( ; i < 0; i = i + GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT)
1994        ;
1995      if (i != 0)
1996        assemble_integer (const0_rtx, i , 1);
1997    }
1998
1999  for (i = 0; i < eh_table_size; ++i)
2000    output_exception_table_entry (asm_out_file, eh_table[i]);
2001
2002  free (eh_table);
2003  clear_function_eh_region ();
2004
2005  /* Ending marker for table.  */
2006  assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
2007
2008  /* for binary compatability, the old __throw checked the second
2009     position for a -1, so we should output at least 2 -1's */
2010  if (! flag_new_exceptions)
2011    assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
2012
2013  putc ('\n', asm_out_file);		/* blank line */
2014}
2015
2016/* Emit code to get EH context.
2017
2018   We have to scan thru the code to find possible EH context registers.
2019   Inlined functions may use it too, and thus we'll have to be able
2020   to change them too.
2021
2022   This is done only if using exceptions_via_longjmp. */
2023
2024void
2025emit_eh_context ()
2026{
2027  rtx insn;
2028  rtx ehc = 0;
2029
2030  if (! doing_eh (0))
2031    return;
2032
2033  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2034    if (GET_CODE (insn) == INSN
2035	&& GET_CODE (PATTERN (insn)) == USE)
2036      {
2037	rtx reg = find_reg_note (insn, REG_EH_CONTEXT, 0);
2038	if (reg)
2039	  {
2040	    rtx insns;
2041
2042	    start_sequence ();
2043
2044	    /* If this is the first use insn, emit the call here.  This
2045	       will always be at the top of our function, because if
2046	       expand_inline_function notices a REG_EH_CONTEXT note, it
2047	       adds a use insn to this function as well.  */
2048	    if (ehc == 0)
2049	      ehc = call_get_eh_context ();
2050
2051	    emit_move_insn (XEXP (reg, 0), ehc);
2052	    insns = get_insns ();
2053	    end_sequence ();
2054
2055	    emit_insns_before (insns, insn);
2056	  }
2057      }
2058}
2059
2060/* Scan the current insns and build a list of handler labels. The
2061   resulting list is placed in the global variable exception_handler_labels.
2062
2063   It is called after the last exception handling region is added to
2064   the current function (when the rtl is almost all built for the
2065   current function) and before the jump optimization pass.  */
2066
2067void
2068find_exception_handler_labels ()
2069{
2070  rtx insn;
2071
2072  exception_handler_labels = NULL_RTX;
2073
2074  /* If we aren't doing exception handling, there isn't much to check.  */
2075  if (! doing_eh (0))
2076    return;
2077
2078  /* For each start of a region, add its label to the list.  */
2079
2080  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2081    {
2082      struct handler_info* ptr;
2083      if (GET_CODE (insn) == NOTE
2084	  && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
2085	{
2086          ptr = get_first_handler (NOTE_BLOCK_NUMBER (insn));
2087          for ( ; ptr; ptr = ptr->next)
2088            {
2089              /* make sure label isn't in the list already */
2090              rtx x;
2091              for (x = exception_handler_labels; x; x = XEXP (x, 1))
2092                if (XEXP (x, 0) == ptr->handler_label)
2093                  break;
2094              if (! x)
2095                exception_handler_labels = gen_rtx_EXPR_LIST (VOIDmode,
2096                               ptr->handler_label, exception_handler_labels);
2097            }
2098	}
2099    }
2100}
2101
2102/* Return a value of 1 if the parameter label number is an exception handler
2103   label. Return 0 otherwise. */
2104
2105int
2106is_exception_handler_label (lab)
2107     int lab;
2108{
2109  rtx x;
2110  for (x = exception_handler_labels ; x ; x = XEXP (x, 1))
2111    if (lab == CODE_LABEL_NUMBER (XEXP (x, 0)))
2112      return 1;
2113  return 0;
2114}
2115
2116/* Perform sanity checking on the exception_handler_labels list.
2117
2118   Can be called after find_exception_handler_labels is called to
2119   build the list of exception handlers for the current function and
2120   before we finish processing the current function.  */
2121
2122void
2123check_exception_handler_labels ()
2124{
2125  rtx insn, insn2;
2126
2127  /* If we aren't doing exception handling, there isn't much to check.  */
2128  if (! doing_eh (0))
2129    return;
2130
2131  /* Make sure there is no more than 1 copy of a label */
2132  for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1))
2133    {
2134      int count = 0;
2135      for (insn2 = exception_handler_labels; insn2; insn2 = XEXP (insn2, 1))
2136        if (XEXP (insn, 0) == XEXP (insn2, 0))
2137          count++;
2138      if (count != 1)
2139       warning ("Counted %d copies of EH region %d in list.\n", count,
2140                                        CODE_LABEL_NUMBER (insn));
2141    }
2142
2143}
2144
2145/* This group of functions initializes the exception handling data
2146   structures at the start of the compilation, initializes the data
2147   structures at the start of a function, and saves and restores the
2148   exception handling data structures for the start/end of a nested
2149   function.  */
2150
2151/* Toplevel initialization for EH things.  */
2152
2153void
2154init_eh ()
2155{
2156}
2157
2158/* Initialize the per-function EH information.  */
2159
2160void
2161init_eh_for_function ()
2162{
2163  ehstack.top = 0;
2164  catchstack.top = 0;
2165  ehqueue.head = ehqueue.tail = 0;
2166  catch_clauses = NULL_RTX;
2167  false_label_stack = 0;
2168  caught_return_label_stack = 0;
2169  protect_list = NULL_TREE;
2170  current_function_ehc = NULL_RTX;
2171}
2172
2173/* Save some of the per-function EH info into the save area denoted by
2174   P.
2175
2176   This is currently called from save_stmt_status.  */
2177
2178void
2179save_eh_status (p)
2180     struct function *p;
2181{
2182  if (p == NULL)
2183    abort ();
2184
2185  p->ehstack = ehstack;
2186  p->catchstack = catchstack;
2187  p->ehqueue = ehqueue;
2188  p->catch_clauses = catch_clauses;
2189  p->false_label_stack = false_label_stack;
2190  p->caught_return_label_stack = caught_return_label_stack;
2191  p->protect_list = protect_list;
2192  p->ehc = current_function_ehc;
2193
2194  init_eh_for_function ();
2195}
2196
2197/* Restore the per-function EH info saved into the area denoted by P.
2198
2199   This is currently called from restore_stmt_status.  */
2200
2201void
2202restore_eh_status (p)
2203     struct function *p;
2204{
2205  if (p == NULL)
2206    abort ();
2207
2208  protect_list = p->protect_list;
2209  caught_return_label_stack = p->caught_return_label_stack;
2210  false_label_stack = p->false_label_stack;
2211  catch_clauses	= p->catch_clauses;
2212  ehqueue = p->ehqueue;
2213  ehstack = p->ehstack;
2214  catchstack = p->catchstack;
2215  current_function_ehc = p->ehc;
2216}
2217
2218/* This section is for the exception handling specific optimization
2219   pass.  First are the internal routines, and then the main
2220   optimization pass.  */
2221
2222/* Determine if the given INSN can throw an exception.  */
2223
2224static int
2225can_throw (insn)
2226     rtx insn;
2227{
2228  /* Calls can always potentially throw exceptions.  */
2229  if (GET_CODE (insn) == CALL_INSN)
2230    return 1;
2231
2232  if (asynchronous_exceptions)
2233    {
2234      /* If we wanted asynchronous exceptions, then everything but NOTEs
2235	 and CODE_LABELs could throw.  */
2236      if (GET_CODE (insn) != NOTE && GET_CODE (insn) != CODE_LABEL)
2237	return 1;
2238    }
2239
2240  return 0;
2241}
2242
2243/* Scan a exception region looking for the matching end and then
2244   remove it if possible. INSN is the start of the region, N is the
2245   region number, and DELETE_OUTER is to note if anything in this
2246   region can throw.
2247
2248   Regions are removed if they cannot possibly catch an exception.
2249   This is determined by invoking can_throw on each insn within the
2250   region; if can_throw returns true for any of the instructions, the
2251   region can catch an exception, since there is an insn within the
2252   region that is capable of throwing an exception.
2253
2254   Returns the NOTE_INSN_EH_REGION_END corresponding to this region, or
2255   calls abort if it can't find one.
2256
2257   Can abort if INSN is not a NOTE_INSN_EH_REGION_BEGIN, or if N doesn't
2258   correspond to the region number, or if DELETE_OUTER is NULL.  */
2259
2260static rtx
2261scan_region (insn, n, delete_outer)
2262     rtx insn;
2263     int n;
2264     int *delete_outer;
2265{
2266  rtx start = insn;
2267
2268  /* Assume we can delete the region.  */
2269  int delete = 1;
2270
2271  if (insn == NULL_RTX
2272      || GET_CODE (insn) != NOTE
2273      || NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_BEG
2274      || NOTE_BLOCK_NUMBER (insn) != n
2275      || delete_outer == NULL)
2276    abort ();
2277
2278  insn = NEXT_INSN (insn);
2279
2280  /* Look for the matching end.  */
2281  while (! (GET_CODE (insn) == NOTE
2282	    && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
2283    {
2284      /* If anything can throw, we can't remove the region.  */
2285      if (delete && can_throw (insn))
2286	{
2287	  delete = 0;
2288	}
2289
2290      /* Watch out for and handle nested regions.  */
2291      if (GET_CODE (insn) == NOTE
2292	  && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
2293	{
2294	  insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &delete);
2295	}
2296
2297      insn = NEXT_INSN (insn);
2298    }
2299
2300  /* The _BEG/_END NOTEs must match and nest.  */
2301  if (NOTE_BLOCK_NUMBER (insn) != n)
2302    abort ();
2303
2304  /* If anything in this exception region can throw, we can throw.  */
2305  if (! delete)
2306    *delete_outer = 0;
2307  else
2308    {
2309      /* Delete the start and end of the region.  */
2310      delete_insn (start);
2311      delete_insn (insn);
2312
2313/* We no longer removed labels here, since flow will now remove any
2314   handler which cannot be called any more. */
2315
2316#if 0
2317      /* Only do this part if we have built the exception handler
2318         labels.  */
2319      if (exception_handler_labels)
2320	{
2321	  rtx x, *prev = &exception_handler_labels;
2322
2323	  /* Find it in the list of handlers.  */
2324	  for (x = exception_handler_labels; x; x = XEXP (x, 1))
2325	    {
2326	      rtx label = XEXP (x, 0);
2327	      if (CODE_LABEL_NUMBER (label) == n)
2328		{
2329		  /* If we are the last reference to the handler,
2330                     delete it.  */
2331		  if (--LABEL_NUSES (label) == 0)
2332		    delete_insn (label);
2333
2334		  if (optimize)
2335		    {
2336		      /* Remove it from the list of exception handler
2337			 labels, if we are optimizing.  If we are not, then
2338			 leave it in the list, as we are not really going to
2339			 remove the region.  */
2340		      *prev = XEXP (x, 1);
2341		      XEXP (x, 1) = 0;
2342		      XEXP (x, 0) = 0;
2343		    }
2344
2345		  break;
2346		}
2347	      prev = &XEXP (x, 1);
2348	    }
2349	}
2350#endif
2351    }
2352  return insn;
2353}
2354
2355/* Perform various interesting optimizations for exception handling
2356   code.
2357
2358   We look for empty exception regions and make them go (away). The
2359   jump optimization code will remove the handler if nothing else uses
2360   it.  */
2361
2362void
2363exception_optimize ()
2364{
2365  rtx insn;
2366  int n;
2367
2368  /* Remove empty regions.  */
2369  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2370    {
2371      if (GET_CODE (insn) == NOTE
2372	  && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
2373	{
2374	  /* Since scan_region will return the NOTE_INSN_EH_REGION_END
2375	     insn, we will indirectly skip through all the insns
2376	     inbetween. We are also guaranteed that the value of insn
2377	     returned will be valid, as otherwise scan_region won't
2378	     return.  */
2379	  insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &n);
2380	}
2381    }
2382}
2383
2384/* Various hooks for the DWARF 2 __throw routine.  */
2385
2386/* Do any necessary initialization to access arbitrary stack frames.
2387   On the SPARC, this means flushing the register windows.  */
2388
2389void
2390expand_builtin_unwind_init ()
2391{
2392  /* Set this so all the registers get saved in our frame; we need to be
2393     able to copy the saved values for any registers from frames we unwind. */
2394  current_function_has_nonlocal_label = 1;
2395
2396#ifdef SETUP_FRAME_ADDRESSES
2397  SETUP_FRAME_ADDRESSES ();
2398#endif
2399}
2400
2401/* Given a value extracted from the return address register or stack slot,
2402   return the actual address encoded in that value.  */
2403
2404rtx
2405expand_builtin_extract_return_addr (addr_tree)
2406     tree addr_tree;
2407{
2408  rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
2409  return eh_outer_context (addr);
2410}
2411
2412/* Given an actual address in addr_tree, do any necessary encoding
2413   and return the value to be stored in the return address register or
2414   stack slot so the epilogue will return to that address.  */
2415
2416rtx
2417expand_builtin_frob_return_addr (addr_tree)
2418     tree addr_tree;
2419{
2420  rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
2421#ifdef RETURN_ADDR_OFFSET
2422  addr = plus_constant (addr, -RETURN_ADDR_OFFSET);
2423#endif
2424  return addr;
2425}
2426
2427/* Given an actual address in addr_tree, set the return address register up
2428   so the epilogue will return to that address.  If the return address is
2429   not in a register, do nothing.  */
2430
2431void
2432expand_builtin_set_return_addr_reg (addr_tree)
2433     tree addr_tree;
2434{
2435  rtx tmp;
2436  rtx ra = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
2437				       0, hard_frame_pointer_rtx);
2438
2439  if (GET_CODE (ra) != REG || REGNO (ra) >= FIRST_PSEUDO_REGISTER)
2440    return;
2441
2442  tmp = force_operand (expand_builtin_frob_return_addr (addr_tree), ra);
2443  if (tmp != ra)
2444    emit_move_insn (ra, tmp);
2445}
2446
2447/* Choose two registers for communication between the main body of
2448   __throw and the stub for adjusting the stack pointer.  The first register
2449   is used to pass the address of the exception handler; the second register
2450   is used to pass the stack pointer offset.
2451
2452   For register 1 we use the return value register for a void *.
2453   For register 2 we use the static chain register if it exists and is
2454     different from register 1, otherwise some arbitrary call-clobbered
2455     register.  */
2456
2457static void
2458eh_regs (r1, r2, outgoing)
2459     rtx *r1, *r2;
2460     int outgoing;
2461{
2462  rtx reg1, reg2;
2463
2464#ifdef FUNCTION_OUTGOING_VALUE
2465  if (outgoing)
2466    reg1 = FUNCTION_OUTGOING_VALUE (build_pointer_type (void_type_node),
2467				    current_function_decl);
2468  else
2469#endif
2470    reg1 = FUNCTION_VALUE (build_pointer_type (void_type_node),
2471			   current_function_decl);
2472
2473#ifdef STATIC_CHAIN_REGNUM
2474  if (outgoing)
2475    reg2 = static_chain_incoming_rtx;
2476  else
2477    reg2 = static_chain_rtx;
2478  if (REGNO (reg2) == REGNO (reg1))
2479#endif /* STATIC_CHAIN_REGNUM */
2480    reg2 = NULL_RTX;
2481
2482  if (reg2 == NULL_RTX)
2483    {
2484      int i;
2485      for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
2486	if (call_used_regs[i] && ! fixed_regs[i] && i != REGNO (reg1))
2487	  {
2488	    reg2 = gen_rtx_REG (Pmode, i);
2489	    break;
2490	  }
2491
2492      if (reg2 == NULL_RTX)
2493	abort ();
2494    }
2495
2496  *r1 = reg1;
2497  *r2 = reg2;
2498}
2499
2500
2501/* Retrieve the register which contains the pointer to the eh_context
2502   structure set the __throw. */
2503
2504rtx
2505get_reg_for_handler ()
2506{
2507  rtx reg1;
2508  reg1 = FUNCTION_VALUE (build_pointer_type (void_type_node),
2509			   current_function_decl);
2510  return reg1;
2511}
2512
2513
2514/* Emit inside of __throw a stub which adjusts the stack pointer and jumps
2515   to the exception handler.  __throw will set up the necessary values
2516   and then return to the stub.  */
2517
2518rtx
2519expand_builtin_eh_stub_old ()
2520{
2521  rtx stub_start = gen_label_rtx ();
2522  rtx after_stub = gen_label_rtx ();
2523  rtx handler, offset;
2524
2525  emit_jump (after_stub);
2526  emit_label (stub_start);
2527
2528  eh_regs (&handler, &offset, 0);
2529
2530  adjust_stack (offset);
2531  emit_indirect_jump (handler);
2532  emit_label (after_stub);
2533  return gen_rtx_LABEL_REF (Pmode, stub_start);
2534}
2535
2536rtx
2537expand_builtin_eh_stub ()
2538{
2539  rtx stub_start = gen_label_rtx ();
2540  rtx after_stub = gen_label_rtx ();
2541  rtx handler, offset;
2542  rtx temp;
2543
2544  emit_jump (after_stub);
2545  emit_label (stub_start);
2546
2547  eh_regs (&handler, &offset, 0);
2548
2549  adjust_stack (offset);
2550
2551  /* Handler is in fact a pointer to the _eh_context structure, we need
2552     to pick out the handler field (first element), and jump to there,
2553     leaving the pointer to _eh_conext in the same hardware register. */
2554
2555  temp = gen_rtx_MEM (Pmode, handler);
2556  MEM_IN_STRUCT_P (temp) = 1;
2557  RTX_UNCHANGING_P (temp) = 1;
2558  emit_move_insn (offset, temp);
2559  emit_insn (gen_rtx_USE (Pmode, handler));
2560
2561  emit_indirect_jump (offset);
2562
2563  emit_label (after_stub);
2564  return gen_rtx_LABEL_REF (Pmode, stub_start);
2565}
2566
2567/* Set up the registers for passing the handler address and stack offset
2568   to the stub above.  */
2569
2570void
2571expand_builtin_set_eh_regs (handler, offset)
2572     tree handler, offset;
2573{
2574  rtx reg1, reg2;
2575
2576  eh_regs (&reg1, &reg2, 1);
2577
2578  store_expr (offset,  reg2, 0);
2579  store_expr (handler, reg1, 0);
2580
2581  /* These will be used by the stub.  */
2582  emit_insn (gen_rtx_USE (VOIDmode, reg1));
2583  emit_insn (gen_rtx_USE (VOIDmode, reg2));
2584}
2585
2586
2587
2588/* This contains the code required to verify whether arbitrary instructions
2589   are in the same exception region. */
2590
2591static int *insn_eh_region = (int *)0;
2592static int maximum_uid;
2593
2594static void
2595set_insn_eh_region (first, region_num)
2596     rtx *first;
2597     int region_num;
2598{
2599  rtx insn;
2600  int rnum;
2601
2602  for (insn = *first; insn; insn = NEXT_INSN (insn))
2603    {
2604      if ((GET_CODE (insn) == NOTE) &&
2605                        (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG))
2606        {
2607          rnum = NOTE_BLOCK_NUMBER (insn);
2608          insn_eh_region[INSN_UID (insn)] =  rnum;
2609          insn = NEXT_INSN (insn);
2610          set_insn_eh_region (&insn, rnum);
2611          /* Upon return, insn points to the EH_REGION_END of nested region */
2612          continue;
2613        }
2614      insn_eh_region[INSN_UID (insn)] = region_num;
2615      if ((GET_CODE (insn) == NOTE) &&
2616            (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
2617        break;
2618    }
2619  *first = insn;
2620}
2621
2622/* Free the insn table, an make sure it cannot be used again. */
2623
2624void
2625free_insn_eh_region ()
2626{
2627  if (!doing_eh (0))
2628    return;
2629
2630  if (insn_eh_region)
2631    {
2632      free (insn_eh_region);
2633      insn_eh_region = (int *)0;
2634    }
2635}
2636
2637/* Initialize the table. max_uid must be calculated and handed into
2638   this routine. If it is unavailable, passing a value of 0 will
2639   cause this routine to calculate it as well. */
2640
2641void
2642init_insn_eh_region (first, max_uid)
2643     rtx first;
2644     int max_uid;
2645{
2646  rtx insn;
2647
2648  if (!doing_eh (0))
2649    return;
2650
2651  if (insn_eh_region)
2652    free_insn_eh_region();
2653
2654  if (max_uid == 0)
2655    for (insn = first; insn; insn = NEXT_INSN (insn))
2656      if (INSN_UID (insn) > max_uid)       /* find largest UID */
2657        max_uid = INSN_UID (insn);
2658
2659  maximum_uid = max_uid;
2660  insn_eh_region = (int *) malloc ((max_uid + 1) * sizeof (int));
2661  insn = first;
2662  set_insn_eh_region (&insn, 0);
2663}
2664
2665
2666/* Check whether 2 instructions are within the same region. */
2667
2668int
2669in_same_eh_region (insn1, insn2)
2670     rtx insn1, insn2;
2671{
2672  int ret, uid1, uid2;
2673
2674  /* If no exceptions, instructions are always in same region. */
2675  if (!doing_eh (0))
2676    return 1;
2677
2678  /* If the table isn't allocated, assume the worst. */
2679  if (!insn_eh_region)
2680    return 0;
2681
2682  uid1 = INSN_UID (insn1);
2683  uid2 = INSN_UID (insn2);
2684
2685  /* if instructions have been allocated beyond the end, either
2686     the table is out of date, or this is a late addition, or
2687     something... Assume the worst. */
2688  if (uid1 > maximum_uid || uid2 > maximum_uid)
2689    return 0;
2690
2691  ret = (insn_eh_region[uid1] == insn_eh_region[uid2]);
2692  return ret;
2693}
2694
2695