From: Jeff Law Date: Sun, 5 Sep 2021 04:08:34 +0000 (-0400) Subject: Improve handling of C bit for setcc insns X-Git-Tag: basepoints/gcc-13~4957 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b27416a7a91b7e6b6b018411ac85cad556ff9903;p=thirdparty%2Fgcc.git Improve handling of C bit for setcc insns gcc/ * config/h8300/h8300.md (QHSI2 mode iterator): New mode iterator. * config/h8300/testcompare.md (store_c): Update name, use new QHSI2 iterator. (store_neg_c, store_shifted_c): New patterns. --- diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index 89bfcf11126c..e81e21b103e7 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -223,6 +223,7 @@ (define_mode_iterator HSI [HI SI]) (define_mode_iterator QHSI [QI HI SI]) +(define_mode_iterator QHSI2 [QI HI SI]) (define_mode_iterator QHSIF [QI HI SI SF]) diff --git a/gcc/config/h8300/testcompare.md b/gcc/config/h8300/testcompare.md index 9ff7a51077e3..0ee3e360bea1 100644 --- a/gcc/config/h8300/testcompare.md +++ b/gcc/config/h8300/testcompare.md @@ -212,11 +212,96 @@ } [(set (attr "length") (symbol_ref "mode == SImode ? 6 : 4"))]) +;; Similarly, but with a negated result +(define_insn "*store_neg_c_" + [(set (match_operand:QHSI 0 "register_operand" "=r") + (neg:QHSI (ne:QHSI (reg:CCC CC_REG) (const_int 0))))] + "reload_completed" + { + if (mode == QImode) + return "subx\t%X0,%X0"; + else if (mode == HImode) + return "subx\t%X0,%X0\;exts.w\t%T0"; + else if (mode == SImode) + return "subx\t%X0,%X0\;exts.w\t%T0\;exts.l\t%S0"; + gcc_unreachable (); + } + [(set + (attr "length") + (symbol_ref "(mode == SImode ? 6 : mode == HImode ? 4 : 2)"))]) + +;; Using b[i]st we can store the C bit into any of the low 16 bits of +;; a destination. We can also rotate it up into the high bit of a 32 bit +;; destination. +(define_insn "*store_shifted_c" + [(set (match_operand:QHSI 0 "register_operand" "=r") + (ashift:QHSI (eqne:QHSI (reg:CCC CC_REG) (const_int 0)) + (match_operand 1 "immediate_operand" "n")))] + "(reload_completed + && (INTVAL (operands[1]) == 31 || INTVAL (operands[1]) <= 15))" + { + if ( == NE) + { + if (mode == QImode) + return "xor.b\t%X0,%X0\;bst\t%1,%X0"; + else if (mode == HImode && INTVAL (operands[1]) < 8) + return "xor.w\t%T0,%T0\;bst\t%1,%X0"; + else if (mode == HImode) + { + operands[1] = GEN_INT (INTVAL (operands[1]) - 8); + output_asm_insn ("xor.w\t%T0,%T0\;bst\t%1,%t0", operands); + return ""; + } + else if (mode == SImode && INTVAL (operands[1]) == 31) + return "xor.l\t%S0,%S0\;rotxr.l\t%S0"; + else if (mode == SImode && INTVAL (operands[1]) < 8) + return "xor.l\t%S0,%S0\;bst\t%1,%X0"; + else if (mode == SImode) + { + operands[1] = GEN_INT (INTVAL (operands[1]) - 8); + output_asm_insn ("xor.l\t%S0,%S0\;bst\t%1,%t0", operands); + return ""; + } + gcc_unreachable (); + } + else if ( == EQ) + { + if (mode == QImode) + return "xor.b\t%X0,%X0\;bist\t%1,%X0"; + else if (mode == HImode && INTVAL (operands[1]) < 8) + return "xor.w\t%T0,%T0\;bist\t%1,%X0"; + else if (mode == HImode) + { + operands[1] = GEN_INT (INTVAL (operands[1]) - 8); + output_asm_insn ("xor.w\t%T0,%T0\;bist\t%1,%t0", operands); + return ""; + } + else if (mode == SImode && INTVAL (operands[1]) == 31) + return "xor.l\t%S0,%S0\;bixor\t#0,%X0\;rotxr.l\t%S0"; + else if (mode == SImode && INTVAL (operands[1]) < 8) + return "xor.l\t%S0,%S0\;bist\t%1,%X0"; + else if (mode == SImode) + { + operands[1] = GEN_INT (INTVAL (operands[1]) - 8); + output_asm_insn ("xor.l\t%S0,%S0\;bist\t%1,%t0", operands); + return ""; + } + gcc_unreachable (); + } + gcc_unreachable (); + } + [(set + (attr "length") + (symbol_ref "(mode == QImode ? 4 + : mode == HImode ? 4 + : == NE ? 6 + : INTVAL (operands[1]) == 31 ? 8 : 6)"))]) + ;; Recognize this scc and generate code we can match -(define_insn_and_split "*store_c_i_" +(define_insn_and_split "*store_c" [(set (match_operand:QHSI 0 "register_operand" "=r") - (geultu:QHSI (match_operand:QHSI 1 "register_operand" "r") - (match_operand:QHSI 2 "register_operand" "r")))] + (geultu:QHSI (match_operand:QHSI2 1 "register_operand" "r") + (match_operand:QHSI2 2 "register_operand" "r")))] "" "#" "&& reload_completed" @@ -224,3 +309,34 @@ (ltu:CCC (match_dup 1) (match_dup 2))) (set (match_dup 0) (:QHSI (reg:CCC CC_REG) (const_int 0)))]) + +;; We can fold in negation of the result and generate better code than +;; what the generic bits would do when testing for C == 1 +(define_insn_and_split "*store_neg_c" + [(set (match_operand:QHSI 0 "register_operand" "=r") + (neg:QHSI + (ltu:QHSI (match_operand:QHSI2 1 "register_operand" "r") + (match_operand:QHSI2 2 "register_operand" "r"))))] + "" + "#" + "&& reload_completed" + [(set (reg:CCC CC_REG) + (ltu:CCC (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (neg:QHSI (ne:QHSI (reg:CCC CC_REG) (const_int 0))))]) + +;; We can use rotates and bst/bist to put the C bit into various places +;; in the destination. +(define_insn_and_split "*store_shifted_c" + [(set (match_operand:QHSI 0 "register_operand" "=r") + (ashift:QHSI (geultu:QHSI (match_operand:QHSI2 1 "register_operand" "r") + (match_operand:QHSI2 2 "register_operand" "r")) + (match_operand 3 "immediate_operand" "n")))] + "INTVAL (operands[3]) == 31 || INTVAL (operands[3]) <= 15" + "#" + "&& reload_completed" + [(set (reg:CCC CC_REG) (ltu:CCC (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (ashift:QHSI (:QHSI (reg:CCC CC_REG) (const_int 0)) + (match_dup 3)))]) +