PR target/6303
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 Apr 2002 06:18:47 +0000 (06:18 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 Apr 2002 06:18:47 +0000 (06:18 +0000)
* dwarf2out.c (rtl_for_decl_location): Call ASM_SIMPLIFY_DWARF_ADDR
before returning.
* config/i386/i386.c (i386_simplify_dwarf_addr): Simplify @GOT only
when inside of MEM by eliminating the indirection too.
* config/s390/s390.h (ASM_SIMPLIFY_DWARF_ADDR): Define.
* config/s390/s390.c (s390_simplify_dwarf_addr): New.
* config/s390/s390-protos.h (s390_simplify_dwarf_addr): Add
prototype.

* gcc.dg/20020415-1.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52358 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/dwarf2out.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20020415-1.c [new file with mode: 0644]

index 6fc0b24..2e9810c 100644 (file)
@@ -1,5 +1,17 @@
 2002-04-16  Jakub Jelinek  <jakub@redhat.com>
 
+       PR target/6303
+       * dwarf2out.c (rtl_for_decl_location): Call ASM_SIMPLIFY_DWARF_ADDR
+       before returning.
+       * config/i386/i386.c (i386_simplify_dwarf_addr): Simplify @GOT only
+       when inside of MEM by eliminating the indirection too.
+       * config/s390/s390.h (ASM_SIMPLIFY_DWARF_ADDR): Define.
+       * config/s390/s390.c (s390_simplify_dwarf_addr): New.
+       * config/s390/s390-protos.h (s390_simplify_dwarf_addr): Add
+       prototype.
+
+2002-04-16  Jakub Jelinek  <jakub@redhat.com>
+
        PR middle-end/6279
        * expr.c (store_expr): Don't copy if DECL_RTL (exp) == target.
 
index 33eab44..275a465 100644 (file)
@@ -5424,11 +5424,15 @@ i386_simplify_dwarf_addr (orig_x)
 {
   rtx x = orig_x, y;
 
+  if (GET_CODE (x) == MEM)
+    x = XEXP (x, 0);
+
   if (TARGET_64BIT)
     {
       if (GET_CODE (x) != CONST
          || GET_CODE (XEXP (x, 0)) != UNSPEC
-         || XINT (XEXP (x, 0), 1) != 15)
+         || XINT (XEXP (x, 0), 1) != 15
+         || GET_CODE (orig_x) != MEM)
        return orig_x;
       return XVECEXP (XEXP (x, 0), 0, 0);
     }
@@ -5463,8 +5467,8 @@ i386_simplify_dwarf_addr (orig_x)
 
   x = XEXP (XEXP (x, 1), 0);
   if (GET_CODE (x) == UNSPEC
-      && (XINT (x, 1) == 6
-         || XINT (x, 1) == 7))
+      && ((XINT (x, 1) == 6 && GET_CODE (orig_x) == MEM)
+         || (XINT (x, 1) == 7 && GET_CODE (orig_x) != MEM)))
     {
       if (y)
        return gen_rtx_PLUS (Pmode, y, XVECEXP (x, 0, 0));
@@ -5474,8 +5478,8 @@ i386_simplify_dwarf_addr (orig_x)
   if (GET_CODE (x) == PLUS
       && GET_CODE (XEXP (x, 0)) == UNSPEC
       && GET_CODE (XEXP (x, 1)) == CONST_INT
-      && (XINT (XEXP (x, 0), 1) == 6
-         || XINT (XEXP (x, 0), 1) == 7))
+      && ((XINT (XEXP (x, 0), 1) == 6 && GET_CODE (orig_x) == MEM)
+         || (XINT (XEXP (x, 0), 1) == 7 && GET_CODE (orig_x) != MEM)))
     {
       x = gen_rtx_PLUS (VOIDmode, XVECEXP (XEXP (x, 0), 0, 0), XEXP (x, 1));
       if (y)
index 2ab387a..2abc4dd 100644 (file)
@@ -70,6 +70,7 @@ extern void s390_dump_literal_pool PARAMS ((rtx, rtx));
 extern void s390_trampoline_template PARAMS ((FILE *));
 extern void s390_initialize_trampoline PARAMS ((rtx, rtx, rtx));
 extern rtx s390_gen_rtx_const_DI PARAMS ((int, int));
+extern rtx s390_simplify_dwarf_addr PARAMS ((rtx));
 #endif /* RTX_CODE */
 
 #ifdef TREE_CODE
index ce601f0..c365f04 100644 (file)
@@ -1861,6 +1861,43 @@ legitimize_address (x, oldx, mode)
   return x;
 }
 
