The midde-end can't deal with the vector types > 16 bytes. In this
case, we return the original mode and warn ABI change if CUM isn't
- NULL. */
+ NULL.
+
+ If INT_RETURN is true, warn ABI change if the vector mode isn't
+ available for function return value. */
static enum machine_mode
-type_natural_mode (const_tree type, const CUMULATIVE_ARGS *cum)
+type_natural_mode (const_tree type, const CUMULATIVE_ARGS *cum,
+ bool in_return)
{
enum machine_mode mode = TYPE_MODE (type);
if (size == 32 && !TARGET_AVX)
{
static bool warnedavx;
+ static bool warnedavx_ret;
if (cum
&& !warnedavx
warning (0, "AVX vector argument without AVX "
"enabled changes the ABI");
}
+ else if (in_return & !warnedavx_ret)
+ {
+ warnedavx_ret = true;
+ warning (0, "AVX vector return without AVX "
+ "enabled changes the ABI");
+ }
+
return TYPE_MODE (type);
}
else if (((size == 8 && TARGET_64BIT) || size == 16)
&& !TARGET_SSE)
{
static bool warnedsse;
+ static bool warnedsse_ret;
if (cum
&& !warnedsse
warning (0, "SSE vector argument without SSE "
"enabled changes the ABI");
}
+ else if (!TARGET_64BIT
+ && in_return
+ & !warnedsse_ret)
+ {
+ warnedsse_ret = true;
+ warning (0, "SSE vector return without SSE "
+ "enabled changes the ABI");
+ }
}
else if ((size == 8 && !TARGET_64BIT) && !TARGET_MMX)
{
static bool warnedmmx;
+ static bool warnedmmx_ret;
if (cum
&& !warnedmmx
warning (0, "MMX vector argument without MMX "
"enabled changes the ABI");
}
+ else if (in_return & !warnedmmx_ret)
+ {
+ warnedmmx_ret = true;
+ warning (0, "MMX vector return without MMX "
+ "enabled changes the ABI");
+ }
}
return mode;
}
words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
if (type)
- mode = type_natural_mode (type, NULL);
+ mode = type_natural_mode (type, NULL, false);
if (TARGET_64BIT && (cum ? cum->call_abi : ix86_abi) == MS_ABI)
function_arg_advance_ms_64 (cum, bytes, words);
enum machine_mode orig_mode, const_tree type,
HOST_WIDE_INT bytes, HOST_WIDE_INT words)
{
- static bool warnedsse, warnedmmx;
-
/* Avoid the AL settings for the Unix64 ABI. */
if (mode == VOIDmode)
return constm1_rtx;
case V2DFmode:
if (!type || !AGGREGATE_TYPE_P (type))
{
- if (!TARGET_SSE && !warnedsse && cum->warn_sse)
- {
- warnedsse = true;
- warning (0, "SSE vector argument without SSE enabled "
- "changes the ABI");
- }
if (cum->sse_nregs)
return gen_reg_or_parallel (mode, orig_mode,
cum->sse_regno + FIRST_SSE_REG);
case V1DImode:
if (!type || !AGGREGATE_TYPE_P (type))
{
- if (!TARGET_MMX && !warnedmmx && cum->warn_mmx)
- {
- warnedmmx = true;
- warning (0, "MMX vector argument without MMX enabled "
- "changes the ABI");
- }
if (cum->mmx_nregs)
return gen_reg_or_parallel (mode, orig_mode,
cum->mmx_regno + FIRST_MMX_REG);
/* To simplify the code below, represent vector types with a vector mode
even if MMX/SSE are not active. */
if (type && TREE_CODE (type) == VECTOR_TYPE)
- mode = type_natural_mode (type, cum);
+ mode = type_natural_mode (type, cum, false);
if (TARGET_64BIT && (cum ? cum->call_abi : ix86_abi) == MS_ABI)
arg = function_arg_ms_64 (cum, mode, omode, named, bytes);
enum machine_mode mode, orig_mode;
orig_mode = TYPE_MODE (valtype);
- mode = type_natural_mode (valtype, NULL);
+ mode = type_natural_mode (valtype, NULL, true);
return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode);
}
#ifdef SUBTARGET_RETURN_IN_MEMORY
return SUBTARGET_RETURN_IN_MEMORY (type, fntype);
#else
- const enum machine_mode mode = type_natural_mode (type, NULL);
+ const enum machine_mode mode = type_natural_mode (type, NULL, true);
if (TARGET_64BIT)
{
#endif
}
-/* When returning SSE vector types, we have a choice of either
- (1) being abi incompatible with a -march switch, or
- (2) generating an error.
- Given no good solution, I think the safest thing is one warning.
- The user won't be able to use -Werror, but....
-
- Choose the STRUCT_VALUE_RTX hook because that's (at present) only
- called in response to actually generating a caller or callee that
- uses such a type. As opposed to TARGET_RETURN_IN_MEMORY, which is called
- via aggregate_value_p for general type probing from tree-ssa. */
-
-static rtx
-ix86_struct_value_rtx (tree type, int incoming ATTRIBUTE_UNUSED)
-{
- static bool warnedsse, warnedmmx;
-
- if (!TARGET_64BIT && type)
- {
- /* Look at the return type of the function, not the function type. */
- enum machine_mode mode = TYPE_MODE (TREE_TYPE (type));
-
- if (!TARGET_SSE && !warnedsse)
- {
- if (mode == TImode
- || (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 16))
- {
- warnedsse = true;
- warning (0, "SSE vector return without SSE enabled "
- "changes the ABI");
- }
- }
-
- if (!TARGET_MMX && !warnedmmx)
- {
- if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 8)
- {
- warnedmmx = true;
- warning (0, "MMX vector return without MMX enabled "
- "changes the ABI");
- }
- }
- }
-
- return NULL;
-}
-
\f
/* Create the va_list data type. */
size = int_size_in_bytes (type);
rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
- nat_mode = type_natural_mode (type, NULL);
+ nat_mode = type_natural_mode (type, NULL, false);
switch (nat_mode)
{
case V8SFmode:
#undef TARGET_PROMOTE_PROTOTYPES
#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
-#undef TARGET_STRUCT_VALUE_RTX
-#define TARGET_STRUCT_VALUE_RTX ix86_struct_value_rtx
#undef TARGET_SETUP_INCOMING_VARARGS
#define TARGET_SETUP_INCOMING_VARARGS ix86_setup_incoming_varargs
#undef TARGET_MUST_PASS_IN_STACK