diff options
author | Richard Henderson <rth@cygnus.com> | 1998-09-15 12:19:12 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 1998-09-15 12:19:12 -0700 |
commit | 710384268d9df98e595cd68c5e8db84d766d5513 (patch) | |
tree | 5f8b92560efd1078cbd16601e8b3502296539971 /gcc/config | |
parent | dfb16e8307d6ca6f9ddf22dea3400324355a60a7 (diff) | |
download | gcc-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.c | 45 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.h | 4 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.md | 16 | ||||
-rw-r--r-- | gcc/config/m68k/m68k.h | 3 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 4 |
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. |