OSDN Git Service

Backport from mainline
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Nov 2013 16:01:46 +0000 (16:01 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Nov 2013 16:01:46 +0000 (16:01 +0000)
2013-11-18  Uros Bizjak  <ubizjak@gmail.com>

* config/i386/i386.c (ix86_decompose_address): Use REG_P instead of
ix86_address_subreg_operand.  Move subreg checks to
ix86_validate_address_register.  Move address override check to
ix86_legitimate_address_p.
(ix86_validate_address_register): New function.
(ix86_legitimate_address_p): Call ix86_validate_address_register
to validate base and index registers.  Add address override check
from ix86_decompose_address.
(ix86_decompose_address): Remove.

Backport from mainline
2013-11-17  Uros Bizjak  <ubizjak@gmail.com>

PR target/59153
* config/i386/i386.c (ix86_address_subreg_operand): Do not
reject non-integer subregs.
(ix86_decompose_address): Do not reject invalid CONST_INT RTXes.
Move check for invalid x32 constant addresses ...
(ix86_legitimate_address_p): ... here.

Bacport from mainline
2012-03-13  Uros Bizjak  <ubizjak@gmail.com>

* config/i386/i386.c (ix86_decompose_address): Prevent %fs:(%reg)
addresses only when %reg is not in word mode.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@205122 138bc75d-0d04-0410-961f-82ee72b054a4

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

index edb6a77..524a9ff 100644 (file)
@@ -1,3 +1,34 @@
+2013-11-19  Uros Bizjak  <ubizjak@gmail.com>
+
+       Backport from mainline
+       2013-11-18  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.c (ix86_decompose_address): Use REG_P instead of
+       ix86_address_subreg_operand.  Move subreg checks to
+       ix86_validate_address_register.  Move address override check to
+       ix86_legitimate_address_p.
+       (ix86_validate_address_register): New function.
+       (ix86_legitimate_address_p): Call ix86_validate_address_register
+       to validate base and index registers.  Add address override check
+       from ix86_decompose_address.
+       (ix86_decompose_address): Remove.
+
+       Backport from mainline
+       2013-11-17  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/59153
+       * config/i386/i386.c (ix86_address_subreg_operand): Do not
+       reject non-integer subregs.
+       (ix86_decompose_address): Do not reject invalid CONST_INT RTXes.
+       Move check for invalid x32 constant addresses ...
+       (ix86_legitimate_address_p): ... here.
+
+       Bacport from mainline
+       2012-03-13  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.c (ix86_decompose_address): Prevent %fs:(%reg)
+       addresses only when %reg is not in word mode.
+
 2013-11-10  Karlson2k  <k2k@narod.ru>
            Kai Tietz  <ktietz@redhat.com>
 
index 4f700a3..a30c3f6 100644 (file)
@@ -11434,30 +11434,6 @@ ix86_live_on_entry (bitmap regs)
     }
 }
 \f
-/* Determine if op is suitable SUBREG RTX for address.  */
-
-static bool
-ix86_address_subreg_operand (rtx op)
-{
-  enum machine_mode mode;
-
-  if (!REG_P (op))
-    return false;
-
-  mode = GET_MODE (op);
-
-  if (GET_MODE_CLASS (mode) != MODE_INT)
-    return false;
-
-  /* Don't allow SUBREGs that span more than a word.  It can lead to spill
-     failures when the register is one word out of a two word structure.  */
-  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
-    return false;
-
-  /* Allow only SUBREGs of non-eliminable hard registers.  */
-  return register_no_elim_operand (op, mode);
-}
-
 /* Extract the parts of an RTL expression that is a valid memory address
    for an instruction.  Return 0 if the structure of the address is
    grossly off.  Return -1 if the address contains ASHIFT, so it is not
@@ -11522,7 +11498,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
     base = addr;
   else if (GET_CODE (addr) == SUBREG)
     {
-      if (ix86_address_subreg_operand (SUBREG_REG (addr)))
+      if (REG_P (SUBREG_REG (addr)))
        base = addr;
       else
        return 0;
@@ -11580,7 +11556,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
              break;
 
            case SUBREG:
-             if (!ix86_address_subreg_operand (SUBREG_REG (op)))
+             if (!REG_P (SUBREG_REG (op)))
                return 0;
              /* FALLTHRU */
 
@@ -11625,19 +11601,6 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
       scale = 1 << scale;
       retval = -1;
     }
