diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2003-05-10 22:59:04 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2003-05-10 22:59:04 +0000 |
commit | 34dc173c2c848264901401da687c6edea165b7c9 (patch) | |
tree | 576cc3eb0bc73f866abed200b78ada8bb9e6cdc2 /gcc | |
parent | a64d0bc69ea6a927a0a16d71681b00099e285d1e (diff) | |
download | gcc-34dc173c2c848264901401da687c6edea165b7c9.zip gcc-34dc173c2c848264901401da687c6edea165b7c9.tar.gz gcc-34dc173c2c848264901401da687c6edea165b7c9.tar.bz2 |
except.c (EH_RETURN_STACKADJ_RTX): Do not define.
* except.c (EH_RETURN_STACKADJ_RTX): Do not define.
(EH_RETURN_HANDLER_RTX): Likewise.
(expand_builtin_eh_return): Do not copy stack adjustment
if EH_RETURN_STACKADJ_RTX is not defined.
(expand_eh_return): Likewise. Also, do not pass stack
adjustment as argument to the eh_return pattern.
* except.h (MUST_USE_SJLJ_EXCEPTIONS): Do not define just
because EH_RETURN_STACKADJ_RTX is not defined.
* unwind-dw.c (uw_update_context_1): If EH_RETURN_STACKADJ_RTX
is not defined, treat stack pointer like a regular register.
(uw_init_context_1): Set up fake initial stack pointer register.
(uw_install_context_1): Do not compute stack adjustment if
EH_RETURN_STACKADJ_RTX is not defined.
* config/i386/i386.md ("eh_return"): Remove first argument.
* config/mips/mips.md ("eh_return"): Likewise.
* config/rs6000/rs6000.md ("eh_return"): Likewise.
* config/sh/sh.md ("eh_return"): Likewise.
* config/s390/s390.h (EH_RETURN_STACKADJ_RTX): Remove.
From-SVN: r66672
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 23 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 5 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 12 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 10 | ||||
-rw-r--r-- | gcc/config/s390/s390.h | 1 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 6 | ||||
-rw-r--r-- | gcc/doc/md.texi | 22 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 13 | ||||
-rw-r--r-- | gcc/except.c | 86 | ||||
-rw-r--r-- | gcc/except.h | 4 | ||||
-rw-r--r-- | gcc/unwind-dw2.c | 41 |
11 files changed, 120 insertions, 103 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9c01b2f..cbc986a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2003-05-11 Ulrich Weigand <uweigand@de.ibm.com> + + * except.c (EH_RETURN_STACKADJ_RTX): Do not define. + (EH_RETURN_HANDLER_RTX): Likewise. + (expand_builtin_eh_return): Do not copy stack adjustment + if EH_RETURN_STACKADJ_RTX is not defined. + (expand_eh_return): Likewise. Also, do not pass stack + adjustment as argument to the eh_return pattern. + * except.h (MUST_USE_SJLJ_EXCEPTIONS): Do not define just + because EH_RETURN_STACKADJ_RTX is not defined. + * unwind-dw.c (uw_update_context_1): If EH_RETURN_STACKADJ_RTX + is not defined, treat stack pointer like a regular register. + (uw_init_context_1): Set up fake initial stack pointer register. + (uw_install_context_1): Do not compute stack adjustment if + EH_RETURN_STACKADJ_RTX is not defined. + + * config/i386/i386.md ("eh_return"): Remove first argument. + * config/mips/mips.md ("eh_return"): Likewise. + * config/rs6000/rs6000.md ("eh_return"): Likewise. + * config/sh/sh.md ("eh_return"): Likewise. + + * config/s390/s390.h (EH_RETURN_STACKADJ_RTX): Remove. + 2003-05-10 Alexander Aganichev <aaganichev@yandex.ru> * config/i386/i386.h (MODES_TIEABLE_P): Fix typo. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index e472f97..64d37f6 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -14284,11 +14284,10 @@ "ix86_expand_epilogue (0); DONE;") (define_expand "eh_return" - [(use (match_operand 0 "register_operand" "")) - (use (match_operand 1 "register_operand" ""))] + [(use (match_operand 0 "register_operand" ""))] "" { - rtx tmp, sa = operands[0], ra = operands[1]; + rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; /* Tricky bit: we write the address of the handler to which we will be returning into someone else's stack frame, one word below the diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 876f0db..718e039 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -9779,21 +9779,19 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" ;; This is used in compiling the unwind routines. (define_expand "eh_return" - [(use (match_operand 0 "general_operand" "")) - (use (match_operand 1 "general_operand" ""))] + [(use (match_operand 0 "general_operand" ""))] "" " { enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode; - if (GET_MODE (operands[1]) != gpr_mode) - operands[1] = convert_to_mode (gpr_mode, operands[1], 0); + if (GET_MODE (operands[0]) != gpr_mode) + operands[0] = convert_to_mode (gpr_mode, operands[0], 0); if (TARGET_64BIT) - emit_insn (gen_eh_set_lr_di (operands[1])); + emit_insn (gen_eh_set_lr_di (operands[0])); else - emit_insn (gen_eh_set_lr_si (operands[1])); + emit_insn (gen_eh_set_lr_si (operands[0])); - emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]); DONE; }") diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 37b88d3..a40dc2b 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -14392,19 +14392,17 @@ ; This is used in compiling the unwind routines. (define_expand "eh_return" - [(use (match_operand 0 "general_operand" "")) - (use (match_operand 1 "general_operand" ""))] + [(use (match_operand 0 "general_operand" ""))] "" " { #if TARGET_AIX - rs6000_emit_eh_toc_restore (operands[0]); + rs6000_emit_eh_toc_restore (EH_RETURN_STACKADJ_RTX); #endif if (TARGET_32BIT) - emit_insn (gen_eh_set_lr_si (operands[1])); + emit_insn (gen_eh_set_lr_si (operands[0])); else - emit_insn (gen_eh_set_lr_di (operands[1])); - emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]); + emit_insn (gen_eh_set_lr_di (operands[0])); DONE; }") diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 5bd0ab4..824a6e2 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -550,7 +550,6 @@ extern int current_function_outgoing_args_size; /* Describe how we implement __builtin_eh_return. */ #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 6 : INVALID_REGNUM) -#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 10) #define EH_RETURN_HANDLER_RTX \ gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, \ TARGET_64BIT? -48 : -40)) diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index f440eec..eb63538 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -7311,18 +7311,16 @@ mov.l\\t1f,r0\\n\\ }") (define_expand "eh_return" - [(use (match_operand 0 "register_operand" "")) - (use (match_operand 1 "register_operand" ""))] + [(use (match_operand 0 "register_operand" ""))] "" { - rtx tmp, sa = operands[0], ra = operands[1]; + rtx tmp, ra = operands[0]; if (TARGET_SHMEDIA64) emit_insn (gen_eh_set_ra_di (ra)); else emit_insn (gen_eh_set_ra_si (ra)); - emit_move_insn (EH_RETURN_STACKADJ_RTX, sa); DONE; }) diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index c808d49..f078520 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -3374,17 +3374,17 @@ and thence the call frame exception handling library routines, are built. It is intended to handle non-trivial actions needed along the abnormal return path. -The pattern takes two arguments. The first is an offset to be applied -to the stack pointer. It will have been copied to some appropriate -location (typically @code{EH_RETURN_STACKADJ_RTX}) which will survive -until after reload to when the normal epilogue is generated. -The second argument is the address of the exception handler to which -the function should return. This will normally need to copied by the -pattern to some special register or memory location. - -This pattern only needs to be defined if call frame exception handling -is to be used, and simple moves involving @code{EH_RETURN_STACKADJ_RTX} -and @code{EH_RETURN_HANDLER_RTX} are not sufficient. +The address of the exception handler to which the function should return +is passed as operand to this pattern. It will normally need to copied by +the pattern to some special register or memory location. +If the pattern needs to determine the location of the target call +frame in order to do so, it may use @code{EH_RETURN_STACKADJ_RTX}, +if defined; it will have already been assigned. + +If this pattern is not defined, the default action will be to simply +copy the return address to @code{EH_RETURN_HANDLER_RTX}. Either +that macro or this pattern needs to be defined if call frame exception +handling is to be used. @cindex @code{prologue} instruction pattern @anchor{prologue instruction pattern} diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index c932422..c7c65a5 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -3016,8 +3016,12 @@ It will be assigned zero on code paths that return normally. Typically this is a call-clobbered hard register that is otherwise untouched by the epilogue, but could also be a stack slot. -You must define this macro if you want to support call frame exception -handling like that provided by DWARF 2. +Do not define this macro if the stack pointer is saved and restored +by the regular prolog and epilog code in the call frame itself; in +this case, the exception handling library routines will update the +stack location to be restored in place. Otherwise, you must define +this macro if you want to support call frame exception handling like +that provided by DWARF 2. @findex EH_RETURN_HANDLER_RTX @item EH_RETURN_HANDLER_RTX @@ -3029,8 +3033,9 @@ Typically this is the location in the call frame at which the normal return address is stored. For targets that return by popping an address off the stack, this might be a memory address just below the @emph{target} call frame rather than inside the current call -frame. @code{EH_RETURN_STACKADJ_RTX} will have already been assigned, -so it may be used to calculate the location of the target call frame. +frame. If defined, @code{EH_RETURN_STACKADJ_RTX} will have already +been assigned, so it may be used to calculate the location of the +target call frame. Some targets have more complex requirements than storing to an address calculable during initial code generation. In that case diff --git a/gcc/except.c b/gcc/except.c index 3cd9b90..d6ab26c 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -76,12 +76,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA /* Provide defaults for stuff that may not be defined when using sjlj exceptions. */ -#ifndef EH_RETURN_STACKADJ_RTX -#define EH_RETURN_STACKADJ_RTX 0 -#endif -#ifndef EH_RETURN_HANDLER_RTX -#define EH_RETURN_HANDLER_RTX 0 -#endif #ifndef EH_RETURN_DATA_REGNO #define EH_RETURN_DATA_REGNO(N) INVALID_REGNUM #endif @@ -3077,77 +3071,73 @@ expand_builtin_frob_return_addr (addr_tree) void expand_builtin_eh_return (stackadj_tree, handler_tree) - tree stackadj_tree, handler_tree; + tree stackadj_tree ATTRIBUTE_UNUSED; + tree handler_tree; { - rtx stackadj, handler; - - stackadj = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj, VOIDmode, 0); - handler = expand_expr (handler_tree, cfun->eh->ehr_handler, VOIDmode, 0); + rtx tmp; +#ifdef EH_RETURN_STACKADJ_RTX + tmp = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj, VOIDmode, 0); #ifdef POINTERS_EXTEND_UNSIGNED - if (GET_MODE (stackadj) != Pmode) - stackadj = convert_memory_address (Pmode, stackadj); - - if (GET_MODE (handler) != Pmode) - handler = convert_memory_address (Pmode, handler); + if (GET_MODE (tmp) != Pmode) + tmp = convert_memory_address (Pmode, tmp); +#endif + if (!cfun->eh->ehr_stackadj) + cfun->eh->ehr_stackadj = copy_to_reg (tmp); + else if (tmp != cfun->eh->ehr_stackadj) + emit_move_insn (cfun->eh->ehr_stackadj, tmp); #endif - if (! cfun->eh->ehr_label) - { - cfun->eh->ehr_stackadj = copy_to_reg (stackadj); - cfun->eh->ehr_handler = copy_to_reg (handler); - cfun->eh->ehr_label = gen_label_rtx (); - } - else - { - if (stackadj != cfun->eh->ehr_stackadj) - emit_move_insn (cfun->eh->ehr_stackadj, stackadj); - if (handler != cfun->eh->ehr_handler) - emit_move_insn (cfun->eh->ehr_handler, handler); - } + tmp = expand_expr (handler_tree, cfun->eh->ehr_handler, VOIDmode, 0); +#ifdef POINTERS_EXTEND_UNSIGNED + if (GET_MODE (tmp) != Pmode) + tmp = convert_memory_address (Pmode, tmp); +#endif + if (!cfun->eh->ehr_handler) + cfun->eh->ehr_handler = copy_to_reg (tmp); + else if (tmp != cfun->eh->ehr_handler) + emit_move_insn (cfun->eh->ehr_handler, tmp); + if (!cfun->eh->ehr_label) + cfun->eh->ehr_label = gen_label_rtx (); emit_jump (cfun->eh->ehr_label); } void expand_eh_return () { - rtx sa, ra, around_label; + rtx around_label; if (! cfun->eh->ehr_label) return; - sa = EH_RETURN_STACKADJ_RTX; - if (! sa) - { - error ("__builtin_eh_return not supported on this target"); - return; - } - current_function_calls_eh_return = 1; +#ifdef EH_RETURN_STACKADJ_RTX + emit_move_insn (EH_RETURN_STACKADJ_RTX, const0_rtx); +#endif + around_label = gen_label_rtx (); - emit_move_insn (sa, const0_rtx); emit_jump (around_label); emit_label (cfun->eh->ehr_label); clobber_return_register (); +#ifdef EH_RETURN_STACKADJ_RTX + emit_move_insn (EH_RETURN_STACKADJ_RTX, cfun->eh->ehr_stackadj); +#endif + #ifdef HAVE_eh_return if (HAVE_eh_return) - emit_insn (gen_eh_return (cfun->eh->ehr_stackadj, cfun->eh->ehr_handler)); + emit_insn (gen_eh_return (cfun->eh->ehr_handler)); else #endif { - ra = EH_RETURN_HANDLER_RTX; - if (! ra) - { - error ("__builtin_eh_return not supported on this target"); - ra = gen_reg_rtx (Pmode); - } - - emit_move_insn (sa, cfun->eh->ehr_stackadj); - emit_move_insn (ra, cfun->eh->ehr_handler); +#ifdef EH_RETURN_HANDLER_RTX + emit_move_insn (EH_RETURN_HANDLER_RTX, cfun->eh->ehr_handler); +#else + error ("__builtin_eh_return not supported on this target"); +#endif } emit_label (around_label); diff --git a/gcc/except.h b/gcc/except.h index d8e7ace..d44c4b8 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -146,7 +146,6 @@ extern tree (*lang_eh_runtime_type) PARAMS ((tree)); #if ! (defined (EH_RETURN_DATA_REGNO) \ && (defined (IA64_UNWIND_INFO) \ || (DWARF2_UNWIND_INFO \ - && defined (EH_RETURN_STACKADJ_RTX) \ && (defined (EH_RETURN_HANDLER_RTX) \ || defined (HAVE_eh_return))))) #define MUST_USE_SJLJ_EXCEPTIONS 1 @@ -163,9 +162,6 @@ extern tree (*lang_eh_runtime_type) PARAMS ((tree)); # ifndef EH_RETURN_DATA_REGNO #error "EH_RETURN_DATA_REGNO required" # endif -# ifndef EH_RETURN_STACKADJ_RTX - #error "EH_RETURN_STACKADJ_RTX required" -# endif # if !defined(EH_RETURN_HANDLER_RTX) && !defined(HAVE_eh_return) #error "EH_RETURN_HANDLER_RTX or eh_return required" # endif diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c index f752ffe..673d164 100644 --- a/gcc/unwind-dw2.c +++ b/gcc/unwind-dw2.c @@ -1076,10 +1076,10 @@ static void uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs) { struct _Unwind_Context orig_context = *context; - _Unwind_Word tmp_sp; void *cfa; long i; +#ifdef EH_RETURN_STACKADJ_RTX /* Special handling here: Many machines do not use a frame pointer, and track the CFA only through offsets from the stack pointer from one frame to the next. In this case, the stack pointer is never @@ -1094,12 +1094,16 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs) frame, and be able to use much easier CFA mechanisms to do it. Always zap the saved stack pointer value for the next frame; carrying the value over from one frame to another doesn't make sense. */ + + _Unwind_Word tmp_sp; + if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ())) { tmp_sp = (_Unwind_Ptr) context->cfa; _Unwind_SetGRPtr (&orig_context, __builtin_dwarf_sp_column (), &tmp_sp); } _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL); +#endif /* Compute this frame's CFA. */ switch (fs->cfa_how) @@ -1202,7 +1206,7 @@ uw_init_context_1 (struct _Unwind_Context *context, abort (); /* Force the frame state to use the known cfa value. */ - context->cfa = outer_cfa; + _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), &outer_cfa); fs.cfa_how = CFA_REG_OFFSET; fs.cfa_reg = __builtin_dwarf_sp_column (); fs.cfa_offset = 0; @@ -1240,7 +1244,6 @@ uw_install_context_1 (struct _Unwind_Context *current, struct _Unwind_Context *target) { long i; - void *target_cfa; #if __GTHREADS { @@ -1263,18 +1266,26 @@ uw_install_context_1 (struct _Unwind_Context *current, memcpy (c, t, dwarf_reg_size_table[i]); } - /* If the last frame records a saved stack pointer, use it. */ - if (_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ())) - target_cfa = (void *)(_Unwind_Ptr) - _Unwind_GetGR (target, __builtin_dwarf_sp_column ()); - else - target_cfa = target->cfa; - - /* We adjust SP by the difference between CURRENT and TARGET's CFA. */ - if (STACK_GROWS_DOWNWARD) - return target_cfa - current->cfa + target->args_size; - else - return current->cfa - target_cfa - target->args_size; +#ifdef EH_RETURN_STACKADJ_RTX + { + void *target_cfa; + + /* If the last frame records a saved stack pointer, use it. */ + if (_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ())) + target_cfa = (void *)(_Unwind_Ptr) + _Unwind_GetGR (target, __builtin_dwarf_sp_column ()); + else + target_cfa = target->cfa; + + /* We adjust SP by the difference between CURRENT and TARGET's CFA. */ + if (STACK_GROWS_DOWNWARD) + return target_cfa - current->cfa + target->args_size; + else + return current->cfa - target_cfa - target->args_size; + } +#else + return 0; +#endif } static inline _Unwind_Ptr |