This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] x86-64 long double complex ABI change (PR/17603)


This reflects an x86-64 ABI change (or clarification) that now requires
XCmode return values to be passed through st0 and st1 rather than
memory.

Having looked at all this again I would question one currently (and
previously) existing construct, though (but I don't immediately know
how
to address this): x86_libcall_value says DCmode gets returned in
FIRST_SSE_REG, but since DCmode entirely fits into one xmm register
this
does not seem to imply use of xmm0 and xmm1 for each of the halves.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

2004-12-16  Jan Beulich  <jbeulich@novell.com>

	PR/17603
	* config/i386/i386.c (enum x86_64_reg_class): Define
	X86_64_COMPLEX_X87_CLASS.
	(x86_64_reg_class_names): Add name for
X86_64_COMPLEX_X87_CLASS.
	(merge_classes): Handle X86_64_COMPLEX_X87_CLASS.
	(classify_argument): XCmode is X86_64_COMPLEX_X87_CLASS.
	(examine_argument): X86_64_COMPLEX_X87_CLASS requires two
	registers when dealing with a return value.
	(construct_container): Handle X86_64_COMPLEX_X87_CLASS.
	Eliminate impossible case of two X87/X87UP pairs (this now is
	being expressed by a single COMPLEX_X87).
	(x86_libcall_value): XCmode gets returned in st0/st1.

---
/home/jbeulich/src/gcc/mainline/2004-12-13.08.53/gcc/config/i386/i386.c	2004-12-13
08:30:01.000000000 +0100
+++ 2004-12-13.08.53/gcc/config/i386/i386.c	2004-12-16
13:38:29.751511752 +0100
@@ -947,10 +947,11 @@ enum x86_64_reg_class
     X86_64_SSEUP_CLASS,
     X86_64_X87_CLASS,
     X86_64_X87UP_CLASS,
+    X86_64_COMPLEX_X87_CLASS,
     X86_64_MEMORY_CLASS
   };
 static const char * const x86_64_reg_class_name[] =
-   {"no", "integer", "integerSI", "sse", "sseSF", "sseDF", "sseup",
"x87", "x87up", "no"};
+   {"no", "integer", "integerSI", "sse", "sseSF", "sseDF", "sseup",
"x87", "x87up", "cplx87", "no"};
 
 #define MAX_CLASSES 4
 static int classify_argument (enum machine_mode, tree,
@@ -2066,9 +2067,14 @@ merge_classes (enum x86_64_reg_class cla
       || class2 == X86_64_INTEGER_CLASS || class2 ==
X86_64_INTEGERSI_CLASS)
     return X86_64_INTEGER_CLASS;
 
-  /* Rule #5: If one of the classes is X87 or X87UP class, MEMORY is
used.  */
-  if (class1 == X86_64_X87_CLASS || class1 == X86_64_X87UP_CLASS
-      || class2 == X86_64_X87_CLASS || class2 == X86_64_X87UP_CLASS)
+  /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87
class,
+     MEMORY is used.  */
+  if (class1 == X86_64_X87_CLASS
+      || class1 == X86_64_X87UP_CLASS
+      || class1 == X86_64_COMPLEX_X87_CLASS
+      || class2 == X86_64_X87_CLASS
+      || class2 == X86_64_X87UP_CLASS
+      || class2 == X86_64_COMPLEX_X87_CLASS)
     return X86_64_MEMORY_CLASS;
 
   /* Rule #6: Otherwise class SSE is used.  */
@@ -2348,8 +2354,10 @@ classify_argument (enum machine_mode mod
       classes[1] = X86_64_SSEDF_CLASS;
       return 2;
     case XCmode:
+      classes[0] = X86_64_COMPLEX_X87_CLASS;
+      return 1;
     case TCmode:
-      /* These modes are larger than 16 bytes.  */
+      /* This modes is larger than 16 bytes.  */
       return 0;
     case V4SFmode:
     case V4SImode:
@@ -2421,6 +2429,8 @@ examine_argument (enum machine_mode mode
 	if (!in_return)
 	  return 0;
 	break;
+      case X86_64_COMPLEX_X87_CLASS:
+	return in_return ? 2 : 0;
       case X86_64_MEMORY_CLASS:
 	abort ();
       }
@@ -2479,6 +2489,7 @@ construct_container (enum machine_mode m
       case X86_64_SSEDF_CLASS:
 	return gen_rtx_REG (mode, SSE_REGNO (sse_regno));
       case X86_64_X87_CLASS:
+      case X86_64_COMPLEX_X87_CLASS:
 	return gen_rtx_REG (mode, FIRST_STACK_REG);
       case X86_64_NO_CLASS:
 	/* Zero sized array, struct or class.  */
@@ -2497,11 +2508,6 @@ construct_container (enum machine_mode m
       && (mode == CDImode || mode == TImode || mode == TFmode)
       && intreg[0] + 1 == intreg[1])
     return gen_rtx_REG (mode, intreg[0]);
-  if (n == 4
-      && class[0] == X86_64_X87_CLASS && class[1] ==
X86_64_X87UP_CLASS
-      && class[2] == X86_64_X87_CLASS && class[3] ==
X86_64_X87UP_CLASS
-      && mode != BLKmode)
-    return gen_rtx_REG (XCmode, FIRST_STACK_REG);
 
   /* Otherwise figure out the entries of the PARALLEL.  */
   for (i = 0; i < n; i++)
@@ -3035,8 +3041,8 @@ ix86_libcall_value (enum machine_mode mo
 	case TFmode:
 	  return gen_rtx_REG (mode, FIRST_SSE_REG);
 	case XFmode:
-	  return gen_rtx_REG (mode, FIRST_FLOAT_REG);
 	case XCmode:
+	  return gen_rtx_REG (mode, FIRST_FLOAT_REG);
 	case TCmode:
 	  return NULL;
 	default:

Attachment: gcc-mainline-x86_64-abi-2.patch
Description: Binary data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]