OSDN Git Service

Backport from mainline
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 2 Aug 2012 16:24:25 +0000 (16:24 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 2 Aug 2012 16:24:25 +0000 (16:24 +0000)
2012-07-24  Uros Bizjak  <ubizjak@gmail.com>

PR target/53961
* config/i386/i386.c (ix86_legitimate_address_p): Move check for
negative constant address for TARGET_X32 ...
(ix86_decompose_address): ... here.  Reject constant addresses
that don't satisfy x86_64_immediate_operand predicate.

2012-07-23  Uros Bizjak  <ubizjak@gmail.com>

PR target/53961
* config/i386/i386.md (*lea): Add asserts to detect invalid addresses.
* config/i386/i386.c (ix86_print_operand_address): Ditto.
(ix86_decompose_address): Allow (zero_extend:DI (subreg:SI (...)))
addresses.  Prevent zero extensions of CONST_INT operands.

2012-07-22  Uros Bizjak  <ubizjak@gmail.com>

PR target/53961
* config/i386/i386.md (*lea): New insn pattern.
(*lea_1): Remove.
(*lea<mode>_2): Ditto.
(*lea_{3,4,5,6}_zext): Ditto.
* config/i386/predicates.md (lea_address_operand): Do not reject
zero-extended address operands.
* config/i386/constraints.md (j): Remove address constraint.
* config/i386/i386.c (ix86_decompose_address): Allow SImode subreg
of an address.
(ix86_print_operand_address): Handle SImode subreg of an address.
(ix86_avoid_lea_for_addr): Reject zero-extended addresses for now.

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

gcc/ChangeLog
gcc/config/i386/constraints.md
gcc/config/i386/i386.c
gcc/config/i386/i386.md
gcc/config/i386/predicates.md

index 9d6dce4..93524ab 100644 (file)
@@ -1,3 +1,37 @@
+2012-08-02  Uros Bizjak  <ubizjak@gmail.com>
+
+       Backport from mainline
+       2012-07-24  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/53961
+       * config/i386/i386.c (ix86_legitimate_address_p): Move check for
+       negative constant address for TARGET_X32 ...
+       (ix86_decompose_address): ... here.  Reject constant addresses
+       that don't satisfy x86_64_immediate_operand predicate.
+
+       2012-07-23  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/53961
+       * config/i386/i386.md (*lea): Add asserts to detect invalid addresses.
+       * config/i386/i386.c (ix86_print_operand_address): Ditto.
+       (ix86_decompose_address): Allow (zero_extend:DI (subreg:SI (...)))
+       addresses.  Prevent zero extensions of CONST_INT operands.
+
+       2012-07-22  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/53961
+       * config/i386/i386.md (*lea): New insn pattern.
+       (*lea_1): Remove.
+       (*lea<mode>_2): Ditto.
+       (*lea_{3,4,5,6}_zext): Ditto.
+       * config/i386/predicates.md (lea_address_operand): Do not reject
+       zero-extended address operands.
+       * config/i386/constraints.md (j): Remove address constraint.
+       * config/i386/i386.c (ix86_decompose_address): Allow SImode subreg
+       of an address.
+       (ix86_print_operand_address): Handle SImode subreg of an address.
+       (ix86_avoid_lea_for_addr): Reject zero-extended addresses for now.
+
 2012-08-01  Uros Bizjak  <ubizjak@gmail.com>
 
        Backport from mainline
index c231779..5a19307 100644 (file)
@@ -19,7 +19,7 @@
 
 ;;; Unused letters:
 ;;;     B     H           T  W
-;;;           h  k          v
+;;;           h jk          v
 
 ;; Integer register constraints.
 ;; It is not necessary to define 'r' here.
   (and (not (match_test "TARGET_X32"))
        (match_operand 0 "memory_operand")))
 
