aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r--gcc/config/rs6000/rs6000.c90
1 files changed, 46 insertions, 44 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index bb521a9..e4a6834 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -4969,6 +4969,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)
{
@@ -5143,8 +5152,6 @@ easy_altivec_constant (rtx op, enum machine_mode mode)
else if (mode == V2DImode)
{
- /* In case the compiler is built 32-bit, CONST_DOUBLE 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;
@@ -5309,9 +5316,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)
@@ -5463,9 +5468,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;
@@ -6703,6 +6706,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
@@ -8167,21 +8171,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. */
@@ -8697,8 +8692,10 @@ rs6000_aggregate_candidate (const_tree type, enum machine_mode *modep)
int count;
tree index = TYPE_DOMAIN (type);
- /* Can't handle incomplete types. */
- if (!COMPLETE_TYPE_P (type))
+ /* Can't handle incomplete types nor sizes that are not
+ fixed. */
+ if (!COMPLETE_TYPE_P (type)
+ || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
return -1;
count = rs6000_aggregate_candidate (TREE_TYPE (type), modep);
@@ -8715,9 +8712,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;
@@ -8729,8 +8724,10 @@ rs6000_aggregate_candidate (const_tree type, enum machine_mode *modep)
int sub_count;
tree field;
- /* Can't handle incomplete types. */
- if (!COMPLETE_TYPE_P (type))
+ /* Can't handle incomplete types nor sizes that are not
+ fixed. */
+ if (!COMPLETE_TYPE_P (type)
+ || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
return -1;
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
@@ -8745,9 +8742,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;
@@ -8761,9 +8756,10 @@ rs6000_aggregate_candidate (const_tree type, enum machine_mode *modep)
int sub_count;
tree field;
- /* Can't handle incomplete types. */
- if (!COMPLETE_TYPE_P (type))
- return -1;
+ /* Can't handle incomplete types nor sizes that are not
+ fixed. */
+ if (!COMPLETE_TYPE_P (type)
+ || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
{
@@ -8777,9 +8773,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;
@@ -12474,16 +12468,14 @@ rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
/* Check whether the 2nd and 3rd arguments are integer constants and in
range and prepare arguments. */
STRIP_NOPS (arg1);
- if (TREE_CODE (arg1) != INTEGER_CST
- || !IN_RANGE (TREE_INT_CST_LOW (arg1), 0, 1))
+ if (TREE_CODE (arg1) != INTEGER_CST || wi::geu_p (arg1, 2))
{
error ("argument 2 must be 0 or 1");
return const0_rtx;
}
STRIP_NOPS (arg2);
- if (TREE_CODE (arg2) != INTEGER_CST
- || !IN_RANGE (TREE_INT_CST_LOW (arg2), 0, 15))
+ if (TREE_CODE (arg2) != INTEGER_CST || wi::geu_p (arg1, 16))
{
error ("argument 3 must be in the range 0..15");
return const0_rtx;
@@ -17456,6 +17448,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))
{
@@ -18495,8 +18488,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];
@@ -25243,6 +25235,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;
@@ -25447,7 +25448,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)) {
@@ -29453,6 +29454,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:
@@ -30092,7 +30094,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);