diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000.h')
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 39 |
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 \ |