> (define_special_predicate "cc_register_zero" > (match_code "reg") > { > return (REGNO (op) == CC_REGNUM > && (GET_MODE (op) == CCmode > || GET_MODE (op) == CC_Zmode > || GET_MODE (op) == CC_NZmode)); > })
... and now that I read the backend more closely, I see "_zero" was a bad name. But more importantly, I see no connection between the comparison used and the CCmode being accepted. And if we fix that, why are you restricting to just Z and NZ? What's wrong with e.g. CFPmode? In the i386 backend, we check comparison+mode correspondence like (match_operator 4 "ix86_carry_flag_operator" [(match_operand 3 "flags_reg_operand") (const_int 0)]) I think you'll want something similar. In the case of CSINC, we can accept all conditions, so let's start with the most general: (match_operator:GPI 2 "aarch64_comparison_operation" [(reg CC_REGNUM) (const_int 0)] or even (match_operand:GPI 2 "aarch64_comparison_operation" "") with (define_predicate "aarch64_comparison_operation" (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu," "unordered,ordered,unlt,unle,unge,ungt") { if (XEXP (op, 1) != const0_rtx) return false; rtx op0 = XEXP (op, 0); if (!REG_P (op0) || REGNO (op0) != CC_REGNUM) return false; return aarch64_get_condition_code (op) >= 0; }) where aarch64_get_condition_code is (1) exported (2) adjusted to return "int" not "unsigned" (3) adjusted to not abort, but return -1 for invalid combinations. and the two existing users of aarch64_get_condition_code are adjusted to gcc_assert that the return value is valid. r~