#! /bin/sh -e

# All lines beginning with `# DPATCH:' are a description of the patch.
# DP: Recognize stack adjustments also in the src of an instruction.

dir=
if [ $# -eq 3 -a "$2" = '-d' ]; then
    pdir="-d $3"
    dir="$3/"
elif [ $# -ne 1 ]; then
    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
    exit 1
fi
case "$1" in
    -patch)
        patch $pdir -f --no-backup-if-mismatch -p1 < $0
        #cd ${dir}gcc && autoconf2.59
        ;;
    -unpatch)
        patch $pdir -f --no-backup-if-mismatch -R -p1 < $0
        #rm ${dir}gcc/configure
        ;;
    *)
        echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
        exit 1
esac
exit 0

---

 gcc/dwarf2out.c |   83 +++++++++++++++++++++++++++++++-------------------------
 1 file changed, 47 insertions(+), 36 deletions(-)

Index: gcc-4.1/gcc/dwarf2out.c
===================================================================
--- gcc-4.1.orig/gcc/dwarf2out.c
+++ gcc-4.1/gcc/dwarf2out.c
@@ -1045,6 +1045,7 @@ stack_adjust_offset (rtx pattern)
   rtx src = SET_SRC (pattern);
   rtx dest = SET_DEST (pattern);
   HOST_WIDE_INT offset = 0;
+  enum machine_mode mode;
   enum rtx_code code;
 
   if (dest == stack_pointer_rtx)
@@ -1059,52 +1060,62 @@ stack_adjust_offset (rtx pattern)
       offset = INTVAL (XEXP (src, 1));
       if (code == PLUS)
 	offset = -offset;
+      return offset;
     }
-  else if (MEM_P (dest))
+  if (MEM_P (dest)
+      && GET_RTX_CLASS (GET_CODE (XEXP (dest, 0))))
     {
       /* (set (mem (pre_dec (reg sp))) (foo)) */
+      mode = GET_MODE (dest);
       src = XEXP (dest, 0);
-      code = GET_CODE (src);
+    }
+  else if (MEM_P (src)
+	   && GET_RTX_CLASS (GET_CODE (XEXP (src, 0))))
+    {
+      /* (set (foo) (mem (post_inc (reg sp)))) */
+      mode = GET_MODE (src);
+      src = XEXP (src, 0);
+    }
+  else
+    return 0;
 
-      switch (code)
+  code = GET_CODE (src);
+  switch (code)
+    {
+    case PRE_MODIFY:
+    case POST_MODIFY:
+      if (XEXP (src, 0) == stack_pointer_rtx)
 	{
-	case PRE_MODIFY:
-	case POST_MODIFY:
-	  if (XEXP (src, 0) == stack_pointer_rtx)
-	    {
-	      rtx val = XEXP (XEXP (src, 1), 1);
-	      /* We handle only adjustments by constant amount.  */
-	      gcc_assert (GET_CODE (XEXP (src, 1)) == PLUS
-			  && GET_CODE (val) == CONST_INT);
-	      offset = -INTVAL (val);
-	      break;
-	    }
-	  return 0;
-
-	case PRE_DEC:
-	case POST_DEC:
-	  if (XEXP (src, 0) == stack_pointer_rtx)
-	    {
-	      offset = GET_MODE_SIZE (GET_MODE (dest));
-	      break;
-	    }
-	  return 0;
+	  rtx val = XEXP (XEXP (src, 1), 1);
+	  /* We handle only adjustments by constant amount.  */
+	  gcc_assert (GET_CODE (XEXP (src, 1)) == PLUS
+		      && GET_CODE (val) == CONST_INT);
+	  offset = -INTVAL (val);
+	  break;
+	}
+      return 0;
 
-	case PRE_INC:
-	case POST_INC:
-	  if (XEXP (src, 0) == stack_pointer_rtx)
-	    {
-	      offset = -GET_MODE_SIZE (GET_MODE (dest));
-	      break;
-	    }
-	  return 0;
+    case PRE_DEC:
+    case POST_DEC:
+      if (XEXP (src, 0) == stack_pointer_rtx)
+	{
+	  offset = GET_MODE_SIZE (mode);
+	  break;
+	}
+      return 0;
 
-	default:
-	  return 0;
+    case PRE_INC:
+    case POST_INC:
+      if (XEXP (src, 0) == stack_pointer_rtx)
+	{
+	  offset = -GET_MODE_SIZE (mode);
+	  break;
 	}
+      return 0;
+
+    default:
+      return 0;
     }
-  else
-    return 0;
 
   return offset;
 }
