aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2003-08-24 20:17:02 -0700
committerRichard Henderson <rth@gcc.gnu.org>2003-08-24 20:17:02 -0700
commita30b6839178e57250791bd821f332151afaffba5 (patch)
tree2d4b98c73960bd2b9f17fa51bbfb7c365f35942a /gcc
parentc681386d04ae1728186dd348f8abe2f60d7a5fa9 (diff)
downloadgcc-a30b6839178e57250791bd821f332151afaffba5.zip
gcc-a30b6839178e57250791bd821f332151afaffba5.tar.gz
gcc-a30b6839178e57250791bd821f332151afaffba5.tar.bz2
i386.i386.c (ix86_return_in_memory): Reformat.
* config/i386.i386.c (ix86_return_in_memory): Reformat. Return true for 16-byte vector modes if sse not enabled; warn for abi change. (ix86_value_regno): Only return xmm0 for 16-byte vector types. * g++.dg/eh/simd-2.C: Add -w for x86. From-SVN: r70771
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.c72
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/eh/simd-2.C1
4 files changed, 64 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 42d313f..440fcdc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2003-08-24 Richard Henderson <rth@redhat.com>
+
+ * config/i386.i386.c (ix86_return_in_memory): Reformat. Return true
+ for 16-byte vector modes if sse not enabled; warn for abi change.
+ (ix86_value_regno): Only return xmm0 for 16-byte vector types.
+
2003-08-24 Kazu Hirata <kazu@cs.umass.edu>
* rtlanal.c (may_trap_p): Simplify an integer comparison.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 1609b74..4984fc4 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2691,29 +2691,59 @@ ix86_function_value (tree valtype)
int
ix86_return_in_memory (tree type)
{
- int needed_intregs, needed_sseregs;
+ int needed_intregs, needed_sseregs, size;
+ enum machine_mode mode = TYPE_MODE (type);
+
if (TARGET_64BIT)
+ return !examine_argument (mode, type, 1, &needed_intregs, &needed_sseregs);
+
+ if (mode == BLKmode)
+ return 1;
+
+ size = int_size_in_bytes (type);
+
+ if (MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P (type) && size <= 8)
+ return 0;
+
+ if (VECTOR_MODE_P (mode) || mode == TImode)
{
- return !examine_argument (TYPE_MODE (type), type, 1,
- &needed_intregs, &needed_sseregs);
- }
- else
- {
- if (TYPE_MODE (type) == BLKmode)
- return 1;
- else if (MS_AGGREGATE_RETURN
- && AGGREGATE_TYPE_P (type)
- && int_size_in_bytes(type) <= 8)
+ /* User-created vectors small enough to fit in EAX. */
+ if (size < 8)
return 0;
- else if ((VECTOR_MODE_P (TYPE_MODE (type))
- && int_size_in_bytes (type) == 8)
- || (int_size_in_bytes (type) > 12
- && TYPE_MODE (type) != TImode
- && TYPE_MODE (type) != TFmode
- && !VECTOR_MODE_P (TYPE_MODE (type))))
+
+ /* MMX/3dNow values are returned on the stack, since we've
+ got to EMMS/FEMMS before returning. */
+ if (size == 8)
return 1;
- return 0;
+
+ /* SSE values are returned in XMM0. */
+ /* ??? Except when it doesn't exist? We have a choice of
+ either (1) being abi incompatible with a -march switch,
+ or (2) generating an error here. Given no good solution,
+ I think the safest thing is one warning. The user won't
+ be able to use -Werror, but... */
+ if (size == 16)
+ {
+ static bool warned;
+
+ if (TARGET_SSE)
+ return 0;
+
+ if (!warned)
+ {
+ warned = true;
+ warning ("SSE vector return without SSE enabled "
+ "changes the ABI");
+ }
+ return 1;
+ }
}
+
+ if (mode == TFmode)
+ return 0;
+ if (size > 12)
+ return 1;
+ return 0;
}
/* Define how to find the value returned by a library function
@@ -2746,10 +2776,14 @@ ix86_libcall_value (enum machine_mode mode)
static int
ix86_value_regno (enum machine_mode mode)
{
+ /* Floating point return values in %st(0). */
if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_FLOAT_RETURNS_IN_80387)
return FIRST_FLOAT_REG;
- if (mode == TImode || VECTOR_MODE_P (mode))
+ /* 16-byte vector modes in %xmm0. See ix86_return_in_memory for where
+ we prevent this case when sse is not available. */
+ if (mode == TImode || (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 16))
return FIRST_SSE_REG;
+ /* Everything else in %eax. */
return 0;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bfcab55..5ed3354 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2003-08-24 Richard Henderson <rth@redhat.com>
+
+ * g++.dg/eh/simd-2.C: Add -w for x86.
+
2003-08-23 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/20030815-1.c: New test.
diff --git a/gcc/testsuite/g++.dg/eh/simd-2.C b/gcc/testsuite/g++.dg/eh/simd-2.C
index e6f1f7b..39f8dc8 100644
--- a/gcc/testsuite/g++.dg/eh/simd-2.C
+++ b/gcc/testsuite/g++.dg/eh/simd-2.C
@@ -1,6 +1,7 @@
// Test EH when V4SI SIMD registers are involved.
// Contributed by Aldy Hernandez (aldy@quesejoda.com).
// { dg-options "-O" }
+// { dg-options "-O -w" { target i?86-*-* } }
// { dg-do run }
typedef int __attribute__((mode(V4SI))) vecint;