#include "flags.h"
#include "function.h"
#include "expr.h"
+#include "libfuncs.h"
#include "insn-config.h"
#include "except.h"
#include "integrate.h"
/* Protect cleanup actions with must-not-throw regions, with a call
to the given failure handler. */
-tree protect_cleanup_actions;
+tree (*lang_protect_cleanup_actions) PARAMS ((void));
/* Return true if type A catches type B. */
int (*lang_eh_type_covers) PARAMS ((tree a, tree b));
rtx exception_handler_labels;
static int call_site_base;
-static int sjlj_funcdef_number;
+static unsigned int sjlj_funcdef_number;
static htab_t type_to_runtime_map;
/* Describe the SjLj_Function_Context structure. */
static struct eh_region *expand_eh_region_end PARAMS ((void));
-static rtx get_exception_filter PARAMS ((void));
+static rtx get_exception_filter PARAMS ((struct function *));
static void collect_eh_region_array PARAMS ((void));
static void resolve_fixup_regions PARAMS ((void));
static void push_uleb128 PARAMS ((varray_type *,
unsigned int));
static void push_sleb128 PARAMS ((varray_type *, int));
-static const char *eh_data_format_name PARAMS ((int));
#ifndef HAVE_AS_LEB128
static int dw2_size_of_call_site_table PARAMS ((void));
static int sjlj_size_of_call_site_table PARAMS ((void));
init_eh ()
{
ggc_add_rtx_root (&exception_handler_labels, 1);
- ggc_add_tree_root (&protect_cleanup_actions, 1);
if (! flag_exceptions)
return;
tree handler;
{
struct eh_region *region;
+ tree protect_cleanup_actions;
rtx around_label;
rtx data_save[2];
emit_label (region->label);
+ /* Give the language a chance to specify an action to be taken if an
+ exception is thrown that would propogate out of the HANDLER. */
+ protect_cleanup_actions
+ = (lang_protect_cleanup_actions
+ ? (*lang_protect_cleanup_actions) ()
+ : NULL_TREE);
+
if (protect_cleanup_actions)
expand_eh_region_start ();
/* In case this cleanup involves an inline destructor with a try block in
it, we need to save the EH return data registers around it. */
data_save[0] = gen_reg_rtx (Pmode);
- emit_move_insn (data_save[0], get_exception_pointer ());
+ emit_move_insn (data_save[0], get_exception_pointer (cfun));
data_save[1] = gen_reg_rtx (word_mode);
- emit_move_insn (data_save[1], get_exception_filter ());
+ emit_move_insn (data_save[1], get_exception_filter (cfun));
expand_expr (handler, const0_rtx, VOIDmode, 0);
/* End an exception region for an exception type filter. ALLOWED is a
TREE_LIST of types to be matched by the runtime. FAILURE is an
- expression to invoke if a mismatch ocurrs. */
+ expression to invoke if a mismatch ocurrs.
+
+ ??? We could use these semantics for calls to rethrow, too; if we can
+ see the surrounding catch clause, we know that the exception we're
+ rethrowing satisfies the "filter" of the catch type. */
void
expand_eh_region_end_allowed (allowed, failure)
emit_label (region->label);
expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ /* We must adjust the stack before we reach the AROUND_LABEL because
+ the call to FAILURE does not occur on all paths to the
+ AROUND_LABEL. */
+ do_pending_stack_adjust ();
emit_label (around_label);
}
within a handler. */
rtx
-get_exception_pointer ()
+get_exception_pointer (fun)
+ struct function *fun;
{
- rtx exc_ptr = cfun->eh->exc_ptr;
- if (! exc_ptr)
+ rtx exc_ptr = fun->eh->exc_ptr;
+ if (fun == cfun && ! exc_ptr)
{
exc_ptr = gen_reg_rtx (Pmode);
- cfun->eh->exc_ptr = exc_ptr;
+ fun->eh->exc_ptr = exc_ptr;
}
return exc_ptr;
}
within a handler. */
static rtx
-get_exception_filter ()
+get_exception_filter (fun)
+ struct function *fun;
{
- rtx filter = cfun->eh->filter;
- if (! filter)
+ rtx filter = fun->eh->filter;
+ if (fun == cfun && ! filter)
{
filter = gen_reg_rtx (word_mode);
- cfun->eh->filter = filter;
+ fun->eh->filter = filter;
}
return filter;
}
for (i = 1; i <= n; ++i)
{
struct eh_region *fixup = cfun->eh->region_array[i];
- struct eh_region *cleanup;
+ struct eh_region *cleanup = 0;
if (! fixup || fixup->type != ERT_FIXUP)
continue;
&& fixup->type == ERT_FIXUP)
{
if (fixup->u.fixup.real_region)
- XEXP (note, 1) = GEN_INT (fixup->u.fixup.real_region->region_number);
+ XEXP (note, 0) = GEN_INT (fixup->u.fixup.real_region->region_number);
else
remove_note (insn, note);
}
/* If we wanted exceptions for non-call insns, then
any may_trap_p instruction could throw. */
|| (flag_non_call_exceptions
+ && GET_CODE (PATTERN (insn)) != CLOBBER
+ && GET_CODE (PATTERN (insn)) != USE
&& may_trap_p (PATTERN (insn)))))
{
REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, GEN_INT (cur),
cur->inner = root;
for (i = 1; i <= ifun_last_region_number; ++i)
- if (n_array[i]->outer == NULL)
+ if (n_array[i] && n_array[i]->outer == NULL)
n_array[i]->outer = cur;
}
else
}
\f
-/* ??? Move from tree.c to tree.h. */
-#define TYPE_HASH(TYPE) ((HOST_WIDE_INT) (TYPE) & 0777777)
-
static int
t2r_eq (pentry, pdata)
const PTR pentry;
seq = get_insns ();
end_sequence ();
emit_insns_before (seq, region->resume);
-
- /* Leave the RESX to be deleted by flow. */
+ flow_delete_insn (region->resume);
}
}
static void
dw2_build_landing_pads ()
{
- int i, j;
+ int i;
+ unsigned int j;
for (i = cfun->eh->last_region_number; i > 0; --i)
{
emit_move_insn (cfun->eh->exc_ptr,
gen_rtx_REG (Pmode, EH_RETURN_DATA_REGNO (0)));
emit_move_insn (cfun->eh->filter,
- gen_rtx_REG (Pmode, EH_RETURN_DATA_REGNO (1)));
+ gen_rtx_REG (word_mode, EH_RETURN_DATA_REGNO (1)));
seq = get_insns ();
end_sequence ();
int last_call_site = -2;
rtx insn, mem;
- mem = change_address (cfun->eh->sjlj_fc, TYPE_MODE (integer_type_node),
- plus_constant (XEXP (cfun->eh->sjlj_fc, 0),
- sjlj_fc_call_site_ofs));
+ mem = adjust_address (cfun->eh->sjlj_fc, TYPE_MODE (integer_type_node),
+ sjlj_fc_call_site_ofs);
for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
{
/* Don't separate a call from it's argument loads. */
before = insn;
if (GET_CODE (insn) == CALL_INSN)
- {
- HARD_REG_SET parm_regs;
- int nparm_regs;
-
- /* Since different machines initialize their parameter registers
- in different orders, assume nothing. Collect the set of all
- parameter registers. */
- CLEAR_HARD_REG_SET (parm_regs);
- nparm_regs = 0;
- for (p = CALL_INSN_FUNCTION_USAGE (insn); p ; p = XEXP (p, 1))
- if (GET_CODE (XEXP (p, 0)) == USE
- && GET_CODE (XEXP (XEXP (p, 0), 0)) == REG)
- {
- if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER)
- abort ();
-
- /* We only care about registers which can hold function
- arguments. */
- if (! FUNCTION_ARG_REGNO_P (REGNO (XEXP (XEXP (p, 0), 0))))
- continue;
-
- SET_HARD_REG_BIT (parm_regs, REGNO (XEXP (XEXP (p, 0), 0)));
- nparm_regs++;
- }
-
- /* Search backward for the first set of a register in this set. */
- while (nparm_regs)
- {
- before = PREV_INSN (before);
-
- /* Given that we've done no other optimizations yet,
- the arguments should be immediately available. */
- if (GET_CODE (before) == CODE_LABEL)
- abort ();
-
- p = single_set (before);
- if (p && GET_CODE (SET_DEST (p)) == REG
- && REGNO (SET_DEST (p)) < FIRST_PSEUDO_REGISTER
- && TEST_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p))))
- {
- CLEAR_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p)));
- nparm_regs--;
- }
- }
- }
+ before = find_first_parameter_load (insn, NULL_RTX);
start_sequence ();
emit_move_insn (mem, GEN_INT (this_call_site));
start_sequence ();
- mem = change_address (fc, Pmode,
- plus_constant (XEXP (fc, 0), sjlj_fc_personality_ofs));
+ /* We're storing this libcall's address into memory instead of
+ calling it directly. Thus, we must call assemble_external_libcall
+ here, as we can not depend on emit_library_call to do it for us. */
+ assemble_external_libcall (eh_personality_libfunc);
+ mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
emit_move_insn (mem, eh_personality_libfunc);
- mem = change_address (fc, Pmode,
- plus_constant (XEXP (fc, 0), sjlj_fc_lsda_ofs));
+ mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
if (cfun->uses_eh_lsda)
{
char buf[20];
/* Load up dispatch index, exc_ptr and filter values from the
function context. */
- mem = change_address (fc, TYPE_MODE (integer_type_node),
- plus_constant (XEXP (fc, 0), sjlj_fc_call_site_ofs));
+ mem = adjust_address (fc, TYPE_MODE (integer_type_node),
+ sjlj_fc_call_site_ofs);
dispatch = copy_to_reg (mem);
- mem = change_address (fc, word_mode,
- plus_constant (XEXP (fc, 0), sjlj_fc_data_ofs));
+ mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs);
if (word_mode != Pmode)
{
#ifdef POINTERS_EXTEND_UNSIGNED
}
emit_move_insn (cfun->eh->exc_ptr, mem);
- mem = change_address (fc, word_mode,
- plus_constant (XEXP (fc, 0),
- sjlj_fc_data_ofs + UNITS_PER_WORD));
+ mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs + UNITS_PER_WORD);
emit_move_insn (cfun->eh->filter, mem);
/* Jump to one of the directly reachable regions. */
connect many of the handlers, and then type information will not
be effective. Still, this is a win over previous implementations. */
- jump_optimize_minimal (get_insns ());
+ rebuild_jump_labels (get_insns ());
find_basic_blocks (get_insns (), max_reg_num (), 0);
- cleanup_cfg ();
+ cleanup_cfg (CLEANUP_PRE_LOOP);
/* These registers are used by the landing pads. Make sure they
have been generated. */
- get_exception_pointer ();
- get_exception_filter ();
+ get_exception_pointer (cfun);
+ get_exception_filter (cfun);
/* Construct the landing pads. */
/* We've totally changed the CFG. Start over. */
find_exception_handler_labels ();
- jump_optimize_minimal (get_insns ());
+ rebuild_jump_labels (get_insns ());
find_basic_blocks (get_insns (), max_reg_num (), 0);
- cleanup_cfg ();
+ cleanup_cfg (CLEANUP_PRE_LOOP);
}
\f
/* This section handles removing dead code for flow. */
region = cfun->eh->region_array[region_number];
type_thrown = NULL_TREE;
- if (region->type == ERT_THROW)
+ if (GET_CODE (insn) == JUMP_INSN
+ && GET_CODE (PATTERN (insn)) == RESX)
+ {
+ /* A RESX leaves a region instead of entering it. Thus the
+ region itself may have been deleted out from under us. */
+ if (region == NULL)
+ return NULL;
+ region = region->outer;
+ }
+ else if (region->type == ERT_THROW)
{
type_thrown = region->u.throw.type;
region = region->outer;
}
- else if (GET_CODE (insn) == JUMP_INSN
- && GET_CODE (PATTERN (insn)) == RESX)
- region = region->outer;
for (; region; region = region->outer)
if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT)
expand_builtin_unwind_init ()
{
/* Set this so all the registers get saved in our frame; we need to be
- able to copy the saved values for any registers from frames we unwind. */
+ able to copy the saved values for any registers from frames we unwind. */
current_function_has_nonlocal_label = 1;
#ifdef SETUP_FRAME_ADDRESSES
{
rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
+#ifdef POINTERS_EXTEND_UNSIGNED
+ addr = convert_memory_address (Pmode, addr);
+#endif
+
#ifdef RETURN_ADDR_OFFSET
addr = force_reg (Pmode, addr);
addr = plus_constant (addr, -RETURN_ADDR_OFFSET);
stackadj = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj, VOIDmode, 0);
handler = expand_expr (handler_tree, cfun->eh->ehr_handler, VOIDmode, 0);
+#ifdef POINTERS_EXTEND_UNSIGNED
+ stackadj = convert_memory_address (Pmode, stackadj);
+ handler = convert_memory_address (Pmode, handler);
+#endif
+
if (! cfun->eh->ehr_label)
{
cfun->eh->ehr_stackadj = copy_to_reg (stackadj);
emit_label (around_label);
}
\f
+/* In the following functions, we represent entries in the action table
+ as 1-based indicies. Special cases are:
+
+ 0: null action record, non-null landing pad; implies cleanups
+ -1: null action record, null landing pad; implies no action
+ -2: no call-site entry; implies must_not_throw
+ -3: we have yet to process outer regions
+
+ Further, no special cases apply to the "next" field of the record.
+ For next, 0 means end of list. */
+
struct action_record
{
int offset;
if (next == -3)
{
next = collect_one_action_chain (ar_hash, region->outer);
- if (next < 0)
+
+ /* If there is no next action, terminate the chain. */
+ if (next == -1)
next = 0;
+ /* If all outer actions are cleanups or must_not_throw,
+ we'll have no action record for it, since we had wanted
+ to encode these states in the call-site record directly.
+ Add a cleanup action to the chain to catch these. */
+ else if (next <= 0)
+ next = add_action_record (ar_hash, 0, 0);
}
next = add_action_record (ar_hash, c->u.catch.filter, next);
}
rtx last_action_insn = NULL_RTX;
rtx last_landing_pad = NULL_RTX;
rtx first_no_action_insn = NULL_RTX;
- int call_site;
+ int call_site = 0;
if (USING_SJLJ_EXCEPTIONS || cfun->eh->region_tree == NULL)
return;
}
\f
-static const char *
-eh_data_format_name (format)
- int format;
-{
- switch (format)
- {
- case DW_EH_PE_absptr: return "absolute";
- case DW_EH_PE_omit: return "omit";
-
- case DW_EH_PE_uleb128: return "uleb128";
- case DW_EH_PE_udata2: return "udata2";
- case DW_EH_PE_udata4: return "udata4";
- case DW_EH_PE_udata8: return "udata8";
- case DW_EH_PE_sleb128: return "sleb128";
- case DW_EH_PE_sdata2: return "sdata2";
- case DW_EH_PE_sdata4: return "sdata4";
- case DW_EH_PE_sdata8: return "sdata8";
-
- case DW_EH_PE_uleb128 | DW_EH_PE_pcrel: return "pcrel uleb128";
- case DW_EH_PE_udata2 | DW_EH_PE_pcrel: return "pcrel udata2";
- case DW_EH_PE_udata4 | DW_EH_PE_pcrel: return "pcrel udata4";
- case DW_EH_PE_udata8 | DW_EH_PE_pcrel: return "pcrel udata8";
- case DW_EH_PE_sleb128 | DW_EH_PE_pcrel: return "pcrel sleb128";
- case DW_EH_PE_sdata2 | DW_EH_PE_pcrel: return "pcrel sdata2";
- case DW_EH_PE_sdata4 | DW_EH_PE_pcrel: return "pcrel sdata4";
- case DW_EH_PE_sdata8 | DW_EH_PE_pcrel: return "pcrel sdata8";
-
- case DW_EH_PE_uleb128 | DW_EH_PE_textrel: return "textrel uleb128";
- case DW_EH_PE_udata2 | DW_EH_PE_textrel: return "textrel udata2";
- case DW_EH_PE_udata4 | DW_EH_PE_textrel: return "textrel udata4";
- case DW_EH_PE_udata8 | DW_EH_PE_textrel: return "textrel udata8";
- case DW_EH_PE_sleb128 | DW_EH_PE_textrel: return "textrel sleb128";
- case DW_EH_PE_sdata2 | DW_EH_PE_textrel: return "textrel sdata2";
- case DW_EH_PE_sdata4 | DW_EH_PE_textrel: return "textrel sdata4";
- case DW_EH_PE_sdata8 | DW_EH_PE_textrel: return "textrel sdata8";
-
- case DW_EH_PE_uleb128 | DW_EH_PE_datarel: return "datarel uleb128";
- case DW_EH_PE_udata2 | DW_EH_PE_datarel: return "datarel udata2";
- case DW_EH_PE_udata4 | DW_EH_PE_datarel: return "datarel udata4";
- case DW_EH_PE_udata8 | DW_EH_PE_datarel: return "datarel udata8";
- case DW_EH_PE_sleb128 | DW_EH_PE_datarel: return "datarel sleb128";
- case DW_EH_PE_sdata2 | DW_EH_PE_datarel: return "datarel sdata2";
- case DW_EH_PE_sdata4 | DW_EH_PE_datarel: return "datarel sdata4";
- case DW_EH_PE_sdata8 | DW_EH_PE_datarel: return "datarel sdata8";
-
- case DW_EH_PE_uleb128 | DW_EH_PE_funcrel: return "funcrel uleb128";
- case DW_EH_PE_udata2 | DW_EH_PE_funcrel: return "funcrel udata2";
- case DW_EH_PE_udata4 | DW_EH_PE_funcrel: return "funcrel udata4";
- case DW_EH_PE_udata8 | DW_EH_PE_funcrel: return "funcrel udata8";
- case DW_EH_PE_sleb128 | DW_EH_PE_funcrel: return "funcrel sleb128";
- case DW_EH_PE_sdata2 | DW_EH_PE_funcrel: return "funcrel sdata2";
- case DW_EH_PE_sdata4 | DW_EH_PE_funcrel: return "funcrel sdata4";
- case DW_EH_PE_sdata8 | DW_EH_PE_funcrel: return "funcrel sdata8";
-
- case DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel:
- return "indirect pcrel uleb128";
- case DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_pcrel:
- return "indirect pcrel udata2";
- case DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_pcrel:
- return "indirect pcrel udata4";
- case DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_pcrel:
- return "indirect pcrel udata8";
- case DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_pcrel:
- return "indirect pcrel sleb128";
- case DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_pcrel:
- return "indirect pcrel sdata2";
- case DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_pcrel:
- return "indirect pcrel sdata4";
- case DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_pcrel:
- return "indirect pcrel sdata8";
-
- case DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_textrel:
- return "indirect textrel uleb128";
- case DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_textrel:
- return "indirect textrel udata2";
- case DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_textrel:
- return "indirect textrel udata4";
- case DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_textrel:
- return "indirect textrel udata8";
- case DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_textrel:
- return "indirect textrel sleb128";
- case DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_textrel:
- return "indirect textrel sdata2";
- case DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_textrel:
- return "indirect textrel sdata4";
- case DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_textrel:
- return "indirect textrel sdata8";
-
- case DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_datarel:
- return "indirect datarel uleb128";
- case DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_datarel:
- return "indirect datarel udata2";
- case DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_datarel:
- return "indirect datarel udata4";
- case DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_datarel:
- return "indirect datarel udata8";
- case DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_datarel:
- return "indirect datarel sleb128";
- case DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_datarel:
- return "indirect datarel sdata2";
- case DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_datarel:
- return "indirect datarel sdata4";
- case DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_datarel:
- return "indirect datarel sdata8";
-
- case DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_funcrel:
- return "indirect funcrel uleb128";
- case DW_EH_PE_indirect | DW_EH_PE_udata2 | DW_EH_PE_funcrel:
- return "indirect funcrel udata2";
- case DW_EH_PE_indirect | DW_EH_PE_udata4 | DW_EH_PE_funcrel:
- return "indirect funcrel udata4";
- case DW_EH_PE_indirect | DW_EH_PE_udata8 | DW_EH_PE_funcrel:
- return "indirect funcrel udata8";
- case DW_EH_PE_indirect | DW_EH_PE_sleb128 | DW_EH_PE_funcrel:
- return "indirect funcrel sleb128";
- case DW_EH_PE_indirect | DW_EH_PE_sdata2 | DW_EH_PE_funcrel:
- return "indirect funcrel sdata2";
- case DW_EH_PE_indirect | DW_EH_PE_sdata4 | DW_EH_PE_funcrel:
- return "indirect funcrel sdata4";
- case DW_EH_PE_indirect | DW_EH_PE_sdata8 | DW_EH_PE_funcrel:
- return "indirect funcrel sdata8";
-
- default:
- abort ();
- }
-}
-
#ifndef HAVE_AS_LEB128
static int
dw2_size_of_call_site_table ()
#endif
int have_tt_data;
int funcdef_number;
+ int tt_format_size = 0;
/* Not all functions need anything. */
if (! cfun->uses_eh_lsda)
have_tt_data = (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) > 0
|| VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) > 0);
- if (have_tt_data)
- assemble_eh_align (GET_MODE_ALIGNMENT (ptr_mode));
+ /* Indicate the format of the @TType entries. */
+ if (! have_tt_data)
+ tt_format = DW_EH_PE_omit;
+ else
+ {
+ tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
+#ifdef HAVE_AS_LEB128
+ ASM_GENERATE_INTERNAL_LABEL (ttype_label, "LLSDATT", funcdef_number);
+#endif
+ tt_format_size = size_of_encoded_value (tt_format);
+
+ assemble_align (tt_format_size * BITS_PER_UNIT);
+ }
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LLSDA", funcdef_number);
/* @LPStart pointer would go here. */
- /* Indicate the format of the @TType entries. */
- if (! have_tt_data)
- tt_format = DW_EH_PE_omit;
- else
- {
- tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
-#ifdef HAVE_AS_LEB128
- ASM_GENERATE_INTERNAL_LABEL (ttype_label, "LLSDATT", funcdef_number);
-#endif
- }
dw2_asm_output_data (1, tt_format, "@TType format (%s)",
eh_data_format_name (tt_format));
ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label);
#else
/* Ug. Alignment queers things. */
- unsigned int before_disp, after_disp, last_disp, disp, align;
+ unsigned int before_disp, after_disp, last_disp, disp;
- align = POINTER_SIZE / BITS_PER_UNIT;
before_disp = 1 + 1;
after_disp = (1 + size_of_uleb128 (call_site_len)
+ call_site_len
+ VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data)
- + VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) * align);
+ + (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data)
+ * tt_format_size));
disp = after_disp;
do
last_disp = disp;
disp_size = size_of_uleb128 (disp);
pad = before_disp + disp_size + after_disp;
- if (pad % align)
- pad = align - (pad % align);
+ if (pad % tt_format_size)
+ pad = tt_format_size - (pad % tt_format_size);
else
pad = 0;
disp = after_disp + pad;
(i ? NULL : "Action record table"));
if (have_tt_data)
- assemble_eh_align (GET_MODE_ALIGNMENT (ptr_mode));
+ assemble_align (tt_format_size * BITS_PER_UNIT);
i = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data);
while (i-- > 0)
dw2_asm_output_encoded_addr_rtx (tt_format,
expand_expr (type, NULL_RTX, VOIDmode,
- EXPAND_INITIALIZER));
+ EXPAND_INITIALIZER),
+ NULL);
}
#ifdef HAVE_AS_LEB128