aboutsummaryrefslogtreecommitdiff
path: root/gcc/rtl.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rtl.h')
-rw-r--r--gcc/rtl.h80
1 files changed, 63 insertions, 17 deletions
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 2fb0c5c..b6555ea 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1585,29 +1585,75 @@ get_full_set_src_cost (rtx x, struct full_rtx_costs *c)
#define SUBREG_PROMOTED_VAR_P(RTX) \
(RTL_FLAG_CHECK1 ("SUBREG_PROMOTED", (RTX), SUBREG)->in_struct)
-#define SUBREG_PROMOTED_UNSIGNED_SET(RTX, VAL) \
-do { \
- rtx const _rtx = RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_UNSIGNED_SET", \
- (RTX), SUBREG); \
- if ((VAL) < 0) \
- _rtx->volatil = 1; \
- else { \
- _rtx->volatil = 0; \
- _rtx->unchanging = (VAL); \
- } \
-} while (0)
-
/* Valid for subregs which are SUBREG_PROMOTED_VAR_P(). In that case
this gives the necessary extensions:
- 0 - signed
- 1 - normal unsigned
+ 0 - signed (SPR_SIGNED)
+ 1 - normal unsigned (SPR_UNSIGNED)
+ 2 - value is both sign and unsign extended for mode
+ (SPR_SIGNED_AND_UNSIGNED).
-1 - pointer unsigned, which most often can be handled like unsigned
extension, except for generating instructions where we need to
- emit special code (ptr_extend insns) on some architectures. */
+ emit special code (ptr_extend insns) on some architectures
+ (SPR_POINTER). */
+
+const int SRP_POINTER = -1;
+const int SRP_SIGNED = 0;
+const int SRP_UNSIGNED = 1;
+const int SRP_SIGNED_AND_UNSIGNED = 2;
+
+/* Sets promoted mode for SUBREG_PROMOTED_VAR_P(). */
+#define SUBREG_PROMOTED_SET(RTX, VAL) \
+do { \
+ rtx const _rtx = RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_SET", \
+ (RTX), SUBREG); \
+ switch (VAL) \
+ { \
+ case SRP_POINTER: \
+ _rtx->volatil = 0; \
+ _rtx->unchanging = 0; \
+ break; \
+ case SRP_SIGNED: \
+ _rtx->volatil = 0; \
+ _rtx->unchanging = 1; \
+ break; \
+ case SRP_UNSIGNED: \
+ _rtx->volatil = 1; \
+ _rtx->unchanging = 0; \
+ break; \
+ case SRP_SIGNED_AND_UNSIGNED: \
+ _rtx->volatil = 1; \
+ _rtx->unchanging = 1; \
+ break; \
+ } \
+} while (0)
+/* Gets the value stored in promoted mode for SUBREG_PROMOTED_VAR_P(),
+ including SRP_SIGNED_AND_UNSIGNED if promoted for
+ both signed and unsigned. */
+#define SUBREG_PROMOTED_GET(RTX) \
+ (2 * (RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_GET", (RTX), SUBREG)->volatil)\
+ + (RTX)->unchanging - 1)
+
+/* Returns sign of promoted mode for SUBREG_PROMOTED_VAR_P(). */
+#define SUBREG_PROMOTED_SIGN(RTX) \
+ ((RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_SIGN", (RTX), SUBREG)->volatil) ? 1\
+ : (RTX)->unchanging - 1)
+
+/* Predicate to check if RTX of SUBREG_PROMOTED_VAR_P() is promoted
+ for SIGNED type. */
+#define SUBREG_PROMOTED_SIGNED_P(RTX) \
+ (RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_SIGNED_P", (RTX), SUBREG)->unchanging)
+
+/* Predicate to check if RTX of SUBREG_PROMOTED_VAR_P() is promoted
+ for UNSIGNED type. */
#define SUBREG_PROMOTED_UNSIGNED_P(RTX) \
- ((RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_UNSIGNED_P", (RTX), SUBREG)->volatil) \
- ? -1 : (int) (RTX)->unchanging)
+ (RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_UNSIGNED_P", (RTX), SUBREG)->volatil)
+
+/* Checks if RTX of SUBREG_PROMOTED_VAR_P() is promoted for given SIGN. */
+#define SUBREG_CHECK_PROMOTED_SIGN(RTX, SIGN) \
+((SIGN) == SRP_POINTER ? SUBREG_PROMOTED_GET (RTX) == SRP_POINTER \
+ : (SIGN) == SRP_SIGNED ? SUBREG_PROMOTED_SIGNED_P (RTX) \
+ : SUBREG_PROMOTED_UNSIGNED_P (RTX))
/* True if the subreg was generated by LRA for reload insns. Such
subregs are valid only during LRA. */