summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/darwin.c3
-rw-r--r--gcc/config/rs6000/darwin.h1
-rw-r--r--gcc/config/rs6000/predicates.md13
-rw-r--r--gcc/config/rs6000/rs6000.c53
-rw-r--r--gcc/config/rs6000/rs6000.h1
-rw-r--r--gcc/config/rs6000/rs6000.md12
-rw-r--r--gcc/genrecog.c8
-rw-r--r--gcc/recog.c3
8 files changed, 54 insertions, 40 deletions
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 2a659483ce2..f882cb86a17 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -1709,16 +1709,19 @@ machopic_select_rtx_section (enum machine_mode mode, rtx x,
{
if (GET_MODE_SIZE (mode) == 8
&& (GET_CODE (x) == CONST_INT
+ || GET_CODE (x) == CONST_WIDE_INT
|| GET_CODE (x) == CONST_DOUBLE))
return darwin_sections[literal8_section];
else if (GET_MODE_SIZE (mode) == 4
&& (GET_CODE (x) == CONST_INT
+ || GET_CODE (x) == CONST_WIDE_INT
|| GET_CODE (x) == CONST_DOUBLE))
return darwin_sections[literal4_section];
else if (HAVE_GAS_LITERAL16
&& TARGET_64BIT
&& GET_MODE_SIZE (mode) == 16
&& (GET_CODE (x) == CONST_INT
+ || GET_CODE (x) == CONST_WIDE_INT
|| GET_CODE (x) == CONST_DOUBLE
|| GET_CODE (x) == CONST_VECTOR))
return darwin_sections[literal16_section];
diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h
index d5919c4c71d..5a248a5b085 100644
--- a/gcc/config/rs6000/darwin.h
+++ b/gcc/config/rs6000/darwin.h
@@ -421,3 +421,4 @@ do { \
/* So far, there is no rs6000_fold_builtin, if one is introduced, then
this will need to be modified similar to the x86 case. */
#define TARGET_FOLD_BUILTIN SUBTARGET_FOLD_BUILTIN
+
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index b5bff044779..97aa1553775 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -19,7 +19,7 @@
;; Return 1 for anything except PARALLEL.
(define_predicate "any_operand"
- (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem"))
+ (match_code "const_int,const_double,const_wide_int,const,symbol_ref,label_ref,subreg,reg,mem"))
;; Return 1 for any PARALLEL.
(define_predicate "any_parallel_operand"
@@ -596,7 +596,7 @@
;; Return 1 if operand is constant zero (scalars and vectors).
(define_predicate "zero_constant"
- (and (match_code "const_int,const_double,const_vector")
+ (and (match_code "const_int,const_double,const_wide_int,const_vector")
(match_test "op == CONST0_RTX (mode)")))
;; Return 1 if operand is 0.0.
@@ -790,7 +790,7 @@
;; Return 1 if op is a constant that is not a logical operand, but could
;; be split into one.
(define_predicate "non_logical_cint_operand"
- (and (match_code "const_int,const_double")
+ (and (match_code "const_int,const_wide_int")
(and (not (match_operand 0 "logical_operand"))
(match_operand 0 "reg_or_logical_cint_operand"))))
@@ -1058,7 +1058,7 @@
;; Return 1 if this operand is a valid input for a move insn.
(define_predicate "input_operand"
(match_code "symbol_ref,const,reg,subreg,mem,
- const_double,const_vector,const_int")
+ const_double,const_wide_int,const_vector,const_int")
{
/* Memory is always valid. */
if (memory_operand (op, mode))
@@ -1071,8 +1071,7 @@
/* Allow any integer constant. */
if (GET_MODE_CLASS (mode) == MODE_INT
- && (GET_CODE (op) == CONST_INT
- || GET_CODE (op) == CONST_DOUBLE))
+ && CONST_SCALAR_INT_P (op))
return 1;
/* Allow easy vector constants. */
@@ -1111,7 +1110,7 @@
;; Return 1 if this operand is a valid input for a vsx_splat insn.
(define_predicate "splat_input_operand"
(match_code "symbol_ref,const,reg,subreg,mem,
- const_double,const_vector,const_int")
+ const_double,const_wide_int,const_vector,const_int")
{
if (MEM_P (op))
{
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index e4402edc8d2..16a1eae2136 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -4597,6 +4597,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)
{
@@ -4770,8 +4779,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;
@@ -4932,9 +4941,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)
@@ -5086,9 +5093,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;
@@ -6284,6 +6289,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
@@ -7633,21 +7639,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. */
@@ -15969,6 +15966,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))
{
@@ -16982,8 +16980,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];
@@ -23371,6 +23368,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;
@@ -23575,7 +23581,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)) {
@@ -27577,6 +27583,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:
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index a5a7a859426..a0a1f2a675c 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2626,3 +2626,4 @@ enum rs6000_builtin_type_index
extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX];
extern GTY(()) tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
+#define TARGET_SUPPORTS_WIDE_INT 1
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 9f749f9a591..41e6f21495f 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -10437,7 +10437,7 @@
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
- (match_operand:DI 1 "const_double_operand" ""))]
+ (match_operand:DI 1 "const_scalar_int_operand" ""))]
"TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
[(set (match_dup 0) (match_dup 2))
(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
@@ -10503,7 +10503,7 @@
(define_split
[(set (match_operand:TI2 0 "int_reg_operand" "")
- (match_operand:TI2 1 "const_double_operand" ""))]
+ (match_operand:TI2 1 "const_scalar_int_operand" ""))]
"TARGET_POWERPC64
&& (VECTOR_MEM_NONE_P (<MODE>mode)
|| (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
@@ -10515,12 +10515,12 @@
<MODE>mode);
operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
<MODE>mode);
- if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ if (CONST_WIDE_INT_P (operands[1]))
{
- operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
- operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
+ operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
+ operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
}
- else if (GET_CODE (operands[1]) == CONST_INT)
+ else if (CONST_INT_P (operands[1]))
{
operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
operands[5] = operands[1];
diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index 691b0281175..dac10e061a3 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -588,6 +588,7 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
&& GET_CODE (src) != PC
&& GET_CODE (src) != CC0
&& !CONST_INT_P (src)
+ && !CONST_WIDE_INT_P (src)
&& GET_CODE (src) != CALL)
{
const char *which;
@@ -772,13 +773,14 @@ add_to_sequence (rtx pattern, struct decision_head *last,
We can optimize the generated code a little if either
(a) the predicate only accepts one code, or (b) the
- predicate does not allow CONST_INT, in which case it
- can match only if the modes match. */
+ predicate does not allow CONST_INT or CONST_WIDE_INT,
+ in which case it can match only if the modes match. */
pred = lookup_predicate (pred_name);
if (pred)
{
test->u.pred.data = pred;
- allows_const_int = pred->codes[CONST_INT];
+ allows_const_int = (pred->codes[CONST_INT]
+ || pred->codes[CONST_WIDE_INT]);
if (was_code == MATCH_PARALLEL
&& pred->singleton != PARALLEL)
message_with_line (pattern_lineno,
diff --git a/gcc/recog.c b/gcc/recog.c
index aa052f32449..1192d2909cc 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1198,7 +1198,8 @@ const_scalar_int_operand (rtx op, enum machine_mode mode)
/* Returns 1 if OP is an operand that is a CONST_WIDE_INT of mode
MODE. This most likely is not as useful as
- const_scalar_int_operand, but is here for consistancy. */
+ const_scalar_int_operand since it does not accept CONST_INTs, but
+ is here for consistancy. */
int
const_wide_int_operand (rtx op, enum machine_mode mode)
{