i386.h (TARGET_SUPPORTS_WIDE_INT): New define.
authorUros Bizjak <ubizjak@gmail.com>
Mon, 4 May 2015 15:05:11 +0000 (17:05 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 4 May 2015 15:05:11 +0000 (17:05 +0200)
* config/i386/i386.h (TARGET_SUPPORTS_WIDE_INT): New define.
* config/i386/i386.c (ix86_legitimate_constant_p): Handle TImode
as CONST_WIDE_INT, not CONST_DOUBLE.
(ix86_cannot_force_const_mem): Handle CONST_WIDE_INT.
(output_pic_addr_const): Do not handle VOIDmode CONST_DOUBLEs.
(ix86_find_base_term): Do not check for CONST_DOUBLE.
(ix86_print_operand): Do not handle non-FPmode CONST_DOUBLEs.
(ix86_build_signbit_mask): Rewrite using wide ints.
(ix86_split_to_parts) [HOST_BITS_PER_WIDE_INT < 64]: Remove.
(ix86_rtx_costs): Handle CONST_WIDE_INT.
(find_constant): Ditto.
* config/i386/i386.md (bts, btr, btc peepholes): Rewrite
using gen_int_mode.
* config/i386/predicates.md (x86_64_immediate_operand)
<case CONST_INT>: Remove HOST_BITS_PER_WIDE_INT == 32 code.
(x86_64_zext_immediate_operand): Remove CONST_DOUBLE handling.
<case CONST_INT>: Remove HOST_BITS_PER_WIDE_INT == 32 code.
(const0_operand): Also match const_wide_int.
(constm1_operand): Ditto.
(const1_operand): Ditto.

From-SVN: r222767

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

index 756071d5df4b13356a0f2528e3a29e87b97698f1..819d7681a5bd84fb4892df939f2e238b84b40ae6 100644 (file)
@@ -1,3 +1,26 @@
+2015-05-04  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.h (TARGET_SUPPORTS_WIDE_INT): New define.
+       * config/i386/i386.c (ix86_legitimate_constant_p): Handle TImode
+       as CONST_WIDE_INT, not CONST_DOUBLE.
+       (ix86_cannot_force_const_mem): Handle CONST_WIDE_INT.
+       (output_pic_addr_const): Do not handle VOIDmode CONST_DOUBLEs.
+       (ix86_find_base_term): Do not check for CONST_DOUBLE.
+       (ix86_print_operand): Do not handle non-FPmode CONST_DOUBLEs.
+       (ix86_build_signbit_mask): Rewrite using wide ints.
+       (ix86_split_to_parts) [HOST_BITS_PER_WIDE_INT < 64]: Remove.
+       (ix86_rtx_costs): Handle CONST_WIDE_INT.
+       (find_constant): Ditto.
+       * config/i386/i386.md (bts, btr, btc peepholes): Rewrite
+       using gen_int_mode.
+       * config/i386/predicates.md (x86_64_immediate_operand)
+       <case CONST_INT>: Remove HOST_BITS_PER_WIDE_INT == 32 code.
+       (x86_64_zext_immediate_operand): Remove CONST_DOUBLE handling.
+       <case CONST_INT>: Remove HOST_BITS_PER_WIDE_INT == 32 code.
+       (const0_operand): Also match const_wide_int.
+       (constm1_operand): Ditto.
+       (const1_operand): Ditto.
+
 2015-05-04  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/65965
index cd7bb567c3525e2ff7d7dd99d9d950b4986d7796..461094f4e26908babded534170df07b4a437a519 100644 (file)
@@ -13077,7 +13077,7 @@ ix86_legitimate_constant_p (machine_mode, rtx x)
 #endif
       break;
 
-    case CONST_DOUBLE:
+    case CONST_WIDE_INT:
       if (GET_MODE (x) == TImode
          && x != CONST0_RTX (TImode)
           && !TARGET_64BIT)
@@ -13107,6 +13107,7 @@ ix86_cannot_force_const_mem (machine_mode mode, rtx x)
   switch (GET_CODE (x))
     {
     case CONST_INT:
+    case CONST_WIDE_INT:
     case CONST_DOUBLE:
     case CONST_VECTOR:
       return false;
@@ -13133,7 +13134,7 @@ is_imported_p (rtx x)
 
 /* Nonzero if the constant value X is a legitimate general operand
    when generating PIC code.  It is given that flag_pic is on and
-   that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
+   that X satisfies CONSTANT_P.  */
 
 bool
 legitimate_pic_operand_p (rtx x)
@@ -14589,20 +14590,9 @@ output_pic_addr_const (FILE *file, rtx x, int code)
       break;
 
     case CONST_DOUBLE:
-      if (GET_MODE (x) == VOIDmode)
-       {
-         /* We can use %d if the number is <32 bits and positive.  */
-         if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
-           fprintf (file, "0x%lx%08lx",
-                    (unsigned long) CONST_DOUBLE_HIGH (x),
-                    (unsigned long) CONST_DOUBLE_LOW (x));
-         else
-           fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
-       }
-      else
-       /* We can't handle floating point constants;
-          TARGET_PRINT_OPERAND must handle them.  */
-       output_operand_lossage ("floating constant misused");
+      /* We can't handle floating point constants;
+        TARGET_PRINT_OPERAND must handle them.  */
+      output_operand_lossage ("floating constant misused");
       break;
 
     case PLUS:
@@ -14962,8 +14952,7 @@ ix86_find_base_term (rtx x)
        return x;
       term = XEXP (x, 0);
       if (GET_CODE (term) == PLUS
-         && (CONST_INT_P (XEXP (term, 1))
-             || GET_CODE (XEXP (term, 1)) == CONST_DOUBLE))
+         && CONST_INT_P (XEXP (term, 1)))
        term = XEXP (term, 0);
       if (GET_CODE (term) != UNSPEC
          || (XINT (term, 1) != UNSPEC_GOTPCREL
@@ -15967,7 +15956,7 @@ ix86_print_operand (FILE *file, rtx x, int code)
 
       if (code != 'P' && code != 'p')
        {
-         if (CONST_INT_P (x) || GET_CODE (x) == CONST_DOUBLE)
+         if (CONST_INT_P (x))
            {
              if (ASSEMBLER_DIALECT == ASM_ATT)
                putc ('$', file);
@@ -19444,12 +19433,9 @@ rtx
 ix86_build_signbit_mask (machine_mode mode, bool vect, bool invert)
 {
   machine_mode vec_mode, imode;
-  HOST_WIDE_INT hi, lo;
-  int shift = 63;
-  rtx v;
-  rtx mask;
+  wide_int w;
+  rtx mask, v;
 
-  /* Find the sign bit, sign extended to 2*HWI.  */
   switch (mode)
     {
     case V16SImode:
@@ -19461,7 +19447,6 @@ ix86_build_signbit_mask (machine_mode mode, bool vect, bool invert)
       vec_mode = mode;
       mode = GET_MODE_INNER (mode);
       imode = SImode;
-      lo = 0x80000000, hi = lo < 0;
       break;
 
     case V8DImode:
@@ -19473,54 +19458,25 @@ ix86_build_signbit_mask (machine_mode mode, bool vect, bool invert)
       vec_mode = mode;
       mode = GET_MODE_INNER (mode);
       imode = DImode;
-      if (HOST_BITS_PER_WIDE_INT >= 64)
-       lo = (HOST_WIDE_INT)1 << shift, hi = -1;
-      else
-       lo = 0, hi = (HOST_WIDE_INT)1 << (shift - HOST_BITS_PER_WIDE_INT);
       break;
 
     case TImode:
     case TFmode:
       vec_mode = VOIDmode;
-      if (HOST_BITS_PER_WIDE_INT >= 64)
-       {
-         imode = TImode;
-         lo = 0, hi = (HOST_WIDE_INT)1 << shift;
-       }
-      else
-       {
-         rtvec vec;
-
-         imode = DImode;
-         lo = 0, hi = (HOST_WIDE_INT)1 << (shift - HOST_BITS_PER_WIDE_INT);
-
-         if (invert)
-           {
-             lo = ~lo, hi = ~hi;
-             v = constm1_rtx;
-           }
-         else
-           v = const0_rtx;
-
-         mask = immed_double_const (lo, hi, imode);
-
-         vec = gen_rtvec (2, v, mask);
-         v = gen_rtx_CONST_VECTOR (V2DImode, vec);
-         v = copy_to_mode_reg (mode, gen_lowpart (mode, v));
-
-         return v;
-       }
-     break;
+      imode = TImode;
+      break;
 
     default:
       gcc_unreachable ();
     }
 
+  w = wi::set_bit_in_zero (GET_MODE_BITSIZE (mode) - 1,
+                          GET_MODE_BITSIZE (mode));
   if (invert)
-    lo = ~lo, hi = ~hi;
+    w = wi::bit_not (w);
 
   /* Force this value into the low part of a fp vector constant.  */
-  mask = immed_double_const (lo, hi, imode);
+  mask = immed_wide_int_const (w, imode);
   mask = gen_lowpart (mode, mask);
 
   if (vec_mode == VOIDmode)
@@ -22735,26 +22691,21 @@ ix86_split_to_parts (rtx operand, rtx *parts, machine_mode mode)
              REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
              real_to_target (l, &r, mode);
 
-             /* Do not use shift by 32 to avoid warning on 32bit systems.  */
-             if (HOST_BITS_PER_WIDE_INT >= 64)
-               parts[0]
-                 = gen_int_mode
-                     ((l[0] & (((HOST_WIDE_INT) 2 << 31) - 1))
-                      + ((((HOST_WIDE_INT) l[1]) << 31) << 1),
-                      DImode);
-             else
-               parts[0] = immed_double_const (l[0], l[1], DImode);
+             /* real_to_target puts 32-bit pieces in each long.  */
+             parts[0] =
+               gen_int_mode
+                 ((l[0] & (HOST_WIDE_INT) 0xffffffff)
+                  | ((l[1] & (HOST_WIDE_INT) 0xffffffff) << 32),
+                  DImode);
 
              if (upper_mode == SImode)
                parts[1] = gen_int_mode (l[2], SImode);
-             else if (HOST_BITS_PER_WIDE_INT >= 64)
-               parts[1]
-                 = gen_int_mode
-                     ((l[2] & (((HOST_WIDE_INT) 2 << 31) - 1))
-                      + ((((HOST_WIDE_INT) l[3]) << 31) << 1),
-                      DImode);
              else
-               parts[1] = immed_double_const (l[2], l[3], DImode);
+               parts[1] =
+                 gen_int_mode
+                   ((l[2] & (HOST_WIDE_INT) 0xffffffff)
+                    | ((l[3] & (HOST_WIDE_INT) 0xffffffff) << 32),
+                    DImode);
            }
          else
            gcc_unreachable ();
@@ -42021,12 +41972,11 @@ ix86_rtx_costs (rtx x, int code_i, int outer_code_i, int opno, int *total,
        *total = 0;
       return true;
 
+    case CONST_WIDE_INT:
+      *total = 0;
+      return true;
+
     case CONST_DOUBLE:
-      if (mode == VOIDmode)
-       {
-         *total = 0;
-         return true;
-       }
       switch (standard_80387_constant_p (x))
        {
        case 1: /* 0.0 */
@@ -50654,6 +50604,7 @@ find_constant (rtx in_rtx, imm_info *imm_values)
          break;
 
        case CONST_DOUBLE:
+       case CONST_WIDE_INT:
          (imm_values->imm)++;
          (imm_values->imm64)++;
          break;
index 6901e2aae8fc740caa85f6efa7d3002953902a94..24ff911df9eea388b936780ce1ceb3b72c6671ea 100644 (file)
@@ -2563,6 +2563,8 @@ extern void debug_dispatch_window (int);
 /* For switching between functions with different target attributes.  */
 #define SWITCHABLE_TARGET 1
 
+#define TARGET_SUPPORTS_WIDE_INT 1
+
 /*
 Local variables:
 version-control: t
index 5cac713e5a31ee85cbe7e9d1a07aead5e937f7af..55c5d06f51e5580f42ac21e5da5b798107eb47c6 100644 (file)
   "TARGET_64BIT && !TARGET_USE_BT"
   [(const_int 0)]
 {
-  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
-  rtx op1;
+  int i = INTVAL (operands[1]);
 
-  if (HOST_BITS_PER_WIDE_INT >= 64)
-    lo = (HOST_WIDE_INT)1 << i, hi = 0;
-  else if (i < HOST_BITS_PER_WIDE_INT)
-    lo = (HOST_WIDE_INT)1 << i, hi = 0;
-  else
-    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
+  rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
 
-  op1 = immed_double_const (lo, hi, DImode);
   if (i >= 31)
     {
       emit_move_insn (operands[2], op1);
   "TARGET_64BIT && !TARGET_USE_BT"
   [(const_int 0)]
 {
-  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
-  rtx op1;
-
-  if (HOST_BITS_PER_WIDE_INT >= 64)
-    lo = (HOST_WIDE_INT)1 << i, hi = 0;
-  else if (i < HOST_BITS_PER_WIDE_INT)
-    lo = (HOST_WIDE_INT)1 << i, hi = 0;
-  else
-    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
+  int i = INTVAL (operands[1]);
 
-  op1 = immed_double_const (~lo, ~hi, DImode);
+  rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
   if (i >= 32)
     {
       emit_move_insn (operands[2], op1);
   "TARGET_64BIT && !TARGET_USE_BT"
   [(const_int 0)]
 {
-  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
-  rtx op1;
+  int i = INTVAL (operands[1]);
 
-  if (HOST_BITS_PER_WIDE_INT >= 64)
-    lo = (HOST_WIDE_INT)1 << i, hi = 0;
-  else if (i < HOST_BITS_PER_WIDE_INT)
-    lo = (HOST_WIDE_INT)1 << i, hi = 0;
-  else
-    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
+  rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
 
-  op1 = immed_double_const (lo, hi, DImode);
   if (i >= 31)
     {
       emit_move_insn (operands[2], op1);
index 92533b553a4f5b836be6ff316e1b40d0dce3ed73..26dd3e1d7f8a38901c5c32d757339f119b6810f7 100644 (file)
   switch (GET_CODE (op))
     {
     case CONST_INT:
-      /* CONST_DOUBLES never match, since HOST_BITS_PER_WIDE_INT is known
-         to be at least 32 and this all acceptable constants are
-        represented as CONST_INT.  */
-      if (HOST_BITS_PER_WIDE_INT == 32)
-       return true;
-      else
-       {
-         HOST_WIDE_INT val = trunc_int_for_mode (INTVAL (op), DImode);
-         return trunc_int_for_mode (val, SImode) == val;
-       }
-      break;
-
+      {
+        HOST_WIDE_INT val = trunc_int_for_mode (INTVAL (op), DImode);
+        return trunc_int_for_mode (val, SImode) == val;
+      }
     case SYMBOL_REF:
       /* For certain code models, the symbolic references are known to fit.
         in CM_SMALL_PIC model we know it fits if it is local to the shared
 
 ;; Return true if VALUE can be stored in the zero extended immediate field.
 (define_predicate "x86_64_zext_immediate_operand"
-  (match_code "const_double,const_int,symbol_ref,label_ref,const")
+  (match_code "const_int,symbol_ref,label_ref,const")
 {
   switch (GET_CODE (op))
     {
-    case CONST_DOUBLE:
-      if (HOST_BITS_PER_WIDE_INT == 32)
-       return (GET_MODE (op) == VOIDmode && !CONST_DOUBLE_HIGH (op));
-      else
-       return false;
-
     case CONST_INT:
-      if (HOST_BITS_PER_WIDE_INT == 32)
-       return INTVAL (op) >= 0;
-      else
-       return !(INTVAL (op) & ~(HOST_WIDE_INT) 0xffffffff);
+      return !(INTVAL (op) & ~(HOST_WIDE_INT) 0xffffffff);
 
     case SYMBOL_REF:
       /* For certain code models, the symbolic references are known to fit.  */
 
 ;; Match exactly zero.
 (define_predicate "const0_operand"
-  (match_code "const_int,const_double,const_vector")
+  (match_code "const_int,const_wide_int,const_double,const_vector")
 {
   if (mode == VOIDmode)
     mode = GET_MODE (op);
 
 ;; Match -1.
 (define_predicate "constm1_operand"
-  (match_code "const_int,const_double,const_vector")
+  (match_code "const_int,const_wide_int,const_double,const_vector")
 {
   if (mode == VOIDmode)
     mode = GET_MODE (op);
 
 ;; Match one or vector filled with ones.
 (define_predicate "const1_operand"
-  (match_code "const_int,const_double,const_vector")
+  (match_code "const_int,const_wide_int,const_double,const_vector")
 {
   if (mode == VOIDmode)
     mode = GET_MODE (op);