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.
{
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);
}
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));
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)
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
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. */
#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.
&& (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)
}
}
+#ifdef ASM_SIMPLIFY_DWARF_ADDR
+ if (rtl)
+ rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
+#endif
return rtl;
}
* 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.
--- /dev/null
+/* 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;
+ }
+}