-  else if (CONST_INT_P (addr))
-    {
-      if (!x86_64_immediate_operand (addr, VOIDmode))
-       return 0;
-
-      /* Constant addresses are sign extended to 64bit, we have to
-        prevent addresses from 0x80000000 to 0xffffffff in x32 mode.  */
-      if (TARGET_X32
-         && val_signbit_known_set_p (SImode, INTVAL (addr)))
-       return 0;
-
-      disp = addr;
-    }
   else
     disp = addr;                       /* displacement */
 
@@ -11646,7 +11609,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
       if (REG_P (index))
        ;
       else if (GET_CODE (index) == SUBREG
-              && ix86_address_subreg_operand (SUBREG_REG (index)))
+              && REG_P (SUBREG_REG (index)))
        ;
       else
        return 0;
@@ -12125,6 +12088,45 @@ ix86_legitimize_reload_address (rtx x,
   return false;
 }
 
+/* Determine if op is suitable RTX for an address register.
+   Return naked register if a register or a register subreg is
+   found, otherwise return NULL_RTX.  */
+
+static rtx
+ix86_validate_address_register (rtx op)
+{
+  enum machine_mode mode = GET_MODE (op);
+
+  /* Only SImode or DImode registers can form the address.  */
+  if (mode != SImode && mode != DImode)
+    return NULL_RTX;
+
+  if (REG_P (op))
+    return op;
+  else if (GET_CODE (op) == SUBREG)
+    {
+      rtx reg = SUBREG_REG (op);
+
+      if (!REG_P (reg))
+       return NULL_RTX;
+
+      mode = GET_MODE (reg);
+
+      /* Don't allow SUBREGs that span more than a word.  It can
+        lead to spill failures when the register is one word out
+        of a two word structure.  */
+      if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
+       return NULL_RTX;
+
+      /* Allow only SUBREGs of non-eliminable hard registers.  */
+      if (register_no_elim_operand (reg, mode))
+       return reg;
+    }
+
+  /* Op is not a register.  */
+  return NULL_RTX;
+}
+
 /* Recognizes RTL expressions that are valid memory addresses for an
    instruction.  The MODE argument is the machine mode for the MEM
    expression that wants to use this address.
@@ -12140,6 +12142,7 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
   struct ix86_address parts;
   rtx base, index, disp;
   HOST_WIDE_INT scale;
+  enum ix86_address_seg seg;
 
   if (ix86_decompose_address (addr, &parts) <= 0)
     /* Decomposition failed.  */
@@ -12149,21 +12152,14 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
   index = parts.index;
   disp = parts.disp;
   scale = parts.scale;
+  seg = parts.seg;
 
   /* Validate base register.  */
   if (base)
     {
-      rtx reg;
-
-      if (REG_P (base))
-       reg = base;
-      else if (GET_CODE (base) == SUBREG && REG_P (SUBREG_REG (base)))
-       reg = SUBREG_REG (base);
-      else
-       /* Base is not a register.  */
-       return false;
+      rtx reg = ix86_validate_address_register (base);
 
-      if (GET_MODE (base) != SImode && GET_MODE (base) != DImode)
+      if (reg == NULL_RTX)
        return false;
 
       if ((strict && ! REG_OK_FOR_BASE_STRICT_P (reg))
@@ -12175,17 +12171,9 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
   /* Validate index register.  */
   if (index)
     {
-      rtx reg;
-
-      if (REG_P (index))
-       reg = index;
-      else if (GET_CODE (index) == SUBREG && REG_P (SUBREG_REG (index)))
-       reg = SUBREG_REG (index);
-      else
-       /* Index is not a register.  */
-       return false;
+      rtx reg = ix86_validate_address_register (index);
 
-      if (GET_MODE (index) != SImode && GET_MODE (index) != DImode)
+      if (reg == NULL_RTX)
        return false;
 
       if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (reg))
@@ -12199,6 +12187,12 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
       && GET_MODE (base) != GET_MODE (index))
     return false;
 
+  /* Address override works only on the (%reg) part of %fs:(%reg).  */
+  if (seg != SEG_DEFAULT
+      && ((base && GET_MODE (base) != word_mode)
+         || (index && GET_MODE (index) != word_mode)))
+    return false;
+
   /* Validate scale factor.  */
   if (scale != 1)
     {
@@ -12320,6 +12314,12 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
               && !x86_64_immediate_operand (disp, VOIDmode))
        /* Displacement is out of range.  */
        return false;
+      /* In x32 mode, constant addresses are sign extended to 64bit, so
+        we have to prevent addresses from 0x80000000 to 0xffffffff.  */
+      else if (TARGET_X32 && !(index || base)
+              && CONST_INT_P (disp)
+              && val_signbit_known_set_p (SImode, INTVAL (disp)))
+       return false;
     }
 
   /* Everything looks valid.  */