+/* In the name of slightly smaller debug output, and to cater to
+   general assembler losage, recognize various UNSPEC sequences
+   and turn them back into a direct symbol reference.  */
+
+rtx
+s390_simplify_dwarf_addr (orig_x)
+     rtx orig_x;
+{
+  rtx x = orig_x, y;
+
+  if (GET_CODE (x) != MEM)
+    return orig_x;
+
+  x = XEXP (x, 0);
+  if (GET_CODE (x) == PLUS
+      && GET_CODE (XEXP (x, 1)) == CONST
+      && GET_CODE (XEXP (x, 0)) == REG
+      && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
+    {
+      y = XEXP (XEXP (x, 1), 0);
+      if (GET_CODE (y) == UNSPEC
+         && XINT (y, 1) == 110)
+       return XVECEXP (y, 0, 0);
+      return orig_x;
+    }
+
+  if (GET_CODE (x) == CONST)
+    {
+      y = XEXP (x, 0);
+      if (GET_CODE (y) == UNSPEC
+         && XINT (y, 1) == 111)
+       return XVECEXP (y, 0, 0);
+      return orig_x;
+    }
+
+  return orig_x;      
+}
 
 /* Output symbolic constant X in assembler syntax to 
    stdio stream FILE.  */
index 1ab431e..b50951a 100644 (file)
@@ -1270,6 +1270,10 @@ extern struct rtx_def *s390_compare_op0, *s390_compare_op1;
 
 #define TARGET_MEM_FUNCTIONS
 
+/* Either simplify a location expression, or return the original.  */
+
+#define ASM_SIMPLIFY_DWARF_ADDR(X) \
+  s390_simplify_dwarf_addr (X)
 
 /* Print operand X (an rtx) in assembler syntax to file FILE.
    CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
index 5a00bf4..b7a6d25 100644 (file)
@@ -8850,7 +8850,12 @@ rtl_for_decl_location (decl)
          && (CONSTANT_P (rtl)
              || (GET_CODE (rtl) == MEM
                  && CONSTANT_P (XEXP (rtl, 0)))))
-       return rtl;
+       {
+#ifdef ASM_SIMPLIFY_DWARF_ADDR
+         rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
+#endif
+         return rtl;
+       }
       rtl = NULL_RTX;
     }
   else if (TREE_CODE (decl) == PARM_DECL)
@@ -8952,6 +8957,10 @@ rtl_for_decl_location (decl)
        }
     }
 
+#ifdef ASM_SIMPLIFY_DWARF_ADDR
+  if (rtl)
+    rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
+#endif
   return rtl;
 }
 
index f5f8515..826b30d 100644 (file)
@@ -2,6 +2,8 @@
 
        * gcc.dg/altivec-5.c: New test.
 
+       * gcc.dg/20020415-1.c: New test.
+
 2002-04-15  Mark Mitchell  <mark@codesourcery.com>
 
        * testsuite/lib/chill.exp: Remove.
diff --git a/gcc/testsuite/gcc.dg/20020415-1.c b/gcc/testsuite/gcc.dg/20020415-1.c
new file mode 100644 (file)
index 0000000..06b3ce0
--- /dev/null
@@ -0,0 +1,35 @@
+/* PR target/6303
+   This testcase ICEd because s390 did not define
+   ASM_SIMPLIFY_DWARF_ADDR hook.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fpic -g" } */
+
+static inline char *
+bar (unsigned long x, char *y)
+{
+  extern const char ext[];
+  const char *a = ext;
+  char *b = y;
+
+  do *--b = a[x % 10]; while ((x /= 10) != 0);
+  return b;
+}
+
+struct A { char *p, *q; };
+struct B { int r, s; };
+
+int
+foo (struct A *a, const struct B *b)
+{
+  char c[(b->r > b->s) ? b->r : b->s];
+  char *d = &c[sizeof c];
+  register char *e;
+
+  e = bar (b->r, d);
+  while (e < d)
+    {
+      register const int f = *e++;
+      if (((a->p >= a->q) ? 1 : (unsigned char) (*a->p++ = f)) == -1)
+       break;
+    }
+}