Add func to check if register is clobbered by clobber_high
authorAlan Hayward <alan.hayward@arm.com>
Mon, 6 Aug 2018 09:38:29 +0000 (09:38 +0000)
committerAlan Hayward <alahay01@gcc.gnu.org>
Mon, 6 Aug 2018 09:38:29 +0000 (09:38 +0000)
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
gcc/rtl.h
gcc/rtlanal.c

index 248a42bce322520a5d5aad4822d0b2985b48370d..36f604d76fcae4bb0fc106107fb72e6d731c8bc4 100644 (file)
@@ -1,3 +1,8 @@
+2018-08-06  Alan Hayward  <alan.hayward@arm.com>
+
+       * 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  <alan.hayward@arm.com>
 
        * emit-rtl.c (verify_rtx_sharing): Check for CLOBBER_HIGH.
index f42d749511d8988b77f8f167c22c42ec0c2ef6d5..d549b0aad0b13de42cb2fd148c002625b90d8c3c 100644 (file)
--- 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
index 9f84d7f2a8c942930f4aa24d856427da78524052..1cab1545744c265f457524860955aaac940efb3d 100644 (file)
@@ -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));
+}