Add CLOBBER_HIGH expression
authorAlan Hayward <alan.hayward@arm.com>
Mon, 6 Aug 2018 09:07:57 +0000 (09:07 +0000)
committerAlan Hayward <alahay01@gcc.gnu.org>
Mon, 6 Aug 2018 09:07:57 +0000 (09:07 +0000)
Includes documentation.

2018-08-06  Alan Hayward  <alan.hayward@arm.com>

* doc/rtl.texi (clobber_high): Add.
(parallel): Add in clobber high
* rtl.c (rtl_check_failed_code3): Add function.
* rtl.def (CLOBBER_HIGH): Add expression.
* rtl.h (RTL_CHECKC3): Add macro.
(rtl_check_failed_code3): Add declaration.
(XC3EXP): Add macro.

From-SVN: r263326

gcc/ChangeLog
gcc/doc/rtl.texi
gcc/rtl.c
gcc/rtl.def
gcc/rtl.h

index 720ce32a6ca4b76b209f8af6560574c8a6144f56..f8834d9f4328a2dfa6710a3fd3a085d4f6a34525 100644 (file)
@@ -1,3 +1,12 @@
+2018-08-06  Alan Hayward  <alan.hayward@arm.com>
+       * doc/rtl.texi (clobber_high): Add.
+       (parallel): Add in clobber high
+       * rtl.c (rtl_check_failed_code3): Add function.
+       * rtl.def (CLOBBER_HIGH): Add expression.
+       * rtl.h (RTL_CHECKC3): Add macro.
+       (rtl_check_failed_code3): Add declaration.
+       (XC3EXP): Add macro.
+
 2018-08-05  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/86386
index a37d9ac538991c507985bda4f825023534321b76..20c57732679f074c7b7a6a5e98715e27a864eba3 100644 (file)
@@ -3296,6 +3296,18 @@ There is one other known use for clobbering a pseudo register in a
 clobbered by the insn.  In this case, using the same pseudo register in
 the clobber and elsewhere in the insn produces the expected results.
 
+@findex clobber_high
+@item (clobber_high @var{x})
+Represents the storing or possible storing of an unpredictable,
+undescribed value into the upper parts of @var{x}. The mode of the expression
+represents the lower parts of the register which will not be overwritten.
+@code{reg} must be a reg expression.
+
+One place this is used is when calling into functions where the registers are
+preserved, but only up to a given number of bits.  For example when using
+Aarch64 SVE, calling a TLS descriptor will cause only the lower 128 bits of
+each of the vector registers to be preserved.
+
 @findex use
 @item (use @var{x})
 Represents the use of the value of @var{x}.  It indicates that the
@@ -3349,7 +3361,8 @@ Represents several side effects performed in parallel.  The square
 brackets stand for a vector; the operand of @code{parallel} is a
 vector of expressions.  @var{x0}, @var{x1} and so on are individual
 side effect expressions---expressions of code @code{set}, @code{call},
-@code{return}, @code{simple_return}, @code{clobber} or @code{use}.
+@code{return}, @code{simple_return}, @code{clobber} @code{use} or
+@code{clobber_high}.
 
 ``In parallel'' means that first all the values used in the individual
 side-effects are computed, and second all the actual side-effects are
index 90bbc7c6861153d87ace20913e5601d7cd62bc2b..985db1c14f040c286d299be7225e827c2ec3dce6 100644 (file)
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -856,6 +856,17 @@ rtl_check_failed_code2 (const_rtx r, enum rtx_code code1, enum rtx_code code2,
      func, trim_filename (file), line);
 }
 
