+2015-10-29 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000.h (ALTIVEC_VECTOR_MODE): Add IEEE 128-bit
+ floating point modes that can go in vector registers.
+ (MODES_TIEABLE_P): Move tests for vector modes before tests for
+ scalar floating point, so that IEEE 128-bit floating point that
+ can go in vector registers bind with vectors and not FP.
+ (struct rs6000_args): Add libcall field.
+
+ * config/rs6000/rs6000.opt (-mfloat128-*): Delete -mfloat128-none
+ and -mfloat128-software switches. Replace them with a binary
+ -mfloat128 switch.
+ (-mfloat128): Likewise.
+
+ * config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): Allow
+ 128-bit floating point types in GPRs, even if the appropriate
+ option enabling the type was not used.
+ (rs6000_debug_reg_global): Remove -mfloat128-{software,none}
+ debugging.
+ (rs6000_setup_reg_addr_masks): Do not allow pre-increment and
+ pre-decrement on IEEE 128-bit floating point values.
+ (rs6000_init_hard_regno_mode_ok): Change test for whether TFmode
+ is IEEE 128-bit floating point.
+ (rs6000_init_hard_regno_mode_ok): Add reload handlers for IEEE
+ 128-bit floating point types that can go in vector registers.
+ (rs6000_option_override_internal): Change -mfloat128-none and
+ -mfloat128-software to -mfloat128, and move code to be near other
+ VSX option handling.
+ (rs6000_option_override_internal): Disable -mfloat128 if we don't
+ have the Altivec ABI.
+ (rs6000_init_builtins): Don't make TFmode use either IFmode or
+ KFmode floating point nodes. Instead, have three separate nodes.
+ (rs6000_scalar_mode_supported_p): Add support for IFmode to allow
+ eventually moving the long double default to IEEE 128-bit floating
+ point.
+ (rs6000_opt_masks): Add -mfloat128.
+ (struct rs6000_opt_var): Fix typo in comment.
+ (init_cumulative_args): Initialize libcall field in
+ CUMULATIVE_ARGS.
+ (rs6000_function_arg): Treat library functions as if they had
+ prototypes to prevent IEEE 128-bit support functions from passing
+ arguments in both GPRs and vector registers.
+ (rs6000_arg_partial_bytes): Likewise.
+
+ * config/rs6000/rs6000-cpus.def (POWERPC_MASKS): Add -mfloat128 as
+ an option that can be turned on via -mcpu=<xxx>.
+
+ * config/rs6000/rs6000-opts.h (enum float128_type_t): Delete, no
+ longer used.
+
+ * config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Define
+ __FLOAT128__ if -mfloat128. Define __LONG_DOUBLE_IEEE128__ if long
+ double is IEEE 128-bit. Define __LONG_DOUBLE_IBM128__ if long
+ double is IBM extended double.
+
+ * config/rs6000/predicates.md (reg_or_indexed_operand): Allow
+ SUBREGs.
+
2015-10-29 Mikhail Maltsev <maltsevm@gmail.com>
* genautomata.c: Use CHECKING_P instead of ENABLE_CHECKING.
&& IN_RANGE (last_regno, FIRST_GPR_REGNO, LAST_GPR_REGNO)
&& ((regno & 1) == 0));
- /* If we don't allow 128-bit binary floating point, disallow the 128-bit
- types from going in any registers. Similarly if __float128 is not
- supported, don't allow __float128/__ibm128 types. */
- if (!TARGET_LONG_DOUBLE_128
- && (mode == TFmode || mode == KFmode || mode == IFmode))
- return false;
-
- if (!TARGET_FLOAT128 && (mode == KFmode || mode == IFmode))
- return false;
-
/* VSX registers that overlap the FPR registers are larger than for non-VSX
implementations. Don't allow an item to be split between a FP register
and an Altivec register. Allow TImode in all VSX registers if the user
const char *trace_str;
const char *abi_str;
const char *cmodel_str;
- const char *float128_str;
struct cl_target_option cl_opts;
/* Modes we want tieable information on. */
fprintf (stderr, DEBUG_FMT_S, "e500_double",
(TARGET_E500_DOUBLE ? "true" : "false"));
- switch (TARGET_FLOAT128)
- {
- case FLOAT128_NONE: float128_str = "none"; break;
- case FLOAT128_SW: float128_str = "software"; break;
- default: float128_str = "unknown"; break;
- }
-
- fprintf (stderr, DEBUG_FMT_S, "float128", float128_str);
-
if (TARGET_LINK_STACK)
fprintf (stderr, DEBUG_FMT_S, "link_stack", "true");
&& (rc == RELOAD_REG_GPR || rc == RELOAD_REG_FPR)
&& GET_MODE_SIZE (m2) <= 8
&& !VECTOR_MODE_P (m2)
+ && !FLOAT128_VECTOR_P (m2)
&& !COMPLEX_MODE_P (m2)
&& !indexed_only_p
&& !(TARGET_E500_DOUBLE && GET_MODE_SIZE (m2) == 8))
align32 = 128;
}
+ /* KF mode (IEEE 128-bit in VSX registers). We do not have arithmetic, so
+ only set the memory modes. Include TFmode if -mabi=ieeelongdouble. */
+ if (TARGET_FLOAT128)
+ {
+ rs6000_vector_mem[KFmode] = VECTOR_VSX;
+ rs6000_vector_align[KFmode] = 128;
+
+ if (FLOAT128_IEEE_P (TFmode))
+ {
+ rs6000_vector_mem[TFmode] = VECTOR_VSX;
+ rs6000_vector_align[TFmode] = 128;
+ }
+ }
+
/* V2DF mode, VSX only. */
if (TARGET_VSX)
{
if (TARGET_FLOAT128)
{
rs6000_constraints[RS6000_CONSTRAINT_wq] = VSX_REGS; /* KFmode */
- if (rs6000_ieeequad)
+ if (FLOAT128_IEEE_P (TFmode))
rs6000_constraints[RS6000_CONSTRAINT_wp] = VSX_REGS; /* TFmode */
}
reg_addr[V4SFmode].reload_load = CODE_FOR_reload_v4sf_di_load;
reg_addr[V2DFmode].reload_store = CODE_FOR_reload_v2df_di_store;
reg_addr[V2DFmode].reload_load = CODE_FOR_reload_v2df_di_load;
+ reg_addr[KFmode].reload_store = CODE_FOR_reload_kf_di_store;
+ reg_addr[KFmode].reload_load = CODE_FOR_reload_kf_di_load;
reg_addr[DFmode].reload_store = CODE_FOR_reload_df_di_store;
reg_addr[DFmode].reload_load = CODE_FOR_reload_df_di_load;
reg_addr[DDmode].reload_store = CODE_FOR_reload_dd_di_store;
reg_addr[SFmode].reload_store = CODE_FOR_reload_sf_di_store;
reg_addr[SFmode].reload_load = CODE_FOR_reload_sf_di_load;
+ if (FLOAT128_IEEE_P (TFmode))
+ {
+ reg_addr[TFmode].reload_store = CODE_FOR_reload_tf_di_store;
+ reg_addr[TFmode].reload_load = CODE_FOR_reload_tf_di_load;
+ }
+
/* Only provide a reload handler for SDmode if lfiwzx/stfiwx are
available. */
if (TARGET_NO_SDMODE_STACK)
reg_addr[V4SFmode].reload_load = CODE_FOR_reload_v4sf_si_load;
reg_addr[V2DFmode].reload_store = CODE_FOR_reload_v2df_si_store;
reg_addr[V2DFmode].reload_load = CODE_FOR_reload_v2df_si_load;
+ reg_addr[KFmode].reload_store = CODE_FOR_reload_kf_si_store;
+ reg_addr[KFmode].reload_load = CODE_FOR_reload_kf_si_load;
reg_addr[DFmode].reload_store = CODE_FOR_reload_df_si_store;
reg_addr[DFmode].reload_load = CODE_FOR_reload_df_si_load;
reg_addr[DDmode].reload_store = CODE_FOR_reload_dd_si_store;
reg_addr[SFmode].reload_store = CODE_FOR_reload_sf_si_store;
reg_addr[SFmode].reload_load = CODE_FOR_reload_sf_si_load;
+ if (FLOAT128_IEEE_P (TFmode))
+ {
+ reg_addr[TFmode].reload_store = CODE_FOR_reload_tf_si_store;
+ reg_addr[TFmode].reload_load = CODE_FOR_reload_tf_si_load;
+ }
+
/* Only provide a reload handler for SDmode if lfiwzx/stfiwx are
available. */
if (TARGET_NO_SDMODE_STACK)
&& optimize >= 3)
rs6000_isa_flags |= OPTION_MASK_P8_FUSION_SIGN;
- /* Set the appropriate IEEE 128-bit floating option. Do not enable float128
- support by default until the libgcc support is added. */
- if (TARGET_FLOAT128 == FLOAT128_UNSET)
- TARGET_FLOAT128 = FLOAT128_NONE;
- else if (TARGET_FLOAT128 == FLOAT128_SW && !TARGET_VSX)
- error ("-mfloat128-software requires VSX support");
-
/* Set -mallow-movmisalign to explicitly on if we have full ISA 2.07
support. If we only have ISA 2.06 support, and the user did not specify
the switch, leave it set to -1 so the movmisalign patterns are enabled,
}
}
+ /* __float128 requires VSX support. */
+ if (TARGET_FLOAT128 && !TARGET_VSX)
+ {
+ if ((rs6000_isa_flags_explicit & OPTION_MASK_FLOAT128) != 0)
+ error ("-mfloat128 requires VSX support");
+
+ rs6000_isa_flags &= ~OPTION_MASK_FLOAT128;
+ }
+
if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET)
rs6000_print_isa_options (stderr, 0, "after defaults", rs6000_isa_flags);
unless the altivec ABI was set. This is set by default for 64-bit, but
not for 32-bit. */
if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
- rs6000_isa_flags &= ~((OPTION_MASK_VSX | OPTION_MASK_ALTIVEC)
+ rs6000_isa_flags &= ~((OPTION_MASK_VSX | OPTION_MASK_ALTIVEC
+ | OPTION_MASK_FLOAT128)
& ~rs6000_isa_flags_explicit);
/* Enable Altivec ABI for AIX -maltivec. */
? CALL_LIBCALL : CALL_NORMAL);
cum->sysv_gregno = GP_ARG_MIN_REG;
cum->stdarg = stdarg_p (fntype);
+ cum->libcall = libcall;
cum->nargs_prototype = 0;
if (incoming || cum->prototype)
rtx r, off;
int i, k = 0;
- /* Do we also need to pass this argument in the parameter
- save area? */
- if (TARGET_64BIT && ! cum->prototype)
+ /* Do we also need to pass this argument in the parameter save area?
+ Library support functions for IEEE 128-bit are assumed to not need the
+ value passed both in GPRs and in vector registers. */
+ if (TARGET_64BIT && !cum->prototype
+ && (!cum->libcall || !FLOAT128_VECTOR_P (elt_mode)))
{
int align_words = ROUND_UP (cum->words, 2);
k = rs6000_psave_function_arg (mode, type, align_words, rvec);
if (USE_ALTIVEC_FOR_ARG_P (cum, elt_mode, named))
{
- /* If we are passing this arg in the fixed parameter save area
- (gprs or memory) as well as VRs, we do not use the partial
- bytes mechanism; instead, rs6000_function_arg will return a
- PARALLEL including a memory element as necessary. */
- if (TARGET_64BIT && ! cum->prototype)
+ /* If we are passing this arg in the fixed parameter save area (gprs or
+ memory) as well as VRs, we do not use the partial bytes mechanism;
+ instead, rs6000_function_arg will return a PARALLEL including a memory
+ element as necessary. Library support functions for IEEE 128-bit are
+ assumed to not need the value passed both in GPRs and in vector
+ registers. */
+ if (TARGET_64BIT && !cum->prototype
+ && (!cum->libcall || !FLOAT128_VECTOR_P (elt_mode)))
return 0;
/* Otherwise, we pass in VRs only. Check for partial copies. */
tree tdecl;
tree ftype;
machine_mode mode;
- machine_mode ieee128_mode;
- machine_mode ibm128_mode;
if (TARGET_DEBUG_BUILTIN)
fprintf (stderr, "rs6000_init_builtins%s%s%s%s\n",
TFmode will be either IEEE 128-bit floating point or the IBM double-double
format that uses a pair of doubles, depending on the switches and
defaults. */
- if (TARGET_IEEEQUAD)
- {
- ieee128_mode = TFmode;
- ibm128_mode = IFmode;
- }
- else
+ if (TARGET_FLOAT128)
{
- ieee128_mode = KFmode;
- ibm128_mode = TFmode;
- }
+ ibm128_float_type_node = make_node (REAL_TYPE);
+ TYPE_PRECISION (ibm128_float_type_node) = 128;
+ layout_type (ibm128_float_type_node);
+ SET_TYPE_MODE (ibm128_float_type_node, IFmode);
+
+ ieee128_float_type_node = make_node (REAL_TYPE);
+ TYPE_PRECISION (ieee128_float_type_node) = 128;
+ layout_type (ieee128_float_type_node);
+ SET_TYPE_MODE (ieee128_float_type_node, KFmode);
- ieee128_float_type_node = make_node (REAL_TYPE);
- TYPE_PRECISION (ieee128_float_type_node) = 128;
- layout_type (ieee128_float_type_node);
- SET_TYPE_MODE (ieee128_float_type_node, ieee128_mode);
+ lang_hooks.types.register_builtin_type (ieee128_float_type_node,
+ "__float128");
- ibm128_float_type_node = make_node (REAL_TYPE);
- TYPE_PRECISION (ibm128_float_type_node) = 128;
- layout_type (ibm128_float_type_node);
- SET_TYPE_MODE (ibm128_float_type_node, ibm128_mode);
+ lang_hooks.types.register_builtin_type (ibm128_float_type_node,
+ "__ibm128");
+ }
/* Initialize the modes for builtin_function_type, mapping a machine mode to
tree type node. */
if (DECIMAL_FLOAT_MODE_P (mode))
return default_decimal_float_supported_p ();
- else if (mode == KFmode)
- return TARGET_FLOAT128;
+ else if (TARGET_FLOAT128 && (mode == KFmode || mode == IFmode))
+ return true;
else
return default_scalar_mode_supported_p (mode);
}
{ "dlmzb", OPTION_MASK_DLMZB, false, true },
{ "efficient-unaligned-vsx", OPTION_MASK_EFFICIENT_UNALIGNED_VSX,
false, true },
+ { "float128", OPTION_MASK_FLOAT128, false, true },
{ "fprnd", OPTION_MASK_FPRND, false, true },
{ "hard-dfp", OPTION_MASK_DFP, false, true },
{ "htm", OPTION_MASK_HTM, false, true },
struct rs6000_opt_var {
const char *name; /* option name */
size_t global_offset; /* offset of the option in global_options. */
- size_t target_offset; /* offset of the option in target optiosn. */
+ size_t target_offset; /* offset of the option in target options. */
};
static struct rs6000_opt_var const rs6000_opt_vars[] =