rldic can support ROTATE as well as ASHIFT inside an AND, provided the AND mask has exactly the shift count low zeros. The added rotate patterns are needed to support the next patch that removes the mask64_2_operand patterns, and may be generally useful too. Note that the costing for the ROTATEs was handled by the last patch.
* config/rs6000/rs6000.md (rotshift): New code iterator. (rldic_<code>_1, rldic_<code>_2, rldic_<code>_3, +splits): Rename from ashldi3_internal4..6. Use rotshift to support both rotate and ashift. diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index f28d48e..dafb04f 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -463,6 +463,8 @@ ; Logical operators. (define_code_iterator iorxor [ior xor]) +(define_code_iterator rotshift [rotate ashift]) + ; Signed/unsigned variants of ops. (define_code_iterator any_extend [sign_extend zero_extend]) (define_code_attr u [(sign_extend "") (zero_extend "u")]) @@ -5856,20 +5858,20 @@ "") -(define_insn "*ashldi3_internal4" +(define_insn "*rldic_<code>_1" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) + (and:DI (rotshift:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "const_int_operand" "i")) (match_operand:DI 3 "const_int_operand" "n")))] "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])" "rldic %0,%1,%H2,%W3" [(set_attr "type" "shift")]) -(define_insn "*ashldi3_internal5" +(define_insn "*rldic_<code>_2" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) + (and:DI (rotshift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) (match_operand:DI 3 "const_int_operand" "n,n")) (const_int 0))) (clobber (match_scratch:DI 4 "=r,r"))] @@ -5884,30 +5886,30 @@ (define_split [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) + (and:DI (rotshift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) (match_operand:DI 3 "const_int_operand" "")) (const_int 0))) (clobber (match_scratch:DI 4 ""))] "TARGET_POWERPC64 && reload_completed && includes_rldic_lshift_p (operands[2], operands[3])" [(set (match_dup 4) - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) + (and:DI (rotshift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 0) (compare:CC (match_dup 4) (const_int 0)))] "") -(define_insn "*ashldi3_internal6" +(define_insn "*rldic_<code>_3" [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) + (and:DI (rotshift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "i,i")) (match_operand:DI 3 "const_int_operand" "n,n")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + (and:DI (rotshift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])" "@ rldic. %0,%1,%H2,%W3 @@ -5919,22 +5921,23 @@ (define_split [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) + (and:DI (rotshift:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "")) (match_operand:DI 3 "const_int_operand" "")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] + (and:DI (rotshift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] "TARGET_POWERPC64 && reload_completed && includes_rldic_lshift_p (operands[2], operands[3])" [(set (match_dup 0) - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) + (and:DI (rotshift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 4) (compare:CC (match_dup 0) (const_int 0)))] "") + (define_insn "*ashldi3_internal7" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") -- Alan Modra Australia Development Lab, IBM