diff options
author | Richard Henderson <rth@redhat.com> | 2005-01-10 13:13:46 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2005-01-10 13:13:46 -0800 |
commit | b3a1ca4966f7b82d7e7e6c865019f0d8c997ce4d (patch) | |
tree | ac5684b70342b8a59a3afedd072cca0f76720d7b | |
parent | 3fd8010046b910ac2477b0feb22f187b653655d1 (diff) | |
download | gcc-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
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 91 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/abi-1.c | 8 |
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" } } */ |