Hi Aaron,

On Thu, Nov 30, 2017 at 11:31:47AM -0600, Aaron Sawdey wrote:
> This does some cleanup/consolidation so that bdz/bdnz are supported by
> a single insn and splitter, and adds a new insn and splitter to support
> the conditional form of those (bdzt/bdzf/bdnzt/bdnzf).
> 
> This is going to be used for the memcmp() builtin expansion patch which
> is next. That also will require the change to canonicalize_condition I
> posted before thanksgiving to prevent doloop from being confused by
> bdnzt et. al. 

>       * 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.
>       Define new code iterator eqne, and new code_attrs bd/bd_neg.

        (eqne): New code_iterator.
etc.

>       (<bd>_<mode>) New name for ctr<mode>_internal[12] now combined into
>       a single define_insn. There is now just a single splitter for this
>       that looks whether the decremented ctr result is going to a register
>       or memory and generates the appropriate rtl.

Colon after ), two spaces after a full stop.  You don't need to explain
what a change is for btw; changelog is *what* changed, not *why*.

>       (<bd>tf_<mode>) A new insn pattern for the conditional form branch
>       decrement (bdnzt/bdnzf/bdzt/bdzf). This also has a splitter similar
>       to the one for <bd>_<mode>.
>       * 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.

> +      && (icode == CODE_FOR_bdz_si
> +       || icode == CODE_FOR_bdz_di
> +       || icode == CODE_FOR_bdnz_si
> +       || icode == CODE_FOR_bdnz_di
> +       || icode == CODE_FOR_bdztf_si
> +       || icode == CODE_FOR_bdnztf_si
> +       || icode == CODE_FOR_bdztf_di
> +       || icode == CODE_FOR_bdnztf_di))

Please swap bdnztf_si and bdztf_di so it is clearer you handle all cases?

> +(define_code_iterator eqne [eq ne])
> +(define_code_attr bd [(ne "bdnz") (eq "bdz")])
> +(define_code_attr bd_neg [(ne "bdz") (eq "bdnz")])

Maybe order those as eq, ne as well?

> +  rtx ctrin = operands[1];
> +  rtx ctrout = operands[0];
> +  rtx ctrtmp = operands[4];

I don't think these temporaries improve legibility at all?

>    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, ctrin, const1_rtx)));
> +  if (gpc_reg_operand (ctrout, <MODE>mode))
> +    emit_insn (gen_add<mode>3 (ctrout, ctrin, constm1_rtx));
> +  else
> +    {
> +      emit_insn (gen_add<mode>3 (ctrtmp, ctrin, constm1_rtx));
> +      emit_move_insn (ctrout, ctrtmp);
> +    } 

(Space at end of line).

> +    /* No DONE so branch comes from the pattern.  */
>  })

> +(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")
> +     (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)))

Those last two lines should be indented the same as the "(and" (they are
sub rtx of the if_then_else).

> +{
> +  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";

Eight leading spaces should be a tab.

> +    }
> +  else
> +    { 

Trailing space.

> +        static char seq[96];
> +        char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
> +     sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
> +     return seq;

The indent should be six spaces on these four lines.

It should be "const char *" really; but output_cbranch has a big bug
as well it seems: it returns a pointer to a string on its stack!  Uh-oh.

> +;; 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)))

Indent of these last two lines.

> +   if (!ispos)
> +      cmpcode = reverse_condition (cmpcode);

Should indent one space less.

> +   // want to generate crand/crandc
> +
> +   emit_insn (gen_rtx_SET (operands[8],
> +                           gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));

Each eight leading spaces should be a tab.

> +   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));

That has a tab after spaces, never correct.

> +         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;
>  })

Looks good otherwise.  I'll ok it when there is a user (or a testcase).
It shouldn't go in before the canonicalize_condition patch, of course.

Thanks!


Segher

Reply via email to