This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Make EH_RETURN_STACKADJ_RTX optional (fixes s390)


Hello Richard,

this patch is an attempt to fix the s390 exception handling
problem in a clean(er) way.

>From the previous discussions, it would appear to me that
the real difference between s390 and other platforms here
is that on s390, the stack pointer register is saved and
restored from the call stack frame, like any other call-
saved register.  This means that uw_install_context can
install the target stack pointer simply by writing it
into the current stack frame, just like any other call-
saved register.

If this is possible, there is no need for the unwinder
routines to perform any special handling w.r.t. the
stack pointer register at all.  This means that there
should be no need to define EH_RETURN_STACKADJ_RTX,
and everything related to this should be omitted by
the library.  This also means that the special-cased
code for 'simulating' the stack pointer register in
uw_update_context (which is what caused the breakage
on s390) is just superfluous.

So, I've thought to fix the problem by allowing a target
not to define EH_RETURN_STACKADJ_RTX.  If this is done,
the unwinder libraries will assume that the stack pointer
register is handled automatically by the code that cares
for the other call-saved registers, and no special action
needs to be taken.  This allows me to remove the dummy
definition we currently have to have on s390 (even though
the adjustment it subsequently ignored).

However, there is one place where this is a bit ugly:
the eh_return pattern gets called with both the handler
address and the stack adjustment value.  It appeared to
me that the cleanest solution would be to disentangle
the stack adjustment handling from the return address
handling.  So I've changed the expand_eh_return routine
to first care for the stack adjustment by placing it
into EH_RETURN_STACKADJ_RTX (if defined), and then
changing the return address by either writing it to
EH_RETURN_HANLDER_RTX or else calling eh_return (with
only the handler address as parameter).

This implied changes to the existing eh_return handlers.
Where they actually needed to know the stack adjustment,
I've changed them to use EH_RETURN_STACKADJ_RTX which
the common code guarantees to set up before expanding
eh_return.

This patch was bootstrapped/regtested on s390-ibm-linux
and s390x-ibm-linux and fixes the Java PR218 test case.
I've also bootstrapped/regtested i686-pc-unknown-linux
without new regressions.  Finally, I've built cross-cc1
to ppc-linux, mips-linux, and sh-linux (the remaining
three targets with eh_return), and verified by inspection
that they still generate identical or equivalent code
for _Unwind_RaiseException in unwind-dw2.s.

OK for mainline?

Bye,
Ulrich


ChangeLog:

	* 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.

Index: gcc/except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.c,v
retrieving revision 1.241
diff -c -p -r1.241 except.c
*** gcc/except.c	7 May 2003 22:11:33 -0000	1.241
--- gcc/except.c	9 May 2003 22:40:19 -0000
*************** Software Foundation, 59 Temple Place - S
*** 76,87 ****
  
  /* 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
--- 76,81 ----
*************** expand_builtin_frob_return_addr (addr_tr
*** 3077,3153 ****
  
  void
  expand_builtin_eh_return (stackadj_tree, handler_tree)
!     tree stackadj_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);
  
  #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);
  #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);
!     }
  
    emit_jump (cfun->eh->ehr_label);
  }
  
  void
  expand_eh_return ()
  {
!   rtx sa, ra, 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;
  
    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 HAVE_eh_return
    if (HAVE_eh_return)
!     emit_insn (gen_eh_return (cfun->eh->ehr_stackadj, 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);
      }
  
    emit_label (around_label);
--- 3071,3143 ----
  
  void
  expand_builtin_eh_return (stackadj_tree, handler_tree)
!     tree stackadj_tree ATTRIBUTE_UNUSED;
!     tree handler_tree;
  {
!   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 (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
  
!   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 around_label;
  
    if (! cfun->eh->ehr_label)
      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_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_handler));
    else
  #endif
      {
! #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);
Index: gcc/except.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.h,v
retrieving revision 1.68
diff -c -p -r1.68 except.h
*** gcc/except.h	4 May 2003 05:22:51 -0000	1.68
--- gcc/except.h	9 May 2003 22:40:19 -0000
*************** extern tree (*lang_eh_runtime_type) PARA
*** 146,152 ****
  #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
--- 146,151 ----
*************** extern tree (*lang_eh_runtime_type) PARA
*** 162,170 ****
  #  define USING_SJLJ_EXCEPTIONS		0
  #  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"
--- 161,166 ----
Index: gcc/unwind-dw2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/unwind-dw2.c,v
retrieving revision 1.30
diff -c -p -r1.30 unwind-dw2.c
*** gcc/unwind-dw2.c	7 May 2003 22:01:37 -0000	1.30
--- gcc/unwind-dw2.c	9 May 2003 22:40:25 -0000
*************** static void
*** 1076,1085 ****
  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;
  
    /* 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
--- 1076,1085 ----
  uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
  {
    struct _Unwind_Context orig_context = *context;
    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
*************** uw_update_context_1 (struct _Unwind_Cont
*** 1094,1105 ****
--- 1094,1109 ----
       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)
*************** uw_init_context_1 (struct _Unwind_Contex
*** 1202,1208 ****
      abort ();
  
    /* Force the frame state to use the known cfa value.  */
