except.c (EH_RETURN_STACKADJ_RTX): Do not define.
authorUlrich Weigand <uweigand@de.ibm.com>
Sat, 10 May 2003 22:59:04 +0000 (22:59 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Sat, 10 May 2003 22:59:04 +0000 (22:59 +0000)
* 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

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/config/mips/mips.md
gcc/config/rs6000/rs6000.md
gcc/config/s390/s390.h
gcc/config/sh/sh.md
gcc/doc/md.texi
gcc/doc/tm.texi
gcc/except.c
gcc/except.h
gcc/unwind-dw2.c

index 9c01b2f76a91f6a7fdc022b5a4e40f113d02b55f..cbc986a6b386e9061e207d7139c8cb75a1ac0f9a 100644 (file)
@@ -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.
index e472f976a6bdc0702170832d263f993b3f8a43fc..64d37f608824051e5911cf54ec0a8e0c9589a199 100644 (file)
   "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
index 876f0dbd31600c78d12ee72618f341bc59de8a44..718e0393ab0c7bbf195eddd88f59184d8b214f71 100644 (file)
@@ -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;
 }")
 
index 37b88d3d256abf81d493c46096601b7f1b1e6fd1..a40dc2b0293fbb53dfdc7f201119d6c8392c668a 100644 (file)
 
 ; 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;
 }")
 
index 5bd0ab4405d656dd530ed443e9c9141d8ba2db67..824a6e277688fbc71dd4d917dc1ad51e6c442f2f 100644 (file)
@@ -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))
index f440eeca716a1fe28cdeea5408ac1d520962b2d6..eb6353840ff3db5a8aec4d8248e2db5b1e50cfb4 100644 (file)
@@ -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;
 })
 
index c808d494e9aba68722e6baad1b1b31a1c0054788..f078520ab3d448608babb5d8476308cd0354775a 100644 (file)
@@ -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}
index c932422ce98467a81e8a8ea2c2fa348839b86b3b..c7c65a59febff477f898a819b3ae54650f538292 100644 (file)
@@ -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
index 3cd9b90d37dc72c9489b0a7efa012fff7f7d3d23..d6ab26c6007d21ae1263f11617a7ecbbad24fbeb 100644 (file)
@@ -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);
index d8e7acec8c46f621d89391602c93bce4b1530473..d44c4b8d9ce60756e81c6a76b9f323ec57685bf7 100644 (file)
@@ -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
index f752ffe0f453cf151d4621bb556ae28eee51b2ff..673d164695dbed0fac720f93794b55a64edca85b 100644 (file)
@@ -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