aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000/rs6000.h')
-rw-r--r--gcc/config/rs6000/rs6000.h39
1 files changed, 32 insertions, 7 deletions
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 3bd2048..f253689 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -402,6 +402,33 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
#define TARGET_DEBUG_TARGET (rs6000_debug & MASK_DEBUG_TARGET)
#define TARGET_DEBUG_BUILTIN (rs6000_debug & MASK_DEBUG_BUILTIN)
+/* Helper macros for TFmode. Quad floating point (TFmode) can be either IBM
+ long double format that uses a pair of doubles, or IEEE 128-bit floating
+ point. KFmode was added as a way to represent IEEE 128-bit floating point,
+ even if the default for long double is the IBM long double format.
+ Similarly IFmode is the IBM long double format even if the default is IEEE
+ 128-bit. */
+#define FLOAT128_IEEE_P(MODE) \
+ (((MODE) == TFmode && TARGET_IEEEQUAD) \
+ || ((MODE) == KFmode))
+
+#define FLOAT128_IBM_P(MODE) \
+ (((MODE) == TFmode && !TARGET_IEEEQUAD) \
+ || ((MODE) == IFmode))
+
+/* Helper macros to say whether a 128-bit floating point type can go in a
+ single vector register, or whether it needs paired scalar values. */
+#define FLOAT128_VECTOR_P(MODE) (TARGET_FLOAT128 && FLOAT128_IEEE_P (MODE))
+
+#define FLOAT128_2REG_P(MODE) \
+ (FLOAT128_IBM_P (MODE) \
+ || ((MODE) == TDmode) \
+ || (!TARGET_FLOAT128 && FLOAT128_IEEE_P (MODE)))
+
+/* Return true for floating point that does not use a vector register. */
+#define SCALAR_FLOAT_MODE_NOT_VECTOR_P(MODE) \
+ (SCALAR_FLOAT_MODE_P (MODE) && !FLOAT128_VECTOR_P (MODE))
+
/* Describe the vector unit used for arithmetic operations. */
extern enum rs6000_vector rs6000_vector_unit[];
@@ -888,11 +915,10 @@ enum data_align { align_abi, align_opt, align_both };
aligned to 4 or 8 bytes. */
#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) \
(STRICT_ALIGNMENT \
- || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode \
- || (MODE) == SDmode || (MODE) == DDmode || (MODE) == TDmode) \
- && (ALIGN) < 32) \
+ || (SCALAR_FLOAT_MODE_NOT_VECTOR_P (MODE) && (ALIGN) < 32) \
|| (!TARGET_EFFICIENT_UNALIGNED_VSX \
- && (VECTOR_MODE_P ((MODE)) && (((int)(ALIGN)) < VECTOR_ALIGN (MODE)))))
+ && ((VECTOR_MODE_P (MODE) || FLOAT128_VECTOR_P (MODE)) \
+ && (((int)(ALIGN)) < VECTOR_ALIGN (MODE)))))
/* Standard register usage. */
@@ -1174,7 +1200,7 @@ enum data_align { align_abi, align_opt, align_both };
? V2DFmode \
: TARGET_E500_DOUBLE && ((MODE) == VOIDmode || (MODE) == DFmode) \
? DFmode \
- : !TARGET_E500_DOUBLE && (MODE) == TFmode && FP_REGNO_P (REGNO) \
+ : !TARGET_E500_DOUBLE && FLOAT128_IBM_P (MODE) && FP_REGNO_P (REGNO) \
? DFmode \
: !TARGET_E500_DOUBLE && (MODE) == TDmode && FP_REGNO_P (REGNO) \
? DImode \
@@ -1185,8 +1211,7 @@ enum data_align { align_abi, align_opt, align_both };
&& (GET_MODE_SIZE (MODE) > 4) \
&& INT_REGNO_P (REGNO)) ? 1 : 0) \
|| (TARGET_VSX && FP_REGNO_P (REGNO) \
- && GET_MODE_SIZE (MODE) > 8 && ((MODE) != TDmode) \
- && ((MODE) != TFmode)))
+ && GET_MODE_SIZE (MODE) > 8 && !FLOAT128_2REG_P (MODE)))
#define VSX_VECTOR_MODE(MODE) \
((MODE) == V4SFmode \