+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
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,
|| 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. */
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:
if (!in_return)
return 0;
break;
+ case X86_64_COMPLEX_X87_CLASS:
+ return in_return ? 2 : 0;
case X86_64_MEMORY_CLASS:
abort ();
}
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. */
&& (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++)
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: