# Language-independent object files.
OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \
- function.o stmt.o expr.o calls.o expmed.o explow.o optabs.o varasm.o \
- rtl.o print-rtl.o rtlanal.o emit-rtl.o real.o \
+ function.o stmt.o except.o expr.o calls.o expmed.o explow.o optabs.o \
+ varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o real.o \
dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o \
integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o \
regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o \
insn-flags.h insn-codes.h expr.h regs.h hard-reg-set.h insn-config.h \
recog.h output.h bytecode.h bc-emit.h
stmt.o : stmt.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h function.h \
- insn-flags.h insn-config.h insn-codes.h hard-reg-set.h expr.h loop.h \
- recog.h bytecode.h bc-typecd.h bc-typecd.def bc-opcode.h bc-optab.h \
- bc-emit.h
+ insn-flags.h insn-config.h insn-codes.h hard-reg-set.h expr.h except.h \
+ loop.h recog.h bytecode.h bc-typecd.h bc-typecd.def bc-opcode.h \
+ bc-optab.h bc-emit.h
+except.o : except.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h function.h \
+ insn-flags.h insn-codes.h expr.h regs.h hard-reg-set.h insn-config.h \
+ recog.h output.h except.h
expr.o : expr.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h function.h regs.h \
insn-flags.h insn-codes.h expr.h insn-config.h recog.h output.h \
typeclass.h bytecode.h bc-opcode.h bc-typecd.h bc-typecd.def bc-optab.h \
sched.o : sched.c $(CONFIG_H) $(RTL_H) basic-block.h regs.h hard-reg-set.h \
flags.h insn-config.h insn-attr.h
final.o : final.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h regs.h \
- recog.h conditions.h insn-config.h insn-attr.h real.h output.h \
+ recog.h conditions.h insn-config.h insn-attr.h except.h real.h output.h \
hard-reg-set.h insn-flags.h insn-codes.h gstab.h xcoffout.h defaults.h
recog.o : recog.c $(CONFIG_H) $(RTL_H) \
regs.h recog.h hard-reg-set.h flags.h insn-config.h insn-attr.h \
#include "flags.h"
#include "regs.h"
#include "hard-reg-set.h"
+#include "except.h"
#include "function.h"
#include "insn-flags.h"
#include "insn-codes.h"
static rtx compare PROTO((tree, enum rtx_code, enum rtx_code));
static rtx do_store_flag PROTO((tree, rtx, enum machine_mode, int));
static tree defer_cleanups_to PROTO((tree));
-extern void (*interim_eh_hook) PROTO((tree));
extern tree truthvalue_conversion PROTO((tree));
/* Record for each mode whether we can move a register directly to or
= tree_cons (NULL_TREE, TREE_OPERAND (exp, 2), cleanups_this_call);
/* That's it for this cleanup. */
TREE_OPERAND (exp, 2) = 0;
- (*interim_eh_hook) (NULL_TREE);
+ expand_eh_region_start ();
}
return RTL_EXPR_RTL (exp);
pop_obstacks ();
- /* Now add in the conditionalized cleanups. */
+ /* Now add in the conditionalized cleanups. */
cleanups_this_call
= tree_cons (NULL_TREE, new_cleanups, cleanups_this_call);
- (*interim_eh_hook) (NULL_TREE);
+ expand_eh_region_start ();
}
return temp;
}
cleanups_this_call = tree_cons (NULL_TREE,
cleanups,
cleanups_this_call);
- (*interim_eh_hook) (NULL_TREE);
+ expand_eh_region_start ();
}
return target;
while (cleanups_this_call != old_cleanups)
{
- (*interim_eh_hook) (TREE_VALUE (cleanups_this_call));
+ expand_eh_region_end (TREE_VALUE (cleanups_this_call));
last = cleanups_this_call;
cleanups_this_call = TREE_CHAIN (cleanups_this_call);
}
{
while (cleanups_this_call != old_cleanups)
{
- (*interim_eh_hook) (TREE_VALUE (cleanups_this_call));
+ expand_eh_region_end (TREE_VALUE (cleanups_this_call));
expand_expr (TREE_VALUE (cleanups_this_call), const0_rtx, VOIDmode, 0);
cleanups_this_call = TREE_CHAIN (cleanups_this_call);
}
pop_obstacks ();
- /* Now add in the conditionalized cleanups. */
+ /* Now add in the conditionalized cleanups. */
cleanups_this_call
= tree_cons (NULL_TREE, new_cleanups, cleanups_this_call);
- (*interim_eh_hook) (NULL_TREE);
+ expand_eh_region_start ();
}
else
{
pop_obstacks ();
- /* Now add in the conditionalized cleanups. */
+ /* Now add in the conditionalized cleanups. */
cleanups_this_call
= tree_cons (NULL_TREE, new_cleanups, cleanups_this_call);
- (*interim_eh_hook) (NULL_TREE);
+ expand_eh_region_start ();
}
else
{
extern rtx memset_libfunc;
extern rtx bzero_libfunc;
+extern rtx throw_libfunc;
+
extern rtx eqhf2_libfunc;
extern rtx nehf2_libfunc;
extern rtx gthf2_libfunc;
#include "hard-reg-set.h"
#include "defaults.h"
#include "output.h"
+#include "except.h"
/* Get N_SLINE and N_SOL from stab.h if we can expect the file to exist. */
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
last_ignored_compare = 0;
new_block = 1;
+ check_exception_handler_labels ();
+
/* Make a map indicating which line numbers appear in this function.
When producing SDB debugging info, delete troublesome line number
notes from inlined functions in other files as well as duplicate
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
break;
+ if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
+ {
+ ASM_OUTPUT_INTERNAL_LABEL (file, "LEHB", NOTE_BLOCK_NUMBER (insn));
+ add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
+#ifdef ASM_OUTPUT_EH_REGION_BEG
+ ASM_OUTPUT_EH_REGION_BEG (file, NOTE_BLOCK_NUMBER (insn));
+#endif
+ break;
+ }
+
+ if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
+ {
+ ASM_OUTPUT_INTERNAL_LABEL (file, "LEHE", NOTE_BLOCK_NUMBER (insn));
+#ifdef ASM_OUTPUT_EH_REGION_END
+ ASM_OUTPUT_EH_REGION_END (file, NOTE_BLOCK_NUMBER (insn));
+#endif
+ break;
+ }
+
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
{
#ifdef FUNCTION_END_PROLOGUE
#include "hard-reg-set.h"
#include "flags.h"
#include "output.h"
+#include "except.h"
#include "obstack.h"
#define obstack_chunk_alloc xmalloc
if (! LABEL_REF_NONLOCAL_P (x))
block_live[BLOCK_NUM (XEXP (x, 0))] = 1;
+ for (x = exception_handler_labels; x; x = XEXP (x, 1))
+ block_live[BLOCK_NUM (XEXP (x, 0))] = 1;
+
/* Record which basic blocks control can drop in to. */
for (i = 0; i < n_basic_blocks; i++)
"NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
"NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
"NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
- "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG"};
+ "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG",
+ "NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END"};
char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
"REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
i.e. the point just after all of the parms have been moved into
their homes, etc. */
#define NOTE_INSN_FUNCTION_BEG -13
+/* These note where exception handling regions begin and end. */
+#define NOTE_INSN_EH_REGION_BEG -14
+#define NOTE_INSN_EH_REGION_END -15
#if 0 /* These are not used, and I don't know what they were for. --rms. */
#include "output.h"
#include "bytecode.h"
#include "bc-emit.h"
+#include "except.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h"
void (*incomplete_decl_finalize_hook) () = 0;
-/* Pointer to function for interim exception handling implementation.
- This interface will change, and it is only here until a better interface
- replaces it. */
-
-void (*interim_eh_hook) PROTO((tree));
-
/* Highest label number used at the end of reload. */
int max_label_num_after_reload;
int flag_pic;
+/* Nonzero means generate extra code for exception handling and enable
+ exception handling. */
+
+int flag_exceptions = 1;
+
/* Nonzero means don't place uninitialized global data in common storage
- by default. */
+ by default. */
int flag_no_common;
{"schedule-insns2", &flag_schedule_insns_after_reload, 1},
{"pic", &flag_pic, 1},
{"PIC", &flag_pic, 2},
+ {"exceptions", &flag_exceptions, 1},
{"fast-math", &flag_fast_math, 1},
{"common", &flag_no_common, 0},
{"inhibit-size-directive", &flag_inhibit_size_directive, 1},
{
return IDENTIFIER_POINTER (DECL_NAME (decl));
}
-
-/* This is the default interim_eh_hook function. */
-
-void
-interim_eh (finalization)
- tree finalization;
-{
- /* Don't do anything by default. */
-}
\f
static int need_error_newline;
}
}
+ /* Now that all possible functions have been output, we can dump
+ the exception table. */
+
+ if (exception_table_p ())
+ output_exception_table ();
+
for (i = 0; i < len; i++)
{
decl = vec[i];
FINALIZE_PIC;
#endif
+ /* Add an unwinder for exception handling, if needed. */
+ emit_unwinder ();
+
insns = get_insns ();
/* Copy any shared structure that should not be shared. */
for all references to such slots. */
/* fixup_stack_slots (); */
+ /* Find all the EH handlers. */
+ find_exception_handler_labels ();
+
/* Always do one jump optimization pass to ensure that JUMP_LABEL fields
are initialized and to compute whether control can drop off the end
of the function. */
decl_printable_name = decl_name;
lang_expand_expr = (struct rtx_def *(*)()) do_abort;
- interim_eh_hook = interim_eh;
/* Initialize whether `char' is signed. */
flag_signed_char = DEFAULT_SIGNED_CHAR;