]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/rs6000/rs6000.c
Merge from trunk.
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.c
index 4c6a529c430cc7661fb7d4f2acba4b7ba3f7744a..df2ca2440b3a455bc3611bd4d99bc1ff4075370f 100644 (file)
@@ -4871,6 +4871,15 @@ num_insns_constant (rtx op, enum machine_mode mode)
       else
        return num_insns_constant_wide (INTVAL (op));
 
+    case CONST_WIDE_INT:
+      {
+       int i;
+       int ins = CONST_WIDE_INT_NUNITS (op) - 1;
+       for (i = 0; i < CONST_WIDE_INT_NUNITS (op); i++)
+         ins += num_insns_constant_wide (CONST_WIDE_INT_ELT (op, i));
+       return ins;
+      }
+
       case CONST_DOUBLE:
        if (mode == SFmode || mode == SDmode)
          {
@@ -5045,8 +5054,8 @@ easy_altivec_constant (rtx op, enum machine_mode mode)
 
   if (mode == V2DImode)
     {
-      /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
-        easy.  */
+      /* In case the compiler is built 32-bit, CONST_WIDE_INT
+        constants are not easy.  */
       if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
          || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
        return false;
@@ -5207,9 +5216,7 @@ paired_expand_vector_init (rtx target, rtx vals)
   for (i = 0; i < n_elts; ++i)
     {
       x = XVECEXP (vals, 0, i);
-      if (!(CONST_INT_P (x)
-           || GET_CODE (x) == CONST_DOUBLE
-           || GET_CODE (x) == CONST_FIXED))
+      if (!CONSTANT_P (x))
        ++n_var;
     }
   if (n_var == 0)
@@ -5361,9 +5368,7 @@ rs6000_expand_vector_init (rtx target, rtx vals)
   for (i = 0; i < n_elts; ++i)
     {
       x = XVECEXP (vals, 0, i);
-      if (!(CONST_INT_P (x)
-           || GET_CODE (x) == CONST_DOUBLE
-           || GET_CODE (x) == CONST_FIXED))
+      if (!CONSTANT_P (x))
        ++n_var, one_var = i;
       else if (x != CONST0_RTX (inner_mode))
        all_const_zero = false;
@@ -6588,6 +6593,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
           && TARGET_NO_TOC
           && ! flag_pic
           && GET_CODE (x) != CONST_INT
+          && GET_CODE (x) != CONST_WIDE_INT
           && GET_CODE (x) != CONST_DOUBLE
           && CONSTANT_P (x)
           && GET_MODE_NUNITS (mode) == 1
@@ -8028,21 +8034,12 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
     }
 
   /* Sanity checks.  Check that we get CONST_DOUBLE only when we should.  */
-  if (GET_CODE (operands[1]) == CONST_DOUBLE
-      && ! FLOAT_MODE_P (mode)
+  if (CONST_WIDE_INT_P (operands[1])
       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
     {
-      /* FIXME.  This should never happen.  */
-      /* Since it seems that it does, do the safe thing and convert
-        to a CONST_INT.  */
-      operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
+      /* This should be fixed with the introduction of CONST_WIDE_INT.  */
+      gcc_unreachable ();
     }
-  gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
-             || FLOAT_MODE_P (mode)
-             || ((CONST_DOUBLE_HIGH (operands[1]) != 0
-                  || CONST_DOUBLE_LOW (operands[1]) < 0)
-                 && (CONST_DOUBLE_HIGH (operands[1]) != -1
-                     || CONST_DOUBLE_LOW (operands[1]) >= 0)));
 
   /* Check if GCC is setting up a block move that will end up using FP
      registers as temporaries.  We must make sure this is acceptable.  */
@@ -8575,9 +8572,7 @@ rs6000_aggregate_candidate (const_tree type, enum machine_mode *modep)
                      - tree_to_uhwi (TYPE_MIN_VALUE (index)));
 
        /* There must be no padding.  */
-       if (!tree_fits_uhwi_p (TYPE_SIZE (type))
-           || ((HOST_WIDE_INT) tree_to_uhwi (TYPE_SIZE (type))
-               != count * GET_MODE_BITSIZE (*modep)))
+       if (wi::ne_p (TYPE_SIZE (type), count * GET_MODE_BITSIZE (*modep)))
          return -1;
 
        return count;
@@ -8605,9 +8600,7 @@ rs6000_aggregate_candidate (const_tree type, enum machine_mode *modep)
          }
 
        /* There must be no padding.  */
-       if (!tree_fits_uhwi_p (TYPE_SIZE (type))
-           || ((HOST_WIDE_INT) tree_to_uhwi (TYPE_SIZE (type))
-               != count * GET_MODE_BITSIZE (*modep)))
+       if (wi::ne_p (TYPE_SIZE (type), count * GET_MODE_BITSIZE (*modep)))
          return -1;
 
        return count;
@@ -8637,9 +8630,7 @@ rs6000_aggregate_candidate (const_tree type, enum machine_mode *modep)
          }
 
        /* There must be no padding.  */
