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;
> + }"