@@ -5246,11 +5246,7 @@ num_insns_constant (rtx op, machine_mode mode)
switch (GET_CODE (op))
{
case CONST_INT:
- if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
- && rs6000_is_valid_and_mask (op, mode))
- return 2;
- else
- return num_insns_constant_wide (INTVAL (op));
+ return num_insns_constant_wide (INTVAL (op));
case CONST_WIDE_INT:
{
@@ -8062,6 +8058,7 @@ struct genimm_ppc : genimm_base <rtx_code, 5>
bool exam_simple (HOST_WIDE_INT c, machine_mode, int budget);
bool exam_sub (HOST_WIDE_INT c, int budget);
+ bool exam_mask (HOST_WIDE_INT c, HOST_WIDE_INT mask, int sub_budget);
bool exam_search (HOST_WIDE_INT c, int budget);
void exam_full (HOST_WIDE_INT c);
void generate (rtx dest, machine_mode mode) const;
@@ -8125,6 +8122,21 @@ genimm_ppc::exam_sub (HOST_WIDE_INT c, int budget)
|| (budget > 1 && exam_search (c, budget)));
}
+/* If we are able to construct C within SUB_BUDGET + 1,
+ return true and fill in the recipe. */
+
+bool
+genimm_ppc::exam_mask (HOST_WIDE_INT c, HOST_WIDE_INT mask, int sub_budget)
+{
+ if (rs6000_is_valid_and_mask_wide (mask, DImode)
+ && exam_sub (c, sub_budget))
+ {
+ opN (AND, mask); /* RLDICL, et al */
+ return true;
+ }
+ return false;
+}
+
/* The body of the recursive search for C within BUDGET.
We've already failed exam_simple. */
@@ -8157,6 +8169,10 @@ genimm_ppc::exam_search (HOST_WIDE_INT c, int budget)
}
}
+ /* If C is a mask itself, apply it to all ones. */
+ if (exam_mask (-1, c, sub_budget))
+ return true;
+
/* Shift the constant left. */
test = HOST_WIDE_INT_UC (0xffffffff00000000);
if ((c & test) == c && exam_sub (c >> 32, sub_budget))
@@ -8209,6 +8225,7 @@ genimm_ppc::generate (rtx dest, machine_mode mode) const
x = op2;
break;
case PLUS:
+ case AND:
case IOR:
case ASHIFT:
x = gen_rtx_fmt_ee (r, mode, op1, op2);
@@ -7106,21 +7106,6 @@
[(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple")
(set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
-; Some DImode loads are best done as a load of -1 followed by a mask
-; instruction.
-(define_split
- [(set (match_operand:DI 0 "gpc_reg_operand")
- (match_operand:DI 1 "const_int_operand"))]
- "TARGET_POWERPC64
- && num_insns_constant (operands[1], DImode) > 1
- && rs6000_is_valid_and_mask (operands[1], DImode)"
- [(set (match_dup 0)
- (const_int -1))
- (set (match_dup 0)
- (and:DI (match_dup 0)
- (match_dup 1)))]
- "")
-
;; Split a load of a large constant into the appropriate five-instruction
;; sequence. Handle anything in a constant number of insns.
;; When non-easy constants can go in the TOC, this should use