Il 18/09/2013 11:45, Zhenqiang Chen ha scritto:
> +;; Expand conditional compare according to the instruction patterns.
> +(define_expand "conditional_compare"
> +  [(set (match_operand 0 "s_register_operand" "")
> +     (match_operator 1 ""
> +      [(match_operator:SI 2 "arm_comparison_operator"
> +       [(match_operand:SI 3 "s_register_operand" "")
> +        (match_operand:SI 4 "arm_add_operand" "")])

My first reaction to this is that this operand should only match
const0_rtx, and operands 2/3 should be the same mode as operand 0 rather
than SImode.  In particular, perhaps they could be CCmode or BImode on
some architectures.

But then Richard is right that this would look a lot like the old
compare + branch patterns.

So either you could do this at expansion time using hooks, like Richard
mentioned, or you could do a pattern matching pass that is specific to
this pattern and combines sets with MODE_CC destinations across multiple
basic blocks.

Paolo


> +      (match_operator:SI 5 "arm_comparison_operator"
> +       [(match_operand:SI 6 "s_register_operand" "")
> +        (match_operand:SI 7 "arm_add_operand" "")])]))]
> +  "TARGET_ARM || TARGET_THUMB2"
> +  "{
> +     enum machine_mode mode;
> +     HOST_WIDE_INT cond_or;
> +     rtx par;
> +     enum rtx_code code = GET_CODE (operands[1]);
> +     cond_or = code == AND? DOM_CC_X_AND_Y : DOM_CC_X_OR_Y;
> +
> +     mode = arm_select_dominance_cc_mode (operands[2],
> +                                       operands[5],
> +                                       cond_or);
> +     /* To match and/ior_scc_scc, mode should not be CCmode.  */
> +     if (mode == CCmode)
> +       FAIL;
> +
> +     operands[2] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
> +                                GET_MODE (operands[3]),
> +                                operands[3], operands[4]);
> +     operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[5]),
> +                                GET_MODE (operands[5]),
> +                                operands[6], operands[7]);
> +     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
> +                                operands[2], operands[5]);
> +
> +      /* Generate insn to match and/ior_scc_scc.  */
> +      par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
> +      XVECEXP (par, 0, 0) = gen_rtx_SET (GET_MODE (operands[0]),
> +                         operands[0], operands[1]);
> +      XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (CCmode,
> +                                          gen_rtx_REG (CCmode, CC_REGNUM));
> +
> +      emit_insn (par);
> +
> +     DONE;
> +  }"

Reply via email to