From 29e597d0e6c853b1487ee86357df704a5e0ab618 Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Wed, 6 May 2015 17:55:10 +0200 Subject: [PATCH] rs6000.md (cstore4_signed_imm): New expander. * config/rs6000/rs6000.md (cstore4_signed_imm): New expander. (cstore4_unsigned_imm): New expander. (cstore4): Remove empty constraint strings. Use the new expanders. From-SVN: r222855 --- gcc/ChangeLog | 7 +++ gcc/config/rs6000/rs6000.md | 113 +++++++++++++++++++++++++++++++++--- 2 files changed, 113 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f7188b26496..3b267c8d3a3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-05-06 Segher Boessenkool + + * config/rs6000/rs6000.md (cstore4_signed_imm): New expander. + (cstore4_unsigned_imm): New expander. + (cstore4): Remove empty constraint strings. Use the new + expanders. + 2015-05-06 Yvan Roux PR target/64208 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 2d15d71cc88..7fc2bb1b4ad 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -11787,10 +11787,102 @@ DONE; }) +(define_expand "cstore4_signed_imm" + [(use (match_operator 1 "signed_comparison_operator" + [(match_operand:GPR 2 "gpc_reg_operand") + (match_operand:GPR 3 "immediate_operand")])) + (clobber (match_operand:GPR 0 "register_operand"))] + "" +{ + bool invert = false; + + enum rtx_code cond_code = GET_CODE (operands[1]); + + rtx op0 = operands[0]; + rtx op1 = operands[2]; + HOST_WIDE_INT val = INTVAL (operands[3]); + + if (cond_code == GE || cond_code == GT) + { + cond_code = reverse_condition (cond_code); + invert = true; + } + + if (cond_code == LE) + val++; + + rtx tmp = gen_reg_rtx (mode); + emit_insn (gen_add3 (tmp, op1, GEN_INT (-val))); + rtx x = gen_reg_rtx (mode); + if (val < 0) + emit_insn (gen_and3 (x, op1, tmp)); + else + emit_insn (gen_ior3 (x, op1, tmp)); + + if (invert) + { + rtx tmp = gen_reg_rtx (mode); + emit_insn (gen_one_cmpl2 (tmp, x)); + x = tmp; + } + + int sh = GET_MODE_BITSIZE (mode) - 1; + emit_insn (gen_lshr3 (op0, x, GEN_INT (sh))); + + DONE; +}) + +(define_expand "cstore4_unsigned_imm" + [(use (match_operator 1 "unsigned_comparison_operator" + [(match_operand:GPR 2 "gpc_reg_operand") + (match_operand:GPR 3 "immediate_operand")])) + (clobber (match_operand:GPR 0 "register_operand"))] + "" +{ + bool invert = false; + + enum rtx_code cond_code = GET_CODE (operands[1]); + + rtx op0 = operands[0]; + rtx op1 = operands[2]; + HOST_WIDE_INT val = INTVAL (operands[3]); + + if (cond_code == GEU || cond_code == GTU) + { + cond_code = reverse_condition (cond_code); + invert = true; + } + + if (cond_code == LEU) + val++; + + rtx tmp = gen_reg_rtx (mode); + rtx tmp2 = gen_reg_rtx (mode); + emit_insn (gen_add3 (tmp, op1, GEN_INT (-val))); + emit_insn (gen_one_cmpl2 (tmp2, op1)); + rtx x = gen_reg_rtx (mode); + if (val < 0) + emit_insn (gen_ior3 (x, tmp, tmp2)); + else + emit_insn (gen_and3 (x, tmp, tmp2)); + + if (invert) + { + rtx tmp = gen_reg_rtx (mode); + emit_insn (gen_one_cmpl2 (tmp, x)); + x = tmp; + } + + int sh = GET_MODE_BITSIZE (mode) - 1; + emit_insn (gen_lshr3 (op0, x, GEN_INT (sh))); + + DONE; +}) + (define_expand "cstore4" [(use (match_operator 1 "rs6000_cbranch_operator" - [(match_operand:GPR 2 "gpc_reg_operand" "") - (match_operand:GPR 3 "reg_or_short_operand" "")])) + [(match_operand:GPR 2 "gpc_reg_operand") + (match_operand:GPR 3 "reg_or_short_operand")])) (clobber (match_operand:GPR 0 "register_operand"))] "" { @@ -11819,11 +11911,18 @@ emit_insn (gen_cstore4_unsigned (operands[0], operands[1], operands[2], operands[3])); - /* The generic code knows tricks to compute signed comparisons against - zero. Let it do its thing. */ - else if (operands[3] == const0_rtx - && signed_comparison_operator (operands[1], VOIDmode)) - FAIL; + /* For signed comparisons against a constant, we can do some simple + bit-twiddling. */ + else if (signed_comparison_operator (operands[1], VOIDmode) + && CONST_INT_P (operands[3])) + emit_insn (gen_cstore4_signed_imm (operands[0], operands[1], + operands[2], operands[3])); + + /* And similarly for unsigned comparisons. */ + else if (unsigned_comparison_operator (operands[1], VOIDmode) + && CONST_INT_P (operands[3])) + emit_insn (gen_cstore4_unsigned_imm (operands[0], operands[1], + operands[2], operands[3])); /* Everything else, use the mfcr brute force. */ else -- 2.30.2