> +static enum rtx_code
> +arm_ccmode_to_code (enum machine_mode mode)
> +{
> +  switch (mode)
> +    {
> +    case CC_DNEmode:
> +      return NE;

Why would you need to encode comparisons in CCmodes?
That looks like a mis-design to me.

> +Conditional compare instruction.  Operand 2 and 5 are RTLs which perform
> +two comparisons.  Operand 1 is AND or IOR, which operates on the result of
> +Operand 2 and 5.  Operand 0 is the result of operand 1.
> +
> +A typical @code{ccmp} pattern looks like
> +
> +@smallexample
> +(define_expand "ccmp"
> +  [(set (match_operand 0 "register_operand" "")
> +        (match_operator 1 ""
> +         [(match_operator:SI 2 "comparison_operator"
> +          [(match_operand:SI 3 "register_operand")
> +           (match_operand:SI 4 "register_operand")])
> +         (match_operator:SI 5 "comparison_operator"
> +          [(match_operand:SI 6 "register_operand")
> +           (match_operand:SI 7 "register_operand")])]))]
> +  ""
> +  "@dots{}")
> +@end smallexample

This documentation is inadequate.  What sorts of input combinations are valid?
 How is the middle-end expected to compose more than two compares, as you
describe in the mail?  What mode should the middle-end use to allocate that
output register?

The only thing that makes a sort of sense to me is something akin to how the
old cmp + bcc patterns worked.  Except that's not especially clean, and there's
a reason we got rid of them.

I think the only clean interface is going to be a new hook or hooks.  The
return value of the hook with be an rtx akin to the PTEST value returned by
prepare_cmp_insn.  Which is a proper input to cbranch/cstore/etc.

I might think that two hooks would be appropriate because it might make the
ccmp hook easier.  I.e.

    res = targetm.cmp_hook(...);
    while (more)
      res = targetm.ccmp_hook(res, ...);

For combinations that can't be implemented with ccmp, the hook can return null.

> +;; The first compare in this pattern is the result of a previous CCMP.
> +;; We can not swap it.  And we only need its flag.
> +(define_insn "*ccmp_and"
> +  [(set (match_operand 6 "dominant_cc_register" "")
> +     (compare
> +      (and:SI
> +       (match_operator 4 "expandable_comparison_operator"
> +        [(match_operand 0 "dominant_cc_register" "")
> +         (match_operand:SI 1 "arm_add_operand" "")])
> +       (match_operator:SI 5 "arm_comparison_operator"
> +        [(match_operand:SI 2 "s_register_operand" 
> +             "l,r,r,r,r")
> +         (match_operand:SI 3 "arm_add_operand" 
> +             "lPy,rI,L,rI,L")]))
> +      (const_int 0)))]
> +  "TARGET_32BIT"
> +  "*
> +  {
> +    static const char *const cmp2[2] =
> +    {
> +      \"cmp%d4\\t%2, %3\",
> +      \"cmn%d4\\t%2, #%n3\"
> +    };
> +    static const char *const ite = \"it\\t%d4\";
> +    static const int cmp_idx[9] = {0, 0, 1, 0, 1};
> +
> +    if (TARGET_THUMB2) {
> +      output_asm_insn (ite, operands);
> +    }
> +    output_asm_insn (cmp2[cmp_idx[which_alternative]], operands);
> +    return \"\";
> +  }"

I would think simply splitting to a normal cond_exec insn post reload would be
significantly cleaner than this.

And for future reference, don't use '"*', just use '{'.  That way you don't
have to escape the embedded quotes, etc.


r~

Reply via email to