i386.c (ix86_delegitimize_address): Handle Darwin addresses with offsets; reorganize.
authorGeoffrey Keating <geoffk@apple.com>
Wed, 8 Mar 2006 00:14:54 +0000 (00:14 +0000)
committerGeoffrey Keating <geoffk@gcc.gnu.org>
Wed, 8 Mar 2006 00:14:54 +0000 (00:14 +0000)
* config/i386/i386.c (ix86_delegitimize_address): Handle Darwin
addresses with offsets; reorganize.

From-SVN: r111826

gcc/ChangeLog
gcc/config/i386/i386.c

index 5f0ca64e3c7bf5bc1879ab8538eb20d31f1e3093..d407068d87df0de8ce30496b562cd1c16627e52d 100644 (file)
@@ -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.
index bf792a91403c9d26e581bfbd26948868c93b4a6c..04b730aa690c0a4e47bf09691cc7368bfa3a36db 100644 (file)
@@ -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;
 }
 \f
 static void