diff options
Diffstat (limited to 'gcc/config/or1k/or1k.cc')
-rw-r--r-- | gcc/config/or1k/or1k.cc | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/gcc/config/or1k/or1k.cc b/gcc/config/or1k/or1k.cc index f1c92c6..868df67 100644 --- a/gcc/config/or1k/or1k.cc +++ b/gcc/config/or1k/or1k.cc @@ -1654,6 +1654,63 @@ or1k_rtx_costs (rtx x, machine_mode mode, int outer_code, int /* opno */, #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS or1k_rtx_costs +static bool +or1k_is_cmov_insn (rtx_insn *seq) +{ + rtx_insn *curr_insn = seq; + rtx set = NULL_RTX; + + /* The pattern may start with a simple set with register operands. Skip + through any of those. */ + while (curr_insn) + { + set = single_set (curr_insn); + if (!set + || !REG_P (SET_DEST (set))) + return false; + + /* If it's not a simple reg or immediate break. */ + if (REG_P (SET_SRC (set)) || CONST_INT_P (SET_SRC (set))) + curr_insn = NEXT_INSN (curr_insn); + else + break; + } + + if (!curr_insn) + return false; + + /* The next instruction should be a compare. OpenRISC has many operators used + for comparison so skip and confirm the next is IF_THEN_ELSE. */ + curr_insn = NEXT_INSN (curr_insn); + if (!curr_insn) + return false; + + /* And the last instruction should be an IF_THEN_ELSE. */ + set = single_set (curr_insn); + if (!set + || !REG_P (SET_DEST (set)) + || GET_CODE (SET_SRC (set)) != IF_THEN_ELSE) + return false; + + return !NEXT_INSN (curr_insn); +} + +/* Implement TARGET_NOCE_CONVERSION_PROFITABLE_P. We detect if the conversion + resulted in a l.cmov instruction and if so we consider it more profitable than + branch instructions. */ + +static bool +or1k_noce_conversion_profitable_p (rtx_insn *seq, + struct noce_if_info *if_info) +{ + if (TARGET_CMOV) + return or1k_is_cmov_insn (seq); + + return default_noce_conversion_profitable_p (seq, if_info); +} + +#undef TARGET_NOCE_CONVERSION_PROFITABLE_P +#define TARGET_NOCE_CONVERSION_PROFITABLE_P or1k_noce_conversion_profitable_p /* A subroutine of the atomic operation splitters. Jump to LABEL if COND is true. Mark the jump as unlikely to be taken. */ |