summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2002-02-13 22:46:22 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2002-02-13 22:46:22 +0100
commitec65b2e3daacfb67c039ca955e62450015f8eea1 (patch)
tree209f638cb0a7ef6ec425acc8b38da9da667447d7 /gcc/config
parent658311e053abebc6fa24f2863d81e802e776057e (diff)
downloadgcc-ec65b2e3daacfb67c039ca955e62450015f8eea1.tar.gz
re PR rtl-optimization/5547 (g++ 3.1 crash in output_operand)
PR optimization/5547: * config/i386/i386.c (i386_simplify_dwarf_addr): Simplify all valid IA-32 address modes involving non-scaled %ebx and GOT/GOTOFF as displacement. * g++.dg/other/debug3.C: New test. From-SVN: r49745
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i386/i386.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 159ac165ac7..40f88b5cc2f 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -5365,7 +5365,7 @@ rtx
i386_simplify_dwarf_addr (orig_x)
rtx orig_x;
{
- rtx x = orig_x;
+ rtx x = orig_x, y;
if (TARGET_64BIT)
{
@@ -5377,22 +5377,54 @@ i386_simplify_dwarf_addr (orig_x)
}
if (GET_CODE (x) != PLUS
- || GET_CODE (XEXP (x, 0)) != REG
|| GET_CODE (XEXP (x, 1)) != CONST)
return orig_x;
+ if (GET_CODE (XEXP (x, 0)) == REG
+ && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
+ /* %ebx + GOT/GOTOFF */
+ y = NULL;
+ else if (GET_CODE (XEXP (x, 0)) == PLUS)
+ {
+ /* %ebx + %reg * scale + GOT/GOTOFF */
+ y = XEXP (x, 0);
+ if (GET_CODE (XEXP (y, 0)) == REG
+ && REGNO (XEXP (y, 0)) == PIC_OFFSET_TABLE_REGNUM)
+ y = XEXP (y, 1);
+ else if (GET_CODE (XEXP (y, 1)) == REG
+ && REGNO (XEXP (y, 1)) == PIC_OFFSET_TABLE_REGNUM)
+ y = XEXP (y, 0);
+ else
+ return orig_x;
+ if (GET_CODE (y) != REG
+ && GET_CODE (y) != MULT
+ && GET_CODE (y) != ASHIFT)
+ return orig_x;
+ }
+ else
+ return orig_x;
+
x = XEXP (XEXP (x, 1), 0);
if (GET_CODE (x) == UNSPEC
&& (XINT (x, 1) == 6
|| XINT (x, 1) == 7))
- return XVECEXP (x, 0, 0);
+ {
+ if (y)
+ return gen_rtx_PLUS (Pmode, y, XVECEXP (x, 0, 0));
+ return 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))
- return gen_rtx_PLUS (VOIDmode, XVECEXP (XEXP (x, 0), 0, 0), XEXP (x, 1));
+ {
+ x = gen_rtx_PLUS (VOIDmode, XVECEXP (XEXP (x, 0), 0, 0), XEXP (x, 1));
+ if (y)
+ return gen_rtx_PLUS (Pmode, y, x);
+ return x;
+ }
return orig_x;
}