(CPP_SPEC): add %(subtarget_cpp_spec).
[official-gcc.git] / gcc / except.c
blob705e1a8bfb69964e96f74be770859fe547174084
1 /* Implements exception handling.
2 Copyright (C) 1989, 92-95, 1996 Free Software Foundation, Inc.
3 Contributed by Mike Stump <mrs@cygnus.com>.
5 This file is part of GNU CC.
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.
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.
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. */
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.
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.
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.
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. -fnosjlj-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.
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.
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.
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.
74 In the current implementaion, 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).
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.
90 At program startup each object file invokes a function named
91 __register_exceptions with the address of its local
92 __EXCEPTION_TABLE__. __register_exceptions is defined in libgcc2.c,
93 and is responsible for recording all of the exception regions into
94 one list (which is kept in a static variable named exception_table_list).
96 The function __throw is actually responsible for doing the
97 throw. In the C++ frontend, __throw is generated on a
98 per-object-file basis for each source file compiled with
99 -fexceptions. Before __throw is invoked, the current context
100 of the throw needs to be placed in the global variable __eh_pc.
102 __throw attempts to find the appropriate exception handler for the
103 PC value stored in __eh_pc by calling __find_first_exception_table_match
104 (which is defined in libgcc2.c). If __find_first_exception_table_match
105 finds a relevant handler, __throw jumps directly to it.
107 If a handler for the context being thrown from can't be found,
108 __throw is responsible for unwinding the stack, determining the
109 address of the caller of the current function (which will be used
110 as the new context to throw from), and then restarting the process
111 of searching for a handler for the new context. __throw may also
112 call abort if it is unable to unwind the stack, and can also
113 call an external library function named __terminate if it reaches
114 the top of the stack without finding an appropriate handler. (By
115 default __terminate invokes abort, but this behavior can be
116 changed by the user to perform some sort of cleanup behavior before
117 exiting).
119 Internal implementation details:
121 To associate a user-defined handler with a block of statements, the
122 function expand_start_try_stmts is used to mark the start of the
123 block of statements with which the handler is to be associated
124 (which is known as a "try block"). All statements that appear
125 afterwards will be associated with the try block.
127 A call to expand_start_all_catch marks the end of the try block,
128 and also marks the start of the "catch block" (the user-defined
129 handler) associated with the try block.
131 This user-defined handler will be invoked for *every* exception
132 thrown with the context of the try block. It is up to the handler
133 to decide whether or not it wishes to handle any given exception,
134 as there is currently no mechanism in this implementation for doing
135 this. (There are plans for conditionally processing an exception
136 based on its "type", which will provide a language-independent
137 mechanism).
139 If the handler chooses not to process the exception (perhaps by
140 looking at an "exception type" or some other additional data
141 supplied with the exception), it can fall through to the end of the
142 handler. expand_end_all_catch and expand_leftover_cleanups
143 add additional code to the end of each handler to take care of
144 rethrowing to the outer exception handler.
146 The handler also has the option to continue with "normal flow of
147 code", or in other words to resume executing at the statement
148 immediately after the end of the exception region. The variable
149 caught_return_label_stack contains a stack of labels, and jumping
150 to the topmost entry's label via expand_goto will resume normal
151 flow to the statement immediately after the end of the exception
152 region. If the handler falls through to the end, the exception will
153 be rethrown to the outer exception region.
155 The instructions for the catch block are kept as a separate
156 sequence, and will be emitted at the end of the function along with
157 the handlers specified via expand_eh_region_end. The end of the
158 catch block is marked with expand_end_all_catch.
160 Any data associated with the exception must currently be handled by
161 some external mechanism maintained in the frontend. For example,
162 the C++ exception mechanism passes an arbitrary value along with
163 the exception, and this is handled in the C++ frontend by using a
164 global variable to hold the value. (This will be changing in the
165 future.)
167 The mechanism in C++ for handling data associated with the
168 exception is clearly not thread-safe. For a thread-based
169 environment, another mechanism must be used (possibly using a
170 per-thread allocation mechanism if the size of the area that needs
171 to be allocated isn't known at compile time.)
173 Internally-generated exception regions (cleanups) are marked by
174 calling expand_eh_region_start to mark the start of the region,
175 and expand_eh_region_end (handler) is used to both designate the
176 end of the region and to associate a specified handler/cleanup with
177 the region. The rtl code in HANDLER will be invoked whenever an
178 exception occurs in the region between the calls to
179 expand_eh_region_start and expand_eh_region_end. After HANDLER is
180 executed, additional code is emitted to handle rethrowing the
181 exception to the outer exception handler. The code for HANDLER will
182 be emitted at the end of the function.
184 TARGET_EXPRs can also be used to designate exception regions. A
185 TARGET_EXPR gives an unwind-protect style interface commonly used
186 in functional languages such as LISP. The associated expression is
187 evaluated, and whether or not it (or any of the functions that it
188 calls) throws an exception, the protect expression is always
189 invoked. This implementation takes care of the details of
190 associating an exception table entry with the expression and
191 generating the necessary code (it actually emits the protect
192 expression twice, once for normal flow and once for the exception
193 case). As for the other handlers, the code for the exception case
194 will be emitted at the end of the function.
196 Cleanups can also be specified by using add_partial_entry (handler)
197 and end_protect_partials. add_partial_entry creates the start of
198 a new exception region; HANDLER will be invoked if an exception is
199 thrown with the context of the region between the calls to
200 add_partial_entry and end_protect_partials. end_protect_partials is
201 used to mark the end of these regions. add_partial_entry can be
202 called as many times as needed before calling end_protect_partials.
203 However, end_protect_partials should only be invoked once for each
204 group of calls to add_partial_entry as the entries are queued
205 and all of the outstanding entries are processed simultaneously
206 when end_protect_partials is invoked. Similarly to the other
207 handlers, the code for HANDLER will be emitted at the end of the
208 function.
210 The generated RTL for an exception region includes
211 NOTE_INSN_EH_REGION_BEG and NOTE_INSN_EH_REGION_END notes that mark
212 the start and end of the exception region. A unique label is also
213 generated at the start of the exception region, which is available
214 by looking at the ehstack variable. The topmost entry corresponds
215 to the current region.
217 In the current implementation, an exception can only be thrown from
218 a function call (since the mechanism used to actually throw an
219 exception involves calling __throw). If an exception region is
220 created but no function calls occur within that region, the region
221 can be safely optimized away (along with its exception handlers)
222 since no exceptions can ever be caught in that region. This
223 optimization is performed unless -fasynchronous-exceptions is
224 given. If the user wishes to throw from a signal handler, or other
225 asynchronous place, -fasynchronous-exceptions should be used when
226 compiling for maximally correct code, at the cost of additional
227 exception regions. Using -fasynchronous-exceptions only produces
228 code that is reasonably safe in such situations, but a correct
229 program cannot rely upon this working. It can be used in failsafe
230 code, where trying to continue on, and proceeding with potentially
231 incorrect results is better than halting the program.
234 Unwinding the stack:
236 The details of unwinding the stack to the next frame can be rather
237 complex. While in many cases a generic __unwind_function routine
238 can be used by the generated exception handling code to do this, it
239 is often necessary to generate inline code to do the unwinding.
241 Whether or not these inlined unwinders are necessary is
242 target-specific.
244 By default, if the target-specific backend doesn't supply a
245 definition for __unwind_function, inlined unwinders will be used
246 instead. The main tradeoff here is in text space utilization.
247 Obviously, if inline unwinders have to be generated repeatedly,
248 this uses much more space than if a single routine is used.
250 However, it is simply not possible on some platforms to write a
251 generalized routine for doing stack unwinding without having some
252 form of additional data associated with each function. The current
253 implementation encodes this data in the form of additional machine
254 instructions. This is clearly not desirable, as it is extremely
255 inefficient. The next implementation will provide a set of metadata
256 for each function that will provide the needed information.
258 The backend macro DOESNT_NEED_UNWINDER is used to conditionalize
259 whether or not per-function unwinders are needed. If DOESNT_NEED_UNWINDER
260 is defined and has a non-zero value, a per-function unwinder is
261 not emitted for the current function.
263 On some platforms it is possible that neither __unwind_function
264 nor inlined unwinders are available. For these platforms it is not
265 possible to throw through a function call, and abort will be
266 invoked instead of performing the throw.
268 Future directions:
270 Currently __throw makes no differentiation between cleanups and
271 user-defined exception regions. While this makes the implementation
272 simple, it also implies that it is impossible to determine if a
273 user-defined exception handler exists for a given exception without
274 completely unwinding the stack in the process. This is undesirable
275 from the standpoint of debugging, as ideally it would be possible
276 to trap unhandled exceptions in the debugger before the process of
277 unwinding has even started.
279 This problem can be solved by marking user-defined handlers in a
280 special way (probably by adding additional bits to exception_table_list).
281 A two-pass scheme could then be used by __throw to iterate
282 through the table. The first pass would search for a relevant
283 user-defined handler for the current context of the throw, and if
284 one is found, the second pass would then invoke all needed cleanups
285 before jumping to the user-defined handler.
287 Many languages (including C++ and Ada) make execution of a
288 user-defined handler conditional on the "type" of the exception
289 thrown. (The type of the exception is actually the type of the data
290 that is thrown with the exception.) It will thus be necessary for
291 __throw to be able to determine if a given user-defined
292 exception handler will actually be executed, given the type of
293 exception.
295 One scheme is to add additional information to exception_table_list
296 as to the types of exceptions accepted by each handler. __throw
297 can do the type comparisons and then determine if the handler is
298 actually going to be executed.
300 There is currently no significant level of debugging support
301 available, other than to place a breakpoint on __throw. While
302 this is sufficient in most cases, it would be helpful to be able to
303 know where a given exception was going to be thrown to before it is
304 actually thrown, and to be able to choose between stopping before
305 every exception region (including cleanups), or just user-defined
306 exception regions. This should be possible to do in the two-pass
307 scheme by adding additional labels to __throw for appropriate
308 breakpoints, and additional debugger commands could be added to
309 query various state variables to determine what actions are to be
310 performed next.
312 Another major problem that is being worked on is the issue with
313 stack unwinding on various platforms. Currently the only platform
314 that has support for __unwind_function is the Sparc; all other
315 ports require per-function unwinders, which causes large amounts of
316 code bloat.
318 Ideally it would be possible to store a small set of metadata with
319 each function that would then make it possible to write a
320 __unwind_function for every platform. This would eliminate the
321 need for per-function unwinders.
323 The main reason the data is needed is that on some platforms the
324 order and types of data stored on the stack can vary depending on
325 the type of function, its arguments and returned values, and the
326 compilation options used (optimization versus non-optimization,
327 -fomit-frame-pointer, processor variations, etc).
329 Unfortunately, this also means that throwing through functions that
330 aren't compiled with exception handling support will still not be
331 possible on some platforms. This problem is currently being
332 investigated, but no solutions have been found that do not imply
333 some unacceptable performance penalties.
335 For setjmp/longjmp based exception handling, some of the details
336 are as above, but there are some additional details. This section
337 discusses the details.
339 We don't use NOTE_INSN_EH_REGION_{BEG,END} pairs. We don't
340 optimize EH regions yet. We don't have to worry about machine
341 specific issues with unwinding the stack, as we rely upon longjmp
342 for all the machine specific details. There is no variable context
343 of a throw, just the one implied by the dynamic handler stack
344 pointed to by the dynamic handler chain. There is no exception
345 table, and no calls to __register_excetpions. __sjthrow is used
346 instead of __throw, and it works by using the dynamic handler
347 chain, and longjmp. -fasynchronous-exceptions has no effect, as
348 the elimination of trivial exception regions is not yet performed.
350 A frontend can set protect_cleanup_actions_with_terminate when all
351 the cleanup actions should be protected with an EH region that
352 calls terminate when an unhandled exception is throw. C++ does
353 this, Ada does not. */
356 #include "config.h"
357 #include <stdio.h>
358 #include "rtl.h"
359 #include "tree.h"
360 #include "flags.h"
361 #include "except.h"
362 #include "function.h"
363 #include "insn-flags.h"
364 #include "expr.h"
365 #include "insn-codes.h"
366 #include "regs.h"
367 #include "hard-reg-set.h"
368 #include "insn-config.h"
369 #include "recog.h"
370 #include "output.h"
371 #include "assert.h"
373 /* One to use setjmp/longjmp method of generating code for exception
374 handling. */
376 int exceptions_via_longjmp = 1;
378 /* One to enable asynchronous exception support. */
380 int asynchronous_exceptions = 0;
382 /* One to protect cleanup actions with a handler that calls
383 __terminate, zero otherwise. */
385 int protect_cleanup_actions_with_terminate = 0;
387 /* A list of labels used for exception handlers. Created by
388 find_exception_handler_labels for the optimization passes. */
390 rtx exception_handler_labels;
392 /* Nonzero means that __throw was invoked.
394 This is used by the C++ frontend to know if code needs to be emitted
395 for __throw or not. */
397 int throw_used;
399 /* The dynamic handler chain. Nonzero if the function has already
400 fetched a pointer to the dynamic handler chain for exception
401 handling. */
403 rtx current_function_dhc;
405 /* The dynamic cleanup chain. Nonzero if the function has already
406 fetched a pointer to the dynamic cleanup chain for exception
407 handling. */
409 rtx current_function_dcc;
411 /* A stack used for keeping track of the currectly active exception
412 handling region. As each exception region is started, an entry
413 describing the region is pushed onto this stack. The current
414 region can be found by looking at the top of the stack, and as we
415 exit regions, the corresponding entries are popped.
417 Entries cannot overlap; they can be nested. So there is only one
418 entry at most that corresponds to the current instruction, and that
419 is the entry on the top of the stack. */
421 static struct eh_stack ehstack;
423 /* A queue used for tracking which exception regions have closed but
424 whose handlers have not yet been expanded. Regions are emitted in
425 groups in an attempt to improve paging performance.
427 As we exit a region, we enqueue a new entry. The entries are then
428 dequeued during expand_leftover_cleanups and expand_start_all_catch,
430 We should redo things so that we either take RTL for the handler,
431 or we expand the handler expressed as a tree immediately at region
432 end time. */
434 static struct eh_queue ehqueue;
436 /* Insns for all of the exception handlers for the current function.
437 They are currently emitted by the frontend code. */
439 rtx catch_clauses;
441 /* A TREE_CHAINed list of handlers for regions that are not yet
442 closed. The TREE_VALUE of each entry contains the handler for the
443 corresponding entry on the ehstack. */
445 static tree protect_list;
447 /* Stacks to keep track of various labels. */
449 /* Keeps track of the label to resume to should one want to resume
450 normal control flow out of a handler (instead of, say, returning to
451 the caller of the current function or exiting the program). Also
452 used as the context of a throw to rethrow an exception to the outer
453 exception region. */
455 struct label_node *caught_return_label_stack = NULL;
457 /* A random data area for the front end's own use. */
459 struct label_node *false_label_stack = NULL;
461 /* The rtx and the tree for the saved PC value. */
463 rtx eh_saved_pc_rtx;
464 tree eh_saved_pc;
466 rtx expand_builtin_return_addr PROTO((enum built_in_function, int, rtx));
468 /* Various support routines to manipulate the various data structures
469 used by the exception handling code. */
471 /* Push a label entry onto the given STACK. */
473 void
474 push_label_entry (stack, rlabel, tlabel)
475 struct label_node **stack;
476 rtx rlabel;
477 tree tlabel;
479 struct label_node *newnode
480 = (struct label_node *) xmalloc (sizeof (struct label_node));
482 if (rlabel)
483 newnode->u.rlabel = rlabel;
484 else
485 newnode->u.tlabel = tlabel;
486 newnode->chain = *stack;
487 *stack = newnode;
490 /* Pop a label entry from the given STACK. */
493 pop_label_entry (stack)
494 struct label_node **stack;
496 rtx label;
497 struct label_node *tempnode;
499 if (! *stack)
500 return NULL_RTX;
502 tempnode = *stack;
503 label = tempnode->u.rlabel;
504 *stack = (*stack)->chain;
505 free (tempnode);
507 return label;
510 /* Return the top element of the given STACK. */
512 tree
513 top_label_entry (stack)
514 struct label_node **stack;
516 if (! *stack)
517 return NULL_TREE;
519 return (*stack)->u.tlabel;
522 /* Make a copy of ENTRY using xmalloc to allocate the space. */
524 static struct eh_entry *
525 copy_eh_entry (entry)
526 struct eh_entry *entry;
528 struct eh_entry *newentry;
530 newentry = (struct eh_entry *) xmalloc (sizeof (struct eh_entry));
531 bcopy ((char *) entry, (char *) newentry, sizeof (struct eh_entry));
533 return newentry;
536 /* Push a new eh_node entry onto STACK. */
538 static void
539 push_eh_entry (stack)
540 struct eh_stack *stack;
542 struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
543 struct eh_entry *entry = (struct eh_entry *) xmalloc (sizeof (struct eh_entry));
545 entry->outer_context = gen_label_rtx ();
546 entry->exception_handler_label = gen_label_rtx ();
547 entry->finalization = NULL_TREE;
549 node->entry = entry;
550 node->chain = stack->top;
551 stack->top = node;
554 /* Pop an entry from the given STACK. */
556 static struct eh_entry *
557 pop_eh_entry (stack)
558 struct eh_stack *stack;
560 struct eh_node *tempnode;
561 struct eh_entry *tempentry;
563 tempnode = stack->top;
564 tempentry = tempnode->entry;
565 stack->top = stack->top->chain;
566 free (tempnode);
568 return tempentry;
571 /* Enqueue an ENTRY onto the given QUEUE. */
573 static void
574 enqueue_eh_entry (queue, entry)
575 struct eh_queue *queue;
576 struct eh_entry *entry;
578 struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
580 node->entry = entry;
581 node->chain = NULL;
583 if (queue->head == NULL)
585 queue->head = node;
587 else
589 queue->tail->chain = node;
591 queue->tail = node;
594 /* Dequeue an entry from the given QUEUE. */
596 static struct eh_entry *
597 dequeue_eh_entry (queue)
598 struct eh_queue *queue;
600 struct eh_node *tempnode;
601 struct eh_entry *tempentry;
603 if (queue->head == NULL)
604 return NULL;
606 tempnode = queue->head;
607 queue->head = queue->head->chain;
609 tempentry = tempnode->entry;
610 free (tempnode);
612 return tempentry;
615 /* Routine to see if exception exception handling is turned on.
616 DO_WARN is non-zero if we want to inform the user that exception
617 handling is turned off.
619 This is used to ensure that -fexceptions has been specified if the
620 compiler tries to use any exception-specific functions. */
623 doing_eh (do_warn)
624 int do_warn;
626 if (! flag_exceptions)
628 static int warned = 0;
629 if (! warned && do_warn)
631 error ("exception handling disabled, use -fexceptions to enable");
632 warned = 1;
634 return 0;
636 return 1;
639 /* Given a return address in ADDR, determine the address we should use
640 to find the corresponding EH region. */
643 eh_outer_context (addr)
644 rtx addr;
646 /* First mask out any unwanted bits. */
647 #ifdef MASK_RETURN_ADDR
648 emit_insn (gen_rtx (SET, Pmode,
649 addr,
650 gen_rtx (AND, Pmode,
651 addr, MASK_RETURN_ADDR)));
652 #endif
654 /* Then subtract out enough to get into the appropriate region. If
655 this is defined, assume we don't need to subtract anything as it
656 is already within the correct region. */
657 #if ! defined (RETURN_ADDR_OFFSET)
658 addr = plus_constant (addr, -1);
659 #endif
661 return addr;
664 /* Start a new exception region for a region of code that has a
665 cleanup action and push the HANDLER for the region onto
666 protect_list. All of the regions created with add_partial_entry
667 will be ended when end_protect_partials is invoked. */
669 void
670 add_partial_entry (handler)
671 tree handler;
673 expand_eh_region_start ();
675 /* Make sure the entry is on the correct obstack. */
676 push_obstacks_nochange ();
677 resume_temporary_allocation ();
679 /* Because this is a cleanup action, we may have to protect the handler
680 with __terminate. */
681 handler = protect_with_terminate (handler);
683 protect_list = tree_cons (NULL_TREE, handler, protect_list);
684 pop_obstacks ();
687 /* Get a reference to the dynamic handler chain. It points to the
688 pointer to the next element in the dynamic handler chain. It ends
689 when there are no more elements in the dynamic handler chain, when
690 the value is &top_elt from libgcc2.c. Immediately after the
691 pointer, is an area suitable for setjmp/longjmp when
692 DONT_USE_BUILTIN_SETJMP is defined, and an area suitable for
693 __builtin_setjmp/__builtin_longjmp when DONT_USE_BUILTIN_SETJMP
694 isn't defined.
696 This routine is here to facilitate the porting of this code to
697 systems with threads. One can either replace the routine we emit a
698 call for here in libgcc2.c, or one can modify this routine to work
699 with their thread system. */
702 get_dynamic_handler_chain ()
704 #if 0
705 /* Do this once we figure out how to get this to the front of the
706 function, and we really only want one per real function, not one
707 per inlined function. */
708 if (current_function_dhc == 0)
710 rtx dhc, insns;
711 start_sequence ();
713 dhc = emit_library_call_value (get_dynamic_handler_chain_libfunc,
714 NULL_RTX, 1,
715 Pmode, 0);
716 current_function_dhc = copy_to_reg (dhc);
717 insns = get_insns ();
718 end_sequence ();
719 emit_insns_before (insns, get_first_nonparm_insn ());
721 #else
722 rtx dhc;
723 dhc = emit_library_call_value (get_dynamic_handler_chain_libfunc,
724 NULL_RTX, 1,
725 Pmode, 0);
726 current_function_dhc = copy_to_reg (dhc);
727 #endif
729 /* We don't want a copy of the dhc, but rather, the single dhc. */
730 return gen_rtx (MEM, Pmode, current_function_dhc);
733 /* Get a reference to the dynamic cleanup chain. It points to the
734 pointer to the next element in the dynamic cleanup chain.
735 Immediately after the pointer, are two Pmode variables, one for a
736 pointer to a function that performs the cleanup action, and the
737 second, the argument to pass to that function. */
740 get_dynamic_cleanup_chain ()
742 rtx dhc, dcc;
744 dhc = get_dynamic_handler_chain ();
745 dcc = plus_constant (dhc, GET_MODE_SIZE (Pmode));
747 current_function_dcc = copy_to_reg (dcc);
749 /* We don't want a copy of the dcc, but rather, the single dcc. */
750 return gen_rtx (MEM, Pmode, current_function_dcc);
753 /* Generate code to evaluate X and jump to LABEL if the value is nonzero.
754 LABEL is an rtx of code CODE_LABEL, in this function. */
756 void
757 jumpif_rtx (x, label)
758 rtx x;
759 rtx label;
761 jumpif (make_tree (type_for_mode (GET_MODE (x), 0), x), label);
764 /* Generate code to evaluate X and jump to LABEL if the value is zero.
765 LABEL is an rtx of code CODE_LABEL, in this function. */
767 void
768 jumpifnot_rtx (x, label)
769 rtx x;
770 rtx label;
772 jumpifnot (make_tree (type_for_mode (GET_MODE (x), 0), x), label);
775 /* Start a dynamic cleanup on the EH runtime dynamic cleanup stack.
776 We just need to create an element for the cleanup list, and push it
777 into the chain.
779 A dynamic cleanup is a cleanup action implied by the presence of an
780 element on the EH runtime dynamic cleanup stack that is to be
781 performed when an exception is thrown. The cleanup action is
782 performed by __sjthrow when an exception is thrown. Only certain
783 actions can be optimized into dynamic cleanup actions. For the
784 restrictions on what actions can be performed using this routine,
785 see expand_eh_region_start_tree. */
787 static void
788 start_dynamic_cleanup (func, arg)
789 tree func;
790 tree arg;
792 rtx dhc, dcc;
793 rtx new_func, new_arg;
794 rtx x, buf;
795 int size;
797 /* We allocate enough room for a pointer to the function, and
798 one argument. */
799 size = 2;
801 /* XXX, FIXME: The stack space allocated this way is too long lived,
802 but there is no allocation routine that allocates at the level of
803 the last binding contour. */
804 buf = assign_stack_local (BLKmode,
805 GET_MODE_SIZE (Pmode)*(size+1),
808 buf = change_address (buf, Pmode, NULL_RTX);
810 /* Store dcc into the first word of the newly allocated buffer. */
812 dcc = get_dynamic_cleanup_chain ();
813 emit_move_insn (buf, dcc);
815 /* Store func and arg into the cleanup list element. */
817 new_func = gen_rtx (MEM, Pmode, plus_constant (XEXP (buf, 0),
818 GET_MODE_SIZE (Pmode)));
819 new_arg = gen_rtx (MEM, Pmode, plus_constant (XEXP (buf, 0),
820 GET_MODE_SIZE (Pmode)*2));
821 x = expand_expr (func, new_func, Pmode, 0);
822 if (x != new_func)
823 emit_move_insn (new_func, x);
825 x = expand_expr (arg, new_arg, Pmode, 0);
826 if (x != new_arg)
827 emit_move_insn (new_arg, x);
829 /* Update the cleanup chain. */
831 emit_move_insn (dcc, XEXP (buf, 0));
834 /* Emit RTL to start a dynamic handler on the EH runtime dynamic
835 handler stack. This should only be used by expand_eh_region_start
836 or expand_eh_region_start_tree. */
838 static void
839 start_dynamic_handler ()
841 rtx dhc, dcc;
842 rtx x, arg, buf;
843 int size;
845 #ifndef DONT_USE_BUILTIN_SETJMP
846 /* The number of Pmode words for the setjmp buffer, when using the
847 builtin setjmp/longjmp, see expand_builtin, case
848 BUILT_IN_LONGJMP. */
849 size = 5;
850 #else
851 #ifdef JMP_BUF_SIZE
852 size = JMP_BUF_SIZE;
853 #else
854 /* Should be large enough for most systems, if it is not,
855 JMP_BUF_SIZE should be defined with the proper value. It will
856 also tend to be larger than necessary for most systems, a more
857 optimal port will define JMP_BUF_SIZE. */
858 size = FIRST_PSEUDO_REGISTER+2;
859 #endif
860 #endif
861 /* XXX, FIXME: The stack space allocated this way is too long lived,
862 but there is no allocation routine that allocates at the level of
863 the last binding contour. */
864 arg = assign_stack_local (BLKmode,
865 GET_MODE_SIZE (Pmode)*(size+1),
868 arg = change_address (arg, Pmode, NULL_RTX);
870 /* Store dhc into the first word of the newly allocated buffer. */
872 dhc = get_dynamic_handler_chain ();
873 dcc = gen_rtx (MEM, Pmode, plus_constant (XEXP (arg, 0),
874 GET_MODE_SIZE (Pmode)));
875 emit_move_insn (arg, dhc);
877 /* Zero out the start of the cleanup chain. */
878 emit_move_insn (dcc, const0_rtx);
880 /* The jmpbuf starts two words into the area allocated. */
881 buf = plus_constant (XEXP (arg, 0), GET_MODE_SIZE (Pmode)*2);
883 #ifdef DONT_USE_BUILTIN_SETJMP
884 x = emit_library_call_value (setjmp_libfunc, NULL_RTX, 1, SImode, 1,
885 buf, Pmode);
886 #else
887 x = expand_builtin_setjmp (buf, NULL_RTX);
888 #endif
890 /* If we come back here for a catch, transfer control to the
891 handler. */
893 jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
895 /* We are committed to this, so update the handler chain. */
897 emit_move_insn (dhc, XEXP (arg, 0));
900 /* Start an exception handling region for the given cleanup action.
901 All instructions emitted after this point are considered to be part
902 of the region until expand_eh_region_end is invoked. CLEANUP is
903 the cleanup action to perform. The return value is true if the
904 exception region was optimized away. If that case,
905 expand_eh_region_end does not need to be called for this cleanup,
906 nor should it be.
908 This routine notices one particular common case in C++ code
909 generation, and optimizes it so as to not need the exception
910 region. It works by creating a dynamic cleanup action, instead of
911 of a using an exception region. */
914 expand_eh_region_start_tree (decl, cleanup)
915 tree decl;
916 tree cleanup;
918 rtx note;
920 /* This is the old code. */
921 if (! doing_eh (0))
922 return 0;
924 /* The optimization only applies to actions protected with
925 terminate, and only applies if we are using the setjmp/longjmp
926 codegen method. */
927 if (exceptions_via_longjmp
928 && protect_cleanup_actions_with_terminate)
930 tree func, arg;
931 tree args;
933 /* Ignore any UNSAVE_EXPR. */
934 if (TREE_CODE (cleanup) == UNSAVE_EXPR)
935 cleanup = TREE_OPERAND (cleanup, 0);
937 /* Further, it only applies if the action is a call, if there
938 are 2 arguments, and if the second argument is 2. */
940 if (TREE_CODE (cleanup) == CALL_EXPR
941 && (args = TREE_OPERAND (cleanup, 1))
942 && (func = TREE_OPERAND (cleanup, 0))
943 && (arg = TREE_VALUE (args))
944 && (args = TREE_CHAIN (args))
946 /* is the second argument 2? */
947 && TREE_CODE (TREE_VALUE (args)) == INTEGER_CST
948 && TREE_INT_CST_LOW (TREE_VALUE (args)) == 2
949 && TREE_INT_CST_HIGH (TREE_VALUE (args)) == 0
951 /* Make sure there are no other arguments. */
952 && TREE_CHAIN (args) == NULL_TREE)
954 /* Arrange for returns and gotos to pop the entry we make on the
955 dynamic cleanup stack. */
956 expand_dcc_cleanup (decl);
957 start_dynamic_cleanup (func, arg);
958 return 1;
962 expand_eh_region_start_for_decl (decl);
964 return 0;
967 /* Just like expand_eh_region_start, except if a cleanup action is
968 entered on the cleanup chain, the TREE_PURPOSE of the element put
969 on the chain is DECL. DECL should be the associated VAR_DECL, if
970 any, otherwise it should be NULL_TREE. */
972 void
973 expand_eh_region_start_for_decl (decl)
974 tree decl;
976 rtx note;
978 /* This is the old code. */
979 if (! doing_eh (0))
980 return;
982 if (exceptions_via_longjmp)
984 /* We need a new block to record the start and end of the
985 dynamic handler chain. We could always do this, but we
986 really want to permit jumping into such a block, and we want
987 to avoid any errors or performance impact in the SJ EH code
988 for now. */
989 expand_start_bindings (0);
991 /* But we don't need or want a new temporary level. */
992 pop_temp_slots ();
994 /* Mark this block as created by expand_eh_region_start. This
995 is so that we can pop the block with expand_end_bindings
996 automatically. */
997 mark_block_as_eh_region ();
999 /* Arrange for returns and gotos to pop the entry we make on the
1000 dynamic handler stack. */
1001 expand_dhc_cleanup (decl);
1004 if (exceptions_via_longjmp == 0)
1005 note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_BEG);
1006 push_eh_entry (&ehstack);
1007 if (exceptions_via_longjmp == 0)
1008 NOTE_BLOCK_NUMBER (note)
1009 = CODE_LABEL_NUMBER (ehstack.top->entry->exception_handler_label);
1010 if (exceptions_via_longjmp)
1011 start_dynamic_handler ();
1014 /* Start an exception handling region. All instructions emitted after
1015 this point are considered to be part of the region until
1016 expand_eh_region_end is invoked. */
1018 void
1019 expand_eh_region_start ()
1021 expand_eh_region_start_for_decl (NULL_TREE);
1024 /* End an exception handling region. The information about the region
1025 is found on the top of ehstack.
1027 HANDLER is either the cleanup for the exception region, or if we're
1028 marking the end of a try block, HANDLER is integer_zero_node.
1030 HANDLER will be transformed to rtl when expand_leftover_cleanups
1031 is invoked. */
1033 void
1034 expand_eh_region_end (handler)
1035 tree handler;
1037 struct eh_entry *entry;
1039 if (! doing_eh (0))
1040 return;
1042 entry = pop_eh_entry (&ehstack);
1044 if (exceptions_via_longjmp == 0)
1046 rtx label;
1047 rtx note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END);
1048 NOTE_BLOCK_NUMBER (note) = CODE_LABEL_NUMBER (entry->exception_handler_label);
1050 label = gen_label_rtx ();
1051 emit_jump (label);
1053 /* Emit a label marking the end of this exception region that
1054 is used for rethrowing into the outer context. */
1055 emit_label (entry->outer_context);
1057 /* Put in something that takes up space, as otherwise the end
1058 address for this EH region could have the exact same address as
1059 its outer region. This would cause us to miss the fact that
1060 resuming exception handling with this PC value would be inside
1061 the outer region. */
1062 emit_insn (gen_nop ());
1063 emit_barrier ();
1064 emit_label (label);
1067 entry->finalization = handler;
1069 enqueue_eh_entry (&ehqueue, entry);
1071 /* If we have already started ending the bindings, don't recurse.
1072 This only happens when exceptions_via_longjmp is true. */
1073 if (is_eh_region ())
1075 /* Because we don't need or want a new temporary level and
1076 because we didn't create one in expand_eh_region_start,
1077 create a fake one now to avoid removing one in
1078 expand_end_bindings. */
1079 push_temp_slots ();
1081 mark_block_as_not_eh_region ();
1083 /* Maybe do this to prevent jumping in and so on... */
1084 expand_end_bindings (NULL_TREE, 0, 0);
1088 /* If we are using the setjmp/longjmp EH codegen method, we emit a
1089 call to __sjthrow.
1091 Otherwise, we emit a call to __throw and note that we threw
1092 something, so we know we need to generate the necessary code for
1093 __throw.
1095 Before invoking throw, the __eh_pc variable must have been set up
1096 to contain the PC being thrown from. This address is used by
1097 __throw to determine which exception region (if any) is
1098 responsible for handling the exception. */
1100 void
1101 emit_throw ()
1103 if (exceptions_via_longjmp)
1105 emit_library_call (sjthrow_libfunc, 0, VOIDmode, 0);
1107 else
1109 #ifdef JUMP_TO_THROW
1110 emit_indirect_jump (throw_libfunc);
1111 #else
1112 SYMBOL_REF_USED (throw_libfunc) = 1;
1113 emit_library_call (throw_libfunc, 0, VOIDmode, 0);
1114 #endif
1115 throw_used = 1;
1117 emit_barrier ();
1120 /* An internal throw with an indirect CONTEXT we want to throw from.
1121 CONTEXT evaluates to the context of the throw. */
1123 static void
1124 expand_internal_throw_indirect (context)
1125 rtx context;
1127 assemble_external (eh_saved_pc);
1128 emit_move_insn (eh_saved_pc_rtx, context);
1129 emit_throw ();
1132 /* An internal throw with a direct CONTEXT we want to throw from.
1133 CONTEXT must be a label; its address will be used as the context of
1134 the throw. */
1136 void
1137 expand_internal_throw (context)
1138 rtx context;
1140 expand_internal_throw_indirect (gen_rtx (LABEL_REF, Pmode, context));
1143 /* Called from expand_exception_blocks and expand_end_catch_block to
1144 emit any pending handlers/cleanups queued from expand_eh_region_end. */
1146 void
1147 expand_leftover_cleanups ()
1149 struct eh_entry *entry;
1151 while ((entry = dequeue_eh_entry (&ehqueue)) != 0)
1153 rtx prev;
1155 /* A leftover try block. Shouldn't be one here. */
1156 if (entry->finalization == integer_zero_node)
1157 abort ();
1159 /* Output the label for the start of the exception handler. */
1160 emit_label (entry->exception_handler_label);
1162 #ifdef HAVE_exception_receiver
1163 if (! exceptions_via_longjmp)
1164 if (HAVE_exception_receiver)
1165 emit_insn (gen_exception_receiver ());
1166 #endif
1168 #ifdef HAVE_nonlocal_goto_receiver
1169 if (! exceptions_via_longjmp)
1170 if (HAVE_nonlocal_goto_receiver)
1171 emit_insn (gen_nonlocal_goto_receiver ());
1172 #endif
1174 /* And now generate the insns for the handler. */
1175 expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
1177 prev = get_last_insn ();
1178 if (prev == NULL || GET_CODE (prev) != BARRIER)
1180 if (exceptions_via_longjmp)
1181 emit_throw ();
1182 else
1184 /* The below can be optimized away, and we could just
1185 fall into the next EH handler, if we are certain they
1186 are nested. */
1187 /* Emit code to throw to the outer context if we fall off
1188 the end of the handler. */
1189 expand_internal_throw (entry->outer_context);
1193 free (entry);
1197 /* Called at the start of a block of try statements. */
1198 void
1199 expand_start_try_stmts ()
1201 if (! doing_eh (1))
1202 return;
1204 expand_eh_region_start ();
1207 /* Generate RTL for the start of a group of catch clauses.
1209 It is responsible for starting a new instruction sequence for the
1210 instructions in the catch block, and expanding the handlers for the
1211 internally-generated exception regions nested within the try block
1212 corresponding to this catch block. */
1214 void
1215 expand_start_all_catch ()
1217 struct eh_entry *entry;
1218 tree label;
1220 if (! doing_eh (1))
1221 return;
1223 /* End the try block. */
1224 expand_eh_region_end (integer_zero_node);
1226 emit_line_note (input_filename, lineno);
1227 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1229 /* The label for the exception handling block that we will save.
1230 This is Lresume in the documention. */
1231 expand_label (label);
1233 if (exceptions_via_longjmp == 0)
1235 /* Put in something that takes up space, as otherwise the end
1236 address for the EH region could have the exact same address as
1237 the outer region, causing us to miss the fact that resuming
1238 exception handling with this PC value would be inside the outer
1239 region. */
1240 emit_insn (gen_nop ());
1243 /* Push the label that points to where normal flow is resumed onto
1244 the top of the label stack. */
1245 push_label_entry (&caught_return_label_stack, NULL_RTX, label);
1247 /* Start a new sequence for all the catch blocks. We will add this
1248 to the global sequence catch_clauses when we have completed all
1249 the handlers in this handler-seq. */
1250 start_sequence ();
1252 while (1)
1254 rtx prev;
1256 entry = dequeue_eh_entry (&ehqueue);
1257 /* Emit the label for the exception handler for this region, and
1258 expand the code for the handler.
1260 Note that a catch region is handled as a side-effect here;
1261 for a try block, entry->finalization will contain
1262 integer_zero_node, so no code will be generated in the
1263 expand_expr call below. But, the label for the handler will
1264 still be emitted, so any code emitted after this point will
1265 end up being the handler. */
1266 emit_label (entry->exception_handler_label);
1268 #ifdef HAVE_exception_receiver
1269 if (! exceptions_via_longjmp)
1270 if (HAVE_exception_receiver)
1271 emit_insn (gen_exception_receiver ());
1272 #endif
1274 #ifdef HAVE_nonlocal_goto_receiver
1275 if (! exceptions_via_longjmp)
1276 if (HAVE_nonlocal_goto_receiver)
1277 emit_insn (gen_nonlocal_goto_receiver ());
1278 #endif
1280 /* When we get down to the matching entry for this try block, stop. */
1281 if (entry->finalization == integer_zero_node)
1283 /* Don't forget to free this entry. */
1284 free (entry);
1285 break;
1288 /* And now generate the insns for the handler. */
1289 expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
1291 prev = get_last_insn ();
1292 if (prev == NULL || GET_CODE (prev) != BARRIER)
1294 if (exceptions_via_longjmp)
1295 emit_throw ();
1296 else
1298 /* Code to throw out to outer context when we fall off end
1299 of the handler. We can't do this here for catch blocks,
1300 so it's done in expand_end_all_catch instead.
1302 The below can be optimized away (and we could just fall
1303 into the next EH handler) if we are certain they are
1304 nested. */
1306 expand_internal_throw (entry->outer_context);
1309 free (entry);
1313 /* Finish up the catch block. At this point all the insns for the
1314 catch clauses have already been generated, so we only have to add
1315 them to the catch_clauses list. We also want to make sure that if
1316 we fall off the end of the catch clauses that we rethrow to the
1317 outer EH region. */
1319 void
1320 expand_end_all_catch ()
1322 rtx new_catch_clause;
1324 if (! doing_eh (1))
1325 return;
1327 if (exceptions_via_longjmp)
1328 emit_throw ();
1329 else
1331 /* Code to throw out to outer context, if we fall off end of catch
1332 handlers. This is rethrow (Lresume, same id, same obj) in the
1333 documentation. We use Lresume because we know that it will throw
1334 to the correct context.
1336 In other words, if the catch handler doesn't exit or return, we
1337 do a "throw" (using the address of Lresume as the point being
1338 thrown from) so that the outer EH region can then try to process
1339 the exception. */
1341 expand_internal_throw (DECL_RTL (top_label_entry (&caught_return_label_stack)));
1344 /* Now we have the complete catch sequence. */
1345 new_catch_clause = get_insns ();
1346 end_sequence ();
1348 /* This level of catch blocks is done, so set up the successful
1349 catch jump label for the next layer of catch blocks. */
1350 pop_label_entry (&caught_return_label_stack);
1352 /* Add the new sequence of catches to the main one for this function. */
1353 push_to_sequence (catch_clauses);
1354 emit_insns (new_catch_clause);
1355 catch_clauses = get_insns ();
1356 end_sequence ();
1358 /* Here we fall through into the continuation code. */
1361 /* End all the pending exception regions on protect_list. The handlers
1362 will be emitted when expand_leftover_cleanups is invoked. */
1364 void
1365 end_protect_partials ()
1367 while (protect_list)
1369 expand_eh_region_end (TREE_VALUE (protect_list));
1370 protect_list = TREE_CHAIN (protect_list);
1374 /* Arrange for __terminate to be called if there is an unhandled throw
1375 from within E. */
1377 tree
1378 protect_with_terminate (e)
1379 tree e;
1381 /* We only need to do this when using setjmp/longjmp EH and the
1382 language requires it, as otherwise we protect all of the handlers
1383 at once, if we need to. */
1384 if (exceptions_via_longjmp && protect_cleanup_actions_with_terminate)
1386 tree handler, result;
1388 /* All cleanups must be on the function_obstack. */
1389 push_obstacks_nochange ();
1390 resume_temporary_allocation ();
1392 handler = make_node (RTL_EXPR);
1393 TREE_TYPE (handler) = void_type_node;
1394 RTL_EXPR_RTL (handler) = const0_rtx;
1395 TREE_SIDE_EFFECTS (handler) = 1;
1396 start_sequence_for_rtl_expr (handler);
1398 emit_library_call (terminate_libfunc, 0, VOIDmode, 0);
1399 emit_barrier ();
1401 RTL_EXPR_SEQUENCE (handler) = get_insns ();
1402 end_sequence ();
1404 result = build (TRY_CATCH_EXPR, TREE_TYPE (e), e, handler);
1405 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e);
1406 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
1407 TREE_READONLY (result) = TREE_READONLY (e);
1409 pop_obstacks ();
1411 e = result;
1414 return e;
1417 /* The exception table that we build that is used for looking up and
1418 dispatching exceptions, the current number of entries, and its
1419 maximum size before we have to extend it.
1421 The number in eh_table is the code label number of the exception
1422 handler for the region. This is added by add_eh_table_entry and
1423 used by output_exception_table_entry. */
1425 static int *eh_table;
1426 static int eh_table_size;
1427 static int eh_table_max_size;
1429 /* Note the need for an exception table entry for region N. If we
1430 don't need to output an explicit exception table, avoid all of the
1431 extra work.
1433 Called from final_scan_insn when a NOTE_INSN_EH_REGION_BEG is seen.
1434 N is the NOTE_BLOCK_NUMBER of the note, which comes from the code
1435 label number of the exception handler for the region. */
1437 void
1438 add_eh_table_entry (n)
1439 int n;
1441 #ifndef OMIT_EH_TABLE
1442 if (eh_table_size >= eh_table_max_size)
1444 if (eh_table)
1446 eh_table_max_size += eh_table_max_size>>1;
1448 if (eh_table_max_size < 0)
1449 abort ();
1451 if ((eh_table = (int *) realloc (eh_table,
1452 eh_table_max_size * sizeof (int)))
1453 == 0)
1454 fatal ("virtual memory exhausted");
1456 else
1458 eh_table_max_size = 252;
1459 eh_table = (int *) xmalloc (eh_table_max_size * sizeof (int));
1462 eh_table[eh_table_size++] = n;
1463 #endif
1466 /* Return a non-zero value if we need to output an exception table.
1468 On some platforms, we don't have to output a table explicitly.
1469 This routine doesn't mean we don't have one. */
1472 exception_table_p ()
1474 if (eh_table)
1475 return 1;
1477 return 0;
1480 /* Output the entry of the exception table corresponding to to the
1481 exception region numbered N to file FILE.
1483 N is the code label number corresponding to the handler of the
1484 region. */
1486 static void
1487 output_exception_table_entry (file, n)
1488 FILE *file;
1489 int n;
1491 char buf[256];
1492 rtx sym;
1494 ASM_GENERATE_INTERNAL_LABEL (buf, "LEHB", n);
1495 sym = gen_rtx (SYMBOL_REF, Pmode, buf);
1496 assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
1498 ASM_GENERATE_INTERNAL_LABEL (buf, "LEHE", n);
1499 sym = gen_rtx (SYMBOL_REF, Pmode, buf);
1500 assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
1502 ASM_GENERATE_INTERNAL_LABEL (buf, "L", n);
1503 sym = gen_rtx (SYMBOL_REF, Pmode, buf);
1504 assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
1506 putc ('\n', file); /* blank line */
1509 /* Output the exception table if we have and need one. */
1511 void
1512 output_exception_table ()
1514 int i;
1515 extern FILE *asm_out_file;
1517 if (! doing_eh (0))
1518 return;
1520 exception_section ();
1522 /* Beginning marker for table. */
1523 assemble_align (GET_MODE_ALIGNMENT (ptr_mode));
1524 assemble_label ("__EXCEPTION_TABLE__");
1526 assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1527 assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1528 assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1529 putc ('\n', asm_out_file); /* blank line */
1531 for (i = 0; i < eh_table_size; ++i)
1532 output_exception_table_entry (asm_out_file, eh_table[i]);
1534 free (eh_table);
1536 /* Ending marker for table. */
1537 assemble_label ("__EXCEPTION_END__");
1538 assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1539 assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1540 assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1541 putc ('\n', asm_out_file); /* blank line */
1544 /* Generate code to initialize the exception table at program startup
1545 time. */
1547 void
1548 register_exception_table ()
1550 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__register_exceptions"), 0,
1551 VOIDmode, 1,
1552 gen_rtx (SYMBOL_REF, Pmode, "__EXCEPTION_TABLE__"),
1553 Pmode);
1556 /* Emit the RTL for the start of the per-function unwinder for the
1557 current function. See emit_unwinder for further information.
1559 DOESNT_NEED_UNWINDER is a target-specific macro that determines if
1560 the current function actually needs a per-function unwinder or not.
1561 By default, all functions need one. */
1563 void
1564 start_eh_unwinder ()
1566 #ifdef DOESNT_NEED_UNWINDER
1567 if (DOESNT_NEED_UNWINDER)
1568 return;
1569 #endif
1571 /* If we are using the setjmp/longjmp implementation, we don't need a
1572 per function unwinder. */
1574 if (exceptions_via_longjmp)
1575 return;
1577 expand_eh_region_start ();
1580 /* Emit insns for the end of the per-function unwinder for the
1581 current function. */
1583 void
1584 end_eh_unwinder ()
1586 tree expr;
1587 rtx return_val_rtx, ret_val, label, end, insns;
1589 if (! doing_eh (0))
1590 return;
1592 #ifdef DOESNT_NEED_UNWINDER
1593 if (DOESNT_NEED_UNWINDER)
1594 return;
1595 #endif
1597 /* If we are using the setjmp/longjmp implementation, we don't need a
1598 per function unwinder. */
1600 if (exceptions_via_longjmp)
1601 return;
1603 assemble_external (eh_saved_pc);
1605 expr = make_node (RTL_EXPR);
1606 TREE_TYPE (expr) = void_type_node;
1607 RTL_EXPR_RTL (expr) = const0_rtx;
1608 TREE_SIDE_EFFECTS (expr) = 1;
1609 start_sequence_for_rtl_expr (expr);
1611 /* ret_val will contain the address of the code where the call
1612 to the current function occurred. */
1613 ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
1614 0, hard_frame_pointer_rtx);
1615 return_val_rtx = copy_to_reg (ret_val);
1617 /* Get the address we need to use to determine what exception
1618 handler should be invoked, and store it in __eh_pc. */
1619 return_val_rtx = eh_outer_context (return_val_rtx);
1620 emit_move_insn (eh_saved_pc_rtx, return_val_rtx);
1622 /* Either set things up so we do a return directly to __throw, or
1623 we return here instead. */
1624 #ifdef JUMP_TO_THROW
1625 emit_move_insn (ret_val, throw_libfunc);
1626 #else
1627 label = gen_label_rtx ();
1628 emit_move_insn (ret_val, gen_rtx (LABEL_REF, Pmode, label));
1629 #endif
1631 #ifdef RETURN_ADDR_OFFSET
1632 return_val_rtx = plus_constant (ret_val, -RETURN_ADDR_OFFSET);
1633 if (return_val_rtx != ret_val)
1634 emit_move_insn (ret_val, return_val_rtx);
1635 #endif
1637 end = gen_label_rtx ();
1638 emit_jump (end);
1640 RTL_EXPR_SEQUENCE (expr) = get_insns ();
1641 end_sequence ();
1643 expand_eh_region_end (expr);
1645 emit_jump (end);
1647 #ifndef JUMP_TO_THROW
1648 emit_label (label);
1649 emit_throw ();
1650 #endif
1652 expand_leftover_cleanups ();
1654 emit_label (end);
1656 #ifdef HAVE_return
1657 if (HAVE_return)
1659 emit_jump_insn (gen_return ());
1660 emit_barrier ();
1662 #endif
1665 /* If necessary, emit insns for the per function unwinder for the
1666 current function. Called after all the code that needs unwind
1667 protection is output.
1669 The unwinder takes care of catching any exceptions that have not
1670 been previously caught within the function, unwinding the stack to
1671 the next frame, and rethrowing using the address of the current
1672 function's caller as the context of the throw.
1674 On some platforms __throw can do this by itself (or with the help
1675 of __unwind_function) so the per-function unwinder is
1676 unnecessary.
1678 We cannot place the unwinder into the function until after we know
1679 we are done inlining, as we don't want to have more than one
1680 unwinder per non-inlined function. */
1682 void
1683 emit_unwinder ()
1685 rtx insns, insn;
1687 start_sequence ();
1688 start_eh_unwinder ();
1689 insns = get_insns ();
1690 end_sequence ();
1692 /* We place the start of the exception region associated with the
1693 per function unwinder at the top of the function. */
1694 if (insns)
1695 emit_insns_after (insns, get_insns ());
1697 start_sequence ();
1698 end_eh_unwinder ();
1699 insns = get_insns ();
1700 end_sequence ();
1702 /* And we place the end of the exception region before the USE and
1703 CLOBBER insns that may come at the end of the function. */
1704 if (insns == 0)
1705 return;
1707 insn = get_last_insn ();
1708 while (GET_CODE (insn) == NOTE
1709 || (GET_CODE (insn) == INSN
1710 && (GET_CODE (PATTERN (insn)) == USE
1711 || GET_CODE (PATTERN (insn)) == CLOBBER)))
1712 insn = PREV_INSN (insn);
1714 if (GET_CODE (insn) == CODE_LABEL
1715 && GET_CODE (PREV_INSN (insn)) == BARRIER)
1717 insn = PREV_INSN (insn);
1719 else
1721 rtx label = gen_label_rtx ();
1722 emit_label_after (label, insn);
1723 insn = emit_jump_insn_after (gen_jump (label), insn);
1724 insn = emit_barrier_after (insn);
1727 emit_insns_after (insns, insn);
1730 /* Scan the current insns and build a list of handler labels. The
1731 resulting list is placed in the global variable exception_handler_labels.
1733 It is called after the last exception handling region is added to
1734 the current function (when the rtl is almost all built for the
1735 current function) and before the jump optimization pass. */
1737 void
1738 find_exception_handler_labels ()
1740 rtx insn;
1741 int max_labelno = max_label_num ();
1742 int min_labelno = get_first_label_num ();
1743 rtx *labels;
1745 exception_handler_labels = NULL_RTX;
1747 /* If we aren't doing exception handling, there isn't much to check. */
1748 if (! doing_eh (0))
1749 return;
1751 /* Generate a handy reference to each label. */
1753 labels = (rtx *) alloca ((max_labelno - min_labelno) * sizeof (rtx));
1754 bzero ((char *) labels, (max_labelno - min_labelno) * sizeof (rtx));
1756 /* Arrange for labels to be indexed directly by CODE_LABEL_NUMBER. */
1757 labels -= min_labelno;
1759 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1761 if (GET_CODE (insn) == CODE_LABEL)
1762 if (CODE_LABEL_NUMBER (insn) >= min_labelno
1763 && CODE_LABEL_NUMBER (insn) < max_labelno)
1764 labels[CODE_LABEL_NUMBER (insn)] = insn;
1767 /* For each start of a region, add its label to the list. */
1769 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1771 if (GET_CODE (insn) == NOTE
1772 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
1774 rtx label = NULL_RTX;
1776 if (NOTE_BLOCK_NUMBER (insn) >= min_labelno
1777 && NOTE_BLOCK_NUMBER (insn) < max_labelno)
1779 label = labels[NOTE_BLOCK_NUMBER (insn)];
1781 if (label)
1782 exception_handler_labels
1783 = gen_rtx (EXPR_LIST, VOIDmode,
1784 label, exception_handler_labels);
1785 else
1786 warning ("didn't find handler for EH region %d",
1787 NOTE_BLOCK_NUMBER (insn));
1789 else
1790 warning ("mismatched EH region %d", NOTE_BLOCK_NUMBER (insn));
1795 /* Perform sanity checking on the exception_handler_labels list.
1797 Can be called after find_exception_handler_labels is called to
1798 build the list of exception handlers for the current function and
1799 before we finish processing the current function. */
1801 void
1802 check_exception_handler_labels ()
1804 rtx insn, handler;
1806 /* If we aren't doing exception handling, there isn't much to check. */
1807 if (! doing_eh (0))
1808 return;
1810 /* Ensure that the CODE_LABEL_NUMBER for the CODE_LABEL entry point
1811 in each handler corresponds to the CODE_LABEL_NUMBER of the
1812 handler. */
1814 for (handler = exception_handler_labels;
1815 handler;
1816 handler = XEXP (handler, 1))
1818 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1820 if (GET_CODE (insn) == CODE_LABEL)
1822 if (CODE_LABEL_NUMBER (insn)
1823 == CODE_LABEL_NUMBER (XEXP (handler, 0)))
1825 if (insn != XEXP (handler, 0))
1826 warning ("mismatched handler %d",
1827 CODE_LABEL_NUMBER (insn));
1828 break;
1832 if (insn == NULL_RTX)
1833 warning ("handler not found %d",
1834 CODE_LABEL_NUMBER (XEXP (handler, 0)));
1837 /* Now go through and make sure that for each region there is a
1838 corresponding label. */
1839 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1841 if (GET_CODE (insn) == NOTE
1842 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
1843 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
1845 for (handler = exception_handler_labels;
1846 handler;
1847 handler = XEXP (handler, 1))
1849 if (CODE_LABEL_NUMBER (XEXP (handler, 0))
1850 == NOTE_BLOCK_NUMBER (insn))
1851 break;
1853 if (handler == NULL_RTX)
1854 warning ("region exists, no handler %d",
1855 NOTE_BLOCK_NUMBER (insn));
1860 /* This group of functions initializes the exception handling data
1861 structures at the start of the compilation, initializes the data
1862 structures at the start of a function, and saves and restores the
1863 exception handling data structures for the start/end of a nested
1864 function. */
1866 /* Toplevel initialization for EH things. */
1868 void
1869 init_eh ()
1871 /* Generate rtl to reference the variable in which the PC of the
1872 current context is saved. */
1873 tree type = build_pointer_type (make_node (VOID_TYPE));
1875 eh_saved_pc = build_decl (VAR_DECL, get_identifier ("__eh_pc"), type);
1876 DECL_EXTERNAL (eh_saved_pc) = 1;
1877 TREE_PUBLIC (eh_saved_pc) = 1;
1878 make_decl_rtl (eh_saved_pc, NULL_PTR, 1);
1879 eh_saved_pc_rtx = DECL_RTL (eh_saved_pc);
1882 /* Initialize the per-function EH information. */
1884 void
1885 init_eh_for_function ()
1887 ehstack.top = 0;
1888 ehqueue.head = ehqueue.tail = 0;
1889 catch_clauses = NULL_RTX;
1890 false_label_stack = 0;
1891 caught_return_label_stack = 0;
1892 protect_list = NULL_TREE;
1893 current_function_dhc = NULL_RTX;
1894 current_function_dcc = NULL_RTX;
1897 /* Save some of the per-function EH info into the save area denoted by
1900 This is currently called from save_stmt_status. */
1902 void
1903 save_eh_status (p)
1904 struct function *p;
1906 assert (p != NULL);
1908 p->ehstack = ehstack;
1909 p->ehqueue = ehqueue;
1910 p->catch_clauses = catch_clauses;
1911 p->false_label_stack = false_label_stack;
1912 p->caught_return_label_stack = caught_return_label_stack;
1913 p->protect_list = protect_list;
1914 p->dhc = current_function_dhc;
1915 p->dcc = current_function_dcc;
1917 init_eh ();
1920 /* Restore the per-function EH info saved into the area denoted by P.
1922 This is currently called from restore_stmt_status. */
1924 void
1925 restore_eh_status (p)
1926 struct function *p;
1928 assert (p != NULL);
1930 protect_list = p->protect_list;
1931 caught_return_label_stack = p->caught_return_label_stack;
1932 false_label_stack = p->false_label_stack;
1933 catch_clauses = p->catch_clauses;
1934 ehqueue = p->ehqueue;
1935 ehstack = p->ehstack;
1936 current_function_dhc = p->dhc;
1937 current_function_dcc = p->dcc;
1940 /* This section is for the exception handling specific optimization
1941 pass. First are the internal routines, and then the main
1942 optimization pass. */
1944 /* Determine if the given INSN can throw an exception. */
1946 static int
1947 can_throw (insn)
1948 rtx insn;
1950 /* Calls can always potentially throw exceptions. */
1951 if (GET_CODE (insn) == CALL_INSN)
1952 return 1;
1954 if (asynchronous_exceptions)
1956 /* If we wanted asynchronous exceptions, then everything but NOTEs
1957 and CODE_LABELs could throw. */
1958 if (GET_CODE (insn) != NOTE && GET_CODE (insn) != CODE_LABEL)
1959 return 1;
1962 return 0;
1965 /* Scan a exception region looking for the matching end and then
1966 remove it if possible. INSN is the start of the region, N is the
1967 region number, and DELETE_OUTER is to note if anything in this
1968 region can throw.
1970 Regions are removed if they cannot possibly catch an exception.
1971 This is determined by invoking can_throw on each insn within the
1972 region; if can_throw returns true for any of the instructions, the
1973 region can catch an exception, since there is an insn within the
1974 region that is capable of throwing an exception.
1976 Returns the NOTE_INSN_EH_REGION_END corresponding to this region, or
1977 calls abort if it can't find one.
1979 Can abort if INSN is not a NOTE_INSN_EH_REGION_BEGIN, or if N doesn't
1980 correspond to the region number, or if DELETE_OUTER is NULL. */
1982 static rtx
1983 scan_region (insn, n, delete_outer)
1984 rtx insn;
1985 int n;
1986 int *delete_outer;
1988 rtx start = insn;
1990 /* Assume we can delete the region. */
1991 int delete = 1;
1993 assert (insn != NULL_RTX
1994 && GET_CODE (insn) == NOTE
1995 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
1996 && NOTE_BLOCK_NUMBER (insn) == n
1997 && delete_outer != NULL);
1999 insn = NEXT_INSN (insn);
2001 /* Look for the matching end. */
2002 while (! (GET_CODE (insn) == NOTE
2003 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
2005 /* If anything can throw, we can't remove the region. */
2006 if (delete && can_throw (insn))
2008 delete = 0;
2011 /* Watch out for and handle nested regions. */
2012 if (GET_CODE (insn) == NOTE
2013 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
2015 insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &delete);
2018 insn = NEXT_INSN (insn);
2021 /* The _BEG/_END NOTEs must match and nest. */
2022 if (NOTE_BLOCK_NUMBER (insn) != n)
2023 abort ();
2025 /* If anything in this exception region can throw, we can throw. */
2026 if (! delete)
2027 *delete_outer = 0;
2028 else
2030 /* Delete the start and end of the region. */
2031 delete_insn (start);
2032 delete_insn (insn);
2034 /* Only do this part if we have built the exception handler
2035 labels. */
2036 if (exception_handler_labels)
2038 rtx x, *prev = &exception_handler_labels;
2040 /* Find it in the list of handlers. */
2041 for (x = exception_handler_labels; x; x = XEXP (x, 1))
2043 rtx label = XEXP (x, 0);
2044 if (CODE_LABEL_NUMBER (label) == n)
2046 /* If we are the last reference to the handler,
2047 delete it. */
2048 if (--LABEL_NUSES (label) == 0)
2049 delete_insn (label);
2051 if (optimize)
2053 /* Remove it from the list of exception handler
2054 labels, if we are optimizing. If we are not, then
2055 leave it in the list, as we are not really going to
2056 remove the region. */
2057 *prev = XEXP (x, 1);
2058 XEXP (x, 1) = 0;
2059 XEXP (x, 0) = 0;
2062 break;
2064 prev = &XEXP (x, 1);
2068 return insn;
2071 /* Perform various interesting optimizations for exception handling
2072 code.
2074 We look for empty exception regions and make them go (away). The
2075 jump optimization code will remove the handler if nothing else uses
2076 it. */
2078 void
2079 exception_optimize ()
2081 rtx insn, regions = NULL_RTX;
2082 int n;
2084 /* The below doesn't apply to setjmp/longjmp EH. */
2085 if (exceptions_via_longjmp)
2086 return;
2088 /* Remove empty regions. */
2089 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2091 if (GET_CODE (insn) == NOTE
2092 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
2094 /* Since scan_region will return the NOTE_INSN_EH_REGION_END
2095 insn, we will indirectly skip through all the insns
2096 inbetween. We are also guaranteed that the value of insn
2097 returned will be valid, as otherwise scan_region won't
2098 return. */
2099 insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &n);