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