+2004-01-06 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (init_cumulative_args): Add handling of MMX_REGPARM.
+ (function_arg_advance): Do not pass aggregates in SSE; deal handling
+ of MMX_REGPARM.
+ (function_arg): Add new warnings about ABI changes; fix SSE_REGPARM;
+ add MMX_REGPARM.
+ * i386.h (ix86_args): Add mmx_words/mmx_regs/mmx_regno fields.
+ (SSE_REGPARM_MAX): Default to 3 on i386 -msse ABI.
+ (MMX_REGPARM_MAX): Similarly for -mmmx.
+
2004-01-05 Kazu Hirata <kazu@cs.umass.edu>
* config/sh/linux.h: Fix comment formatting.
else
cum->nregs = ix86_regparm;
cum->sse_nregs = SSE_REGPARM_MAX;
+ cum->mmx_nregs = MMX_REGPARM_MAX;
cum->maybe_vaarg = false;
/* Use ecx and edx registers if function has fastcall attribute */
if (TARGET_DEBUG_ARG)
fprintf (stderr,
- "function_adv (sz=%d, wds=%2d, nregs=%d, mode=%s, named=%d)\n\n",
- words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
+ "function_adv (sz=%d, wds=%2d, nregs=%d, ssenregs=%d, mode=%s, named=%d)\n\n",
+ words, cum->words, cum->nregs, cum->sse_nregs, GET_MODE_NAME (mode), named);
if (TARGET_64BIT)
{
int int_nregs, sse_nregs;
}
else
{
- if (TARGET_SSE && mode == TImode)
+ if (TARGET_SSE && SSE_REG_MODE_P (mode)
+ && (!type || !AGGREGATE_TYPE_P (type)))
{
cum->sse_words += words;
cum->sse_nregs -= 1;
cum->sse_regno = 0;
}
}
+ else if (TARGET_MMX && MMX_REG_MODE_P (mode)
+ && (!type || !AGGREGATE_TYPE_P (type)))
+ {
+ cum->mmx_words += words;
+ cum->mmx_nregs -= 1;
+ cum->mmx_regno += 1;
+ if (cum->mmx_nregs <= 0)
+ {
+ cum->mmx_nregs = 0;
+ cum->mmx_regno = 0;
+ }
+ }
else
{
cum->words += words;
int bytes =
(mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ static bool warnedsse, warnedmmx;
/* Handle a hidden AL argument containing number of registers for varargs
x86-64 functions. For i386 ABI just return constm1_rtx to avoid
}
break;
case TImode:
- if (cum->sse_nregs)
- ret = gen_rtx_REG (mode, cum->sse_regno);
+ case V16QImode:
+ case V8HImode:
+ case V4SImode:
+ case V2DImode:
+ case V4SFmode:
+ case V2DFmode:
+ if (!type || !AGGREGATE_TYPE_P (type))
+ {
+ if (!TARGET_SSE && !warnedmmx)
+ {
+ warnedsse = true;
+ warning ("SSE vector argument without SSE enabled "
+ "changes the ABI");
+ }
+ if (cum->sse_nregs)
+ ret = gen_rtx_REG (mode, cum->sse_regno + FIRST_SSE_REG);
+ }
+ break;
+ case V8QImode:
+ case V4HImode:
+ case V2SImode:
+ case V2SFmode:
+ if (!type || !AGGREGATE_TYPE_P (type))
+ {
+ if (!TARGET_MMX && !warnedmmx)
+ {
+ warnedmmx = true;
+ warning ("MMX vector argument without MMX enabled "
+ "changes the ABI");
+ }
+ if (cum->mmx_nregs)
+ ret = gen_rtx_REG (mode, cum->mmx_regno + FIRST_MMX_REG);
+ }
break;
}
int sse_words; /* # sse words passed so far */
int sse_nregs; /* # sse registers available for passing */
int sse_regno; /* next available sse register number */
+ int mmx_words; /* # mmx words passed so far */
+ int mmx_nregs; /* # mmx registers available for passing */
+ int mmx_regno; /* next available mmx register number */
int maybe_vaarg; /* true for calls to possibly vardic fncts. */
} CUMULATIVE_ARGS;
#define REGPARM_MAX (TARGET_64BIT ? 6 : 3)
-#define SSE_REGPARM_MAX (TARGET_64BIT ? 8 : 0)
+#define SSE_REGPARM_MAX (TARGET_64BIT ? 8 : (TARGET_SSE ? 3 : 0))
+
+#define MMX_REGPARM_MAX (TARGET_64BIT ? 0 : (TARGET_MMX ? 3 : 0))
\f
/* Specify the machine mode that this machine uses