OSDN Git Service

2004-12-17 Jan Beulich <jbeulich@novell.com>
authorjbeulich <jbeulich@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 17 Dec 2004 08:53:58 +0000 (08:53 +0000)
committerjbeulich <jbeulich@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 17 Dec 2004 08:53:58 +0000 (08:53 +0000)
PR target/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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@92312 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c

index 64724e2..ebf8220 100644 (file)
@@ -1,3 +1,18 @@
+2004-12-17  Jan Beulich  <jbeulich@novell.com>
+
+       PR target/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.
+
 2004-12-17  Steven Bosscher  <stevenb@suse.de>
 
        * tree.c (type_contains_placeholder_1): Always return false
index 6ecf8a4..06c8bb0 100644 (file)
@@ -948,10 +948,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,
@@ -2072,9 +2073,14 @@ merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
       || 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.  */
@@ -2354,8 +2360,10 @@ classify_argument (enum machine_mode mode, tree type,
       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:
@@ -2427,6 +2435,8 @@ examine_argument (enum machine_mode mode, tree type, int in_return,
        if (!in_return)
          return 0;
        break;
+      case X86_64_COMPLEX_X87_CLASS:
+       return in_return ? 2 : 0;
       case X86_64_MEMORY_CLASS:
        abort ();
       }
@@ -2485,6 +2495,7 @@ construct_container (enum machine_mode mode, tree type, int in_return,
       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.  */
@@ -2503,11 +2514,6 @@ construct_container (enum machine_mode mode, tree type, int in_return,
       && (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++)
@@ -3070,8 +3076,8 @@ ix86_libcall_value (enum machine_mode mode)
        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: