No need to special-case this in several places anymore. Cc: David Edelsohn <dje....@gmail.com> --- * config/rs6000/rs6000.c (num_insns_constant): Remove test for rs6000_is_valid_and_mask. (genimm_ppc::exam_mask): New. (genimm_ppc::exam_search): Use it. (genimm_ppc::generate): Handle AND. * config/rs6000/rs6000.md (rs6000_is_valid_and_mask splitter): Remove. --- gcc/config/rs6000/rs6000.c | 27 ++++++++++++++++++++++----- gcc/config/rs6000/rs6000.md | 15 --------------- 2 files changed, 22 insertions(+), 20 deletions(-)
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index a864a7e..6af5cf3 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -5246,11 +5246,7 @@ num_insns_constant (rtx op, machine_mode mode) switch (GET_CODE (op)) { case CONST_INT: - if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1 - && rs6000_is_valid_and_mask (op, mode)) - return 2; - else - return num_insns_constant_wide (INTVAL (op)); + return num_insns_constant_wide (INTVAL (op)); case CONST_WIDE_INT: { @@ -8062,6 +8058,7 @@ struct genimm_ppc : genimm_base <rtx_code, 5> bool exam_simple (HOST_WIDE_INT c, machine_mode, int budget); bool exam_sub (HOST_WIDE_INT c, int budget); + bool exam_mask (HOST_WIDE_INT c, HOST_WIDE_INT mask, int sub_budget); bool exam_search (HOST_WIDE_INT c, int budget); void exam_full (HOST_WIDE_INT c); void generate (rtx dest, machine_mode mode) const; @@ -8125,6 +8122,21 @@ genimm_ppc::exam_sub (HOST_WIDE_INT c, int budget) || (budget > 1 && exam_search (c, budget))); } +/* If we are able to construct C within SUB_BUDGET + 1, + return true and fill in the recipe. */ + +bool +genimm_ppc::exam_mask (HOST_WIDE_INT c, HOST_WIDE_INT mask, int sub_budget) +{ + if (rs6000_is_valid_and_mask_wide (mask, DImode) + && exam_sub (c, sub_budget)) + { + opN (AND, mask); /* RLDICL, et al */ + return true; + } + return false; +} + /* The body of the recursive search for C within BUDGET. We've already failed exam_simple. */ @@ -8157,6 +8169,10 @@ genimm_ppc::exam_search (HOST_WIDE_INT c, int budget) } } + /* If C is a mask itself, apply it to all ones. */ + if (exam_mask (-1, c, sub_budget)) + return true; + /* Shift the constant left. */ test = HOST_WIDE_INT_UC (0xffffffff00000000); if ((c & test) == c && exam_sub (c >> 32, sub_budget)) @@ -8209,6 +8225,7 @@ genimm_ppc::generate (rtx dest, machine_mode mode) const x = op2; break; case PLUS: + case AND: case IOR: case ASHIFT: x = gen_rtx_fmt_ee (r, mode, op1, op2); diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 527ad98..9161931 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -7106,21 +7106,6 @@ [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple") (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")]) -; Some DImode loads are best done as a load of -1 followed by a mask -; instruction. -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand") - (match_operand:DI 1 "const_int_operand"))] - "TARGET_POWERPC64 - && num_insns_constant (operands[1], DImode) > 1 - && rs6000_is_valid_and_mask (operands[1], DImode)" - [(set (match_dup 0) - (const_int -1)) - (set (match_dup 0) - (and:DI (match_dup 0) - (match_dup 1)))] - "") - ;; Split a load of a large constant into the appropriate five-instruction ;; sequence. Handle anything in a constant number of insns. ;; When non-easy constants can go in the TOC, this should use -- 2.4.3