diff options
author | Jakub Jelinek <jakub@redhat.com> | 2002-02-13 22:46:22 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2002-02-13 22:46:22 +0100 |
commit | ec65b2e3daacfb67c039ca955e62450015f8eea1 (patch) | |
tree | 209f638cb0a7ef6ec425acc8b38da9da667447d7 /gcc/config | |
parent | 658311e053abebc6fa24f2863d81e802e776057e (diff) | |
download | gcc-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.c | 40 |
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; } |