+void
+rtl_check_failed_code3 (const_rtx r, enum rtx_code code1, enum rtx_code code2,
+                       enum rtx_code code3, const char *file, int line,
+                       const char *func)
+{
+  internal_error
+    ("RTL check: expected code '%s', '%s' or '%s', have '%s' in %s, at %s:%d",
+     GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (code3),
+     GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
+}
+
 void
 rtl_check_failed_code_mode (const_rtx r, enum rtx_code code, machine_mode mode,
                            bool not_mode, const char *file, int line,
index 2578a0ccb9e83a0b353c90d90c7e5631728b3918..0ed27505545037d64756cd36047307ec4b314395 100644 (file)
@@ -312,6 +312,16 @@ DEF_RTL_EXPR(USE, "use", "e", RTX_EXTRA)
    is considered undeletable before reload.  */
 DEF_RTL_EXPR(CLOBBER, "clobber", "e", RTX_EXTRA)
 
+/* Indicate that the upper parts of something are clobbered in a way that we
+   don't want to explain.  The MODE references the lower bits that will be
+   preserved.  Anything above that size will be clobbered.
+
+   CLOBBER_HIGH only occurs as the operand of a PARALLEL rtx.  It cannot appear
+   in other contexts, and unlike CLOBBER, it cannot appear on its own.
+   CLOBBER_HIGH can only be used with fixed register rtxes.  */
+
+DEF_RTL_EXPR(CLOBBER_HIGH, "clobber_high", "e", RTX_EXTRA)
+
 /* Call a subroutine.
    Operand 1 is the address to call.
    Operand 2 is the number of arguments.  */
index 565ce3abbe4e199609a6915de648736b43aa838d..5e07e9bee80ff4ba18a775f8137a14e7c0e99363 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1100,6 +1100,14 @@ is_a_helper <rtx_note *>::test (rtx_insn *insn)
                               __FUNCTION__); \
      &_rtx->u.fld[_n]; }))
 
+#define RTL_CHECKC3(RTX, N, C1, C2, C3) __extension__                  \
+(*({ __typeof (RTX) const _rtx = (RTX); const int _n = (N);            \
+     const enum rtx_code _code = GET_CODE (_rtx);                      \
+     if (_code != (C1) && _code != (C2) && _code != (C3))              \
+       rtl_check_failed_code3 (_rtx, (C1), (C2), (C3), __FILE__,       \
+                              __LINE__, __FUNCTION__);                 \
+     &_rtx->u.fld[_n]; }))
+
 #define RTVEC_ELT(RTVEC, I) __extension__                              \
 (*({ __typeof (RTVEC) const _rtvec = (RTVEC); const int _i = (I);      \
      if (_i < 0 || _i >= GET_NUM_ELEM (_rtvec))                                \
@@ -1190,6 +1198,10 @@ extern void rtl_check_failed_code1 (const_rtx, enum rtx_code, const char *,
 extern void rtl_check_failed_code2 (const_rtx, enum rtx_code, enum rtx_code,
                                    const char *, int, const char *)
     ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
+extern void rtl_check_failed_code3 (const_rtx, enum rtx_code, enum rtx_code,
+                                   enum rtx_code, const char *, int,
+                                   const char *)
+    ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
 extern void rtl_check_failed_code_mode (const_rtx, enum rtx_code, machine_mode,
                                        bool, const char *, int, const char *)
     ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
@@ -1208,6 +1220,7 @@ extern void rtvec_check_failed_bounds (const_rtvec, int, const char *, int,
 #define RTL_CHECK2(RTX, N, C1, C2)  ((RTX)->u.fld[N])
 #define RTL_CHECKC1(RTX, N, C)     ((RTX)->u.fld[N])
 #define RTL_CHECKC2(RTX, N, C1, C2) ((RTX)->u.fld[N])
+#define RTL_CHECKC3(RTX, N, C1, C2, C3) ((RTX)->u.fld[N])
 #define RTVEC_ELT(RTVEC, I)        ((RTVEC)->elem[I])
 #define XWINT(RTX, N)              ((RTX)->u.hwint[N])
 #define CWI_ELT(RTX, I)                    ((RTX)->u.hwiv.elem[I])
@@ -1362,6 +1375,7 @@ extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
 #define XCVECLEN(RTX, N, C)    GET_NUM_ELEM (XCVEC (RTX, N, C))
 
 #define XC2EXP(RTX, N, C1, C2)      (RTL_CHECKC2 (RTX, N, C1, C2).rt_rtx)
+#define XC3EXP(RTX, N, C1, C2, C3)  (RTL_CHECKC3 (RTX, N, C1, C2, C3).rt_rtx)
 \f
 
 /* Methods of rtx_expr_list.  */
@@ -2632,7 +2646,7 @@ do {                                                                      \
 
 /* For a SET rtx, SET_DEST is the place that is set
    and SET_SRC is the value it is set to.  */
-#define SET_DEST(RTX) XC2EXP (RTX, 0, SET, CLOBBER)
+#define SET_DEST(RTX) XC3EXP (RTX, 0, SET, CLOBBER, CLOBBER_HIGH)
 #define SET_SRC(RTX) XCEXP (RTX, 1, SET)
 #define SET_IS_RETURN_P(RTX)                                           \
   (RTL_FLAG_CHECK1 ("SET_IS_RETURN_P", (RTX), SET)->jump)