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~

Reply via email to