> +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~