From 6a7fa0c213063683b2011c735bbf78ee8185fbfd Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Mon, 6 Aug 2018 09:38:29 +0000 Subject: 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/rtlanal.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'gcc/rtlanal.c') diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 9f84d7f..1cab154 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)); +} -- cgit v1.1