aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2002-04-16 08:18:47 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2002-04-16 08:18:47 +0200
commit4c8c0deca527fa28fc3c1ef8867f6b9348dda433 (patch)
treeb6cc3f213dc4555253d6e1f91a6f9b0fbb0649df
parenta9772b60f3716f6f82d695bd0fc0300b87ca0b89 (diff)
downloadgcc-4c8c0deca527fa28fc3c1ef8867f6b9348dda433.zip
gcc-4c8c0deca527fa28fc3c1ef8867f6b9348dda433.tar.gz
gcc-4c8c0deca527fa28fc3c1ef8867f6b9348dda433.tar.bz2
re PR target/6303 (output_operand: invalid expression as operand)
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
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/i386/i386.c14
-rw-r--r--gcc/config/s390/s390-protos.h1
-rw-r--r--gcc/config/s390/s390.c37
-rw-r--r--gcc/config/s390/s390.h4
-rw-r--r--gcc/dwarf2out.c11
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/gcc.dg/20020415-1.c35
8 files changed, 110 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6fc0b24..2e9810c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 33eab44..275a465 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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)
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 2ab387a..2abc4dd 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -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
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index ce601f0..c365f04 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -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. */
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 1ab431e..b50951a 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -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.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 5a00bf4..b7a6d25 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f5f8515..826b30d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..06b3ce0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20020415-1.c
@@ -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;
+ }
+}