From 6a7fa0c213063683b2011c735bbf78ee8185fbfd Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Mon, 6 Aug 2018 09:38:29 +0000 Subject: [PATCH] Add func to check if register is clobbered by clobber_high gcc/ * rtl.h (reg_is_clobbered_by_clobber_high): Add declarations. * rtlanal.c (reg_is_clobbered_by_clobber_high): Add function. From-SVN: r263328 --- gcc/ChangeLog | 5 +++++ gcc/rtl.h | 10 ++++++++++ gcc/rtlanal.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 248a42bce32..36f604d76fc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2018-08-06 Alan Hayward + + * rtl.h (reg_is_clobbered_by_clobber_high): Add declarations. + * rtlanal.c (reg_is_clobbered_by_clobber_high): Add function. + 2018-08-06 Alan Hayward * emit-rtl.c (verify_rtx_sharing): Check for CLOBBER_HIGH. 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.30.2