* PATCH: PR target/34001: Incorrect x86 fastcall behavior @ 2007-11-09 17:32 H.J. Lu 2007-11-09 18:23 ` Richard Guenther 2007-11-16 11:01 ` Ye, Joey 0 siblings, 2 replies; 20+ messages in thread From: H.J. Lu @ 2007-11-09 17:32 UTC (permalink / raw) To: gcc-patches; +Cc: jh, ubizjak From http://msdn2.microsoft.com/en-us/library/6xa169sk(VS.80).aspx "The first two DWORD or smaller arguments are passed in ECX and EDX registers; all other arguments are passed right to left." But it isn't clear if it applies to structure/union. We tested all MS compilers we have and verified that the above doesn't apply to structure/union. To make fastcall compatible with MS compilers, we should only put scalar arguments in ECX and EDX. H.J. --- 2007-11-09 H.J. Lu <hongjiu.lu@intel.com> PR target/34001 * config/i386/i386.c (function_arg_32): Don't pass aggregate arguments in ECX/EDX for fastcall. --- gcc/config/i386/i386.c.fastcall 2007-11-06 19:52:12.000000000 -0800 +++ gcc/config/i386/i386.c 2007-11-08 11:48:38.000000000 -0800 @@ -4233,8 +4233,10 @@ function_arg_32 (CUMULATIVE_ARGS *cum, e int regno = cum->regno; /* Fastcall allocates the first two DWORD (SImode) or - smaller arguments to ECX and EDX. */ - if (cum->fastcall) + smaller arguments to ECX and EDX if it isn't an + aggregate type . */ + if (cum->fastcall + && (!type || !AGGREGATE_TYPE_P (type))) { if (mode == BLKmode || mode == DImode) break; ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-09 17:32 PATCH: PR target/34001: Incorrect x86 fastcall behavior H.J. Lu @ 2007-11-09 18:23 ` Richard Guenther 2007-11-09 21:57 ` H.J. Lu 2007-11-12 1:18 ` Mark Mitchell 2007-11-16 11:01 ` Ye, Joey 1 sibling, 2 replies; 20+ messages in thread From: Richard Guenther @ 2007-11-09 18:23 UTC (permalink / raw) To: H.J. Lu; +Cc: gcc-patches, jh, ubizjak On Nov 9, 2007 6:00 PM, H.J. Lu <hjl@lucon.org> wrote: > From > > http://msdn2.microsoft.com/en-us/library/6xa169sk(VS.80).aspx > > "The first two DWORD or smaller arguments are passed in ECX and EDX > registers; all other arguments are passed right to left." > > But it isn't clear if it applies to structure/union. We tested all MS > compilers we have and verified that the above doesn't apply to > structure/union. To make fastcall compatible with MS compilers, we > should only put scalar arguments in ECX and EDX. This would be an ABI change from previous releases. Regardless of whether we want to do this, an entry for the 4.3 changes document should be added. Richard. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-09 18:23 ` Richard Guenther @ 2007-11-09 21:57 ` H.J. Lu 2007-11-18 13:14 ` Gerald Pfeifer 2007-11-12 1:18 ` Mark Mitchell 1 sibling, 1 reply; 20+ messages in thread From: H.J. Lu @ 2007-11-09 21:57 UTC (permalink / raw) To: Richard Guenther; +Cc: gcc-patches, jh, ubizjak On Fri, Nov 09, 2007 at 06:06:17PM +0100, Richard Guenther wrote: > On Nov 9, 2007 6:00 PM, H.J. Lu <hjl@lucon.org> wrote: > > From > > > > http://msdn2.microsoft.com/en-us/library/6xa169sk(VS.80).aspx > > > > "The first two DWORD or smaller arguments are passed in ECX and EDX > > registers; all other arguments are passed right to left." > > > > But it isn't clear if it applies to structure/union. We tested all MS > > compilers we have and verified that the above doesn't apply to > > structure/union. To make fastcall compatible with MS compilers, we > > should only put scalar arguments in ECX and EDX. > > This would be an ABI change from previous releases. Regardless of > whether we want to do this, an entry for the 4.3 changes document > should be added. > This is for gcc-4.3/changes.html. H.J. ---- Index: gcc-4.3/changes.html =================================================================== RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-4.3/changes.html,v retrieving revision 1.82 diff -r1.82 changes.html 40a41,43 > <li><code>Fastcall</code> for i386 has been changed not to pass > aggregate arguments in register, following Microsoft compilers.</li> > ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-09 21:57 ` H.J. Lu @ 2007-11-18 13:14 ` Gerald Pfeifer 2007-11-18 15:04 ` H.J. Lu 0 siblings, 1 reply; 20+ messages in thread From: Gerald Pfeifer @ 2007-11-18 13:14 UTC (permalink / raw) To: H.J. Lu; +Cc: Richard Guenther, gcc-patches, jh, ubizjak On Fri, 9 Nov 2007, H.J. Lu wrote: >> This would be an ABI change from previous releases. Regardless of >> whether we want to do this, an entry for the 4.3 changes document >> should be added. > This is for gcc-4.3/changes.html. The documentation change looks good, thanks. You may want to write "registers" instead of "registers", I believe. Gerald ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-18 13:14 ` Gerald Pfeifer @ 2007-11-18 15:04 ` H.J. Lu 2007-11-18 15:53 ` Gerald Pfeifer 0 siblings, 1 reply; 20+ messages in thread From: H.J. Lu @ 2007-11-18 15:04 UTC (permalink / raw) To: Gerald Pfeifer; +Cc: Richard Guenther, gcc-patches, jh, ubizjak On Sat, Nov 17, 2007 at 10:30:09PM +0100, Gerald Pfeifer wrote: > On Fri, 9 Nov 2007, H.J. Lu wrote: > >> This would be an ABI change from previous releases. Regardless of > >> whether we want to do this, an entry for the 4.3 changes document > >> should be added. > > This is for gcc-4.3/changes.html. > > The documentation change looks good, thanks. You may want to write > "registers" instead of "registers", I believe. > Like this? H.J. ---- Index: changes.html =================================================================== RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-4.3/changes.html,v retrieving revision 1.82 diff -u -p -r1.82 changes.html --- changes.html 2 Nov 2007 07:27:23 -0000 1.82 +++ changes.html 18 Nov 2007 07:57:47 -0000 @@ -38,6 +38,9 @@ <li>The i386 <code>-msvr3-shlib</code> option has been removed since it is no longer used.</li> + <li><code>Fastcall</code> for i386 has been changed not to pass + aggregate arguments in registers, following Microsoft compilers.</li> + <li>Support for the AOF assembler has been removed from the ARM back end; this affects only the targets <code>arm-semi-aof</code> and <code>armel-semi-aof</code>, which are no longer recognized. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-18 15:04 ` H.J. Lu @ 2007-11-18 15:53 ` Gerald Pfeifer 0 siblings, 0 replies; 20+ messages in thread From: Gerald Pfeifer @ 2007-11-18 15:53 UTC (permalink / raw) To: H.J. Lu; +Cc: Richard Guenther, gcc-patches, jh, ubizjak On Sat, 17 Nov 2007, H.J. Lu wrote: > Like this? Yup. Gerald ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-09 18:23 ` Richard Guenther 2007-11-09 21:57 ` H.J. Lu @ 2007-11-12 1:18 ` Mark Mitchell 2007-11-12 8:00 ` H.J. Lu 1 sibling, 1 reply; 20+ messages in thread From: Mark Mitchell @ 2007-11-12 1:18 UTC (permalink / raw) To: Richard Guenther; +Cc: H.J. Lu, gcc-patches, jh, ubizjak Richard Guenther wrote: >> But it isn't clear if it applies to structure/union. We tested all MS >> compilers we have and verified that the above doesn't apply to >> structure/union. To make fastcall compatible with MS compilers, we >> should only put scalar arguments in ECX and EDX. > > This would be an ABI change from previous releases. Regardless of > whether we want to do this, an entry for the 4.3 changes document > should be added. I would suggest that this be done only on Windows, if it's for MS compatibility. Unless the code before is actually broken, why should make a incompatible ABI change? At least, we should add a switch. -- Mark Mitchell CodeSourcery mark@codesourcery.com (650) 331-3385 x713 ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-12 1:18 ` Mark Mitchell @ 2007-11-12 8:00 ` H.J. Lu 2007-11-13 10:56 ` Mark Mitchell 0 siblings, 1 reply; 20+ messages in thread From: H.J. Lu @ 2007-11-12 8:00 UTC (permalink / raw) To: Mark Mitchell; +Cc: Richard Guenther, gcc-patches, jh, ubizjak On Sun, Nov 11, 2007 at 03:21:08PM -0800, Mark Mitchell wrote: > Richard Guenther wrote: > > >> But it isn't clear if it applies to structure/union. We tested all MS > >> compilers we have and verified that the above doesn't apply to > >> structure/union. To make fastcall compatible with MS compilers, we > >> should only put scalar arguments in ECX and EDX. > > > > This would be an ABI change from previous releases. Regardless of > > whether we want to do this, an entry for the 4.3 changes document > > should be added. > > I would suggest that this be done only on Windows, if it's for MS > compatibility. Unless the code before is actually broken, why should > make a incompatible ABI change? At least, we should add a switch. From "info gcc", `fastcall' On the Intel 386, the `fastcall' attribute causes the compiler to pass the first argument (if of integral type) in the register ECX ^^^^^^^^^^^^^^^^^^^ and the second argument (if of integral type) in the register EDX. ^^^^^^^^^^^^^^^^^^^ Subsequent and other typed arguments are passed on the stack. The called function will pop the arguments off the stack. If the number of arguments is variable all arguments are pushed on the stack. It looks like gcc document follows MS compiler and we didn't implement it correctly. If we want to add a switch, the default should follow gcc document. H.J. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-12 8:00 ` H.J. Lu @ 2007-11-13 10:56 ` Mark Mitchell 2007-11-13 16:19 ` H.J. Lu 0 siblings, 1 reply; 20+ messages in thread From: Mark Mitchell @ 2007-11-13 10:56 UTC (permalink / raw) To: H.J. Lu; +Cc: Richard Guenther, gcc-patches, jh, ubizjak H.J. Lu wrote: >> I would suggest that this be done only on Windows, if it's for MS >> compatibility. Unless the code before is actually broken, why should >> make a incompatible ABI change? At least, we should add a switch. > It looks like gcc document follows MS compiler and we didn't implement > it correctly. If we want to add a switch, the default should follow > gcc document. Why? I don't have a strong opinion, and, in any case, this issue is something for the x86 maintainers to determine. But what's the virtue in changing the GCC ABI for GNU/Linux (or any other non-Windows OS) applications? Especially in a way that makes it use a less efficient calling sequence? -- Mark Mitchell CodeSourcery mark@codesourcery.com (650) 331-3385 x713 ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-13 10:56 ` Mark Mitchell @ 2007-11-13 16:19 ` H.J. Lu 2007-11-13 17:09 ` Mark Mitchell 0 siblings, 1 reply; 20+ messages in thread From: H.J. Lu @ 2007-11-13 16:19 UTC (permalink / raw) To: Mark Mitchell; +Cc: Richard Guenther, gcc-patches, jh, ubizjak On Mon, Nov 12, 2007 at 10:48:20PM -0800, Mark Mitchell wrote: > H.J. Lu wrote: > > >> I would suggest that this be done only on Windows, if it's for MS > >> compatibility. Unless the code before is actually broken, why should > >> make a incompatible ABI change? At least, we should add a switch. > > > It looks like gcc document follows MS compiler and we didn't implement > > it correctly. If we want to add a switch, the default should follow > > gcc document. > > Why? I don't have a strong opinion, and, in any case, this issue is > something for the x86 maintainers to determine. But what's the virtue > in changing the GCC ABI for GNU/Linux (or any other non-Windows OS) > applications? Especially in a way that makes it use a less efficient > calling sequence? > stdcall is a Windows feature. However, using different calling conversions on Windows and non-Windows will make OS-independent assembly code hard to write. Given that we have been doing the wrong thing on Windows wthout noticing anything up to now, make it right shouldn't cause more trouble. We can add a warning when we detect the ABI correction. BTW, on Linux, we use regparm, which is more efficient than stdcall. H.J. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-13 16:19 ` H.J. Lu @ 2007-11-13 17:09 ` Mark Mitchell 2007-11-13 20:20 ` H.J. Lu 0 siblings, 1 reply; 20+ messages in thread From: Mark Mitchell @ 2007-11-13 17:09 UTC (permalink / raw) To: H.J. Lu; +Cc: Richard Guenther, gcc-patches, jh, ubizjak H.J. Lu wrote: > stdcall is a Windows feature. However, using different calling > conversions on Windows and non-Windows will make OS-independent > assembly code hard to write. Given that we have been doing the wrong > thing on Windows wthout noticing anything up to now, make it right > shouldn't cause more trouble. We can add a warning when we detect the > ABI correction. > > BTW, on Linux, we use regparm, which is more efficient than stdcall. Like I said, I think this is for the x86 maintainers to decide. But, I think that breaking backwards compatibility, especially at the binary level, is something we ought to think about very carefully. -- Mark Mitchell CodeSourcery mark@codesourcery.com (650) 331-3385 x713 ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-13 17:09 ` Mark Mitchell @ 2007-11-13 20:20 ` H.J. Lu 2007-11-27 7:45 ` H.J. Lu 0 siblings, 1 reply; 20+ messages in thread From: H.J. Lu @ 2007-11-13 20:20 UTC (permalink / raw) To: Mark Mitchell; +Cc: Richard Guenther, gcc-patches, jh, ubizjak On Tue, Nov 13, 2007 at 08:28:55AM -0800, Mark Mitchell wrote: > H.J. Lu wrote: > > > stdcall is a Windows feature. However, using different calling > > conversions on Windows and non-Windows will make OS-independent > > assembly code hard to write. Given that we have been doing the wrong > > thing on Windows wthout noticing anything up to now, make it right > > shouldn't cause more trouble. We can add a warning when we detect the > > ABI correction. > > > > BTW, on Linux, we use regparm, which is more efficient than stdcall. > > Like I said, I think this is for the x86 maintainers to decide. But, I > think that breaking backwards compatibility, especially at the binary > level, is something we ought to think about very carefully. > It depends on how you see it. To me, the current behavior is binary incompatible with MS compilers, for which this feature is designed for. My patch makes it binary incompatible with older gcc, but makes the new gcc binary compatible with all assembly codes and object files which conform to gcc document as well as MS compilers. H.J. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-13 20:20 ` H.J. Lu @ 2007-11-27 7:45 ` H.J. Lu 2007-11-27 9:32 ` Uros Bizjak 0 siblings, 1 reply; 20+ messages in thread From: H.J. Lu @ 2007-11-27 7:45 UTC (permalink / raw) To: Mark Mitchell; +Cc: Richard Guenther, gcc-patches, jh, ubizjak On Tue, Nov 13, 2007 at 10:36:24AM -0800, H.J. Lu wrote: > On Tue, Nov 13, 2007 at 08:28:55AM -0800, Mark Mitchell wrote: > > H.J. Lu wrote: > > > > > stdcall is a Windows feature. However, using different calling > > > conversions on Windows and non-Windows will make OS-independent > > > assembly code hard to write. Given that we have been doing the wrong > > > thing on Windows wthout noticing anything up to now, make it right > > > shouldn't cause more trouble. We can add a warning when we detect the > > > ABI correction. > > > > > > BTW, on Linux, we use regparm, which is more efficient than stdcall. > > > > Like I said, I think this is for the x86 maintainers to decide. But, I > > think that breaking backwards compatibility, especially at the binary > > level, is something we ought to think about very carefully. > > > > It depends on how you see it. To me, the current behavior is binary > incompatible with MS compilers, for which this feature is designed > for. My patch makes it binary incompatible with older gcc, but > makes the new gcc binary compatible with all assembly codes and > object files which conform to gcc document as well as MS compilers. > We have changed the i386 fastcall abi between gcc 3.4 and gcc 4.0: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34001#c7 I think we should fix it for gcc 4.3. Jan, Uros, can you take a look at it? Thanks. H.J. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-27 7:45 ` H.J. Lu @ 2007-11-27 9:32 ` Uros Bizjak 2007-11-28 0:45 ` Jan Hubicka 0 siblings, 1 reply; 20+ messages in thread From: Uros Bizjak @ 2007-11-27 9:32 UTC (permalink / raw) To: H.J. Lu; +Cc: Mark Mitchell, Richard Guenther, gcc-patches, jh On Nov 27, 2007 3:41 AM, H.J. Lu <hjl@lucon.org> wrote: > > It depends on how you see it. To me, the current behavior is binary > > incompatible with MS compilers, for which this feature is designed > > for. My patch makes it binary incompatible with older gcc, but > > makes the new gcc binary compatible with all assembly codes and > > object files which conform to gcc document as well as MS compilers. > > > > We have changed the i386 fastcall abi between gcc 3.4 and gcc 4.0: > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34001#c7 > > I think we should fix it for gcc 4.3. Jan, Uros, can you take a look > at it? Jan is an expert for ABI issues, so IMO he should have the last word. Uros. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-27 9:32 ` Uros Bizjak @ 2007-11-28 0:45 ` Jan Hubicka 2007-11-28 10:38 ` H.J. Lu 0 siblings, 1 reply; 20+ messages in thread From: Jan Hubicka @ 2007-11-28 0:45 UTC (permalink / raw) To: Uros Bizjak; +Cc: H.J. Lu, Mark Mitchell, Richard Guenther, gcc-patches, jh > On Nov 27, 2007 3:41 AM, H.J. Lu <hjl@lucon.org> wrote: > > > > It depends on how you see it. To me, the current behavior is binary > > > incompatible with MS compilers, for which this feature is designed > > > for. My patch makes it binary incompatible with older gcc, but > > > makes the new gcc binary compatible with all assembly codes and > > > object files which conform to gcc document as well as MS compilers. > > > > > > > We have changed the i386 fastcall abi between gcc 3.4 and gcc 4.0: > > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34001#c7 > > > > I think we should fix it for gcc 4.3. Jan, Uros, can you take a look > > at it? > > Jan is an expert for ABI issues, so IMO he should have the last word. I was participating in the x86-64 ABI decisions so I can give some insight there, but i386 well predates me :) My understanding is that fastcall was invented for compatibility with "standard" conventions used by MS and Watcom compilers, so we should follow what they do (ie not pass aggregates in registers) more if it actually is documented in our texinfo. I don't like much the idea of changing behaviour for Windows targets only, it seems like good trap for code trying to be portable across both. So I personally would vote for changing default behaviour and documenting it in NEWS document as suggested. I would not expect much fallout - it is uncommon to pass little aggregates to assembly code and using fastcall in library API would be quite silly. Honza > > Uros. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-28 0:45 ` Jan Hubicka @ 2007-11-28 10:38 ` H.J. Lu 0 siblings, 0 replies; 20+ messages in thread From: H.J. Lu @ 2007-11-28 10:38 UTC (permalink / raw) To: Jan Hubicka; +Cc: Uros Bizjak, Mark Mitchell, Richard Guenther, gcc-patches On Tue, Nov 27, 2007 at 11:43:01PM +0100, Jan Hubicka wrote: > > On Nov 27, 2007 3:41 AM, H.J. Lu <hjl@lucon.org> wrote: > > > > > > It depends on how you see it. To me, the current behavior is binary > > > > incompatible with MS compilers, for which this feature is designed > > > > for. My patch makes it binary incompatible with older gcc, but > > > > makes the new gcc binary compatible with all assembly codes and > > > > object files which conform to gcc document as well as MS compilers. > > > > > > > > > > We have changed the i386 fastcall abi between gcc 3.4 and gcc 4.0: > > > > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34001#c7 > > > > > > I think we should fix it for gcc 4.3. Jan, Uros, can you take a look > > > at it? > > > > Jan is an expert for ABI issues, so IMO he should have the last word. > > I was participating in the x86-64 ABI decisions so I can give some > insight there, but i386 well predates me :) > > My understanding is that fastcall was invented for compatibility with > "standard" conventions used by MS and Watcom compilers, so we should > follow what they do (ie not pass aggregates in registers) more if it > actually is documented in our texinfo. > > I don't like much the idea of changing behaviour for Windows targets > only, it seems like good trap for code trying to be portable across > both. So I personally would vote for changing default behaviour and > documenting it in NEWS document as suggested. > > I would not expect much fallout - it is uncommon to pass little > aggregates to assembly code and using fastcall in library API would be > quite silly. > > Honza This is the change I checked in. I also checked in the change for gcc 4.3 change document. H.J. --- 2007-11-27 H.J. Lu <hongjiu.lu@intel.com> Joey Ye <joey.ye@intel.com> PR target/34001 * config/i386/i386.c (function_arg_32): Don't pass aggregate arguments in ECX/EDX for fastcall. Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 130486) +++ config/i386/i386.c (working copy) @@ -4253,10 +4253,13 @@ function_arg_32 (CUMULATIVE_ARGS *cum, e int regno = cum->regno; /* Fastcall allocates the first two DWORD (SImode) or - smaller arguments to ECX and EDX. */ + smaller arguments to ECX and EDX if it isn't an + aggregate type . */ if (cum->fastcall) { - if (mode == BLKmode || mode == DImode) + if (mode == BLKmode + || mode == DImode + || (type && AGGREGATE_TYPE_P (type))) break; /* ECX not EAX is the first allocated register. */ ^ permalink raw reply [flat|nested] 20+ messages in thread
* RE: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-09 17:32 PATCH: PR target/34001: Incorrect x86 fastcall behavior H.J. Lu 2007-11-09 18:23 ` Richard Guenther @ 2007-11-16 11:01 ` Ye, Joey 2007-11-16 11:07 ` H.J. Lu 1 sibling, 1 reply; 20+ messages in thread From: Ye, Joey @ 2007-11-16 11:01 UTC (permalink / raw) To: H.J. Lu; +Cc: jh, ubizjak, gcc-patches HJ, You patch has a minor problem that fastcall will pass non-scalar integer parameter in EAX/ECX/EDX, which is still imcompatible to MS fastcall. MSVC pass parameter on stack unless it is scalar integer less equal to 32 bits. With this patch GCC fastcall passes first parameter in EAX when it is not a scalar integer less equal to 32 bits. Check following example and review the patch fixing it: #define MAGIC 123 typedef struct { char c1, c2; } a_type; int #ifdef _GNU_C_ __attribute__ ((fastcall)) #else __fastcall #endif foo(a_type a, int b, int c, int d) { return a.c1 + b + c + d; } int main() { a_type a; a.c1=MAGIC; return foo(a,0,1,2) == MAGIC + 1 ? 0 : 1; } MSVC 6 and 7: @foo@16: 00000000: 55 push ebp 00000001: 8B EC mov ebp,esp 00000003: 83 EC 08 sub esp,8 00000006: 89 55 F8 mov dword ptr [ebp-8],edx ;arg3 in edx 00000009: 89 4D FC mov dword ptr [ebp-4],ecx ;arg2 in ecx 0000000C: 0F BE 45 08 movsx eax,byte ptr [ebp+8] ;arg1 in stack 00000010: 03 45 FC add eax,dword ptr [ebp-4] 00000013: 03 45 F8 add eax,dword ptr [ebp-8] 00000016: 03 45 0C add eax,dword ptr [ebp+0Ch] ;arg4 in stack 00000019: 8B E5 mov esp,ebp 0000001B: 5D pop ebp 0000001C: C2 08 00 ret 8 _main: 0000001F: 55 push ebp 00000020: 8B EC mov ebp,esp 00000022: 51 push ecx 00000023: C6 45 FC 7B mov byte ptr [ebp-4],7Bh 00000027: 6A 02 push 2 ;param4 in stack 00000029: BA 01 00 00 00 mov edx,1 ;param3 in edx 0000002E: 33 C9 xor ecx,ecx ;param2 in ecx 00000030: 66 8B 45 FC mov ax,word ptr [ebp-4] ;param1 in eax 00000034: 50 push eax 00000035: E8 00 00 00 00 call 0000003A 0000003A: 33 C9 xor ecx,ecx 0000003C: 83 F8 7C cmp eax,7Ch 0000003F: 0F 95 C1 setne cl 00000042: 8B C1 mov eax,ecx 00000044: 8B E5 mov esp,ebp 00000046: 5D pop ebp 00000047: C3 ret GCC 4.3 with your fastcall patch: .file "f.c" .text .globl foo .type foo, @function foo: pushl %ebp movl %esp, %ebp subl $8, %esp movw %ax, -2(%ebp) ;arg1 in eax movl %edx, -8(%ebp) ;arg2 in edx movzbl -2(%ebp), %eax movsbl %al,%eax addl -8(%ebp), %eax addl 8(%ebp), %eax ;arg3 in stack addl 12(%ebp), %eax ;arg4 in stack leave ret $8 .size foo, .-foo .globl main .type main, @function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $24, %esp movb $123, -6(%ebp) movzwl -6(%ebp), %eax ; param1 in eax movl $2, 4(%esp) ; param4 in stack movl $1, (%esp) ; param3 in stack movl $0, %edx ; param2 in edx call foo subl $8, %esp cmpl $124, %eax setne %al movzbl %al, %eax movl -4(%ebp), %ecx leave leal -4(%ecx), %esp ret .size main, .-main .ident "GCC: (GNU) 4.3.0 20071104 (experimental) [trunk revision 129880]" .section .note.GNU-stack,"",@progbits Here is a patch to fix it: Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c (revision 129880) +++ gcc/config/i386/i386.c (working copy) @@ -4229,9 +4229,12 @@ int regno = cum->regno; /* Fastcall allocates the first two DWORD (SImode) or - smaller arguments to ECX and EDX. */ + smaller arguments to ECX and EDX if it isn't an + aggregate type . */ if (cum->fastcall) { + if (type && AGGREGATE_TYPE_P (type)) + break; if (mode == BLKmode || mode == DImode) break; With this patch generated code will be: .file "f.c" .text .globl foo .type foo, @function foo: pushl %ebp movl %esp, %ebp subl $4, %esp movl %edx, -4(%ebp) movzbl 8(%ebp), %eax movsbl %al,%eax addl -4(%ebp), %eax addl 12(%ebp), %eax addl 16(%ebp), %eax leave ret $12 .size foo, .-foo .globl main .type main, @function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $28, %esp movb $123, -6(%ebp) movl $2, 8(%esp) movl $1, 4(%esp) movzwl -6(%ebp), %eax movw %ax, (%esp) movl $0, %edx call foo subl $12, %esp cmpl $124, %eax setne %al movzbl %al, %eax movl -4(%ebp), %ecx leave leal -4(%ecx), %esp ret .size main, .-main .ident "GCC: (GNU) 4.3.0 20071104 (experimental) [trunk revision 129880]" .section .note.GNU-stack,"",@progbits Thanks - Joey -----Original Message----- From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-owner@gcc.gnu.org] On Behalf Of H.J. Lu Sent: 2007年11月10日 1:01 To: gcc-patches@gcc.gnu.org Cc: jh@suse.cz; ubizjak@gmail.com Subject: PATCH: PR target/34001: Incorrect x86 fastcall behavior From http://msdn2.microsoft.com/en-us/library/6xa169sk(VS.80).aspx "The first two DWORD or smaller arguments are passed in ECX and EDX registers; all other arguments are passed right to left." But it isn't clear if it applies to structure/union. We tested all MS compilers we have and verified that the above doesn't apply to structure/union. To make fastcall compatible with MS compilers, we should only put scalar arguments in ECX and EDX. H.J. --- 2007-11-09 H.J. Lu <hongjiu.lu@intel.com> PR target/34001 * config/i386/i386.c (function_arg_32): Don't pass aggregate arguments in ECX/EDX for fastcall. --- gcc/config/i386/i386.c.fastcall 2007-11-06 19:52:12.000000000 -0800 +++ gcc/config/i386/i386.c 2007-11-08 11:48:38.000000000 -0800 @@ -4233,8 +4233,10 @@ function_arg_32 (CUMULATIVE_ARGS *cum, e int regno = cum->regno; /* Fastcall allocates the first two DWORD (SImode) or - smaller arguments to ECX and EDX. */ - if (cum->fastcall) + smaller arguments to ECX and EDX if it isn't an + aggregate type . */ + if (cum->fastcall + && (!type || !AGGREGATE_TYPE_P (type))) { if (mode == BLKmode || mode == DImode) break; ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-16 11:01 ` Ye, Joey @ 2007-11-16 11:07 ` H.J. Lu 2007-11-16 16:27 ` H.J. Lu 0 siblings, 1 reply; 20+ messages in thread From: H.J. Lu @ 2007-11-16 11:07 UTC (permalink / raw) To: Ye, Joey; +Cc: jh, ubizjak, gcc-patches On Fri, Nov 16, 2007 at 12:35:47PM +0800, Ye, Joey wrote: > HJ, > > You patch has a minor problem that fastcall will pass non-scalar integer parameter in EAX/ECX/EDX, which is still imcompatible to MS fastcall. MSVC pass parameter on stack unless it is scalar integer less equal to 32 bits. > > With this patch GCC fastcall passes first parameter in EAX when it is not a scalar integer less equal to 32 bits. Check following example and review the patch fixing it: > > Here is a patch to fix it: > Index: gcc/config/i386/i386.c > =================================================================== > --- gcc/config/i386/i386.c (revision 129880) > +++ gcc/config/i386/i386.c (working copy) > @@ -4229,9 +4229,12 @@ > int regno = cum->regno; > > /* Fastcall allocates the first two DWORD (SImode) or > - smaller arguments to ECX and EDX. */ > + smaller arguments to ECX and EDX if it isn't an > + aggregate type . */ > if (cum->fastcall) > { > + if (type && AGGREGATE_TYPE_P (type)) > + break; > if (mode == BLKmode || mode == DImode) > break; > Yes, this version is correct. Thanks. H.J. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior 2007-11-16 11:07 ` H.J. Lu @ 2007-11-16 16:27 ` H.J. Lu 0 siblings, 0 replies; 20+ messages in thread From: H.J. Lu @ 2007-11-16 16:27 UTC (permalink / raw) To: Ye, Joey; +Cc: jh, ubizjak, gcc-patches On Thu, Nov 15, 2007 at 08:51:02PM -0800, H.J. Lu wrote: > On Fri, Nov 16, 2007 at 12:35:47PM +0800, Ye, Joey wrote: > > HJ, > > > > You patch has a minor problem that fastcall will pass non-scalar integer parameter in EAX/ECX/EDX, which is still imcompatible to MS fastcall. MSVC pass parameter on stack unless it is scalar integer less equal to 32 bits. > > > > With this patch GCC fastcall passes first parameter in EAX when it is not a scalar integer less equal to 32 bits. Check following example and review the patch fixing it: > > > > Here is a patch to fix it: > > Index: gcc/config/i386/i386.c > > =================================================================== > > --- gcc/config/i386/i386.c (revision 129880) > > +++ gcc/config/i386/i386.c (working copy) > > @@ -4229,9 +4229,12 @@ > > int regno = cum->regno; > > > > /* Fastcall allocates the first two DWORD (SImode) or > > - smaller arguments to ECX and EDX. */ > > + smaller arguments to ECX and EDX if it isn't an > > + aggregate type . */ > > if (cum->fastcall) > > { > > + if (type && AGGREGATE_TYPE_P (type)) > > + break; > > if (mode == BLKmode || mode == DImode) > > break; > > > > Yes, this version is correct. Thanks. > > Here is an equivalent patch. H.J. ---- 2007-11-15 H.J. Lu <hongjiu.lu@intel.com> Joey Ye <joey.ye@intel.com> PR target/34001 * config/i386/i386.c (function_arg_32): Don't pass aggregate arguments in ECX/EDX for fastcall. --- gcc/config/i386/i386.c.fastcall 2007-11-16 05:41:46.000000000 -0800 +++ gcc/config/i386/i386.c 2007-11-16 05:46:43.000000000 -0800 @@ -4257,10 +4257,12 @@ function_arg_32 (CUMULATIVE_ARGS *cum, e int regno = cum->regno; /* Fastcall allocates the first two DWORD (SImode) or - smaller arguments to ECX and EDX. */ + smaller arguments to ECX and EDX if it isn't an + aggregate type . */ if (cum->fastcall) { - if (mode == BLKmode || mode == DImode) + if (mode == BLKmode || mode == DImode + || (type && AGGREGATE_TYPE_P (type))) break; /* ECX not EAX is the first allocated register. */ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: PATCH: PR target/34001: Incorrect x86 fastcall behavior
@ 2007-11-13 14:14 Ross Ridge
0 siblings, 0 replies; 20+ messages in thread
From: Ross Ridge @ 2007-11-13 14:14 UTC (permalink / raw)
To: gcc-patches
Mark Mitchell writes:
> Why? I don't have a strong opinion, and, in any case, this issue is
> something for the x86 maintainers to determine. But what's the virtue
> in changing the GCC ABI for GNU/Linux (or any other non-Windows OS)
> applications? Especially in a way that makes it use a less efficient
> calling sequence?
I can only see two reasons why fastcall would've been used on non-Windows
OS. One is for compatibility with assembler or object code that was
originally written for Windows. The other is in code that should've
used the more efficient regparam(3) attribute. Changing the behavior
of fastcall to be compatible with Microsoft's compiler shouldn't cause
problems in the first case. In the second case I think code that would
break would be very rare, probably non-existant. Code like this would
have to use the fastcall attribute in a function that both takes a small
aggregate by value and could be called from a function compiled with a
different version of GCC.
Ross Ridge
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2007-11-28 1:24 UTC | newest] Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-11-09 17:32 PATCH: PR target/34001: Incorrect x86 fastcall behavior H.J. Lu 2007-11-09 18:23 ` Richard Guenther 2007-11-09 21:57 ` H.J. Lu 2007-11-18 13:14 ` Gerald Pfeifer 2007-11-18 15:04 ` H.J. Lu 2007-11-18 15:53 ` Gerald Pfeifer 2007-11-12 1:18 ` Mark Mitchell 2007-11-12 8:00 ` H.J. Lu 2007-11-13 10:56 ` Mark Mitchell 2007-11-13 16:19 ` H.J. Lu 2007-11-13 17:09 ` Mark Mitchell 2007-11-13 20:20 ` H.J. Lu 2007-11-27 7:45 ` H.J. Lu 2007-11-27 9:32 ` Uros Bizjak 2007-11-28 0:45 ` Jan Hubicka 2007-11-28 10:38 ` H.J. Lu 2007-11-16 11:01 ` Ye, Joey 2007-11-16 11:07 ` H.J. Lu 2007-11-16 16:27 ` H.J. Lu 2007-11-13 14:14 Ross Ridge
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).