This gets rid of some patterns I added a long time ago for ANDs that can be performed by two rotate and mask insns.
* config/rs6000/preficates.md (and64_2_operand): Delete. (and_2rld_operand): Delete. * config/rs6000/rs6000.md (and<mode>3): Expand two insn mask_operand_wrap and mask64_2_operand AND/ROTATE. (andsi3_internal6): Delete. (anddi3_2rld, anddi3_2rld_dot, anddi3_2rld_dot2): Delete. * config/rs6000/rs6000.md (rs6000_rtx_costs): Cost AND constants matching mask64_2_operand. diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index c408b0f..44eca2a 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -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") diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index a4a72f3..941ad02 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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; diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index dafb04f..420441b 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -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 -- Alan Modra Australia Development Lab, IBM