Given a CLOBBER_HIGH expression and a register, it checks if the register will be clobbered.
A second version exists for the cases where the expressions are not available. The function will be used throughout the following patches. 2018-07-25 Alan Hayward <alan.hayw...@arm.com> * rtl.h (reg_is_clobbered_by_clobber_high): Add declarations. * rtlanal.c (reg_is_clobbered_by_clobber_high): Add function. --- gcc/rtl.h | 10 ++++++++++ gcc/rtlanal.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/gcc/rtl.h b/gcc/rtl.h index f42d749511d..d549b0aad0b 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -3467,6 +3467,16 @@ extern bool tablejump_p (const rtx_insn *, rtx_insn **, rtx_jump_table_data **); extern int computed_jump_p (const rtx_insn *); extern bool tls_referenced_p (const_rtx); extern bool contains_mem_rtx_p (rtx x); +extern bool reg_is_clobbered_by_clobber_high (unsigned int, machine_mode, + const_rtx); + +/* Convenient wrapper for reg_is_clobbered_by_clobber_high. */ +inline bool +reg_is_clobbered_by_clobber_high (const_rtx x, const_rtx clobber_high_op) +{ + return reg_is_clobbered_by_clobber_high (REGNO (x), GET_MODE (x), + clobber_high_op); +} /* Overload for refers_to_regno_p for checking a single register. */ inline bool diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 9f84d7f2a8c..1cab1545744 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -6551,3 +6551,32 @@ tls_referenced_p (const_rtx x) return true; return false; } + +/* Return true if reg REGNO with mode REG_MODE would be clobbered by the + clobber_high operand in CLOBBER_HIGH_OP. */ + +bool +reg_is_clobbered_by_clobber_high (unsigned int regno, machine_mode reg_mode, + const_rtx clobber_high_op) +{ + unsigned int clobber_regno = REGNO (clobber_high_op); + machine_mode clobber_mode = GET_MODE (clobber_high_op); + unsigned char regno_nregs = hard_regno_nregs (regno, reg_mode); + + /* Clobber high should always span exactly one register. */ + gcc_assert (REG_NREGS (clobber_high_op) == 1); + + /* Clobber high needs to match with one of the registers in X. */ + if (clobber_regno < regno || clobber_regno >= regno + regno_nregs) + return false; + + gcc_assert (reg_mode != BLKmode && clobber_mode != BLKmode); + + if (reg_mode == VOIDmode) + return clobber_mode != VOIDmode; + + /* Clobber high will clobber if its size might be greater than the size of + register regno. */ + return maybe_gt (exact_div (GET_MODE_SIZE (reg_mode), regno_nregs), + GET_MODE_SIZE (clobber_mode)); +} -- 2.15.2 (Apple Git-101.1)