aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGeoffrey Keating <geoffk@apple.com>2006-03-08 00:14:54 +0000
committerGeoffrey Keating <geoffk@gcc.gnu.org>2006-03-08 00:14:54 +0000
commitdbde310dda2aca41bfb44d1ea1e09d473820ea41 (patch)
tree1e721b898de7ea38638f01d7d167708e522fcbe0 /gcc
parentfb638355db9972c6cf5b9a8cfa49b0e9238083cb (diff)
downloadgcc-dbde310dda2aca41bfb44d1ea1e09d473820ea41.zip
gcc-dbde310dda2aca41bfb44d1ea1e09d473820ea41.tar.gz
gcc-dbde310dda2aca41bfb44d1ea1e09d473820ea41.tar.bz2
i386.c (ix86_delegitimize_address): Handle Darwin addresses with offsets; reorganize.
* config/i386/i386.c (ix86_delegitimize_address): Handle Darwin addresses with offsets; reorganize. From-SVN: r111826
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog3
-rw-r--r--gcc/config/i386/i386.c81
2 files changed, 46 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5f0ca64..d407068 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,8 @@
2006-03-07 Geoffrey Keating <geoffk@apple.com>
+ * config/i386/i386.c (ix86_delegitimize_address): Handle Darwin
+ addresses with offsets; reorganize.
+
* dwarf2out.c (DWARF2_FRAME_REG_OUT): Move up in file.
(expand_builtin_dwarf_sp_column): Call DWARF2_FRAME_REG_OUT.
(expand_builtin_init_dwarf_reg_sizes): Likewise.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index bf792a9..04b730a 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -7083,12 +7083,24 @@ i386_output_dwarf_dtprel (FILE *file, int size, rtx x)
/* In the name of slightly smaller debug output, and to cater to
general assembler lossage, recognize PIC+GOTOFF and turn it back
- into a direct symbol reference. */
+ into a direct symbol reference.
+
+ On Darwin, this is necessary to avoid a crash, because Darwin
+ has a different PIC label for each routine but the DWARF debugging
+ information is not associated with any particular routine, so it's
+ necessary to remove references to the PIC label from RTL stored by
+ the DWARF output code. */
static rtx
ix86_delegitimize_address (rtx orig_x)
{
- rtx x = orig_x, y;
+ rtx x = orig_x;
+ /* reg_addend is NULL or a multiple of some register. */
+ rtx reg_addend = NULL_RTX;
+ /* const_addend is NULL or a const_int. */
+ rtx const_addend = NULL_RTX;
+ /* This is the result, or NULL. */
+ rtx result = NULL_RTX;
if (GET_CODE (x) == MEM)
x = XEXP (x, 0);
@@ -7110,59 +7122,52 @@ ix86_delegitimize_address (rtx 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);
+ reg_addend = XEXP (x, 0);
+ if (GET_CODE (XEXP (reg_addend, 0)) == REG
+ && REGNO (XEXP (reg_addend, 0)) == PIC_OFFSET_TABLE_REGNUM)
+ reg_addend = XEXP (reg_addend, 1);
+ else if (GET_CODE (XEXP (reg_addend, 1)) == REG
+ && REGNO (XEXP (reg_addend, 1)) == PIC_OFFSET_TABLE_REGNUM)
+ reg_addend = XEXP (reg_addend, 0);
else
return orig_x;
- if (GET_CODE (y) != REG
- && GET_CODE (y) != MULT
- && GET_CODE (y) != ASHIFT)
+ if (GET_CODE (reg_addend) != REG
+ && GET_CODE (reg_addend) != MULT
+ && GET_CODE (reg_addend) != ASHIFT)
return orig_x;
}
else
return orig_x;
x = XEXP (XEXP (x, 1), 0);
- if (GET_CODE (x) == UNSPEC
- && ((XINT (x, 1) == UNSPEC_GOT && GET_CODE (orig_x) == MEM)
- || (XINT (x, 1) == UNSPEC_GOTOFF && GET_CODE (orig_x) != MEM)))
- {
- 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) == UNSPEC_GOT && GET_CODE (orig_x) == MEM)
- || (XINT (XEXP (x, 0), 1) == UNSPEC_GOTOFF
- && GET_CODE (orig_x) != MEM)))
+ && GET_CODE (XEXP (x, 1)) == CONST_INT)
{
- 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;
+ const_addend = XEXP (x, 1);
+ x = XEXP (x, 0);
}
+ if (GET_CODE (x) == UNSPEC
+ && ((XINT (x, 1) == UNSPEC_GOT && GET_CODE (orig_x) == MEM)
+ || (XINT (x, 1) == UNSPEC_GOTOFF && GET_CODE (orig_x) != MEM)))
+ result = XVECEXP (x, 0, 0);
+
if (TARGET_MACHO && darwin_local_data_pic (x)
&& GET_CODE (orig_x) != MEM)
- {
- x = XEXP (x, 0);
- if (y)
- return gen_rtx_PLUS (Pmode, y, x);
- return x;
- }
- return orig_x;
+ result = XEXP (x, 0);
+
+ if (! result)
+ return orig_x;
+
+ if (const_addend)
+ result = gen_rtx_PLUS (Pmode, result, const_addend);
+ if (reg_addend)
+ result = gen_rtx_PLUS (Pmode, reg_addend, result);
+ return result;
}
static void