diff options
author | Alan Hayward <alan.hayward@arm.com> | 2018-08-06 09:38:29 +0000 |
---|---|---|
committer | Alan Hayward <alahay01@gcc.gnu.org> | 2018-08-06 09:38:29 +0000 |
commit | 6a7fa0c213063683b2011c735bbf78ee8185fbfd (patch) | |
tree | 7e88dabc4b2041dc9eeedc5bafb3835656b42851 /gcc/rtlanal.c | |
parent | 14196e023fa2a07f86e864a9492e7cf3950d5ce9 (diff) |
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
Diffstat (limited to 'gcc/rtlanal.c')
-rw-r--r-- | gcc/rtlanal.c | 29 |
1 files changed, 29 insertions, 0 deletions
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)); +} |