Commit 601e86a5 by Alan Hayward Committed by Alan Hayward

Add CLOBBER_HIGH expression

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
parent 6e9f49e4
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> 2018-08-05 H.J. Lu <hongjiu.lu@intel.com>
PR target/86386 PR target/86386
......
...@@ -3296,6 +3296,18 @@ There is one other known use for clobbering a pseudo register in a ...@@ -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 clobbered by the insn. In this case, using the same pseudo register in
the clobber and elsewhere in the insn produces the expected results. 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 @findex use
@item (use @var{x}) @item (use @var{x})
Represents the use of the value of @var{x}. It indicates that the 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 ...@@ -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 brackets stand for a vector; the operand of @code{parallel} is a
vector of expressions. @var{x0}, @var{x1} and so on are individual vector of expressions. @var{x0}, @var{x1} and so on are individual
side effect expressions---expressions of code @code{set}, @code{call}, 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 ``In parallel'' means that first all the values used in the individual
side-effects are computed, and second all the actual side-effects are side-effects are computed, and second all the actual side-effects are
......
...@@ -857,6 +857,17 @@ rtl_check_failed_code2 (const_rtx r, enum rtx_code code1, enum rtx_code code2, ...@@ -857,6 +857,17 @@ rtl_check_failed_code2 (const_rtx r, enum rtx_code code1, enum rtx_code code2,
} }
void 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, rtl_check_failed_code_mode (const_rtx r, enum rtx_code code, machine_mode mode,
bool not_mode, const char *file, int line, bool not_mode, const char *file, int line,
const char *func) const char *func)
......
...@@ -312,6 +312,16 @@ DEF_RTL_EXPR(USE, "use", "e", RTX_EXTRA) ...@@ -312,6 +312,16 @@ DEF_RTL_EXPR(USE, "use", "e", RTX_EXTRA)
is considered undeletable before reload. */ is considered undeletable before reload. */
DEF_RTL_EXPR(CLOBBER, "clobber", "e", RTX_EXTRA) 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. /* Call a subroutine.
Operand 1 is the address to call. Operand 1 is the address to call.
Operand 2 is the number of arguments. */ Operand 2 is the number of arguments. */
......
...@@ -1100,6 +1100,14 @@ is_a_helper <rtx_note *>::test (rtx_insn *insn) ...@@ -1100,6 +1100,14 @@ is_a_helper <rtx_note *>::test (rtx_insn *insn)
__FUNCTION__); \ __FUNCTION__); \
&_rtx->u.fld[_n]; })) &_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__ \ #define RTVEC_ELT(RTVEC, I) __extension__ \
(*({ __typeof (RTVEC) const _rtvec = (RTVEC); const int _i = (I); \ (*({ __typeof (RTVEC) const _rtvec = (RTVEC); const int _i = (I); \
if (_i < 0 || _i >= GET_NUM_ELEM (_rtvec)) \ 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 *, ...@@ -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, extern void rtl_check_failed_code2 (const_rtx, enum rtx_code, enum rtx_code,
const char *, int, const char *) const char *, int, const char *)
ATTRIBUTE_NORETURN ATTRIBUTE_COLD; 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, extern void rtl_check_failed_code_mode (const_rtx, enum rtx_code, machine_mode,
bool, const char *, int, const char *) bool, const char *, int, const char *)
ATTRIBUTE_NORETURN ATTRIBUTE_COLD; ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
...@@ -1208,6 +1220,7 @@ extern void rtvec_check_failed_bounds (const_rtvec, int, const char *, int, ...@@ -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_CHECK2(RTX, N, C1, C2) ((RTX)->u.fld[N])
#define RTL_CHECKC1(RTX, N, C) ((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_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 RTVEC_ELT(RTVEC, I) ((RTVEC)->elem[I])
#define XWINT(RTX, N) ((RTX)->u.hwint[N]) #define XWINT(RTX, N) ((RTX)->u.hwint[N])
#define CWI_ELT(RTX, I) ((RTX)->u.hwiv.elem[I]) #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 *, ...@@ -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 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 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)
/* Methods of rtx_expr_list. */ /* Methods of rtx_expr_list. */
...@@ -2632,7 +2646,7 @@ do { \ ...@@ -2632,7 +2646,7 @@ do { \
/* For a SET rtx, SET_DEST is the place that is set /* For a SET rtx, SET_DEST is the place that is set
and SET_SRC is the value it is set to. */ 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_SRC(RTX) XCEXP (RTX, 1, SET)
#define SET_IS_RETURN_P(RTX) \ #define SET_IS_RETURN_P(RTX) \
(RTL_FLAG_CHECK1 ("SET_IS_RETURN_P", (RTX), SET)->jump) (RTL_FLAG_CHECK1 ("SET_IS_RETURN_P", (RTX), SET)->jump)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment