diff options
author | Aaron Sawdey <acsawdey@linux.vnet.ibm.com> | 2018-01-08 15:07:06 +0000 |
---|---|---|
committer | Aaron Sawdey <acsawdey@gcc.gnu.org> | 2018-01-08 09:07:06 -0600 |
commit | 8f2c60230485a3510ad719c2e5efaea594e95992 (patch) | |
tree | 8134cf66ee2422604ebf19ded7af726ddc3689f0 /gcc | |
parent | b33086c0a74ecc4ca0abb4011bb30564198f034e (diff) | |
download | gcc-8f2c60230485a3510ad719c2e5efaea594e95992.zip gcc-8f2c60230485a3510ad719c2e5efaea594e95992.tar.gz gcc-8f2c60230485a3510ad719c2e5efaea594e95992.tar.bz2 |
rs6000.md (cceq_ior_compare): Remove * so I can use it to generate rtl.
2018-01-08 Aaron Sawdey <acsawdey@linux.vnet.ibm.com>
* 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.
(<bd>_<mode>): New name for ctr<mode>_internal[12] now combined into
a single define_insn.
(<bd>tf_<mode>): 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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 189 |
2 files changed, 141 insertions, 65 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f8d2b34..b5aeb0e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2018-01-08 Aaron Sawdey <acsawdey@linux.vnet.ibm.com> + + * 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. + (<bd>_<mode>): New name for ctr<mode>_internal[12] now combined into + a single define_insn. + (<bd>tf_<mode>): 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 <rguenther@suse.de> PR tree-optimization/83563 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 2cbfbfc..3d3ead4 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<mode> insns. -(define_insn "ctr<mode>_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<mode>_internal2" +(define_insn "<bd>_<mode>" [(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 "<bd> %l0"; else - return "bdnz $+8\;b %l0"; + return "<bd_neg> $+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>mode)) + emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx)); + else + { + emit_insn (gen_add<mode>3 (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 "<bd>tf_<mode>" [(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 "<bd>t %j3,%l0"; + else + return "<bd>f %j3,%l0"; + } + else + { + static char seq[96]; + char *bcs = output_cbranch (operands[3], "$+8", 1, insn); + sprintf(seq, "<bd_neg> $+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>mode)) + emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx)); + else + { + emit_insn (gen_add<mode>3 (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))] |