aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1998-09-15 12:19:12 -0700
committerRichard Henderson <rth@gcc.gnu.org>1998-09-15 12:19:12 -0700
commit710384268d9df98e595cd68c5e8db84d766d5513 (patch)
tree5f8b92560efd1078cbd16601e8b3502296539971 /gcc/config
parentdfb16e8307d6ca6f9ddf22dea3400324355a60a7 (diff)
downloadgcc-710384268d9df98e595cd68c5e8db84d766d5513.zip
gcc-710384268d9df98e595cd68c5e8db84d766d5513.tar.gz
gcc-710384268d9df98e595cd68c5e8db84d766d5513.tar.bz2
tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused.
* tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused. Kill. (BUILT_IN_FP, BUILT_IN_SP, BUILT_IN_SET_RETURN_ADDR_REG): Kill. (BUILT_IN_EH_STUB_OLD, BUILT_IN_EH_STUB, BUILT_IN_SET_EH_REGS): Kill. (BUILT_IN_EH_RETURN, BUILT_IN_DWARF_CFA): New. * c-decl.c (init_decl_processing): Update accordingly. * expr.c (expand_builtin): Likewise. * cp/decl.c (init_decl_processing): Likewise. * rtl.h (global_rtl): Add cfa entry. (virtual_cfa_rtx, VIRTUAL_CFA_REGNUM): New. (LAST_VIRTUAL_REGISTER): Update. * emit-rtl.c (global_rtl): Add cfa entry. (init_emit): Initialize it. * function.c (cfa_offset): New. (instantiate_virtual_regs): Initialize it. (instantiate_virtual_regs_1): Instantiate virtual_cfa_rtx. (expand_function_end): Call expand_eh_return. * tm.texi (ARG_POINTER_CFA_OFFSET): New. * except.c (current_function_eh_stub_label): Kill. (current_function_eh_old_stub_label): Likwise; update all references. (expand_builtin_set_return_addr_reg): Kill. (expand_builtin_eh_stub_old, expand_builtin_eh_stub): Kill. (expand_builtin_set_eh_regs): Kill. (eh_regs): Produce a third reg for the actual handler address. (eh_return_context, eh_return_stack_adjust): New. (eh_return_handler, eh_return_stub_label): New. (init_eh_for_function): Initialize them. (expand_builtin_eh_return, expand_eh_return): New. * except.h: Update prototypes. * flow.c (find_basic_blocks_1): Update references to the stub label. * function.h (struct function): Kill stub label elements. * libgcc2.c (in_reg_window): For REG_SAVED_REG, check that the register number is one that would be in the previous window. Provide a dummy definition for non-windowed targets. (get_reg_addr): New function. (get_reg, put_reg, copy_reg): Use it. (__throw): Rely on in_reg_window, not INCOMING_REGNO. Kill stub generating code and use __builtin_eh_return. Use __builtin_dwarf_cfa. * alpha.c (alpha_eh_epilogue_sp_ofs): New. (alpha_init_expanders): Initialize it. (alpha_expand_epilogue): Use it. * alpha.h: Declare it. * alpha.md (eh_epilogue): New. * m68h.h (ARG_POINTER_CFA_OFFSET): New. * sparc.h (ARG_POINTER_CFA_OFFSET): New. From-SVN: r22436
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/alpha/alpha.c45
-rw-r--r--gcc/config/alpha/alpha.h4
-rw-r--r--gcc/config/alpha/alpha.md16
-rw-r--r--gcc/config/m68k/m68k.h3
-rw-r--r--gcc/config/sparc/sparc.h4
5 files changed, 57 insertions, 15 deletions
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index f0795f3..2b29714 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -79,6 +79,10 @@ char *alpha_mlat_string; /* -mmemory-latency= */
rtx alpha_compare_op0, alpha_compare_op1;
int alpha_compare_fp_p;
+/* Define the information needed to modify the epilogue for EH. */
+
+rtx alpha_eh_epilogue_sp_ofs;
+
/* Non-zero if inside of a function, because the Alpha asm can't
handle .files inside of functions. */
@@ -2431,6 +2435,7 @@ void
alpha_init_expanders ()
{
alpha_return_addr_rtx = NULL_RTX;
+ alpha_eh_epilogue_sp_ofs = NULL_RTX;
/* Arrange to save and restore machine status around nested functions. */
save_machine_status = alpha_save_machine_status;
@@ -3731,9 +3736,13 @@ alpha_expand_epilogue ()
/* Restore registers in order, excepting a true frame pointer. */
- FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA),
- gen_rtx_MEM (DImode, plus_constant(sa_reg,
- reg_offset))));
+ if (! alpha_eh_epilogue_sp_ofs)
+ {
+ FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA),
+ gen_rtx_MEM (DImode,
+ plus_constant(sa_reg,
+ reg_offset))));
+ }
reg_offset += 8;
imask &= ~(1L << REG_RA);
@@ -3763,21 +3772,28 @@ alpha_expand_epilogue ()
}
}
- if (frame_size)
+ if (frame_size || alpha_eh_epilogue_sp_ofs)
{
+ sp_adj1 = stack_pointer_rtx;
+
+ if (alpha_eh_epilogue_sp_ofs)
+ {
+ sp_adj1 = gen_rtx_REG (DImode, 23);
+ emit_move_insn (sp_adj1,
+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+ alpha_eh_epilogue_sp_ofs));
+ }
+
/* If the stack size is large, begin computation into a temporary
register so as not to interfere with a potential fp restore,
which must be consecutive with an SP restore. */
if (frame_size < 32768)
- {
- sp_adj1 = stack_pointer_rtx;
- sp_adj2 = GEN_INT (frame_size);
- }
+ sp_adj2 = GEN_INT (frame_size);
else if (frame_size < 0x40007fffL)
{
int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
- sp_adj2 = plus_constant (stack_pointer_rtx, frame_size - low);
+ sp_adj2 = plus_constant (sp_adj1, frame_size - low);
if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
sp_adj1 = sa_reg;
else
@@ -3789,21 +3805,20 @@ alpha_expand_epilogue ()
}
else
{
- sp_adj2 = gen_rtx_REG (DImode, 23);
- FRP (sp_adj1 = alpha_emit_set_const (sp_adj2, DImode, frame_size, 3));
- if (!sp_adj1)
+ rtx tmp = gen_rtx_REG (DImode, 23);
+ FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
+ if (!sp_adj2)
{
/* We can't drop new things to memory this late, afaik,
so build it up by pieces. */
#if HOST_BITS_PER_WIDE_INT == 64
- FRP (sp_adj1 = alpha_emit_set_long_const (sp_adj2, frame_size));
- if (!sp_adj1)
+ FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size));
+ if (!sp_adj2)
abort ();
#else
abort ();
#endif
}
- sp_adj2 = stack_pointer_rtx;
}
/* From now on, things must be in order. So emit blockages. */
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 2021e67..0a99e07 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -1180,6 +1180,10 @@ extern struct rtx_def *alpha_builtin_saveregs ();
extern struct rtx_def *alpha_compare_op0, *alpha_compare_op1;
extern int alpha_compare_fp_p;
+/* Define the information needed to modify the epilogue for EH. */
+
+extern struct rtx_def *alpha_eh_epilogue_sp_ofs;
+
/* Make (or fake) .linkage entry for function call.
IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
extern void alpha_need_linkage ();
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 232fb01..a214cc4 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -5144,6 +5144,22 @@
""
"alpha_expand_epilogue (); DONE;")
+(define_expand "eh_epilogue"
+ [(use (match_operand:DI 0 "register_operand" "r"))
+ (use (match_operand:DI 1 "register_operand" "r"))
+ (use (match_operand:DI 2 "register_operand" "r"))]
+ "! TARGET_OPEN_VMS"
+ "
+{
+ alpha_eh_epilogue_sp_ofs = operands[1];
+ if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 26)
+ {
+ rtx ra = gen_rtx_REG (Pmode, 26);
+ emit_move_insn (ra, operands[2]);
+ operands[2] = ra;
+ }
+}")
+
(define_expand "builtin_longjmp"
[(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
"! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index 1c17e28..a4bfef9 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -858,6 +858,9 @@ extern enum reg_class regno_reg_class[];
/* Offset of first parameter from the argument pointer register value. */
#define FIRST_PARM_OFFSET(FNDECL) 8
+/* Offset of the CFA from the argument pointer register value. */
+#define ARG_POINTER_CFA_OFFSET 8
+
/* Value is the number of byte of arguments automatically
popped when returning from a subroutine call.
FUNDECL is the declaration node of the function (as a tree),
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index c68c3d0..d5812d0 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1478,6 +1478,10 @@ extern char leaf_reg_remap[];
(TARGET_ARCH64 ? (SPARC_STACK_BIAS + 16 * UNITS_PER_WORD) \
: (STRUCT_VALUE_OFFSET + UNITS_PER_WORD))
+/* Offset from the argument pointer register value to the CFA. */
+
+#define ARG_POINTER_CFA_OFFSET SPARC_STACK_BIAS
+
/* When a parameter is passed in a register, stack space is still
allocated for it.
!v9: All 6 possible integer registers have backing store allocated.