From 8f2c60230485a3510ad719c2e5efaea594e95992 Mon Sep 17 00:00:00 2001 From: Aaron Sawdey Date: Mon, 8 Jan 2018 15:07:06 +0000 Subject: [PATCH] rs6000.md (cceq_ior_compare): Remove * so I can use it to generate rtl. 2018-01-08 Aaron Sawdey * config/rs6000/rs6000.md (cceq_ior_compare): Remove * so I can use it to generate rtl. (cceq_ior_compare_complement): Give it a name so I can use it, and change boolean_or_operator predicate to boolean_operator so it can be used to generate a crand. (eqne): New code iterator. (bd/bd_neg): New code_attrs. (_): New name for ctr_internal[12] now combined into a single define_insn. (tf_): A new insn pattern for the conditional form branch decrement (bdnzt/bdnzf/bdzt/bdzf). * config/rs6000/rs6000.c (rs6000_legitimate_combined_insn): Updated with the new names of the branch decrement patterns, and added the names of the branch decrement conditional patterns. From-SVN: r256344 --- gcc/ChangeLog | 17 ++++ gcc/config/rs6000/rs6000.md | 189 +++++++++++++++++++++++------------- 2 files changed, 141 insertions(+), 65 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f8d2b34ea72..b5aeb0ec519 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2018-01-08 Aaron Sawdey + + * config/rs6000/rs6000.md (cceq_ior_compare): Remove * so I can use it + to generate rtl. + (cceq_ior_compare_complement): Give it a name so I can use it, and + change boolean_or_operator predicate to boolean_operator so it can + be used to generate a crand. + (eqne): New code iterator. + (bd/bd_neg): New code_attrs. + (_): New name for ctr_internal[12] now combined into + a single define_insn. + (tf_): A new insn pattern for the conditional form branch + decrement (bdnzt/bdnzf/bdzt/bdzf). + * config/rs6000/rs6000.c (rs6000_legitimate_combined_insn): Updated + with the new names of the branch decrement patterns, and added the + names of the branch decrement conditional patterns. + 2018-01-08 Richard Biener PR tree-optimization/83563 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 2cbfbfc4517..3d3ead4ec49 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -12797,7 +12797,7 @@ ; which are generated by the branch logic. ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB) -(define_insn "*cceq_ior_compare" +(define_insn "cceq_ior_compare" [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") (compare:CCEQ (match_operator:SI 1 "boolean_operator" [(match_operator:SI 2 @@ -12817,9 +12817,9 @@ ; Why is the constant -1 here, but 1 in the previous pattern? ; Because ~1 has all but the low bit set. -(define_insn "" +(define_insn "cceq_ior_compare_complement" [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") - (compare:CCEQ (match_operator:SI 1 "boolean_or_operator" + (compare:CCEQ (match_operator:SI 1 "boolean_operator" [(not:SI (match_operator:SI 2 "branch_positive_comparison_operator" [(match_operand 3 @@ -13036,34 +13036,13 @@ ;; rs6000_legitimate_combined_insn prevents combine creating any of ;; the ctr insns. -(define_insn "ctr_internal1" - [(set (pc) - (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b") - (const_int 1)) - (label_ref (match_operand 0)) - (pc))) - (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") - (plus:P (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) - (clobber (match_scratch:P 4 "=X,X,&r,r"))] - "" -{ - if (which_alternative != 0) - return "#"; - else if (get_attr_length (insn) == 4) - return "bdnz %l0"; - else - return "bdz $+8\;b %l0"; -} - [(set_attr "type" "branch") - (set_attr "length" "*,16,20,20")]) - -;; Similar but use EQ +(define_code_iterator eqne [eq ne]) +(define_code_attr bd [(eq "bdz") (ne "bdnz")]) +(define_code_attr bd_neg [(eq "bdnz") (ne "bdz")]) -(define_insn "ctr_internal2" +(define_insn "_" [(set (pc) - (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b") + (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b") (const_int 1)) (label_ref (match_operand 0)) (pc))) @@ -13077,15 +13056,14 @@ if (which_alternative != 0) return "#"; else if (get_attr_length (insn) == 4) - return "bdz %l0"; + return " %l0"; else - return "bdnz $+8\;b %l0"; + return " $+8\;b %l0"; } [(set_attr "type" "branch") (set_attr "length" "*,16,20,20")]) -;; Now the splitters if we could not allocate the CTR register - +;; Now the splitter if we could not allocate the CTR register (define_split [(set (pc) (if_then_else (match_operator 2 "comparison_operator" @@ -13093,56 +13071,137 @@ (const_int 1)]) (match_operand 5) (match_operand 6))) - (set (match_operand:P 0 "int_reg_operand") + (set (match_operand:P 0 "nonimmediate_operand") (plus:P (match_dup 1) (const_int -1))) (clobber (match_scratch:CC 3)) (clobber (match_scratch:P 4))] "reload_completed" - [(set (match_dup 3) - (compare:CC (match_dup 1) - (const_int 1))) - (set (match_dup 0) - (plus:P (match_dup 1) - (const_int -1))) - (set (pc) + [(set (pc) (if_then_else (match_dup 7) (match_dup 5) (match_dup 6)))] { operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3], const0_rtx); + emit_insn (gen_rtx_SET (operands[3], + gen_rtx_COMPARE (CCmode, operands[1], const1_rtx))); + if (gpc_reg_operand (operands[0], mode)) + emit_insn (gen_add3 (operands[0], operands[1], constm1_rtx)); + else + { + emit_insn (gen_add3 (operands[4], operands[1], constm1_rtx)); + emit_move_insn (operands[0], operands[4]); + } + /* No DONE so branch comes from the pattern. */ }) -(define_split +;; patterns for bdnzt/bdnzf/bdzt/bdzf +;; Note that in the case of long branches we have to decompose this into +;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition +;; and the CR bit, which means there is no way to conveniently invert the +;; comparison as is done with plain bdnz/bdz. + +(define_insn "tf_" [(set (pc) - (if_then_else (match_operator 2 "comparison_operator" - [(match_operand:P 1 "gpc_reg_operand") - (const_int 1)]) - (match_operand 5) - (match_operand 6))) - (set (match_operand:P 0 "nonimmediate_operand") - (plus:P (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3)) - (clobber (match_scratch:P 4))] - "reload_completed && !gpc_reg_operand (operands[0], SImode)" - [(set (match_dup 3) - (compare:CC (match_dup 1) - (const_int 1))) - (set (match_dup 4) + (if_then_else + (and + (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b") + (const_int 1)) + (match_operator 3 "branch_comparison_operator" + [(match_operand 4 "cc_reg_operand" "y,y,y,y") + (const_int 0)])) + (label_ref (match_operand 0)) + (pc))) + (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") (plus:P (match_dup 1) (const_int -1))) - (set (match_dup 0) - (match_dup 4)) - (set (pc) - (if_then_else (match_dup 7) - (match_dup 5) - (match_dup 6)))] + (clobber (match_scratch:P 5 "=X,X,&r,r")) + (clobber (match_scratch:CC 6 "=X,&y,&y,&y")) + (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))] + "" { - operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3], - const0_rtx); + if (which_alternative != 0) + return "#"; + else if (get_attr_length (insn) == 4) + { + if (branch_positive_comparison_operator (operands[3], + GET_MODE (operands[3]))) + return "t %j3,%l0"; + else + return "f %j3,%l0"; + } + else + { + static char seq[96]; + char *bcs = output_cbranch (operands[3], "$+8", 1, insn); + sprintf(seq, " $+12\;%s;b %%l0", bcs); + return seq; + } +} + [(set_attr "type" "branch") + (set_attr "length" "*,16,20,20")]) + +;; Now the splitter if we could not allocate the CTR register +(define_split + [(set (pc) + (if_then_else + (and + (match_operator 1 "comparison_operator" + [(match_operand:P 0 "gpc_reg_operand") + (const_int 1)]) + (match_operator 3 "branch_comparison_operator" + [(match_operand 2 "cc_reg_operand") + (const_int 0)])) + (match_operand 4) + (match_operand 5))) + (set (match_operand:P 6 "int_reg_operand") + (plus:P (match_dup 0) + (const_int -1))) + (clobber (match_scratch:P 7)) + (clobber (match_scratch:CC 8)) + (clobber (match_scratch:CCEQ 9))] + "reload_completed" +[(pc)] +{ + rtx ctr = operands[0]; + rtx ctrcmp = operands[1]; + rtx ccin = operands[2]; + rtx cccmp = operands[3]; + rtx dst1 = operands[4]; + rtx dst2 = operands[5]; + rtx ctrout = operands[6]; + rtx ctrtmp = operands[7]; + enum rtx_code cmpcode = GET_CODE (ctrcmp); + bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp)); + if (!ispos) + cmpcode = reverse_condition (cmpcode); + /* Generate crand/crandc here. */ + emit_insn (gen_rtx_SET (operands[8], + gen_rtx_COMPARE (CCmode, ctr, const1_rtx))); + rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx); + + rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp); + if (ispos) + emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc, + operands[8], cccmp, ccin)); + else + emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc, + operands[8], cccmp, ccin)); + if (gpc_reg_operand (operands[0], mode)) + emit_insn (gen_add3 (ctrout, ctr, constm1_rtx)); + else + { + emit_insn (gen_add3 (ctrtmp, ctr, constm1_rtx)); + emit_move_insn (ctrout, ctrtmp); + } + rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx); + emit_jump_insn (gen_rtx_SET (pc_rtx, + gen_rtx_IF_THEN_ELSE (VOIDmode, cmp, + dst1, dst2))); + DONE; }) + (define_insn "trap" [(trap_if (const_int 1) (const_int 0))] -- 2.30.2