Patchwork Fix complex argument passing on Solaris 8/9 x86

login
register
mail settings
Submitter Rainer Orth
Date July 12, 2010, 1:41 p.m.
Message ID <yddtyo4stp5.fsf@manam.CeBiTec.Uni-Bielefeld.DE>
Download mbox | patch
Permalink /patch/58612/
State New
Headers show

Comments

Rainer Orth - July 12, 2010, 1:41 p.m.
All complex execution tests were failing on Solaris 8 and 9/x86.
There's a mismatch between caller and callee when passing complex
values.  The following testcase shows the problem:

s8 $ cat complex.c
#include <stdio.h>

int
main (void)
{
  _Complex double cd = 1 + 2 * (__extension__ 1.0iF);
  _Complex double ce = 2 + 3 * (__extension__ 1.0iF);
  _Complex double cr;

  printf ("__real__ cd = %g __imag__ cd = %g\n", __real__ cd, __imag__ cd);
  printf ("__real__ ce = %g __imag__ ce = %g\n", __real__ ce, __imag__ ce);
  cr = cd * ce;
  printf ("__real__ cr = %g __imag__ cr = %g\n", __real__ cr, __imag__ cr);

  return 0;
}
s8 $ gcc -o complex complex.c
s8 $ ./complex
__real__ cd = 1 __imag__ cd = 2
__real__ ce = 2 __imag__ ce = 3
__real__ cr = -8.12265e+152 __imag__ cr = 1.36845e-310
s11 $ gcc -o complex complex.c
s11 $ ./complex
__real__ cd = 1 __imag__ cd = 2
__real__ ce = 2 __imag__ ce = 3
__real__ cr = -4 __imag__ cr = 7

Running complex under gdb reveals that __muldc3 expects its first
argument at 0x8(%ebp) while it actually is at 0xc(%ebp):

S8:

0x080507a1 <__muldc3+1>:     	mov    %esp,%ebp
0x080507a3 <__muldc3+3>:     	push   %ebx
0x080507a4 <__muldc3+4>:     	sub    $0x3c,%esp
0x080507a7 <__muldc3+7>:     	fldl   0x8(%ebp)
0x080507aa <__muldc3+10>:    	fldl   0x10(%ebp)
0x080507ad <__muldc3+13>:    	fldl   0x18(%ebp)
0x080507b0 <__muldc3+16>:    	fldl   0x20(%ebp)

S11:

0x08050da0 <__muldc3+0>:        sub    $0x3c,%esp
0x08050da3 <__muldc3+3>:        fldl   0x44(%esp)
0x08050da7 <__muldc3+7>:        fldl   0x4c(%esp)
0x08050dab <__muldc3+11>:       fldl   0x54(%esp)
0x08050daf <__muldc3+15>:       fldl   0x5c(%esp)

This is due to the fact that while Solaris 10+ uses
ix86_sol10_return_in_memory, Solaris 8 and 9 use the default
return_in_memory_32.  At least if I use the S10 function on Solaris 8/9,
too, everything is fine, and I cannot at all imagine that the Solaris
2/x86 32-bit ABI should have changed incompatibly between Solaris 9 and
10.  To be honest, I don't really understand how this can cause the
observed caller/callee mismatch, but obviously it does.

Right now, return_in_memory_32 and ix86_sol10_return_in_memory are
inconsistent in other areas (like no AVX support, cf. PR target/44452),
so I plan to address this by merging the two functions to avoid such
discrepancies in the future.

Bootstrapped without regressions on Solaris 8 to 11/x86, ok for mainline
(and the 4.4 and 4.5 branches after testing)?

Thanks.
	Rainer


2010-06-19  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	* config/i386/i386.c (ix86_sol10_return_in_memory): Rename to
	ix86_solaris_return_in_memory.
	* config/i386-protos.h: Reflect this.
	* config/i386/vx-common.h (SUBTARGET_RETURN_IN_MEMORY): Likewise.
	* config/i386/sol2-10.h (SUBTARGET_RETURN_IN_MEMORY): Likewise.
	Move ...
	* config/i386/sol2.h (SUBTARGET_RETURN_IN_MEMORY): ... here.
Uros Bizjak - July 12, 2010, 3:18 p.m.
On Mon, 2010-07-12 at 15:41 +0200, Rainer Orth wrote:

