+2009-04-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/39678
+ * config/i386/i386.c (classify_argument): Handle SCmode with
+ (bit_offset % 64) != 0.
+
2009-04-09 Sandra Loosemore <sandra@codesourcery.com>
* doc/invoke.texi (Optimize Options): Add cross-reference to
return 2;
case SCmode:
classes[0] = X86_64_SSE_CLASS;
- return 1;
+ if (!(bit_offset % 64))
+ return 1;
+ else
+ {
+ static bool warned;
+
+ if (!warned && warn_psabi)
+ {
+ warned = true;
+ inform (input_location,
+ "The ABI of passing structure with complex float"
+ " member has changed in GCC 4.4");
+ }
+ classes[1] = X86_64_SSESF_CLASS;
+ return 2;
+ }
case DCmode:
classes[0] = X86_64_SSEDF_CLASS;
classes[1] = X86_64_SSEDF_CLASS;
+2009-04-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/39678
+ * g++.dg/torture/pr39678.C: New.
+ * gcc.dg/compat/struct-complex-2.h: Likewise.
+ * gcc.dg/compat/struct-complex-2_main.c: Likewise.
+ * gcc.dg/compat/struct-complex-2_x.c: Likewise.
+ * gcc.dg/compat/struct-complex-2_y.c: Likewise.
+ * gcc.dg/torture/pr39678.c: Likewise.
+ * gcc.target/i386/pr39678.c: Likewise.
+
+ * gcc.dg/compat/struct-complex-1_x.c: Add -Wno-psabi.
+ * gcc.dg/compat/struct-complex-1_y.c: Likewise.
+
+ * gcc.target/x86_64/abi/test_passing_structs.c: Include
+ <complex.h>. Add tests for structure with complex float.
+
2009-04-10 Ben Elliston <bje@au.ibm.com>
Joseph Myers <joseph@codesourcery.com>
--- /dev/null
+/* PR target/39678 */
+/* { dg-do run } */
+/* { dg-options "-Wno-psabi" } */
+struct Y {};
+struct X {
+ struct Y y;
+ __complex__ float val;
+};
+
+struct X __attribute__((noinline))
+foo (float *p)
+{
+ struct X x;
+ __real x.val = p[0];
+ __imag x.val = p[1];
+ return x;
+}
+extern "C" void abort (void);
+float a[2] = { 3., -2. };
+int main()
+{
+ struct X x = foo(a);
+ if (__real x.val != 3. || __imag x.val != -2.)
+ abort ();
+ return 0;
+}
-/* { dg-options "-O" } */
+/* { dg-options "-O -Wno-psabi" } */
+
#ifdef __x86_64__
#include "struct-complex-1.h"
-/* { dg-options "-O" } */
+/* { dg-options "-O -Wno-psabi" } */
#ifdef __x86_64__
#include <stdlib.h>
--- /dev/null
+#include <complex.h>
+
+struct st
+{
+ int s1;
+ float complex x;
+};
+
+typedef struct { float r, i; } _complex;
+
+struct stc
+{
+ int s1;
+ _complex x;
+};
--- /dev/null
+/* { dg-options "-O" } */
+
+#ifdef __x86_64__
+/* Test function argument passing. PR target/39678. */
+
+extern void struct_complex_2_x (void);
+extern void exit (int);
+
+int
+main ()
+{
+ struct_complex_2_x ();
+ exit (0);
+}
+#else
+int
+main ()
+{
+ return 0;
+}
+#endif
--- /dev/null
+/* { dg-options "-O -Wno-psabi" } */
+
+
+#ifdef __x86_64__
+#include "struct-complex-2.h"
+
+struct st st1;
+struct stc st2;
+
+extern void foo ();
+extern void bar ();
+
+int
+struct_complex_2_x ()
+{
+ st1.s1 = 1;
+ __real__ st1.x = 2;
+ __imag__ st1.x = 4;
+ st2.s1 = 1;
+ st2.x.r = 2;
+ st2.x.i = 4;
+ foo (st1);
+ foo (st2);
+ bar (st1);
+ bar (st2);
+ return 0;
+}
+#else
+int dummy_x;
+#endif
--- /dev/null
+/* { dg-options "-O -Wno-psabi" } */
+
+#ifdef __x86_64__
+#include <stdlib.h>
+#include "struct-complex-2.h"
+
+void
+bar(struct st x)
+{
+ if (x.s1 != 1
+ || __real__ x.x != 2 || __imag__ x.x != 4)
+ abort ();
+}
+
+void
+foo(struct stc x)
+{
+ if (x.s1 != 1 || x.x.r != 2 || x.x.i != 4)
+ abort ();
+}
+#else
+int dummy_y;
+#endif
--- /dev/null
+/* PR target/39678 */
+/* { dg-do run } */
+/* { dg-options "-Wno-psabi" } */
+
+struct X {
+ char c;
+ __complex__ float val;
+};
+
+struct X __attribute__((noinline))
+foo (float *p)
+{
+ struct X x;
+ x.c = -3;
+ __real x.val = p[0];
+ __imag x.val = p[1];
+ return x;
+}
+extern void abort (void);
+float a[2] = { 3., -2. };
+int main()
+{
+ struct X x = foo(a);
+ if (x.c != -3 || __real x.val != a[0] || __imag x.val != a[1])
+ abort ();
+ return 0;
+}
--- /dev/null
+/* PR target/39678 */
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2" } */
+
+struct X {
+ char c;
+ __complex__ float val;
+};
+
+struct X
+foo (float *p)
+{ /* { dg-message "note: The ABI of passing structure with complex float member has changed in GCC 4.4" } */
+ struct X x;
+ x.c = -3;
+ __real x.val = p[0];
+ __imag x.val = p[1];
+ return x;
+}
#include "defines.h"
#include "args.h"
+#include <complex.h>
struct IntegerRegisters iregs;
struct FloatRegisters fregs;
check_int_arguments;
}
+struct complex1_struct
+{
+ int c;
+ __complex__ float x;
+};
+
+struct complex1a_struct
+{
+ long l;
+ float f;
+};
+
+struct complex2_struct
+{
+ int c;
+ __complex__ float x;
+ float y;
+};
+
+struct complex2a_struct
+{
+ long l;
+ double d;
+};
+
+void
+check_struct_passing9 (struct complex1_struct is ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+ check_float_arguments;
+}
+
+void
+check_struct_passing10 (struct complex2_struct is ATTRIBUTE_UNUSED)
+{
+ check_int_arguments;
+ check_double_arguments;
+}
+
static struct flex1_struct f1s = { 60, { } };
static struct flex2_struct f2s = { 61, { } };
};
int i;
#endif
+ struct complex1_struct c1s = { 4, ( -13.4 + 3.5*I ) };
+ union
+ {
+ struct complex1_struct c;
+ struct complex1a_struct u;
+ } c1u;
+ struct complex2_struct c2s = { 4, ( -13.4 + 3.5*I ), -34.5 };
+ union
+ {
+ struct complex2_struct c;
+ struct complex2a_struct u;
+ } c2u;
clear_struct_registers;
iregs.I0 = is.i;
clear_int_hardware_registers;
WRAP_CALL (check_struct_passing8)(f2s);
+ clear_struct_registers;
+ c1u.c = c1s;
+ iregs.I0 = c1u.u.l;
+ num_iregs = 1;
+ fregs.xmm0._float [0] = c1u.u.f;
+ num_fregs = 1;
+ clear_int_hardware_registers;
+ clear_float_hardware_registers;
+ WRAP_CALL (check_struct_passing9)(c1s);
+
+ clear_struct_registers;
+ c2u.c = c2s;
+ iregs.I0 = c2u.u.l;
+ num_iregs = 1;
+ fregs.xmm0._double[0] = c2u.u.d;
+ num_fregs = 1;
+ clear_int_hardware_registers;
+ clear_float_hardware_registers;
+ WRAP_CALL (check_struct_passing10)(c2s);
+
return 0;
}