-       if (!tree_fits_uhwi_p (TYPE_SIZE (type))
-           || ((HOST_WIDE_INT) tree_to_uhwi (TYPE_SIZE (type))
-               != count * GET_MODE_BITSIZE (*modep)))
+       if (wi::ne_p (TYPE_SIZE (type), count * GET_MODE_BITSIZE (*modep)))
          return -1;
 
        return count;
@@ -12153,7 +12144,7 @@ rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
         range and prepare arguments.  */
       STRIP_NOPS (arg1);
       if (TREE_CODE (arg1) != INTEGER_CST
-         || !IN_RANGE (TREE_INT_CST_LOW (arg1), 0, 1))
+         || !IN_RANGE (TREE_INT_CST_ELT (arg1, 0), 0, 1))
        {
          error ("argument 2 must be 0 or 1");
          return const0_rtx;
@@ -12161,7 +12152,7 @@ rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
 
       STRIP_NOPS (arg2);
       if (TREE_CODE (arg2) != INTEGER_CST
-         || !IN_RANGE (TREE_INT_CST_LOW (arg2), 0, 15))
+         || !IN_RANGE (TREE_INT_CST_ELT (arg2, 0), 0, 15))
        {
          error ("argument 3 must be in the range 0..15");
          return const0_rtx;
@@ -16876,6 +16867,7 @@ rs6000_output_move_128bit (rtx operands[])
   /* Constants.  */
   else if (dest_regno >= 0
           && (GET_CODE (src) == CONST_INT
+              || GET_CODE (src) == CONST_WIDE_INT
               || GET_CODE (src) == CONST_DOUBLE
               || GET_CODE (src) == CONST_VECTOR))
     {
@@ -17890,8 +17882,7 @@ rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
       if (TARGET_RELOCATABLE
          && in_section != toc_section
          && !recurse
-         && GET_CODE (x) != CONST_INT
-         && GET_CODE (x) != CONST_DOUBLE
+         && !CONST_SCALAR_INT_P (x)
          && CONSTANT_P (x))
        {
          char buf[256];
@@ -24605,6 +24596,15 @@ rs6000_hash_constant (rtx k)
     case LABEL_REF:
       return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
 
+    case CONST_WIDE_INT:
+      {
+       int i;
+       flen = CONST_WIDE_INT_NUNITS (k);
+       for (i = 0; i < flen; i++)
+         result = result * 613 + CONST_WIDE_INT_ELT (k, i);
+       return result;
+      }
+
     case CONST_DOUBLE:
       if (mode != VOIDmode)
        return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
@@ -24809,7 +24809,7 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
 
   /* If we're going to put a double constant in the TOC, make sure it's
      aligned properly when strict alignment is on.  */
-  if (GET_CODE (x) == CONST_DOUBLE
+  if ((CONST_DOUBLE_P (x) || CONST_WIDE_INT_P (x))
       && STRICT_ALIGNMENT
       && GET_MODE_BITSIZE (mode) >= 64
       && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
@@ -28797,6 +28797,7 @@ rs6000_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
       /* FALLTHRU */
 
     case CONST_DOUBLE:
+    case CONST_WIDE_INT:
     case CONST:
     case HIGH:
     case SYMBOL_REF:
@@ -29436,7 +29437,7 @@ rs6000_emit_swrsqrt (rtx dst, rtx src)
   gcc_assert (code != CODE_FOR_nothing);
 
   /* Load up the constant 1.5 either as a scalar, or as a vector.  */
-  real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
+  real_from_integer (&dconst3_2, VOIDmode, 3, SIGNED);
   SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
 
   halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);