re PR target/6303 (output_operand: invalid expression as operand)
authorJakub Jelinek <jakub@redhat.com>
Tue, 16 Apr 2002 06:18:47 +0000 (08:18 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 16 Apr 2002 06:18:47 +0000 (08:18 +0200)
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.

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

From-SVN: r52358

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 6fc0b2454dc5456faa64267cda53bbdf96459325..2e9810c374fc949eaaa546c1eea21b3311b9beea 100644 (file)
@@ -1,3 +1,15 @@
+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
index 33eab44b660e55dc67babcc71b7ca3673f49507c..275a465b4b0d2e689d6383ce6cc0be0a76149182 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 2ab387a59cc062b399d9f3e8d94eb0f801f25818..2abc4ddd473c71f6b5625c6c9c27ae451a483b44 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 ce601f0ab48a5524cc6553fa1cf20da01f72c733..c365f0498545eec586f27bb78720b4c99ab54e4b 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 1ab431e1f41bf5fc205ce465f35cc4e97e565462..b50951a9a4114a379c36202fd8d1647725cf9792 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 5a00bf4fcf4b8171ac99ce6ce748a834cb00dc1c..b7a6d255fb2f9c086b04c1914949c7281971fc2e 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 f5f85153d5961e6fe82a7ca4f228be96414b7d1c..826b30d6cba63d7bda116b088dcdb61288ab3a1b 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;
+    }
+}