> 2010-06-19  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
> 
> 	* config/i386/i386.c (ix86_sol10_return_in_memory): Rename to
> 	ix86_solaris_return_in_memory.
> 	* config/i386-protos.h: Reflect this.
> 	* config/i386/vx-common.h (SUBTARGET_RETURN_IN_MEMORY): Likewise.
> 	* config/i386/sol2-10.h (SUBTARGET_RETURN_IN_MEMORY): Likewise.
> 	Move ...
> 	* config/i386/sol2.h (SUBTARGET_RETURN_IN_MEMORY): ... here.

You can approve this patch yourself, since it only touches solaris
specific parts.

Thanks,
Uros.

Patch

diff -r 2bb0d54482e5 gcc/config/i386/i386-protos.h
--- a/gcc/config/i386/i386-protos.h	Fri Jul 09 12:46:32 2010 +0200
+++ b/gcc/config/i386/i386-protos.h	Fri Jul 09 12:51:21 2010 +0200
@@ -141,7 +141,7 @@ 
 extern bool ix86_function_arg_regno_p (int);
 extern void ix86_asm_output_function_label (FILE *, const char *, tree);
 extern int ix86_function_arg_boundary (enum machine_mode, tree);
-extern bool ix86_sol10_return_in_memory (const_tree,const_tree);
+extern bool ix86_solaris_return_in_memory (const_tree,const_tree);
 extern rtx ix86_force_to_memory (enum machine_mode, rtx);
 extern void ix86_free_from_memory (enum machine_mode);
 extern enum calling_abi ix86_cfun_abi (void);
diff -r 2bb0d54482e5 gcc/config/i386/i386.c
--- a/gcc/config/i386/i386.c	Fri Jul 09 12:46:32 2010 +0200
+++ b/gcc/config/i386/i386.c	Fri Jul 09 12:51:21 2010 +0200
@@ -6871,12 +6871,12 @@ 
 }
 
 /* Return false iff TYPE is returned in memory.  This version is used
-   on Solaris 10.  It is similar to the generic ix86_return_in_memory,
+   on Solaris 2.  It is similar to the generic ix86_return_in_memory,
    but differs notably in that when MMX is available, 8-byte vectors
    are returned in memory, rather than in MMX registers.  */
 
 bool
-ix86_sol10_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
+ix86_solaris_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
 {
   int size;
   enum machine_mode mode = type_natural_mode (type, NULL);
diff -r 2bb0d54482e5 gcc/config/i386/sol2-10.h
--- a/gcc/config/i386/sol2-10.h	Fri Jul 09 12:46:32 2010 +0200
+++ b/gcc/config/i386/sol2-10.h	Fri Jul 09 12:51:21 2010 +0200
@@ -145,7 +145,3 @@ 
 
 #undef TARGET_ASM_NAMED_SECTION
 #define TARGET_ASM_NAMED_SECTION i386_solaris_elf_named_section
-
-#undef SUBTARGET_RETURN_IN_MEMORY
-#define SUBTARGET_RETURN_IN_MEMORY(TYPE, FNTYPE) \
-	ix86_sol10_return_in_memory (TYPE, FNTYPE)
diff -r 2bb0d54482e5 gcc/config/i386/sol2.h
--- a/gcc/config/i386/sol2.h	Fri Jul 09 12:46:32 2010 +0200
+++ b/gcc/config/i386/sol2.h	Fri Jul 09 12:51:21 2010 +0200
@@ -140,6 +140,10 @@ 
 /* Register the Solaris-specific #pragma directives.  */
 #define REGISTER_SUBTARGET_PRAGMAS() solaris_register_pragmas ()
 
+#undef SUBTARGET_RETURN_IN_MEMORY
+#define SUBTARGET_RETURN_IN_MEMORY(TYPE, FNTYPE) \
+	ix86_solaris_return_in_memory (TYPE, FNTYPE)
+
 /* Output a simple call for .init/.fini.  */
 #define ASM_OUTPUT_CALL(FILE, FN)				\
   do								\
diff -r 2bb0d54482e5 gcc/config/i386/vx-common.h
--- a/gcc/config/i386/vx-common.h	Fri Jul 09 12:46:32 2010 +0200
+++ b/gcc/config/i386/vx-common.h	Fri Jul 09 12:51:21 2010 +0200
@@ -1,5 +1,5 @@ 
 /* IA32 VxWorks and VxWorks AE target definitions.
-   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -20,7 +20,7 @@ 
 #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
   asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
 
-/* VxWorks uses the same ABI as Solaris 10.  */
+/* VxWorks uses the same ABI as Solaris 2.  */
 
 #define SUBTARGET_RETURN_IN_MEMORY(TYPE, FNTYPE) \
-	ix86_sol10_return_in_memory (TYPE, FNTYPE)
+	ix86_solaris_return_in_memory (TYPE, FNTYPE)