On 07/16/2018 10:10 AM, Sam Tebbs wrote: > +++ b/gcc/config/aarch64/aarch64.c > @@ -1439,6 +1439,14 @@ aarch64_hard_regno_caller_save_mode (unsigned regno, > unsigned, > return SImode; > } > > +/* Implement IS_LEFT_CONSECUTIVE. Check if an integer's bits are consecutive > + ones from the MSB. */ > +bool > +aarch64_is_left_consecutive (HOST_WIDE_INT i) > +{ > + return (i | (i - 1)) == HOST_WIDE_INT_M1; > +} > + ... > +(define_insn "*aarch64_bfxil" > + [(set (match_operand:DI 0 "register_operand" "=r") > + (ior:DI (and:DI (match_operand:DI 1 "register_operand" "r") > + (match_operand 3 "const_int_operand")) > + (and:DI (match_operand:DI 2 "register_operand" "0") > + (match_operand 4 "const_int_operand"))))] > + "INTVAL (operands[3]) == ~INTVAL (operands[4]) > + && aarch64_is_left_consecutive (INTVAL (operands[4]))"
Better is to use a define_predicate to merge both that second test and the const_int_operand. (I'm not sure about the "left_consecutive" language either. Isn't it more descriptive to say that op3 is a power of 2 minus 1?) (define_predicate "pow2m1_operand" (and (match_code "const_int") (match_test "exact_pow2 (INTVAL(op) + 1) > 0"))) and use (match_operand:DI 3 "pow2m1_operand") and then just the INTVAL (operands[3]) == ~INTVAL (operands[4]) test. Also, don't omit the modes for the constants. Also, there's no reason this applies only to DI mode; use the GPI iterator and %<w> in the output template. > + HOST_WIDE_INT op3 = INTVAL (operands[3]); > + operands[3] = GEN_INT (ceil_log2 (op3)); > + output_asm_insn ("bfxil\\t%0, %1, 0, %3", operands); > + return ""; You can just return the string that you passed to output_asm_insn. > + } > + [(set_attr "type" "bfx")] The other aliases of the BFM insn use type "bfm"; "bfx" appears to be aliases of UBFM and SBFM. Not that it appears to matter to the scheduling descriptions, but it is inconsistent. r~