diff options
Diffstat (limited to 'gcc/config/rx/rx-protos.h')
-rw-r--r-- | gcc/config/rx/rx-protos.h | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/gcc/config/rx/rx-protos.h b/gcc/config/rx/rx-protos.h index b3c5bfc7a7f..0bb885d2da1 100644 --- a/gcc/config/rx/rx-protos.h +++ b/gcc/config/rx/rx-protos.h @@ -63,6 +63,112 @@ extern void rx_notice_update_cc (rtx, rtx); extern void rx_split_cbranch (machine_mode, enum rtx_code, rtx, rtx, rtx); extern machine_mode rx_select_cc_mode (enum rtx_code, rtx, rtx); + +extern bool rx_reg_dead_or_unused_after_insn (const rtx_insn* i, int regno); +extern void rx_copy_reg_dead_or_unused_notes (rtx reg, const rtx_insn* src, + rtx_insn* dst); + +extern bool rx_fuse_in_memory_bitop (rtx* operands, rtx_insn* curr_insn, + rtx (*gen_insn)(rtx, rtx)); + +/* Result value of rx_find_set_of_reg. */ +struct set_of_reg +{ + /* The insn where sh_find_set_of_reg stopped looking. + Can be NULL_RTX if the end of the insn list was reached. */ + rtx_insn* insn; + + /* The set rtx of the specified reg if found, NULL_RTX otherwise. */ + const_rtx set_rtx; + + /* The set source rtx of the specified reg if found, NULL_RTX otherwise. + Usually, this is the most interesting return value. */ + rtx set_src; +}; + +/* FIXME: Copy-pasta from SH. Move to rtl.h. + Given a reg rtx and a start insn, try to find the insn that sets + the specified reg by using the specified insn stepping function, + such as 'prev_nonnote_nondebug_insn_bb'. When the insn is found, + try to extract the rtx of the reg set. */ +template <typename F> inline set_of_reg +rx_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc, + bool ignore_reg_reg_copies = false) +{ + set_of_reg result; + result.insn = insn; + result.set_rtx = NULL_RTX; + result.set_src = NULL_RTX; + + if (!REG_P (reg) || insn == NULL_RTX) + return result; + + for (rtx_insn* i = stepfunc (insn); i != NULL_RTX; i = stepfunc (i)) + { + if (BARRIER_P (i)) + break; + if (!INSN_P (i) || DEBUG_INSN_P (i)) + continue; + if (reg_set_p (reg, i)) + { + if (CALL_P (i)) + break; + + result.insn = i; + result.set_rtx = set_of (reg, i); + + if (result.set_rtx == NULL_RTX || GET_CODE (result.set_rtx) != SET) + break; + + result.set_src = XEXP (result.set_rtx, 1); + + if (ignore_reg_reg_copies && REG_P (result.set_src)) + { + reg = result.set_src; + continue; + } + if (ignore_reg_reg_copies && SUBREG_P (result.set_src) + && REG_P (SUBREG_REG (result.set_src))) + { + reg = SUBREG_REG (result.set_src); + continue; + } + + break; + } + } + + /* If the searched reg is found inside a (mem (post_inc:SI (reg))), set_of + will return NULL and set_rtx will be NULL. + In this case report a 'not found'. result.insn will always be non-null + at this point, so no need to check it. */ + if (result.set_src != NULL && result.set_rtx == NULL) + result.set_src = NULL; + + return result; +} + +/* FIXME: Move to rtlh.h. */ +template <typename F> inline rtx_insn* +rx_find_use_of_reg (rtx reg, rtx_insn* insn, F stepfunc) +{ + if (!REG_P (reg) || insn == NULL_RTX) + return NULL; + + for (rtx_insn* i = stepfunc (insn); i != NULL_RTX; i = stepfunc (i)) + { + if (BARRIER_P (i)) + break; + if (!INSN_P (i) || DEBUG_INSN_P (i)) + continue; + if (reg_overlap_mentioned_p (reg, PATTERN (i)) + || (CALL_P (i) && find_reg_fusage (i, USE, reg))) + return i; + } + + return NULL; +} + #endif #endif /* GCC_RX_PROTOS_H */ |