New instructions setbc and setbcr. setbc sets a GPR to 1 if some condition register bit is set, and 0 otherwise; setbcr does it the other way around.
2020-05-06 Segher Boessenkool <seg...@kernel.crashing.org> * config/rs6000/rs6000.md (setbc_<un>signed_<GPR:mode>): New define_insn. (*setbcr_<un>signed_<GPR:mode>): Likewise. (cstore<mode>4): Use setbc[r] if available. (<code><GPR:mode><GPR2:mode>2_isel): Avoid for TARGET_FUTURE. (eq<mode>3): Use setbc for TARGET_FUTURE. (*eq<mode>3): Avoid for TARGET_FUTURE. (ne<mode>3): Replace :P with :GPR; use setbc for TARGET_FUTURE; else for non-Pmode, use gen_eq and gen_xor. (*ne<mode>3): Avoid for TARGET_FUTURE. (*eqsi3_ext<mode>): Avoid for TARGET_FUTURE; fix missing && 1. --- gcc/config/rs6000/rs6000.md | 73 +++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 6173994797c..e8dc576779a 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -5138,6 +5138,25 @@ (define_insn "*isel_reversed_<un>signed_<GPR:mode>" } [(set_attr "type" "isel")]) +; Set Boolean Condition (Reverse) +(define_insn "setbc_<un>signed_<GPR:mode>" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (match_operator:GPR 1 "scc_comparison_operator" + [(match_operand:CCEITHER 2 "cc_reg_operand" "y") + (const_int 0)]))] + "TARGET_FUTURE" + "setbc %0,%j1" + [(set_attr "type" "isel")]) + +(define_insn "*setbcr_<un>signed_<GPR:mode>" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (match_operator:GPR 1 "scc_rev_comparison_operator" + [(match_operand:CCEITHER 2 "cc_reg_operand" "y") + (const_int 0)]))] + "TARGET_FUTURE" + "setbcr %0,%j1" + [(set_attr "type" "isel")]) + ;; Floating point conditional move (define_expand "mov<mode>cc" [(set (match_operand:SFDF 0 "gpc_reg_operand") @@ -11425,6 +11444,10 @@ (define_expand "cstore<mode>4" (clobber (match_operand:GPR 0 "gpc_reg_operand"))] "" { + /* Everything is best done with setbc[r] if available. */ + if (TARGET_FUTURE) + rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx); + /* Expanding EQ and NE directly to some machine instructions does not help but does hurt combine. So don't. */ if (GET_CODE (operands[1]) == EQ) @@ -11837,7 +11860,7 @@ (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel" (clobber (match_scratch:GPR 3 "=r")) (clobber (match_scratch:GPR 4 "=r")) (clobber (match_scratch:<UNS> 5 "=y"))] - "TARGET_ISEL + "!TARGET_FUTURE && TARGET_ISEL && !(<CODE> == EQ && operands[2] == const0_rtx) && !(<CODE> == NE && operands[2] == const0_rtx && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)" @@ -11917,6 +11940,16 @@ (define_expand "eq<mode>3" (clobber (match_scratch:GPR 4 "=r"))])] "" { + if (TARGET_FUTURE) + { + rtx cc = gen_reg_rtx (CCmode); + rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]); + emit_insn (gen_rtx_SET (cc, compare)); + rtx eq = gen_rtx_fmt_ee (EQ, <MODE>mode, cc, const0_rtx); + emit_insn (gen_setbc_signed_<mode> (operands[0], eq, cc)); + DONE; + } + if (TARGET_ISEL && operands[2] != const0_rtx) { emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1], @@ -11931,7 +11964,7 @@ (define_insn_and_split "*eq<mode>3" (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) (clobber (match_scratch:GPR 3 "=r")) (clobber (match_scratch:GPR 4 "=r"))] - "!(TARGET_ISEL && operands[2] != const0_rtx)" + "!TARGET_FUTURE && !(TARGET_ISEL && operands[2] != const0_rtx)" "#" "&& 1" [(set (match_dup 4) @@ -11955,14 +11988,32 @@ (define_insn_and_split "*eq<mode>3" (define_expand "ne<mode>3" [(parallel [ - (set (match_operand:P 0 "gpc_reg_operand" "=r") - (ne:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))) - (clobber (match_scratch:P 3 "=r")) - (clobber (match_scratch:P 4 "=r")) - (clobber (reg:P CA_REGNO))])] + (set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (ne:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) + (clobber (match_scratch:GPR 3 "=r")) + (clobber (match_scratch:GPR 4 "=r")) + (clobber (reg:GPR CA_REGNO))])] "" { + if (TARGET_FUTURE) + { + rtx cc = gen_reg_rtx (CCmode); + rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]); + emit_insn (gen_rtx_SET (cc, compare)); + rtx ne = gen_rtx_fmt_ee (NE, <MODE>mode, cc, const0_rtx); + emit_insn (gen_setbc_signed_<mode> (operands[0], ne, cc)); + DONE; + } + + if (<MODE>mode != Pmode) + { + rtx x = gen_reg_rtx (<MODE>mode); + emit_insn (gen_eq<mode>3 (x, operands[1], operands[2])); + emit_insn (gen_xor<mode>3 (operands[0], x, const1_rtx)); + DONE; + } + if (TARGET_ISEL && operands[2] != const0_rtx) { emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1], @@ -11978,7 +12029,7 @@ (define_insn_and_split "*ne<mode>3" (clobber (match_scratch:P 3 "=r")) (clobber (match_scratch:P 4 "=r")) (clobber (reg:P CA_REGNO))] - "!(TARGET_ISEL && operands[2] != const0_rtx)" + "!TARGET_FUTURE && !(TARGET_ISEL && operands[2] != const0_rtx)" "#" "&& 1" [(parallel [(set (match_dup 4) @@ -12205,9 +12256,9 @@ (define_insn_and_split "*eqsi3_ext<mode>" (match_operand:SI 2 "scc_eq_operand" "rKLI"))) (clobber (match_scratch:SI 3 "=r")) (clobber (match_scratch:SI 4 "=r"))] - "" + "!TARGET_FUTURE" "#" - "" + "&& 1" [(set (match_dup 4) (clz:SI (match_dup 3))) (set (match_dup 0) -- 2.17.1