@@ -902,14 +902,6 @@
(and (match_test "TARGET_POWERPC64 && mode == DImode")
(match_operand 0 "mask64_operand"))))
-;; Like and_operand, but also match constants that can be implemented
-;; with two rldicl or rldicr insns.
-(define_predicate "and64_2_operand"
- (ior (match_operand 0 "mask64_2_operand")
- (if_then_else (match_test "fixed_regs[CR0_REGNO]")
- (match_operand 0 "gpc_reg_operand")
- (match_operand 0 "logical_operand"))))
-
;; Return 1 if the operand is either a non-special register or a
;; constant that can be used as the operand of a logical AND.
(define_predicate "and_operand"
@@ -920,13 +912,6 @@
(match_operand 0 "gpc_reg_operand")
(match_operand 0 "logical_operand"))))
-;; Return 1 if the operand is a constant that can be used as the operand
-;; of a logical AND, implemented with two rld* insns, and it cannot be done
-;; using just one insn.
-(define_predicate "and_2rld_operand"
- (and (match_operand 0 "and64_2_operand")
- (not (match_operand 0 "and_operand"))))
-
;; Return 1 if the operand is either a logical operand or a short cint operand.
(define_predicate "scc_eq_operand"
(ior (match_operand 0 "logical_operand")
@@ -30688,7 +30688,10 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
|| outer_code == IOR
|| outer_code == XOR)
&& (INTVAL (x)
- & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
+ & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0)
+ || (outer_code == AND
+ && mode == DImode
+ && mask64_2_operand (x, mode)))
{
*total = COSTS_N_INSNS (1);
return true;
@@ -2906,9 +2906,53 @@
operands[2] = force_reg (<MODE>mode, operands[2]);
}
- if ((<MODE>mode == DImode && !and64_2_operand (operands[2], <MODE>mode))
- || (<MODE>mode != DImode && !and_operand (operands[2], <MODE>mode)))
- operands[2] = force_reg (<MODE>mode, operands[2]);
+ if (!and_operand (operands[2], <MODE>mode))
+ {
+ if (TARGET_POWERPC64
+ && <MODE>mode == SImode && mask_operand_wrap (operands[2], SImode))
+ {
+ /* Handle the PowerPC64 rlwinm corner case. */
+ rtx out[3];
+ rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
+ int mb = extract_MB (operands[2]);
+ int me = extract_ME (operands[2]);
+ out[0] = GEN_INT (me + 1);
+ out[1] = GEN_INT (~((unsigned HOST_WIDE_INT) -1 << (33 + me - mb)));
+ out[2] = GEN_INT (32 - (me + 1));
+ emit_insn (gen_rtx_SET (tmp,
+ gen_rtx_AND (SImode,
+ gen_rtx_ROTATE (SImode,
+ operands[1],
+ out[0]),
+ out[1])));
+ emit_insn (gen_rtx_SET (operands[0],
+ gen_rtx_ROTATE (SImode,
+ tmp,
+ out[2])));
+ DONE;
+ }
+ if (TARGET_POWERPC64
+ && <MODE>mode == DImode && mask64_2_operand (operands[2], DImode))
+ {
+ rtx out[4];
+ rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : operands[0];
+ build_mask64_2_operands (operands[2], out);
+ emit_insn (gen_rtx_SET (tmp,
+ gen_rtx_AND (DImode,
+ gen_rtx_ROTATE (DImode,
+ operands[1],
+ out[0]),
+ out[1])));
+ emit_insn (gen_rtx_SET (operands[0],
+ gen_rtx_AND (DImode,
+ gen_rtx_ROTATE (DImode,
+ tmp,
+ out[2]),
+ out[3])));
+ DONE;
+ }
+ operands[2] = force_reg (<MODE>mode, operands[2]);
+ }
})
@@ -3097,31 +3141,6 @@
(set_attr "length" "4,4,8,8")])
-;; Handle the PowerPC64 rlwinm corner case
-
-(define_insn_and_split "*andsi3_internal6"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (and:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand:SI 2 "mask_operand_wrap" "i")))]
- "TARGET_POWERPC64"
- "#"
- "TARGET_POWERPC64"
- [(set (match_dup 0)
- (and:SI (rotate:SI (match_dup 1) (match_dup 3))
- (match_dup 4)))
- (set (match_dup 0)
- (rotate:SI (match_dup 0) (match_dup 5)))]
- "
-{
- int mb = extract_MB (operands[2]);
- int me = extract_ME (operands[2]);
- operands[3] = GEN_INT (me + 1);
- operands[5] = GEN_INT (32 - (me + 1));
- operands[4] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
-}"
- [(set_attr "length" "8")])
-
-
(define_expand "<code><mode>3"
[(set (match_operand:SDI 0 "gpc_reg_operand" "")
(iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
@@ -6017,87 +6036,6 @@
(const_int 0)))]
"")
-
-(define_insn_and_split "*anddi3_2rld"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
- (match_operand:DI 2 "and_2rld_operand" "n")))]
- "TARGET_POWERPC64"
- "#"
- ""
- [(set (match_dup 0)
- (and:DI (rotate:DI (match_dup 1)
- (match_dup 4))
- (match_dup 5)))
- (set (match_dup 0)
- (and:DI (rotate:DI (match_dup 0)
- (match_dup 6))
- (match_dup 7)))]
-{
- build_mask64_2_operands (operands[2], &operands[4]);
-}
- [(set_attr "length" "8")])
-
-(define_insn_and_split "*anddi3_2rld_dot"
- [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
- (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
- (match_operand:DI 2 "and_2rld_operand" "n,n"))
- (const_int 0)))
- (clobber (match_scratch:DI 0 "=r,r"))]
- "TARGET_64BIT && rs6000_gen_cell_microcode"
- "@
- #
- #"
- "&& reload_completed"
- [(set (match_dup 0)
- (and:DI (rotate:DI (match_dup 1)
- (match_dup 4))
- (match_dup 5)))
- (parallel [(set (match_dup 3)
- (compare:CC (and:DI (rotate:DI (match_dup 0)
- (match_dup 6))
- (match_dup 7))
- (const_int 0)))
- (clobber (match_dup 0))])]
-{
- build_mask64_2_operands (operands[2], &operands[4]);
-}
- [(set_attr "type" "two")
- (set_attr "dot" "yes")
- (set_attr "length" "8,12")])
-
-(define_insn_and_split "*anddi3_2rld_dot2"
- [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
- (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
- (match_operand:DI 2 "and_2rld_operand" "n,n"))
- (const_int 0)))
- (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
- (and:DI (match_dup 1)
- (match_dup 2)))]
- "TARGET_64BIT && rs6000_gen_cell_microcode"
- "@
- #
- #"
- "&& reload_completed"
- [(set (match_dup 0)
- (and:DI (rotate:DI (match_dup 1)
- (match_dup 4))
- (match_dup 5)))
- (parallel [(set (match_dup 3)
- (compare:CC (and:DI (rotate:DI (match_dup 0)
- (match_dup 6))
- (match_dup 7))
- (const_int 0)))
- (set (match_dup 0)
- (and:DI (rotate:DI (match_dup 0)
- (match_dup 6))
- (match_dup 7)))])]
-{
- build_mask64_2_operands (operands[2], &operands[4]);
-}
- [(set_attr "type" "two")
- (set_attr "dot" "yes")
- (set_attr "length" "8,12")])
;; 128-bit logical operations expanders