!   context->cfa = outer_cfa;
    fs.cfa_how = CFA_REG_OFFSET;
    fs.cfa_reg = __builtin_dwarf_sp_column ();
    fs.cfa_offset = 0;
--- 1206,1212 ----
      abort ();
  
    /* Force the frame state to use the known cfa value.  */
!   _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;
*************** uw_install_context_1 (struct _Unwind_Con
*** 1240,1246 ****
  		      struct _Unwind_Context *target)
  {
    long i;
-   void *target_cfa;
  
  #if __GTHREADS
    {
--- 1244,1249 ----
*************** uw_install_context_1 (struct _Unwind_Con
*** 1263,1280 ****
  	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;
  }
  
  static inline _Unwind_Ptr
--- 1266,1291 ----
  	memcpy (c, t, dwarf_reg_size_table[i]);
      }
  
! #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
Index: gcc/config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.457
diff -c -p -r1.457 i386.md
*** gcc/config/i386/i386.md	24 Apr 2003 18:43:22 -0000	1.457
--- gcc/config/i386/i386.md	9 May 2003 22:41:06 -0000
***************
*** 14284,14294 ****
    "ix86_expand_epilogue (0); DONE;")
  
  (define_expand "eh_return"
!   [(use (match_operand 0 "register_operand" ""))
!    (use (match_operand 1 "register_operand" ""))]
    ""
  {
!   rtx tmp, sa = operands[0], ra = operands[1];
  
    /* 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
--- 14284,14293 ----
    "ix86_expand_epilogue (0); DONE;")
  
  (define_expand "eh_return"
!   [(use (match_operand 0 "register_operand" ""))]
    ""
  {
!   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
Index: gcc/config/mips/mips.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.md,v
retrieving revision 1.166
diff -c -p -r1.166 mips.md
*** gcc/config/mips/mips.md	6 May 2003 11:23:42 -0000	1.166
--- gcc/config/mips/mips.md	9 May 2003 22:41:10 -0000
*************** ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n
*** 9779,9799 ****
  
  ;; This is used in compiling the unwind routines.
  (define_expand "eh_return"
!   [(use (match_operand 0 "general_operand" ""))
!    (use (match_operand 1 "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 (TARGET_64BIT)
!     emit_insn (gen_eh_set_lr_di (operands[1]));
    else
!     emit_insn (gen_eh_set_lr_si (operands[1]));
  
-   emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]);
    DONE;
  }")
  
--- 9779,9797 ----
  
  ;; This is used in compiling the unwind routines.
  (define_expand "eh_return"
!   [(use (match_operand 0 "general_operand" ""))]
    ""
    "
  {
    enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
  
!   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[0]));
    else
!     emit_insn (gen_eh_set_lr_si (operands[0]));
  
    DONE;
  }")
  
Index: gcc/config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.252
diff -c -p -r1.252 rs6000.md
*** gcc/config/rs6000/rs6000.md	3 May 2003 23:13:57 -0000	1.252
--- gcc/config/rs6000/rs6000.md	9 May 2003 22:41:14 -0000
***************
*** 14392,14410 ****
  
  ; This is used in compiling the unwind routines.
  (define_expand "eh_return"
!   [(use (match_operand 0 "general_operand" ""))
!    (use (match_operand 1 "general_operand" ""))]
    ""
    "
  {
  #if TARGET_AIX
!     rs6000_emit_eh_toc_restore (operands[0]);
  #endif
    if (TARGET_32BIT)
!     emit_insn (gen_eh_set_lr_si (operands[1]));
    else
!     emit_insn (gen_eh_set_lr_di (operands[1]));
!   emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]);
    DONE;
  }")
  
--- 14392,14408 ----
  
  ; This is used in compiling the unwind routines.
  (define_expand "eh_return"
!   [(use (match_operand 0 "general_operand" ""))]
    ""
    "
  {
  #if TARGET_AIX
!   rs6000_emit_eh_toc_restore (EH_RETURN_STACKADJ_RTX);
  #endif
    if (TARGET_32BIT)
!     emit_insn (gen_eh_set_lr_si (operands[0]));
    else
!     emit_insn (gen_eh_set_lr_di (operands[0]));
    DONE;
  }")
  
Index: gcc/config/s390/s390.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.h,v
retrieving revision 1.70
diff -c -p -r1.70 s390.h
*** gcc/config/s390/s390.h	29 Apr 2003 14:16:47 -0000	1.70
--- gcc/config/s390/s390.h	9 May 2003 22:41:14 -0000
*************** extern int current_function_outgoing_arg
*** 550,556 ****
  
  /* 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))
--- 550,555 ----
Index: gcc/config/sh/sh.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.md,v
retrieving revision 1.143
diff -c -p -r1.143 sh.md
*** gcc/config/sh/sh.md	17 Apr 2003 10:24:59 -0000	1.143
--- gcc/config/sh/sh.md	9 May 2003 22:41:20 -0000
*************** mov.l\\t1f,r0\\n\\
*** 7311,7328 ****
  }")
  
  (define_expand "eh_return"
!   [(use (match_operand 0 "register_operand" ""))
!    (use (match_operand 1 "register_operand" ""))]
    ""
  {
!   rtx tmp, sa = operands[0], ra = operands[1];
  
    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;
  })
  
--- 7311,7326 ----
  }")
  
  (define_expand "eh_return"
!   [(use (match_operand 0 "register_operand" ""))]
    ""
  {
!   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));
  
    DONE;
  })
  
Index: gcc/doc/md.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/md.texi,v
retrieving revision 1.65
diff -c -p -r1.65 md.texi
*** gcc/doc/md.texi	26 Apr 2003 20:44:26 -0000	1.65
--- gcc/doc/md.texi	9 May 2003 22:41:22 -0000
*************** and thence the call frame exception hand
*** 3374,3390 ****
  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.
  
  @cindex @code{prologue} instruction pattern
  @anchor{prologue instruction pattern}
--- 3374,3390 ----
  built.  It is intended to handle non-trivial actions needed along
  the abnormal return path.
  
! 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}
Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.216
diff -c -p -r1.216 tm.texi
*** gcc/doc/tm.texi	28 Apr 2003 20:02:28 -0000	1.216
--- gcc/doc/tm.texi	9 May 2003 22:41:27 -0000
*************** It will be assigned zero on code paths t
*** 3016,3023 ****
  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.
  
  @findex EH_RETURN_HANDLER_RTX
  @item EH_RETURN_HANDLER_RTX
--- 3016,3027 ----
  Typically this is a call-clobbered hard register that is otherwise
  untouched by the epilogue, but could also be a stack slot.
  
! 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
*************** Typically this is the location in the ca
*** 3029,3036 ****
  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.
  
  Some targets have more complex requirements than storing to an
  address calculable during initial code generation.  In that case
--- 3033,3041 ----
  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.  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
-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]