-(define_address_constraint "j"
-  "@internal Address operand that can be zero extended in LEA instruction."
-  (and (not (match_code "const_int"))
-       (match_operand 0 "address_operand")))
-
 ;; Integer constant constraints.
 (define_constraint "I"
   "Integer constant in the range 0 @dots{} 31, for 32-bit shifts."
index 3dc2b7e..c6e8bb2 100644 (file)
@@ -11425,16 +11425,41 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
     {
       if (GET_CODE (addr) == ZERO_EXTEND
          && GET_MODE (XEXP (addr, 0)) == SImode)
-       addr = XEXP (addr, 0);
+       {
+         addr = XEXP (addr, 0);
+         if (CONST_INT_P (addr))
+           return 0;
+       }             
       else if (GET_CODE (addr) == AND
               && const_32bit_mask (XEXP (addr, 1), DImode))
        {
          addr = XEXP (addr, 0);
 
-         /* Strip subreg.  */
+         /* Adjust SUBREGs.  */
          if (GET_CODE (addr) == SUBREG
              && GET_MODE (SUBREG_REG (addr)) == SImode)
-           addr = SUBREG_REG (addr);
+           {
+             addr = SUBREG_REG (addr);
+             if (CONST_INT_P (addr))
+               return 0;
+           }
+         else if (GET_MODE (addr) == DImode)
+           addr = gen_rtx_SUBREG (SImode, addr, 0);
+         else if (GET_MODE (addr) != VOIDmode)
+           return 0;
+       }
+    }
+
+  /* Allow SImode subregs of DImode addresses,
+     they will be emitted with addr32 prefix.  */
+  if (TARGET_64BIT && GET_MODE (addr) == SImode)
+    {
+      if (GET_CODE (addr) == SUBREG
+         && GET_MODE (SUBREG_REG (addr)) == DImode)
+       {
+         addr = SUBREG_REG (addr);
+         if (CONST_INT_P (addr))
+           return 0;
        }
     }
 
@@ -11545,6 +11570,19 @@ 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 */
 
@@ -12048,13 +12086,6 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
   rtx base, index, disp;
   HOST_WIDE_INT scale;
 
-  /* Since constant address in x32 is signed extended to 64bit,
-     we have to prevent addresses from 0x80000000 to 0xffffffff.  */
-  if (TARGET_X32
-      && CONST_INT_P (addr)
-      && INTVAL (addr) < 0)
-    return false;
-
   if (ix86_decompose_address (addr, &parts) <= 0)
     /* Decomposition failed.  */
     return false;
@@ -14589,12 +14620,20 @@ ix86_print_operand_address (FILE *file, rtx addr)
     }
   else
     {
-      /* Print SImode register names for zero-extended
-        addresses to force addr32 prefix.  */
-      if (TARGET_64BIT
-         && (GET_CODE (addr) == ZERO_EXTEND
-             || GET_CODE (addr) == AND))
+      /* Print SImode register names to force addr32 prefix.  */
+      if (GET_CODE (addr) == SUBREG)
        {
+         gcc_assert (TARGET_64BIT);
+         gcc_assert (GET_MODE (addr) == SImode);
+         gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
+         gcc_assert (!code);
+         code = 'l';
+       }
+      else if (GET_CODE (addr) == ZERO_EXTEND
+              || GET_CODE (addr) == AND)
+       {
+         gcc_assert (TARGET_64BIT);
+         gcc_assert (GET_MODE (addr) == DImode);
          gcc_assert (!code);
          code = 'l';
        }
@@ -16802,6 +16841,11 @@ ix86_avoid_lea_for_addr (rtx insn, rtx operands[])
   struct ix86_address parts;
   int ok;
 
+  /* FIXME: Handle zero-extended addresses.  */
+  if (GET_CODE (operands[1]) == ZERO_EXTEND
+      || GET_CODE (operands[1]) == AND)
+    return false;
+
   /* Check we need to optimize.  */
   if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
     return false;
index 2889166..c66026b 100644 (file)
   DONE;
 })
 \f
