OSDN Git Service

(gen_lowpart_common): When converting a floating point value into an
[pf3gnuchains/gcc-fork.git] / gcc / except.c
1 /* Implements exception handling.
2    Copyright (C) 1989, 92-95, 1996 Free Software Foundation, Inc.
3    Contributed by Mike Stump <mrs@cygnus.com>.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, 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 assocated 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    It is appropriate to speak of the "context of a throw". This
47    context refers to the address where the exception is thrown from,
48    and is used to determine which exception region will handle the
49    exception.
50
51    Regions of code within a function can be marked such that if it
52    contains the context of a throw, control will be passed to a
53    designated "exception handler". These areas are known as "exception
54    regions".  Exception regions cannot overlap, but they can be nested
55    to any arbitrary depth. Also, exception regions cannot cross
56    function boundaries.
57
58    Each object file that is compiled with exception handling contains a
59    static array of exception handlers named __EXCEPTION_TABLE__. Each entry
60    contains the starting and ending addresses of the exception region,
61    and the address of the handler designated for that region.
62
63    At program startup each object file invokes a function named
64    __register_exceptions with the address of its local
65    __EXCEPTION_TABLE__. __register_exceptions is defined in libgcc2.c,
66    and is responsible for recording all of the exception regions into
67    one list (which is kept in a static variable named exception_table_list).
68
69    The function __throw () is actually responsible for doing the
70    throw. In the C++ frontend, __throw () is generated on a
71    per-object-file basis for each source file compiled with
72    -fexceptions. 
73
74    __throw () attempts to find the appropriate exception handler for the 
75    PC value stored in __eh_pc by calling __find_first_exception_table_match
76    (which is defined in libgcc2.c). If an appropriate handler is
77    found, __throw jumps directly to it.
78
79    If a handler for the address being thrown from can't be found,
80    __throw is responsible for unwinding the stack, determining the
81    address of the caller of the current function (which will be used
82    as the new context to throw from), and then searching for a handler
83    for the new context. __throw may also call abort () if it is unable
84    to unwind the stack, and can also call an external library function
85    named __terminate if it reaches the top of the stack without
86    finding an appropriate handler.
87
88    Note that some of the regions and handlers are implicitly
89    generated. The handlers for these regions perform necessary
90    cleanups (in C++ these cleanups are responsible for invoking
91    necessary object destructors) before rethrowing the exception to
92    the outer exception region.
93
94    Internal implementation details:
95
96    The start of an exception region is indicated by calling
97    expand_eh_region_start (). expand_eh_region_end (handler) is
98    subsequently invoked to end the region and to associate a handler
99    with the region. This is used to create a region that has an
100    associated cleanup routine for performing tasks like object
101    destruction.
102
103    To associate a user-defined handler with a block of statements, the
104    function expand_start_try_stmts () is used to mark the start of the
105    block of statements with which the handler is to be associated
106    (which is usually known as a "try block"). All statements that
107    appear afterwards will be associated with the try block.
108
109    A call to expand_start_all_catch () will mark the end of the try
110    block, and also marks the start of the "catch block" associated
111    with the try block. This catch block will only be invoked if an
112    exception is thrown through the try block. The instructions for the
113    catch block are kept as a separate sequence, and will be emitted at
114    the end of the function along with the handlers specified via
115    expand_eh_region_end (). The end of the catch block is marked with
116    expand_end_all_catch ().
117
118    Any data associated with the exception must currently be handled by
119    some external mechanism maintained in the frontend.  For example,
120    the C++ exception mechanism passes an arbitrary value along with
121    the exception, and this is handled in the C++ frontend by using a
122    global variable to hold the value.
123
124    Internally-generated exception regions are marked by calling
125    expand_eh_region_start () to mark the start of the region, and
126    expand_eh_region_end () is used to both designate the end of the
127    region and to associate a handler/cleanup with the region. These
128    functions generate the appropriate RTL sequences to mark the start
129    and end of the exception regions and ensure that an appropriate
130    exception region entry will be added to the exception region table.
131    expand_eh_region_end () also queues the provided handler to be
132    emitted at the end of the current function.
133
134    TARGET_EXPRs can also be used to designate exception regions. A
135    TARGET_EXPR gives an unwind-protect style interface commonly used
136    in functional languages such as LISP. The associated expression is
137    evaluated, and if it (or any of the functions that it calls) throws
138    an exception it is caught by the associated cleanup. The backend
139    also takes care of the details of associating an exception table
140    entry with the expression and generating the necessary code.
141
142    The generated RTL for an exception region includes
143    NOTE_INSN_EH_REGION_BEG and NOTE_INSN_EH_REGION_END notes that mark
144    the start and end of the exception region. A unique label is also
145    generated at the start of the exception region.
146
147    In the current implementation, an exception can only be thrown from
148    a function call (since the mechanism used to actually throw an
149    exception involves calling __throw).  If an exception region is
150    created but no function calls occur within that region, the region
151    can be safely optimized away since no exceptions can ever be caught
152    in that region.
153
154    Unwinding the stack:
155
156    The details of unwinding the stack to the next frame can be rather
157    complex. While in many cases a generic __unwind_function () routine
158    can be used by the generated exception handling code to do this, it
159    is often necessary to generate inline code to do the unwinding.
160
161    Whether or not these inlined unwinders are necessary is
162    target-specific.
163
164    By default, if the target-specific backend doesn't supply a
165    definition for __unwind_function (), inlined unwinders will be used
166    instead. The main tradeoff here is in text space utilization.
167    Obviously, if inline unwinders have to be generated repeatedly,
168    this uses more space than if a single routine is used.
169
170    The backend macro DOESNT_NEED_UNWINDER is used to conditionalize
171    whether or not per-function unwinders are needed. If DOESNT_NEED_UNWINDER
172    is defined and has a non-zero value, a per-function unwinder is
173    not emitted for the current function.
174
175    On some platforms it is possible that neither __unwind_function ()
176    nor inlined unwinders are available. For these platforms it is not
177    possible to throw through a function call, and abort () will be
178    invoked instead of performing the throw. */
179
180
181 #include "config.h"
182 #include <stdio.h>
183 #include "rtl.h"
184 #include "tree.h"
185 #include "flags.h"
186 #include "except.h"
187 #include "function.h"
188 #include "insn-flags.h"
189 #include "expr.h"
190 #include "insn-codes.h"
191 #include "regs.h"
192 #include "hard-reg-set.h"
193 #include "insn-config.h"
194 #include "recog.h"
195 #include "output.h"
196 #include "assert.h"
197
198 /* A list of labels used for exception handlers.  Created by
199    find_exception_handler_labels for the optimization passes.  */
200
201 rtx exception_handler_labels;
202
203 /* Nonzero means that __throw was invoked. 
204
205    This is used by the C++ frontend to know if code needs to be emitted
206    for __throw or not.  */
207
208 int throw_used;
209
210 /* A stack used for keeping track of the currectly active exception
211    handling region.  As each exception region is started, an entry
212    describing the region is pushed onto this stack.  The current
213    region can be found by looking at the top of the stack, and as we
214    exit regions, the corresponding entries are popped. 
215
216    Entries cannot overlap; they must be nested. So there is only one
217    entry at most that corresponds to the current instruction, and that
218    is the entry on the top of the stack.  */
219
220 struct eh_stack ehstack;
221
222 /* A queue used for tracking which exception regions have closed but
223    whose handlers have not yet been expanded. Regions are emitted in
224    groups in an attempt to improve paging performance.
225
226    As we exit a region, we enqueue a new entry. The entries are then
227    dequeued during expand_leftover_cleanups () and expand_start_all_catch (),
228
229    We should redo things so that we either take RTL for the handler,
230    or we expand the handler expressed as a tree immediately at region
231    end time.  */
232
233 struct eh_queue ehqueue;
234
235 /* Insns for all of the exception handlers for the current function.
236    They are currently emitted by the frontend code. */
237
238 rtx catch_clauses;
239
240 /* A TREE_CHAINed list of handlers for regions that are not yet
241    closed. The TREE_VALUE of each entry contains the handler for the
242    corresponding entry on the ehstack. */
243
244 static tree protect_list;
245
246 /* Stacks to keep track of various labels.  */
247
248 /* Keeps track of the label to resume to should one want to resume
249    normal control flow out of a handler (instead of, say, returning to
250    the caller of the current function or exiting the program).  Also
251    used as the context of a throw to rethrow an exception to the outer
252    exception region. */
253
254 struct label_node *caught_return_label_stack = NULL;
255
256 /* A random data area for the front end's own use.  */
257
258 struct label_node *false_label_stack = NULL;
259
260 /* The rtx and the tree for the saved PC value.  */
261
262 rtx eh_saved_pc_rtx;
263 tree eh_saved_pc;
264
265 rtx expand_builtin_return_addr  PROTO((enum built_in_function, int, rtx));
266 \f
267 /* Various support routines to manipulate the various data structures
268    used by the exception handling code.  */
269
270 /* Push a label entry onto the given STACK.  */
271
272 void
273 push_label_entry (stack, rlabel, tlabel)
274      struct label_node **stack;
275      rtx rlabel;
276      tree tlabel;
277 {
278   struct label_node *newnode
279     = (struct label_node *) xmalloc (sizeof (struct label_node));
280
281   if (rlabel)
282     newnode->u.rlabel = rlabel;
283   else
284     newnode->u.tlabel = tlabel;
285   newnode->chain = *stack;
286   *stack = newnode;
287 }
288
289 /* Pop a label entry from the given STACK.  */
290
291 rtx
292 pop_label_entry (stack)
293      struct label_node **stack;
294 {
295   rtx label;
296   struct label_node *tempnode;
297
298   if (! *stack)
299     return NULL_RTX;
300
301   tempnode = *stack;
302   label = tempnode->u.rlabel;
303   *stack = (*stack)->chain;
304   free (tempnode);
305
306   return label;
307 }
308
309 /* Return the top element of the given STACK.  */
310
311 tree
312 top_label_entry (stack)
313      struct label_node **stack;
314 {
315   if (! *stack)
316     return NULL_TREE;
317
318   return (*stack)->u.tlabel;
319 }
320
321 /* Make a copy of ENTRY using xmalloc to allocate the space.  */
322
323 static struct eh_entry *
324 copy_eh_entry (entry)
325      struct eh_entry *entry;
326 {
327   struct eh_entry *newentry;
328
329   newentry = (struct eh_entry *) xmalloc (sizeof (struct eh_entry));
330   bcopy ((char *) entry, (char *) newentry, sizeof (struct eh_entry));
331
332   return newentry;
333 }
334
335 /* Push a new eh_node entry onto STACK, and return the start label for
336    the entry. */
337
338 static rtx
339 push_eh_entry (stack)
340      struct eh_stack *stack;
341 {
342   struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
343   struct eh_entry *entry = (struct eh_entry *) xmalloc (sizeof (struct eh_entry));
344
345   entry->start_label = gen_label_rtx ();
346   entry->end_label = gen_label_rtx ();
347   entry->exception_handler_label = gen_label_rtx ();
348   entry->finalization = NULL_TREE;
349
350   node->entry = entry;
351   node->chain = stack->top;
352   stack->top = node;
353
354   return entry->start_label;
355 }
356
357 /* Pop an entry from the given STACK.  */
358
359 static struct eh_entry *
360 pop_eh_entry (stack)
361      struct eh_stack *stack;
362 {
363   struct eh_node *tempnode;
364   struct eh_entry *tempentry;
365   
366   tempnode = stack->top;
367   tempentry = tempnode->entry;
368   stack->top = stack->top->chain;
369   free (tempnode);
370
371   return tempentry;
372 }
373
374 /* Enqueue an ENTRY onto the given QUEUE.  */
375
376 static void
377 enqueue_eh_entry (queue, entry)
378      struct eh_queue *queue;
379      struct eh_entry *entry;
380 {
381   struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
382
383   node->entry = entry;
384   node->chain = NULL;
385
386   if (queue->head == NULL)
387     {
388       queue->head = node;
389     }
390   else
391     {
392       queue->tail->chain = node;
393     }
394   queue->tail = node;
395 }
396
397 /* Dequeue an entry from the given QUEUE.  */
398
399 static struct eh_entry *
400 dequeue_eh_entry (queue)
401      struct eh_queue *queue;
402 {
403   struct eh_node *tempnode;
404   struct eh_entry *tempentry;
405
406   if (queue->head == NULL)
407     return NULL;
408
409   tempnode = queue->head;
410   queue->head = queue->head->chain;
411
412   tempentry = tempnode->entry;
413   free (tempnode);
414
415   return tempentry;
416 }
417 \f
418 /* Routine to see if exception exception handling is turned on.
419    DO_WARN is non-zero if we want to inform the user that exception
420    handling is turned off. 
421
422    This is used to ensure that -fexceptions has been specified if the
423    compiler tries to use any exception-specific functions. */
424
425 int
426 doing_eh (do_warn)
427      int do_warn;
428 {
429   if (! flag_exceptions)
430     {
431       static int warned = 0;
432       if (! warned && do_warn)
433         {
434           error ("exception handling disabled, use -fexceptions to enable");
435           warned = 1;
436         }
437       return 0;
438     }
439   return 1;
440 }
441
442 /* Given a return address in ADDR, determine the address we should use
443    to find the corresponding EH region. */
444
445 rtx
446 eh_outer_context (addr)
447      rtx addr;
448 {
449   /* First mask out any unwanted bits.  */
450 #ifdef MASK_RETURN_ADDR
451   emit_insn (gen_rtx (SET, Pmode,
452                       addr,
453                       gen_rtx (AND, Pmode,
454                                addr, MASK_RETURN_ADDR)));
455 #endif
456
457   /* Then subtract out enough to get into the appropriate region.  If
458      this is defined, assume we don't need to subtract anything as it
459      is already within the correct region.  */
460 #if ! defined (RETURN_ADDR_OFFSET)
461   addr = plus_constant (addr, -1);
462 #endif
463
464   return addr;
465 }
466
467 /* Start a new exception region and push the HANDLER for the region
468    onto protect_list. All of the regions created with add_partial_entry
469    will be ended when end_protect_partials () is invoked. */
470
471 void
472 add_partial_entry (handler)
473      tree handler;
474 {
475   expand_eh_region_start ();
476
477   /* Make sure the entry is on the correct obstack. */
478   push_obstacks_nochange ();
479   resume_temporary_allocation ();
480   protect_list = tree_cons (NULL_TREE, handler, protect_list);
481   pop_obstacks ();
482 }
483
484 /* Output a note marking the start of an exception handling region.
485    All instructions emitted after this point are considered to be part
486    of the region until expand_eh_region_end () is invoked. */
487
488 void
489 expand_eh_region_start ()
490 {
491   rtx note;
492
493   /* This is the old code.  */
494   if (! doing_eh (0))
495     return;
496
497 #if 0
498   /* Maybe do this to prevent jumping in and so on...  */
499   pushlevel (0);
500 #endif
501
502   note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_BEG);
503   emit_label (push_eh_entry (&ehstack));
504   NOTE_BLOCK_NUMBER (note)
505     = CODE_LABEL_NUMBER (ehstack.top->entry->exception_handler_label);
506 }
507
508 /* Output a note marking the end of the exception handling region on
509    the top of ehstack.
510
511    HANDLER is either the cleanup for the exception region, or if we're
512    marking the end of a try block, HANDLER is integer_zero_node.
513
514    HANDLER will be transformed to rtl when expand_leftover_cleanups ()
515    is invoked. */
516
517 void
518 expand_eh_region_end (handler)
519      tree handler;
520 {
521   rtx note;
522
523   struct eh_entry *entry;
524
525   if (! doing_eh (0))
526     return;
527
528   entry = pop_eh_entry (&ehstack);
529
530   note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END);
531   NOTE_BLOCK_NUMBER (note) = CODE_LABEL_NUMBER (entry->exception_handler_label);
532
533   /* Emit a label marking the end of this exception region. */
534   emit_label (entry->end_label);
535
536   /* Put in something that takes up space, as otherwise the end
537      address for this EH region could have the exact same address as
538      its outer region. This would cause us to miss the fact that
539      resuming exception handling with this PC value would be inside
540      the outer region.  */
541   emit_insn (gen_nop ());
542
543   entry->finalization = handler;
544
545   enqueue_eh_entry (&ehqueue, entry);
546
547 #if 0
548   /* Maybe do this to prevent jumping in and so on...  */
549   poplevel (1, 0, 0);
550 #endif
551 }
552
553 /* Emit a call to __throw and note that we threw something, so we know
554    we need to generate the necessary code for __throw.  
555
556    Before invoking throw, the __eh_pc variable must have been set up
557    to contain the PC being thrown from. This address is used by
558    __throw () to determine which exception region (if any) is
559    responsible for handling the exception. */
560
561 static void
562 emit_throw ()
563 {
564 #ifdef JUMP_TO_THROW
565   emit_indirect_jump (throw_libfunc);
566 #else
567   SYMBOL_REF_USED (throw_libfunc) = 1;
568   emit_library_call (throw_libfunc, 0, VOIDmode, 0);
569 #endif
570   throw_used = 1;
571   emit_barrier ();
572 }
573
574 /* An internal throw with an indirect CONTEXT we want to throw from.
575    CONTEXT evaluates to the context of the throw. */
576
577 static void
578 expand_internal_throw_indirect (context)
579      rtx context;
580 {
581   assemble_external (eh_saved_pc);
582   emit_move_insn (eh_saved_pc_rtx, context);
583   emit_throw ();
584 }
585
586 /* An internal throw with a direct CONTEXT we want to throw from.
587    CONTEXT must be a label; its address will be used as the context of
588    the throw. */
589
590 void
591 expand_internal_throw (context)
592      rtx context;
593 {
594   expand_internal_throw_indirect (gen_rtx (LABEL_REF, Pmode, context));
595 }
596
597 /* Called from expand_exception_blocks and expand_end_catch_block to
598    emit any pending handlers/cleanups queued from expand_eh_region_end (). */
599
600 void
601 expand_leftover_cleanups ()
602 {
603   struct eh_entry *entry;
604
605   while ((entry = dequeue_eh_entry (&ehqueue)) != 0)
606     {
607       rtx prev;
608
609       /* A leftover try block. Shouldn't be one here.  */
610       if (entry->finalization == integer_zero_node)
611         abort ();
612
613       /* Output the label for the start of the exception handler. */
614       emit_label (entry->exception_handler_label);
615
616       /* And now generate the insns for the handler. */
617       expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
618
619       prev = get_last_insn ();
620       if (! (prev && GET_CODE (prev) == BARRIER))
621         {
622           /* The below can be optimized away, and we could just fall into the
623              next EH handler, if we are certain they are nested.  */
624           /* Emit code to throw to the outer context if we fall off
625              the end of the handler.  */
626           expand_internal_throw (entry->end_label);
627         }
628
629       free (entry);
630     }
631 }
632
633 /* Called at the start of a block of try statements. */
634 void
635 expand_start_try_stmts ()
636 {
637   if (! doing_eh (1))
638     return;
639
640   expand_eh_region_start ();
641 }
642
643 /* Generate RTL for the start of a group of catch clauses. 
644
645    It is responsible for starting a new instruction sequence for the
646    instructions in the catch block, and expanding the handlers for the
647    internally-generated exception regions nested within the try block
648    corresponding to this catch block. */
649
650 void
651 expand_start_all_catch ()
652 {
653   struct eh_entry *entry;
654   tree label;
655
656   if (! doing_eh (1))
657     return;
658
659   /* End the try block. */
660   expand_eh_region_end (integer_zero_node);
661
662   emit_line_note (input_filename, lineno);
663   label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
664
665   /* The label for the exception handling block that we will save.
666      This is Lresume in the documention.  */
667   expand_label (label);
668   
669   /* Put in something that takes up space, as otherwise the end
670      address for the EH region could have the exact same address as
671      the outer region, causing us to miss the fact that resuming
672      exception handling with this PC value would be inside the outer
673      region.  */
674   emit_insn (gen_nop ());
675
676   /* Push the label that points to where normal flow is resumed onto
677      the top of the label stack. */
678   push_label_entry (&caught_return_label_stack, NULL_RTX, label);
679
680   /* Start a new sequence for all the catch blocks.  We will add this
681      to the global sequence catch_clauses when we have completed all
682      the handlers in this handler-seq.  */
683   start_sequence ();
684
685   while (1)
686     {
687       rtx prev;
688
689       entry = dequeue_eh_entry (&ehqueue);
690       /* Emit the label for the exception handler for this region, and
691          expand the code for the handler. 
692
693          Note that a catch region is handled as a side-effect here;
694          for a try block, entry->finalization will contain
695          integer_zero_node, so no code will be generated in the
696          expand_expr call below. But, the label for the handler will
697          still be emitted, so any code emitted after this point will
698          end up being the handler. */
699       emit_label (entry->exception_handler_label);
700       expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
701
702       /* When we get down to the matching entry for this try block, stop.  */
703       if (entry->finalization == integer_zero_node)
704         {
705           /* Don't forget to free this entry. */
706           free (entry);
707           break;
708         }
709
710       prev = get_last_insn ();
711       if (prev == NULL || GET_CODE (prev) != BARRIER)
712         {
713           /* Code to throw out to outer context when we fall off end
714              of the handler. We can't do this here for catch blocks,
715              so it's done in expand_end_all_catch () instead.
716
717              The below can be optimized away (and we could just fall
718              into the next EH handler) if we are certain they are
719              nested.  */
720
721           expand_internal_throw (entry->end_label);
722         }
723       free (entry);
724     }
725 }
726
727 /* Finish up the catch block.  At this point all the insns for the
728    catch clauses have already been generated, so we only have to add
729    them to the catch_clauses list. We also want to make sure that if
730    we fall off the end of the catch clauses that we rethrow to the
731    outer EH region. */
732
733 void
734 expand_end_all_catch ()
735 {
736   rtx new_catch_clause;
737
738   if (! doing_eh (1))
739     return;
740
741   /* Code to throw out to outer context, if we fall off end of catch
742      handlers.  This is rethrow (Lresume, same id, same obj) in the
743      documentation. We use Lresume because we know that it will throw
744      to the correct context.
745
746      In other words, if the catch handler doesn't exit or return, we
747      do a "throw" (using the address of Lresume as the point being
748      thrown from) so that the outer EH region can then try to process
749      the exception. */
750
751   expand_internal_throw (DECL_RTL (top_label_entry (&caught_return_label_stack)));
752
753   /* Now we have the complete catch sequence.  */
754   new_catch_clause = get_insns ();
755   end_sequence ();
756   
757   /* This level of catch blocks is done, so set up the successful
758      catch jump label for the next layer of catch blocks.  */
759   pop_label_entry (&caught_return_label_stack);
760
761   /* Add the new sequence of catches to the main one for this function.  */
762   push_to_sequence (catch_clauses);
763   emit_insns (new_catch_clause);
764   catch_clauses = get_insns ();
765   end_sequence ();
766   
767   /* Here we fall through into the continuation code.  */
768 }
769
770 /* End all the pending exception regions on protect_list. The handlers
771    will be emitted when expand_leftover_cleanups () is invoked. */
772
773 void
774 end_protect_partials ()
775 {
776   while (protect_list)
777     {
778       expand_eh_region_end (TREE_VALUE (protect_list));
779       protect_list = TREE_CHAIN (protect_list);
780     }
781 }
782 \f
783 /* The exception table that we build that is used for looking up and
784    dispatching exceptions, the current number of entries, and its
785    maximum size before we have to extend it. 
786
787    The number in eh_table is the code label number of the exception
788    handler for the region. This is added by add_eh_table_entry () and
789    used by output_exception_table_entry (). */
790
791 static int *eh_table;
792 static int eh_table_size;
793 static int eh_table_max_size;
794
795 /* Note the need for an exception table entry for region N.  If we
796    don't need to output an explicit exception table, avoid all of the
797    extra work.
798
799    Called from final_scan_insn when a NOTE_INSN_EH_REGION_BEG is seen.
800    N is the NOTE_BLOCK_NUMBER of the note, which comes from the code
801    label number of the exception handler for the region. */
802
803 void
804 add_eh_table_entry (n)
805      int n;
806 {
807 #ifndef OMIT_EH_TABLE
808   if (eh_table_size >= eh_table_max_size)
809     {
810       if (eh_table)
811         {
812           eh_table_max_size += eh_table_max_size>>1;
813
814           if (eh_table_max_size < 0)
815             abort ();
816
817           if ((eh_table = (int *) realloc (eh_table,
818                                            eh_table_max_size * sizeof (int)))
819               == 0)
820             fatal ("virtual memory exhausted");
821         }
822       else
823         {
824           eh_table_max_size = 252;
825           eh_table = (int *) xmalloc (eh_table_max_size * sizeof (int));
826         }
827     }
828   eh_table[eh_table_size++] = n;
829 #endif
830 }
831
832 /* Return a non-zero value if we need to output an exception table.
833
834    On some platforms, we don't have to output a table explicitly.
835    This routine doesn't mean we don't have one.  */
836
837 int
838 exception_table_p ()
839 {
840   if (eh_table)
841     return 1;
842
843   return 0;
844 }
845
846 /* Output the entry of the exception table corresponding to to the
847    exception region numbered N to file FILE. 
848
849    N is the code label number corresponding to the handler of the
850    region. */
851
852 static void
853 output_exception_table_entry (file, n)
854      FILE *file;
855      int n;
856 {
857   char buf[256];
858   rtx sym;
859
860   ASM_GENERATE_INTERNAL_LABEL (buf, "LEHB", n);
861   sym = gen_rtx (SYMBOL_REF, Pmode, buf);
862   assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
863
864   ASM_GENERATE_INTERNAL_LABEL (buf, "LEHE", n);
865   sym = gen_rtx (SYMBOL_REF, Pmode, buf);
866   assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
867
868   ASM_GENERATE_INTERNAL_LABEL (buf, "L", n);
869   sym = gen_rtx (SYMBOL_REF, Pmode, buf);
870   assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
871
872   putc ('\n', file);            /* blank line */
873 }
874
875 /* Output the exception table if we have and need one. */
876
877 void
878 output_exception_table ()
879 {
880   int i;
881   extern FILE *asm_out_file;
882
883   if (! doing_eh (0))
884     return;
885
886   exception_section ();
887
888   /* Beginning marker for table.  */
889   assemble_align (GET_MODE_ALIGNMENT (ptr_mode));
890   assemble_label ("__EXCEPTION_TABLE__");
891
892   assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
893   assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
894   assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
895   putc ('\n', asm_out_file);            /* blank line */
896
897   for (i = 0; i < eh_table_size; ++i)
898     output_exception_table_entry (asm_out_file, eh_table[i]);
899
900   free (eh_table);
901
902   /* Ending marker for table.  */
903   assemble_label ("__EXCEPTION_END__");
904   assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
905   assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
906   assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
907   putc ('\n', asm_out_file);            /* blank line */
908 }
909
910 /* Generate code to initialize the exception table at program startup
911    time.  */
912
913 void
914 register_exception_table ()
915 {
916   emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__register_exceptions"), 0,
917                      VOIDmode, 1,
918                      gen_rtx (SYMBOL_REF, Pmode, "__EXCEPTION_TABLE__"),
919                      Pmode);
920 }
921 \f
922 /* Emit the RTL for the start of the per-function unwinder for the
923    current function. See emit_unwinder () for further information.
924
925    DOESNT_NEED_UNWINDER is a target-specific macro that determines if
926    the current function actually needs a per-function unwinder or not.
927    By default, all functions need one. */
928
929 void
930 start_eh_unwinder ()
931 {
932 #ifdef DOESNT_NEED_UNWINDER
933   if (DOESNT_NEED_UNWINDER)
934     return;
935 #endif
936
937   expand_eh_region_start ();
938 }
939
940 /* Emit insns for the end of the per-function unwinder for the
941    current function.  */
942
943 void
944 end_eh_unwinder ()
945 {
946   tree expr;
947   rtx return_val_rtx, ret_val, label, end, insns;
948
949   if (! doing_eh (0))
950     return;
951
952 #ifdef DOESNT_NEED_UNWINDER
953   if (DOESNT_NEED_UNWINDER)
954     return;
955 #endif
956
957   assemble_external (eh_saved_pc);
958
959   expr = make_node (RTL_EXPR);
960   TREE_TYPE (expr) = void_type_node;
961   RTL_EXPR_RTL (expr) = const0_rtx;
962   TREE_SIDE_EFFECTS (expr) = 1;
963   start_sequence_for_rtl_expr (expr);
964
965   /* ret_val will contain the address of the code where the call
966      to the current function occurred. */
967   ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
968                                         0, hard_frame_pointer_rtx);
969   return_val_rtx = copy_to_reg (ret_val);
970
971   /* Get the address we need to use to determine what exception
972      handler should be invoked, and store it in __eh_pc. */
973   return_val_rtx = eh_outer_context (return_val_rtx);
974   emit_move_insn (eh_saved_pc_rtx, return_val_rtx);
975   
976   /* Either set things up so we do a return directly to __throw, or
977      we return here instead. */
978 #ifdef JUMP_TO_THROW
979   emit_move_insn (ret_val, throw_libfunc);
980 #else
981   label = gen_label_rtx ();
982   emit_move_insn (ret_val, gen_rtx (LABEL_REF, Pmode, label));
983 #endif
984
985 #ifdef RETURN_ADDR_OFFSET
986   return_val_rtx = plus_constant (ret_val, -RETURN_ADDR_OFFSET);
987   if (return_val_rtx != ret_val)
988     emit_move_insn (ret_val, return_val_rtx);
989 #endif
990   
991   end = gen_label_rtx ();
992   emit_jump (end);  
993
994   RTL_EXPR_SEQUENCE (expr) = get_insns ();
995   end_sequence ();
996   expand_eh_region_end (expr);
997
998   emit_jump (end);
999
1000 #ifndef JUMP_TO_THROW
1001   emit_label (label);
1002   emit_throw ();
1003 #endif
1004   
1005   expand_leftover_cleanups ();
1006
1007   emit_label (end);
1008 }
1009
1010 /* If necessary, emit insns for the per function unwinder for the
1011    current function.  Called after all the code that needs unwind
1012    protection is output.  
1013
1014    The unwinder takes care of catching any exceptions that have not
1015    been previously caught within the function, unwinding the stack to
1016    the next frame, and rethrowing using the address of the current
1017    function's caller as the context of the throw.
1018
1019    On some platforms __throw can do this by itself (or with the help
1020    of __unwind_function) so the per-function unwinder is
1021    unnecessary.
1022   
1023    We cannot place the unwinder into the function until after we know
1024    we are done inlining, as we don't want to have more than one
1025    unwinder per non-inlined function.  */
1026
1027 void
1028 emit_unwinder ()
1029 {
1030   rtx insns, insn;
1031
1032   start_sequence ();
1033   start_eh_unwinder ();
1034   insns = get_insns ();
1035   end_sequence ();
1036
1037   /* We place the start of the exception region associated with the
1038      per function unwinder at the top of the function.  */
1039   if (insns)
1040     emit_insns_after (insns, get_insns ());
1041
1042   start_sequence ();
1043   end_eh_unwinder ();
1044   insns = get_insns ();
1045   end_sequence ();
1046
1047   /* And we place the end of the exception region before the USE and
1048      CLOBBER insns that may come at the end of the function.  */
1049   if (insns == 0)
1050     return;
1051
1052   insn = get_last_insn ();
1053   while (GET_CODE (insn) == NOTE
1054          || (GET_CODE (insn) == INSN
1055              && (GET_CODE (PATTERN (insn)) == USE
1056                  || GET_CODE (PATTERN (insn)) == CLOBBER)))
1057     insn = PREV_INSN (insn);
1058
1059   if (GET_CODE (insn) == CODE_LABEL
1060       && GET_CODE (PREV_INSN (insn)) == BARRIER)
1061     {
1062       insn = PREV_INSN (insn);
1063     }
1064   else
1065     {
1066       rtx label = gen_label_rtx ();
1067       emit_label_after (label, insn);
1068       insn = emit_jump_insn_after (gen_jump (label), insn);
1069       insn = emit_barrier_after (insn);
1070     }
1071     
1072   emit_insns_after (insns, insn);
1073 }
1074
1075 /* Scan the current insns and build a list of handler labels. The
1076    resulting list is placed in the global variable exception_handler_labels.
1077
1078    It is called after the last exception handling region is added to
1079    the current function (when the rtl is almost all built for the
1080    current function) and before the jump optimization pass.  */
1081
1082 void
1083 find_exception_handler_labels ()
1084 {
1085   rtx insn;
1086   int max_labelno = max_label_num ();
1087   int min_labelno = get_first_label_num ();
1088   rtx *labels;
1089
1090   exception_handler_labels = NULL_RTX;
1091
1092   /* If we aren't doing exception handling, there isn't much to check.  */
1093   if (! doing_eh (0))
1094     return;
1095
1096   /* Generate a handy reference to each label.  */
1097
1098   labels = (rtx *) alloca ((max_labelno - min_labelno) * sizeof (rtx));
1099
1100   /* Eeeeeeew. */
1101   labels -= min_labelno;
1102
1103   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1104     {
1105       if (GET_CODE (insn) == CODE_LABEL)
1106         if (CODE_LABEL_NUMBER (insn) >= min_labelno
1107             && CODE_LABEL_NUMBER (insn) < max_labelno)
1108           labels[CODE_LABEL_NUMBER (insn)] = insn;
1109     }
1110
1111   /* For each start of a region, add its label to the list.  */
1112
1113   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1114     {
1115       if (GET_CODE (insn) == NOTE
1116           && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
1117         {
1118           rtx label = NULL_RTX;
1119
1120           if (NOTE_BLOCK_NUMBER (insn) >= min_labelno
1121               && NOTE_BLOCK_NUMBER (insn) < max_labelno)
1122             {
1123               label = labels[NOTE_BLOCK_NUMBER (insn)];
1124
1125               if (label)
1126                 exception_handler_labels
1127                   = gen_rtx (EXPR_LIST, VOIDmode,
1128                              label, exception_handler_labels);
1129               else
1130                 warning ("didn't find handler for EH region %d",
1131                          NOTE_BLOCK_NUMBER (insn));
1132             }
1133           else
1134             warning ("mismatched EH region %d", NOTE_BLOCK_NUMBER (insn));
1135         }
1136     }
1137 }
1138
1139 /* Perform sanity checking on the exception_handler_labels list.
1140
1141    Can be called after find_exception_handler_labels is called to
1142    build the list of exception handlers for the current function and
1143    before we finish processing the current function.  */
1144
1145 void
1146 check_exception_handler_labels ()
1147 {
1148   rtx insn, handler;
1149
1150   /* If we aren't doing exception handling, there isn't much to check.  */
1151   if (! doing_eh (0))
1152     return;
1153
1154   /* Ensure that the CODE_LABEL_NUMBER for the CODE_LABEL entry point
1155      in each handler corresponds to the CODE_LABEL_NUMBER of the
1156      handler. */
1157
1158   for (handler = exception_handler_labels;
1159        handler;
1160        handler = XEXP (handler, 1))
1161     {
1162       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1163         {
1164           if (GET_CODE (insn) == CODE_LABEL)
1165             {
1166               if (CODE_LABEL_NUMBER (insn)
1167                   == CODE_LABEL_NUMBER (XEXP (handler, 0)))
1168                 {
1169                   if (insn != XEXP (handler, 0))
1170                     warning ("mismatched handler %d",
1171                              CODE_LABEL_NUMBER (insn));
1172                   break;
1173                 }
1174             }
1175         }
1176       if (insn == NULL_RTX)
1177         warning ("handler not found %d",
1178                  CODE_LABEL_NUMBER (XEXP (handler, 0)));
1179     }
1180
1181   /* Now go through and make sure that for each region there is a
1182      corresponding label.  */
1183   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1184     {
1185       if (GET_CODE (insn) == NOTE
1186           && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG ||
1187               NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
1188         {
1189           for (handler = exception_handler_labels;
1190                handler;
1191                handler = XEXP (handler, 1))
1192             {
1193               if (CODE_LABEL_NUMBER (XEXP (handler, 0))
1194                   == NOTE_BLOCK_NUMBER (insn))
1195                 break;
1196             }
1197           if (handler == NULL_RTX)
1198             warning ("region exists, no handler %d",
1199                      NOTE_BLOCK_NUMBER (insn));
1200         }
1201     }
1202 }
1203 \f
1204 /* This group of functions initializes the exception handling data
1205    structures at the start of the compilation, initializes the data
1206    structures at the start of a function, and saves and restores the
1207    exception handling data structures for the start/end of a nested
1208    function.  */
1209
1210 /* Toplevel initialization for EH things.  */ 
1211
1212 void
1213 init_eh ()
1214 {
1215   /* Generate rtl to reference the variable in which the PC of the
1216      current context is saved. */
1217   tree type = build_pointer_type (make_node (VOID_TYPE));
1218
1219   eh_saved_pc = build_decl (VAR_DECL, get_identifier ("__eh_pc"), type);
1220   DECL_EXTERNAL (eh_saved_pc) = 1;
1221   TREE_PUBLIC (eh_saved_pc) = 1;
1222   make_decl_rtl (eh_saved_pc, NULL_PTR, 1);
1223   eh_saved_pc_rtx = DECL_RTL (eh_saved_pc);
1224 }
1225
1226 /* Initialize the per-function EH information. */
1227
1228 void
1229 init_eh_for_function ()
1230 {
1231   ehstack.top = 0;
1232   ehqueue.head = ehqueue.tail = 0;
1233   catch_clauses = NULL_RTX;
1234   false_label_stack = 0;
1235   caught_return_label_stack = 0;
1236   protect_list = NULL_TREE;
1237 }
1238
1239 /* Save some of the per-function EH info into the save area denoted by
1240    P. 
1241
1242    This is currently called from save_stmt_status (). */
1243
1244 void
1245 save_eh_status (p)
1246      struct function *p;
1247 {
1248   assert (p != NULL);
1249
1250   p->ehstack = ehstack;
1251   p->ehqueue = ehqueue;
1252   p->catch_clauses = catch_clauses;
1253   p->false_label_stack = false_label_stack;
1254   p->caught_return_label_stack = caught_return_label_stack;
1255   p->protect_list = protect_list;
1256
1257   init_eh ();
1258 }
1259
1260 /* Restore the per-function EH info saved into the area denoted by P.  
1261
1262    This is currently called from restore_stmt_status. */
1263
1264 void
1265 restore_eh_status (p)
1266      struct function *p;
1267 {
1268   assert (p != NULL);
1269
1270   protect_list = p->protect_list;
1271   caught_return_label_stack = p->caught_return_label_stack;
1272   false_label_stack = p->false_label_stack;
1273   catch_clauses = p->catch_clauses;
1274   ehqueue = p->ehqueue;
1275   ehstack = p->ehstack;
1276 }
1277 \f
1278 /* This section is for the exception handling specific optimization
1279    pass.  First are the internal routines, and then the main
1280    optimization pass.  */
1281
1282 /* Determine if the given INSN can throw an exception.  */
1283
1284 static int
1285 can_throw (insn)
1286      rtx insn;
1287 {
1288   /* Calls can always potentially throw exceptions. */
1289   if (GET_CODE (insn) == CALL_INSN)
1290     return 1;
1291
1292 #ifdef ASYNCH_EXCEPTIONS
1293   /* If we wanted asynchronous exceptions, then everything but NOTEs
1294      and CODE_LABELs could throw. */
1295   if (GET_CODE (insn) != NOTE && GET_CODE (insn) != CODE_LABEL)
1296     return 1;
1297 #endif
1298
1299   return 0;
1300 }
1301
1302 /* Scan a exception region looking for the matching end and then
1303    remove it if possible. INSN is the start of the region, N is the
1304    region number, and DELETE_OUTER is to note if anything in this
1305    region can throw.
1306
1307    Regions are removed if they cannot possibly catch an exception.
1308    This is determined by invoking can_throw () on each insn within the
1309    region; if can_throw returns true for any of the instructions, the
1310    region can catch an exception, since there is an insn within the
1311    region that is capable of throwing an exception.
1312
1313    Returns the NOTE_INSN_EH_REGION_END corresponding to this region, or
1314    calls abort () if it can't find one.
1315
1316    Can abort if INSN is not a NOTE_INSN_EH_REGION_BEGIN, or if N doesn't
1317    correspond to the region number, or if DELETE_OUTER is NULL. */
1318
1319 static rtx
1320 scan_region (insn, n, delete_outer)
1321      rtx insn;
1322      int n;
1323      int *delete_outer;
1324 {
1325   rtx start = insn;
1326
1327   /* Assume we can delete the region.  */
1328   int delete = 1;
1329
1330   assert (insn != NULL_RTX
1331           && GET_CODE (insn) == NOTE
1332           && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
1333           && NOTE_BLOCK_NUMBER (insn) == n
1334           && delete_outer != NULL);
1335
1336   insn = NEXT_INSN (insn);
1337
1338   /* Look for the matching end.  */
1339   while (! (GET_CODE (insn) == NOTE
1340             && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
1341     {
1342       /* If anything can throw, we can't remove the region.  */
1343       if (delete && can_throw (insn))
1344         {
1345           delete = 0;
1346         }
1347
1348       /* Watch out for and handle nested regions.  */
1349       if (GET_CODE (insn) == NOTE
1350           && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
1351         {
1352           insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &delete);
1353         }
1354
1355       insn = NEXT_INSN (insn);
1356     }
1357
1358   /* The _BEG/_END NOTEs must match and nest.  */
1359   if (NOTE_BLOCK_NUMBER (insn) != n)
1360     abort ();
1361
1362   /* If anything in this exception region can throw, we can throw.  */
1363   if (! delete)
1364     *delete_outer = 0;
1365   else
1366     {
1367       /* Delete the start and end of the region.  */
1368       delete_insn (start);
1369       delete_insn (insn);
1370
1371       /* Only do this part if we have built the exception handler
1372          labels.  */
1373       if (exception_handler_labels)
1374         {
1375           rtx x, *prev = &exception_handler_labels;
1376
1377           /* Find it in the list of handlers.  */
1378           for (x = exception_handler_labels; x; x = XEXP (x, 1))
1379             {
1380               rtx label = XEXP (x, 0);
1381               if (CODE_LABEL_NUMBER (label) == n)
1382                 {
1383                   /* If we are the last reference to the handler,
1384                      delete it.  */
1385                   if (--LABEL_NUSES (label) == 0)
1386                     delete_insn (label);
1387
1388                   if (optimize)
1389                     {
1390                       /* Remove it from the list of exception handler
1391                          labels, if we are optimizing.  If we are not, then
1392                          leave it in the list, as we are not really going to
1393                          remove the region.  */
1394                       *prev = XEXP (x, 1);
1395                       XEXP (x, 1) = 0;
1396                       XEXP (x, 0) = 0;
1397                     }
1398
1399                   break;
1400                 }
1401               prev = &XEXP (x, 1);
1402             }
1403         }
1404     }
1405   return insn;
1406 }
1407
1408 /* Perform various interesting optimizations for exception handling
1409    code.
1410
1411    We look for empty exception regions and make them go (away). The
1412    jump optimization code will remove the handler if nothing else uses
1413    it. */
1414
1415 void
1416 exception_optimize ()
1417 {
1418   rtx insn, regions = NULL_RTX;
1419   int n;
1420
1421   /* Remove empty regions.  */
1422   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1423     {
1424       if (GET_CODE (insn) == NOTE
1425           && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
1426         {
1427           /* Since scan_region () will return the NOTE_INSN_EH_REGION_END
1428              insn, we will indirectly skip through all the insns
1429              inbetween. We are also guaranteed that the value of insn
1430              returned will be valid, as otherwise scan_region () won't
1431              return. */
1432           insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &n);
1433         }
1434     }
1435 }