aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2005-01-10 13:13:46 -0800
committerRichard Henderson <rth@gcc.gnu.org>2005-01-10 13:13:46 -0800
commitb3a1ca4966f7b82d7e7e6c865019f0d8c997ce4d (patch)
treeac5684b70342b8a59a3afedd072cca0f76720d7b /gcc
parent3fd8010046b910ac2477b0feb22f187b653655d1 (diff)
downloadgcc-b3a1ca4966f7b82d7e7e6c865019f0d8c997ce4d.zip
gcc-b3a1ca4966f7b82d7e7e6c865019f0d8c997ce4d.tar.gz
gcc-b3a1ca4966f7b82d7e7e6c865019f0d8c997ce4d.tar.bz2
i386.c (ix86_function_value): Use type_natural_mode.
* config/i386/i386.c (ix86_function_value): Use type_natural_mode. (ix86_return_in_memory): Likewise. (function_arg_advance): Likewise. Mirror structure in function_arg for choosing register to advance. From-SVN: r93156
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/i386/i386.c91
-rw-r--r--gcc/testsuite/gcc.target/i386/abi-1.c8
3 files changed, 75 insertions, 31 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f9d67ab..3aac273 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2005-01-10 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (ix86_function_value): Use type_natural_mode.
+ (ix86_return_in_memory): Likewise.
+ (function_arg_advance): Likewise. Mirror structure in function_arg
+ for choosing register to advance.
+
2005-01-10 Kazu Hirata <kazu@cs.umass.edu>
* tree-vectorizer.c, tree.def: Fix comment typos.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 91bbac3..27b2339 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2663,11 +2663,15 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
(mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ if (type)
+ mode = type_natural_mode (type);
+
if (TARGET_DEBUG_ARG)
fprintf (stderr, "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;
@@ -2685,32 +2689,20 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
}
else
{
- if (TARGET_SSE && SSE_REG_MODE_P (mode)
- && (!type || !AGGREGATE_TYPE_P (type)))
- {
- cum->sse_words += words;
- cum->sse_nregs -= 1;
- cum->sse_regno += 1;
- if (cum->sse_nregs <= 0)
- {
- cum->sse_nregs = 0;
- 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
+ switch (mode)
{
+ default:
+ break;
+
+ case BLKmode:
+ if (bytes < 0)
+ break;
+ /* FALLTHRU */
+
+ case DImode:
+ case SImode:
+ case HImode:
+ case QImode:
cum->words += words;
cum->nregs -= words;
cum->regno += words;
@@ -2720,9 +2712,46 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
cum->nregs = 0;
cum->regno = 0;
}
+ break;
+
+ case TImode:
+ case V16QImode:
+ case V8HImode:
+ case V4SImode:
+ case V2DImode:
+ case V4SFmode:
+ case V2DFmode:
+ if (!type || !AGGREGATE_TYPE_P (type))
+ {
+ cum->sse_words += words;
+ cum->sse_nregs -= 1;
+ cum->sse_regno += 1;
+ if (cum->sse_nregs <= 0)
+ {
+ cum->sse_nregs = 0;
+ cum->sse_regno = 0;
+ }
+ }
+ break;
+
+ case V8QImode:
+ case V4HImode:
+ case V2SImode:
+ case V2SFmode:
+ if (!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;
+ }
+ }
+ break;
}
}
- return;
}
/* Define where to put the arguments to a function.
@@ -2999,10 +3028,11 @@ ix86_function_value_regno_p (int regno)
rtx
ix86_function_value (tree valtype)
{
+ enum machine_mode natmode = type_natural_mode (valtype);
+
if (TARGET_64BIT)
{
- rtx ret = construct_container (type_natural_mode (valtype),
- TYPE_MODE (valtype), valtype,
+ rtx ret = construct_container (natmode, TYPE_MODE (valtype), valtype,
1, REGPARM_MAX, SSE_REGPARM_MAX,
x86_64_int_return_registers, 0);
/* For zero sized structures, construct_container return NULL, but we
@@ -3012,8 +3042,7 @@ ix86_function_value (tree valtype)
return ret;
}
else
- return gen_rtx_REG (TYPE_MODE (valtype),
- ix86_value_regno (TYPE_MODE (valtype)));
+ return gen_rtx_REG (TYPE_MODE (valtype), ix86_value_regno (natmode));
}
/* Return false iff type is returned in memory. */
@@ -3021,7 +3050,7 @@ int
ix86_return_in_memory (tree type)
{
int needed_intregs, needed_sseregs, size;
- enum machine_mode mode = TYPE_MODE (type);
+ enum machine_mode mode = type_natural_mode (type);
if (TARGET_64BIT)
return !examine_argument (mode, type, 1, &needed_intregs, &needed_sseregs);
diff --git a/gcc/testsuite/gcc.target/i386/abi-1.c b/gcc/testsuite/gcc.target/i386/abi-1.c
new file mode 100644
index 0000000..032274c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/abi-1.c
@@ -0,0 +1,8 @@
+/* Make certain that we pass V2DF in the correct register for SSE1. */
+/* { dg-do compile } */
+/* { dg-options "-O1 -msse -mno-sse2" } */
+
+typedef double v2df __attribute__((vector_size (16)));
+v2df foo (void) { return (v2df){ 1.0, 2.0 }; }
+
+/* { dg-final { scan-assembler "xmm0" } } */