+;; Load effective address instructions
+
+(define_insn_and_split "*lea<mode>"
+  [(set (match_operand:SWI48 0 "register_operand" "=r")
+       (match_operand:SWI48 1 "lea_address_operand" "p"))]
+  ""
+{
+  rtx addr = operands[1];
+
+  if (GET_CODE (addr) == SUBREG)
+    {
+      gcc_assert (TARGET_64BIT);
+      gcc_assert (<MODE>mode == SImode);
+      gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
+      return "lea{l}\t{%E1, %0|%0, %E1}";
+    }
+  else if (GET_CODE (addr) == ZERO_EXTEND
+          || GET_CODE (addr) == AND)
+    {
+      gcc_assert (TARGET_64BIT);
+      gcc_assert (<MODE>mode == DImode);
+      return "lea{l}\t{%E1, %k0|%k0, %E1}";
+    }
+  else 
+    return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
+}
+  "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
+  [(const_int 0)]
+{
+  ix86_split_lea_for_addr (operands, <MODE>mode);
+  DONE;
+}
+  [(set_attr "type" "lea")
+   (set_attr "mode" "<MODE>")])
+\f
 ;; Add instructions
 
 (define_expand "add<mode>3"
   [(set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
-(define_insn_and_split "*lea_1"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
-  "TARGET_64BIT"
-  "lea{l}\t{%E1, %0|%0, %E1}"
-  "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
-  [(const_int 0)]
-{
-  ix86_split_lea_for_addr (operands, SImode);
-  DONE;
-}
-  [(set_attr "type" "lea")
-   (set_attr "mode" "SI")])
-
-(define_insn_and_split "*lea<mode>_2"
-  [(set (match_operand:SWI48 0 "register_operand" "=r")
-       (match_operand:SWI48 1 "lea_address_operand" "p"))]
-  ""
-  "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
-  "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
-  [(const_int 0)]
-{
-  ix86_split_lea_for_addr (operands, <MODE>mode);
-  DONE;
-}
-  [(set_attr "type" "lea")
-   (set_attr "mode" "<MODE>")])
-
-(define_insn "*lea_3_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (zero_extend:DI
-         (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
-  "TARGET_64BIT"
-  "lea{l}\t{%E1, %k0|%k0, %E1}"
-  [(set_attr "type" "lea")
-   (set_attr "mode" "SI")])
-
-(define_insn "*lea_4_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (zero_extend:DI
-         (match_operand:SI 1 "lea_address_operand" "j")))]
-  "TARGET_64BIT"
-  "lea{l}\t{%E1, %k0|%k0, %E1}"
-  [(set_attr "type" "lea")
-   (set_attr "mode" "SI")])
-
-(define_insn "*lea_5_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (and:DI
-         (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
-         (match_operand:DI 2 "const_32bit_mask" "n")))]
-  "TARGET_64BIT"
-  "lea{l}\t{%E1, %k0|%k0, %E1}"
-  [(set_attr "type" "lea")
-   (set_attr "mode" "SI")])
-
-(define_insn "*lea_6_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (and:DI
-         (match_operand:DI 1 "lea_address_operand" "p")
-         (match_operand:DI 2 "const_32bit_mask" "n")))]
-  "TARGET_64BIT"
-  "lea{l}\t{%E1, %k0|%k0, %E1}"
-  [(set_attr "type" "lea")
-   (set_attr "mode" "SI")])
-
 (define_insn "*add<mode>_1"
   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
        (plus:SWI48
index 32f73da..596b0a8 100644 (file)
   struct ix86_address parts;
   int ok;
 
-  /*  LEA handles zero-extend by itself.  */
-  if (GET_CODE (op) == ZERO_EXTEND
-      || GET_CODE (op) == AND)
-    return false;
-
   ok = ix86_decompose_address (op, &parts);
   gcc_assert (ok);
   return parts.seg == SEG_DEFAULT;