This is the mail archive of the 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] RETURN_IN_MEMORY for cygwin and mingw32


The default i386 definition of RETURN_IN_MEMORY causes incomapatibility with
objects produced by native Win32 MSVC compiler and hence the Win32api.

The following testcase illustrates. With other windows compilers, the
Large_IntAdd and longlongadd produce the same asm code 

With GCC, Large_IntAdd pushes a pointer for the result to the stack and the
function uses this pointer to store the result, while longlongadd returns in
registers edx:eax

This is also a regression from 2.95.3, which produced the same code
for both functions on mingw32 and cygwin targets.

/* large.c */
#ifndef __GNUC__
#  define STDCALL __stdcall
#  define LONGLONG __int64 
#  define STDCALL __attribute__((stdcall))
#  define LONGLONG long long 

typedef union _LARGE_INT
     unsigned low;
     unsigned high;
   } parts;
  LONGLONG quad;     

Large_IntAdd (LARGE_INT i1, LARGE_INT i2)
  LARGE_INT res;
  res.quad = i1.quad + i2.quad;
  return res;

longlongadd  (LONGLONG i1, LONGLONG i2)
{ return i1 + i2; }


gcc -S -O2 -fomit-frame-pointer large.c produces:

	.file	"large.c"
	.p2align 2,,3
.globl _Large_IntAdd@16
	.def	_Large_IntAdd@16;	.scl	2;	.type	32;	.endef
	movl	16(%esp), %edx
	addl	8(%esp), %edx
	movl	20(%esp), %ecx
	movl	4(%esp), %eax
	adcl	12(%esp), %ecx
	movl	%edx, (%eax)
	movl	%ecx, 4(%eax)
	ret	$20
	.p2align 2,,3
.globl _longlongadd@16
	.def	_longlongadd@16;	.scl	2;	.type	32;	.endef
	movl	12(%esp), %eax
	movl	16(%esp), %edx
	addl	4(%esp), %eax
	adcl	8(%esp), %edx
	ret	$16

After adding the following patch to config/i386/cygwin.h (copied from
i386-interix.h), the asm ouput for Large_IntAdd is identical to that of
longlongadd and is consistent with the LARGE_INTEGER functions in the
win32 api.

However, given the recent discussion on RETURN_IN_MEMORY
I'm not sure if this is the "right thing".   Is there a better way?


2003-02-05  Danny Smith  <>

	* config/i386/cygwin.h (RETURN_IN_MEMORY): Override default
	with MSVC compatible definition
Index: cygwin.h
RCS file: /cvs/gcc/gcc/gcc/config/i386/cygwin.h,v
retrieving revision 1.76
diff -c -3 -p -r1.76 cygwin.h
*** cygwin.h	19 Dec 2002 22:00:32 -0000	1.76
--- cygwin.h	5 Feb 2003 22:02:25 -0000
*************** extern int i386_pe_dllimport_name_p PARA
*** 410,415 ****
--- 410,421 ----
+ /* MSVC returns aggregate types of up to 8 bytes via registers. */
+   (TYPE_MODE (TYPE) == BLKmode || \
+      (AGGREGATE_TYPE_P (TYPE) && int_size_in_bytes(TYPE) > 8 ))
  /* No data type wants to be aligned rounder than this.  */
  #define BIGGEST_ALIGNMENT 128 - Yahoo! Movies
- What's on at your local cinema?

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