From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25122 invoked by alias); 2 Dec 2002 21:25:36 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 25098 invoked from network); 2 Dec 2002 21:25:35 -0000 Received: from unknown (HELO cicero1.cybercity.dk) (212.242.40.4) by sources.redhat.com with SMTP; 2 Dec 2002 21:25:35 -0000 Received: from user5.cybercity.dk (fxp0.user5.ip.cybercity.dk [212.242.41.51]) by cicero1.cybercity.dk (Postfix) with ESMTP id 7E66C15FD68; Mon, 2 Dec 2002 22:25:33 +0100 (CET) Received: from CHLAPTOP (port57.ds1-trg.adsl.cybercity.dk [212.242.245.122]) by user5.cybercity.dk (Postfix) with ESMTP id 43FF1147; Mon, 2 Dec 2002 22:25:31 +0100 (CET) From: "Casper Hornstrup" To: "'Richard Henderson'" Cc: Subject: RE: [PATCH] Fastcall support on cygwin and mingw targets Date: Mon, 02 Dec 2002 13:25:00 -0000 Message-ID: <004a01c29a49$53e398b0$0300000a@csiteoffice.csite.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_004B_01C29A51.B5AB0DF0" X-Priority: 3 (Normal) X-MSMail-Priority: Normal In-Reply-To: <20021125233927.GO25134@redhat.com> X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106 Importance: Normal X-SW-Source: 2002-12/txt/msg00137.txt.bz2 This is a multi-part message in MIME format. ------=_NextPart_000_004B_01C29A51.B5AB0DF0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-length: 4121 > -----Original Message----- > From: gcc-patches-owner@gcc.gnu.org > [mailto:gcc-patches-owner@gcc.gnu.org] On Behalf Of Richard Henderson > Sent: 26. november 2002 00:39 > To: Casper Hornstrup > Cc: gcc-patches@gcc.gnu.org > Subject: Re: [PATCH] Fastcall support on cygwin and mingw targets > > > First, please avoid putting the patch into a tarball. It > just makes it harder to review. > > On Thu, Nov 14, 2002 at 05:28:25PM +0100, Casper Hornstrup wrote: > > ! /* Output a reference to a label. Fastcall symbols are > prefixed with @, > > ! whereas symbols for functions using other calling > conventions don't > > ! have a prefix (unless they are marked dllimport or dllexport). > > ! Internally, @ is used as a prefix for symbols that are > marked dllimport > > ! or dllexport so internally the prefix + is used for > fastcall symbols. */ > > #undef ASM_OUTPUT_LABELREF > > ! #define ASM_OUTPUT_LABELREF(STREAM, NAME) \ > > (1) This is now so big it should be moved to an external function. > (2) The frobbing of @ and + is confusing. It is not *required* > that @ be used for dllimport/export. I'd prefer to first see > a patch that replaced the literal @ with a macro; then the macro > can expand to something other than @, and your life is happier. > > > + The @code{fastcall} calling convention exists in Windows > for Intel > > + processors only. > > This is false. It exists on all ia32 targets. The name > mangling only happens on Windows, but that is not required > for the calling convention to be in effect. > > > > r~ > I have fixed these issues. Patch attached. gcc/testsuite/ChangeLog 2002-11-13 Casper S. Hornstrup * gcc.c-torture/compile/20021110-1.c: New test. * gcc.c-torture/compile/20021110-1.x: Likewise. * gcc.c-torture/compile/20021110-2.c: Likewise. * gcc.c-torture/compile/20021110-2.x: Likewise. * gcc.c-torture/compile/20021110-3.c: Likewise. * gcc.c-torture/compile/20021110-3.x: Likewise. * gcc.c-torture/compile/20021110-4.c: Likewise. * gcc.c-torture/compile/20021110-4.x: Likewise. gcc/ChangeLog 2002-11-13 Casper S. Hornstrup * config/i386/i386.c (ix86_handle_cdecl_attribute): Check for attributes incompatible with fastcall attribute. (ix86_handle_regparm_attribute): Likewise. 2002-11-13 Danny Smith * config/i386/i386.c (ix86_comp_type_attributes): Check for mismatched fastcall types. 2002-11-13 Eric Kohl * config/i386/cygwin.h (TARGET_OS_CPP_BUILTINS): Add fastcall attributes. (ASM_OUTPUT_LABELREF): Define as i386_pe_output_labelref. * config/i386/i386-protos.h (i386_pe_output_labelref): Declare. * config/i386/winnt.c (i386_pe_mark_dllimport). Convert internal fastcall decoration to MS-compatible decoration. Add __imp_ prefix in i386_pe_output_labelref rather than here. * config/i386/i386.c (ix86_attribute_table): Accept 'fastcall' as a valid attribute. (ix86_return_pops_args): Fastcall functions pop the stack. (init_cumulative_args): Reserve registers ECX and EDX if function has fastcall attribute. (function_arg): Use registers ECX and EDX if function has fastcall attribute. * config/i386/i386.h (CUMULATIVE_ARGS): Add fastcall attribute flag. (FASTCALL_PREFIX): Define as '+'. * config/i386/mingw32.h (TARGET_OS_CPP_BUILTINS): Add fastcall attributes. * config/i386/winnt.c (gen_fastcall_suffix): New function. Decorates a label name with a preliminary fastcall prefix (+) and the stdcall suffix. (i386_pe_encode_section_info): Call gen_fastcall_suffix() if a symbol has a fastcall attribute. (i386_pe_strip_name_encoding): Return length of internal fastcall prefix (+). (i386_pe_output_labelref): New function. Outputs a label reference. (i386_pe_fastcall_name_p): New function. Checks a symbol for presence of internal fastcall prefix ('+' prefix). (i386_pe_asm_file_end): Converts internal fastcall prefix ('+' prefix) into the Microsoft compatible '@' prefix. * doc/extend.texi: Add documentation of fastcall attribute. ------=_NextPart_000_004B_01C29A51.B5AB0DF0 Content-Type: application/octet-stream; name="fastcall.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="fastcall.diff" Content-length: 22484 ? testsuite/gcc.c-torture/compile/20021110-1.c=0A= ? testsuite/gcc.c-torture/compile/20021110-1.x=0A= ? testsuite/gcc.c-torture/compile/20021110-2.c=0A= ? testsuite/gcc.c-torture/compile/20021110-2.x=0A= ? testsuite/gcc.c-torture/compile/20021110-3.c=0A= ? testsuite/gcc.c-torture/compile/20021110-3.x=0A= ? testsuite/gcc.c-torture/compile/20021110-4.c=0A= ? testsuite/gcc.c-torture/compile/20021110-4.x=0A= Index: config/i386/cygwin.h=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /cvsroot/gcc/gcc/gcc/config/i386/cygwin.h,v=0A= retrieving revision 1.74=0A= diff -c -3 -p -r1.74 cygwin.h=0A= *** config/i386/cygwin.h 24 Sep 2002 12:48:55 -0000 1.74=0A= --- config/i386/cygwin.h 2 Dec 2002 21:10:16 -0000=0A= *************** Boston, MA 02111-1307, USA. */=0A= *** 61,71 ****=0A= --- 61,73 ----=0A= builtin_define ("_X86_=3D1"); \=0A= builtin_assert ("system=3Dwinnt"); \=0A= builtin_define ("__stdcall=3D__attribute__((__stdcall__))"); \=0A= + builtin_define ("__fastcall=3D__attribute__((__fastcall__))"); \=0A= builtin_define ("__cdecl=3D__attribute__((__cdecl__))"); \=0A= builtin_define ("__declspec(x)=3D__attribute__((x))"); \=0A= if (!flag_iso) \=0A= { \=0A= builtin_define ("_stdcall=3D__attribute__((__stdcall__))"); \=0A= + builtin_define ("_fastcall=3D__attribute__((__fastcall__))"); \=0A= builtin_define ("_cdecl=3D__attribute__((__cdecl__))"); \=0A= } \=0A= MAYBE_UWIN_CPP_BUILTINS (); \=0A= *************** do { \=0A= *** 271,279 ****=0A= =0C=0A= /* Output a reference to a label. */=0A= #undef ASM_OUTPUT_LABELREF=0A= ! #define ASM_OUTPUT_LABELREF(STREAM, NAME) \=0A= ! fprintf (STREAM, "%s%s", USER_LABEL_PREFIX, \=0A= ! i386_pe_strip_name_encoding (NAME)) \=0A= =20=20=0A= /* Output a common block. */=0A= #undef ASM_OUTPUT_COMMON=0A= --- 273,279 ----=0A= =0C=0A= /* Output a reference to a label. */=0A= #undef ASM_OUTPUT_LABELREF=0A= ! #define ASM_OUTPUT_LABELREF i386_pe_output_labelref=0A= =20=20=0A= /* Output a common block. */=0A= #undef ASM_OUTPUT_COMMON=0A= Index: config/i386/i386-protos.h=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /cvsroot/gcc/gcc/gcc/config/i386/i386-protos.h,v=0A= retrieving revision 1.86=0A= diff -c -3 -p -r1.86 i386-protos.h=0A= *** config/i386/i386-protos.h 21 Nov 2002 22:54:19 -0000 1.86=0A= --- config/i386/i386-protos.h 2 Dec 2002 21:10:16 -0000=0A= *************** extern void i386_pe_asm_file_end PARAMS=20=0A= *** 229,231 ****=0A= --- 229,232 ----=0A= extern void i386_pe_encode_section_info PARAMS ((tree, int));=0A= extern const char *i386_pe_strip_name_encoding PARAMS ((const char *));= =0A= extern const char *i386_pe_strip_name_encoding_full PARAMS ((const char *= ));=0A= + extern void i386_pe_output_labelref PARAMS ((FILE *, const char *));=0A= Index: config/i386/i386.c=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /cvsroot/gcc/gcc/gcc/config/i386/i386.c,v=0A= retrieving revision 1.493=0A= diff -c -3 -p -r1.493 i386.c=0A= *** config/i386/i386.c 2 Dec 2002 18:44:05 -0000 1.493=0A= --- config/i386/i386.c 2 Dec 2002 21:10:24 -0000=0A= *************** const struct attribute_spec ix86_attribu=0A= *** 1355,1360 ****=0A= --- 1355,1363 ----=0A= /* Stdcall attribute says callee is responsible for popping arguments= =0A= if they are not variable. */=0A= { "stdcall", 0, 0, false, true, true, ix86_handle_cdecl_attribute }= ,=0A= + /* Fastcall attribute says callee is responsible for popping arguments= =0A= + if they are not variable. */=0A= + { "fastcall", 0, 0, false, true, true, ix86_handle_cdecl_attribute }= ,=0A= /* Cdecl attribute says the callee is a normal C declaration */=0A= { "cdecl", 0, 0, false, true, true, ix86_handle_cdecl_attribute }= ,=0A= /* Regparm attribute specifies how many integer arguments are to be=0A= *************** const struct attribute_spec ix86_attribu=0A= *** 1368,1374 ****=0A= { NULL, 0, 0, false, false, false, NULL }=0A= };=0A= =20=20=0A= ! /* Handle a "cdecl" or "stdcall" attribute;=0A= arguments as in struct attribute_spec.handler. */=0A= static tree=0A= ix86_handle_cdecl_attribute (node, name, args, flags, no_add_attrs)=0A= --- 1371,1377 ----=0A= { NULL, 0, 0, false, false, false, NULL }=0A= };=0A= =20=20=0A= ! /* Handle a "cdecl", "stdcall", or "fastcall" attribute;=0A= arguments as in struct attribute_spec.handler. */=0A= static tree=0A= ix86_handle_cdecl_attribute (node, name, args, flags, no_add_attrs)=0A= *************** ix86_handle_cdecl_attribute (node, name,=0A= *** 1387,1392 ****=0A= --- 1390,1416 ----=0A= IDENTIFIER_POINTER (name));=0A= *no_add_attrs =3D true;=0A= }=0A= + else=0A= + {=0A= + if (is_attribute_p ("fastcall", name))=0A= + {=0A= + if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (*node)))=0A= + {=0A= + error ("fastcall and stdcall attributes are not compatible"= );=0A= + }=0A= + else if (lookup_attribute ("regparm", TYPE_ATTRIBUTES (*node))= )=0A= + {=0A= + error ("fastcall and regparm attributes are not compatible"= );=0A= + }=0A= + }=0A= + else if (is_attribute_p ("stdcall", name))=0A= + {=0A= + if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))=0A= + {=0A= + error ("fastcall and stdcall attributes are not compatible"= );=0A= + }=0A= + }=0A= + }=0A= =20=20=0A= if (TARGET_64BIT)=0A= {=0A= *************** ix86_handle_regparm_attribute (node, nam=0A= *** 1433,1438 ****=0A= --- 1457,1467 ----=0A= IDENTIFIER_POINTER (name), REGPARM_MAX);=0A= *no_add_attrs =3D true;=0A= }=0A= +=20=0A= + if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))=0A= + {=0A= + error ("fastcall and regparm attributes are not compatible");=0A= + }=0A= }=0A= =20=20=0A= return NULL_TREE;=0A= *************** ix86_comp_type_attributes (type1, type2)=0A= *** 1453,1458 ****=0A= --- 1482,1492 ----=0A= if (TREE_CODE (type1) !=3D FUNCTION_TYPE)=0A= return 1;=0A= =20=20=0A= + /* Check for mismatched fastcall types */=20=0A= + if (!lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type1))=0A= + !=3D !lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type2)))=0A= + return 0;=20=0A= +=20=0A= /* Check for mismatched return types (cdecl vs stdcall). */=0A= if (!lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type1))=0A= !=3D !lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type2)))=0A= *************** ix86_return_pops_args (fundecl, funtype,=0A= *** 1503,1510 ****=0A= /* Cdecl functions override -mrtd, and never pop the stack. */=0A= if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) {=0A= =20=20=0A= ! /* Stdcall functions will pop the stack if not variable args. */=0A= ! if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))=0A= rtd =3D 1;=0A= =20=20=0A= if (rtd=0A= --- 1537,1545 ----=0A= /* Cdecl functions override -mrtd, and never pop the stack. */=0A= if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) {=0A= =20=20=0A= ! /* Stdcall and fastcall functions will pop the stack if not variable = args. */=0A= ! if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype))=0A= ! || lookup_attribute ("fastcall", TYPE_ATTRIBUTES (funtype)))=0A= rtd =3D 1;=0A= =20=20=0A= if (rtd=0A= *************** init_cumulative_args (cum, fntype, libna=0A= *** 1590,1595 ****=0A= --- 1625,1641 ----=0A= }=0A= cum->maybe_vaarg =3D false;=0A= =20=20=0A= + /* Use ecx and edx registers if function has fastcall attribute */=0A= + if (fntype && !TARGET_64BIT)=0A= + {=0A= + if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype)))=0A= + {=0A= + cum->nregs =3D 2;=0A= + cum->fastcall =3D 1;=0A= + }=0A= + }=0A= +=20=0A= +=20=0A= /* Determine if this function has variable arguments. This is=0A= indicated by the last argument being 'void_type_mode' if there=0A= are no variable arguments. If there are variable arguments, then=0A= *************** init_cumulative_args (cum, fntype, libna=0A= *** 1604,1610 ****=0A= if (next_param =3D=3D 0 && TREE_VALUE (param) !=3D void_type_node)=0A= {=0A= if (!TARGET_64BIT)=0A= ! cum->nregs =3D 0;=0A= cum->maybe_vaarg =3D true;=0A= }=0A= }=0A= --- 1650,1659 ----=0A= if (next_param =3D=3D 0 && TREE_VALUE (param) !=3D void_type_node)=0A= {=0A= if (!TARGET_64BIT)=0A= ! {=0A= ! cum->nregs =3D 0;=0A= ! cum->fastcall =3D 0;=0A= ! }=0A= cum->maybe_vaarg =3D true;=0A= }=0A= }=0A= *************** function_arg (cum, mode, type, named)=0A= *** 2254,2260 ****=0A= case HImode:=0A= case QImode:=0A= if (words <=3D cum->nregs)=0A= ! ret =3D gen_rtx_REG (mode, cum->regno);=0A= break;=0A= case TImode:=0A= if (cum->sse_nregs)=0A= --- 2303,2324 ----=0A= case HImode:=0A= case QImode:=0A= if (words <=3D cum->nregs)=0A= ! {=0A= ! int regno =3D cum->regno;=0A= !=20=0A= ! /* Fastcall allocates the first two DWORD (SImode) or=0A= ! smaller arguments to ECX and EDX. */=0A= ! if (cum->fastcall)=0A= ! {=0A= ! if (mode =3D=3D BLKmode || mode =3D=3D DImode)=0A= ! break;=0A= !=20=20=0A= ! /* ECX not EAX is the first allocated register. */=0A= ! if (regno =3D=3D 0)=0A= ! regno =3D 2;=0A= ! }=0A= ! ret =3D gen_rtx_REG (mode, regno);=0A= ! }=0A= break;=0A= case TImode:=0A= if (cum->sse_nregs)=0A= Index: config/i386/i386.h=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /cvsroot/gcc/gcc/gcc/config/i386/i386.h,v=0A= retrieving revision 1.308=0A= diff -c -3 -p -r1.308 i386.h=0A= *** config/i386/i386.h 27 Nov 2002 20:04:16 -0000 1.308=0A= --- config/i386/i386.h 2 Dec 2002 21:10:27 -0000=0A= *************** typedef struct ix86_args {=0A= *** 1665,1670 ****=0A= --- 1665,1671 ----=0A= int words; /* # words passed so far */=0A= int nregs; /* # registers available for passing */=0A= int regno; /* next available register number */=0A= + int fastcall; /* fastcall calling convention is used */=0A= int sse_words; /* # sse words passed so far */=0A= int sse_nregs; /* # sse registers available for passing */=0A= int sse_regno; /* next available sse register number */=0A= *************** enum fp_cw_mode {FP_CW_STORED, FP_CW_UNI=0A= *** 3446,3451 ****=0A= --- 3447,3453 ----=0A= #define MACHINE_DEPENDENT_REORG(X) x86_machine_dependent_reorg(X)=0A= =20=20=0A= #define DLL_IMPORT_EXPORT_PREFIX '@'=0A= + #define FASTCALL_PREFIX '+'=0A= =20=20=0A= /*=0A= Local variables:=0A= Index: config/i386/mingw32.h=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /cvsroot/gcc/gcc/gcc/config/i386/mingw32.h,v=0A= retrieving revision 1.27=0A= diff -c -3 -p -r1.27 mingw32.h=0A= *** config/i386/mingw32.h 29 Jun 2002 09:10:04 -0000 1.27=0A= --- config/i386/mingw32.h 2 Dec 2002 21:10:27 -0000=0A= *************** Boston, MA 02111-1307, USA. */=0A= *** 50,60 ****=0A= --- 50,62 ----=0A= builtin_define_std ("WINNT"); \=0A= builtin_define ("_X86_=3D1"); \=0A= builtin_define ("__stdcall=3D__attribute__((__stdcall__))"); \=0A= + builtin_define ("__fastcall=3D__attribute__((__fastcall__))"); \=0A= builtin_define ("__cdecl=3D__attribute__((__cdecl__))"); \=0A= builtin_define ("__declspec(x)=3D__attribute__((x))"); \=0A= if (!flag_iso) \=0A= { \=0A= builtin_define ("_stdcall=3D__attribute__((__stdcall__))"); \=0A= + builtin_define ("_fastcall=3D__attribute__((__fastcall__))"); \=0A= builtin_define ("_cdecl=3D__attribute__((__cdecl__))"); \=0A= } \=0A= EXTRA_OS_CPP_BUILTINS (); \=0A= Index: config/i386/winnt.c=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /cvsroot/gcc/gcc/gcc/config/i386/winnt.c,v=0A= retrieving revision 1.37=0A= diff -c -3 -p -r1.37 winnt.c=0A= *** config/i386/winnt.c 27 Nov 2002 20:04:16 -0000 1.37=0A= --- config/i386/winnt.c 2 Dec 2002 21:10:27 -0000=0A= *************** Boston, MA 02111-1307, USA. */=0A= *** 46,55 ****=0A= --- 46,57 ----=0A= =20=20=0A= static tree associated_type PARAMS ((tree));=0A= const char * gen_stdcall_suffix PARAMS ((tree));=0A= + const char * gen_fastcall_suffix PARAMS ((tree));=0A= int i386_pe_dllexport_p PARAMS ((tree));=0A= int i386_pe_dllimport_p PARAMS ((tree));=0A= void i386_pe_mark_dllexport PARAMS ((tree));=0A= void i386_pe_mark_dllimport PARAMS ((tree));=0A= + static int i386_pe_fastcall_name_p PARAMS ((const char *));=0A= =20=20=0A= /* Handle a "dllimport" or "dllexport" attribute;=0A= arguments as in struct attribute_spec.handler. */=0A= *************** i386_pe_mark_dllimport (decl)=0A= *** 313,320 ****=0A= return;=0A= }=0A= =20=20=0A= ! newname =3D alloca (strlen (oldname) + 11);=0A= ! sprintf (newname, "%ci._imp__%s", DLL_IMPORT_EXPORT_PREFIX, oldname);= =0A= =20=20=0A= /* We pass newname through get_identifier to ensure it has a unique=0A= address. RTL processing can sometimes peek inside the symbol ref=0A= --- 315,322 ----=0A= return;=0A= }=0A= =20=20=0A= ! newname =3D alloca (strlen (oldname) + 4);=0A= ! sprintf (newname, "%ci.%s", DLL_IMPORT_EXPORT_PREFIX, oldname);=0A= =20=20=0A= /* We pass newname through get_identifier to ensure it has a unique=0A= address. RTL processing can sometimes peek inside the symbol ref=0A= *************** i386_pe_mark_dllimport (decl)=0A= *** 332,337 ****=0A= --- 334,378 ----=0A= }=0A= =20=20=0A= /* Return string which is the former assembler name modified with a=20=0A= + prefix consisting of a plus (+) and a suffix consisting of an=0A= + atsign (@) followed by the number of bytes of arguments.=0A= + The leading plus (+) is later replaced by an atsign (@). This=0A= + trick is used because leading atsigns are already used internally. */= =0A= +=20=0A= + const char *=0A= + gen_fastcall_suffix (decl)=0A= + tree decl;=0A= + {=0A= + int total =3D 0;=0A= +=20=0A= + const char *asmname =3D IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))= ;=0A= + char *newsym;=0A= +=20=0A= + if (TYPE_ARG_TYPES (TREE_TYPE (decl)))=0A= + if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))=0A= + =3D=3D void_type_node)=0A= + {=0A= + tree formal_type =3D TYPE_ARG_TYPES (TREE_TYPE (decl));=0A= +=20=0A= + while (TREE_VALUE (formal_type) !=3D void_type_node)=0A= + {=0A= + int parm_size=0A= + =3D TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));=0A= + /* Must round up to include padding. This is done the same=0A= + way as in store_one_arg. */=0A= + parm_size =3D ((parm_size + PARM_BOUNDARY - 1)=0A= + / PARM_BOUNDARY * PARM_BOUNDARY);=0A= + total +=3D parm_size;=0A= + formal_type =3D TREE_CHAIN (formal_type);=0A= + }=0A= + }=0A= +=20=0A= + newsym =3D xmalloc (strlen (asmname) + 11);=0A= + sprintf (newsym, "%c%s@%d", FASTCALL_PREFIX, asmname, total/BITS_PER_UN= IT);=0A= + return IDENTIFIER_POINTER (get_identifier (newsym));=0A= + }=0A= +=20=0A= + /* Return string which is the former assembler name modified with a=20=0A= suffix consisting of an atsign (@) followed by the number of bytes of= =20=0A= arguments */=0A= =20=20=0A= *************** i386_pe_encode_section_info (decl, first=0A= *** 387,396 ****=0A= }=0A= =20=20=0A= if (TREE_CODE (decl) =3D=3D FUNCTION_DECL)=0A= ! if (lookup_attribute ("stdcall",=0A= ! TYPE_ATTRIBUTES (TREE_TYPE (decl))))=0A= ! XEXP (DECL_RTL (decl), 0) =3D=20=0A= ! gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl));=0A= =20=20=0A= /* Mark the decl so we can tell from the rtl whether the object is=0A= dllexport'd or dllimport'd. */=0A= --- 428,443 ----=0A= }=0A= =20=20=0A= if (TREE_CODE (decl) =3D=3D FUNCTION_DECL)=0A= ! {=0A= ! if (lookup_attribute ("stdcall",=0A= ! TYPE_ATTRIBUTES (TREE_TYPE (decl))))=0A= ! XEXP (DECL_RTL (decl), 0) =3D=20=0A= ! gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl));=0A= ! else if (lookup_attribute ("fastcall",=0A= ! TYPE_ATTRIBUTES (TREE_TYPE (decl))))=0A= ! XEXP (DECL_RTL (decl), 0) =3D=0A= ! gen_rtx (SYMBOL_REF, Pmode, gen_fastcall_suffix (decl));=0A= ! }=0A= =20=20=0A= /* Mark the decl so we can tell from the rtl whether the object is=0A= dllexport'd or dllimport'd. */=0A= *************** i386_pe_strip_name_encoding (str)=0A= *** 432,438 ****=0A= {=0A= if (*str =3D=3D DLL_IMPORT_EXPORT_PREFIX)=0A= str +=3D 3;=0A= ! if (*str =3D=3D '*')=0A= str +=3D 1;=0A= return str;=0A= }=0A= --- 479,485 ----=0A= {=0A= if (*str =3D=3D DLL_IMPORT_EXPORT_PREFIX)=0A= str +=3D 3;=0A= ! if (*str =3D=3D '*' || *str =3D=3D FASTCALL_PREFIX)=0A= str +=3D 1;=0A= return str;=0A= }=0A= *************** i386_pe_strip_name_encoding_full (str)=0A= *** 453,458 ****=0A= --- 500,542 ----=0A= return name;=0A= }=0A= =20=20=0A= + /* Output a reference to a label. Fastcall symbols are prefixed with @,= =0A= + whereas symbols for functions using other calling conventions don't=0A= + have a prefix (unless they are marked dllimport or dllexport).=0A= + Internally, @ is used as a prefix for symbols that are marked dllimpor= t=0A= + or dllexport so internally the prefix + is used for fastcall symbols. = */=0A= +=20=0A= + void i386_pe_output_labelref (stream, name)=0A= + FILE *stream;=0A= + const char *name;=0A= + {=0A= + if (strncmp (name,"@i.",3) =3D=3D 0)=0A= + {=0A= + if (name[3] =3D=3D FASTCALL_PREFIX)=0A= + {=0A= + fprintf (stream, "__imp_@%s",=0A= + i386_pe_strip_name_encoding (name));=0A= + }=0A= + else=0A= + {=0A= + fprintf (stream, "__imp__%s",=0A= + i386_pe_strip_name_encoding (name));=0A= + }=0A= + }=0A= + else if ((name[0] =3D=3D FASTCALL_PREFIX)=0A= + || ((name[0] =3D=3D DLL_IMPORT_EXPORT_PREFIX)=0A= + && (name[3] =3D=3D FASTCALL_PREFIX)))=0A= + {=0A= + fprintf (stream, "@%s",=0A= + i386_pe_strip_name_encoding (name));=0A= + }=0A= + else=0A= + {=0A= + fprintf (stream, "%s%s", USER_LABEL_PREFIX,=0A= + i386_pe_strip_name_encoding (name));=0A= + }=0A= + }=0A= +=20=0A= void=0A= i386_pe_unique_section (decl, reloc)=0A= tree decl;=0A= *************** i386_pe_record_exported_symbol (name, is=0A= *** 660,665 ****=0A= --- 744,760 ----=0A= export_head =3D p;=0A= }=0A= =20=20=0A= + /* Return non-zero if SYMBOL is marked as being fastcall. */=0A= +=20=0A= + static int=0A= + i386_pe_fastcall_name_p (symbol)=0A= + const char *symbol;=0A= + {=0A= + return (symbol[0] =3D=3D FASTCALL_PREFIX)=0A= + || (symbol[0] =3D=3D DLL_IMPORT_EXPORT_PREFIX=0A= + && symbol[3] =3D=3D FASTCALL_PREFIX);=0A= + }=0A= +=20=0A= /* This is called at the end of assembly. For each external function=0A= which has not been defined, we output a declaration now. We also=0A= output the .drectve section. */=0A= *************** i386_pe_asm_file_end (file)=0A= *** 692,698 ****=0A= drectve_section ();=0A= for (q =3D export_head; q !=3D NULL; q =3D q->next)=0A= {=0A= ! fprintf (file, "\t.ascii \" -export:%s%s\"\n",=0A= i386_pe_strip_name_encoding (q->name),=0A= (q->is_data) ? ",data" : "");=0A= }=0A= --- 787,794 ----=0A= drectve_section ();=0A= for (q =3D export_head; q !=3D NULL; q =3D q->next)=0A= {=0A= ! fprintf (file, "\t.ascii \" -export:%s%s%s\"\n",=0A= ! (i386_pe_fastcall_name_p(q->name)) ? "@" : "",=0A= i386_pe_strip_name_encoding (q->name),=0A= (q->is_data) ? ",data" : "");=0A= }=0A= Index: doc/extend.texi=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /cvsroot/gcc/gcc/gcc/doc/extend.texi,v=0A= retrieving revision 1.108=0A= diff -c -3 -p -r1.108 extend.texi=0A= *** doc/extend.texi 27 Nov 2002 06:32:13 -0000 1.108=0A= --- doc/extend.texi 2 Dec 2002 21:10:33 -0000=0A= *************** pass arguments, unless it takes a variab=0A= *** 2373,2378 ****=0A= --- 2373,2386 ----=0A= The PowerPC compiler for Windows NT currently ignores the @code{stdcall}= =0A= attribute.=0A= =20=20=0A= + @item fastcall=0A= + @cindex functions that pop the argument stack on the 386=0A= + On the Intel 386, the @code{fastcall} attribute causes the compiler to=0A= + pass the first two arguments in the registers ECX and EDX. Subsequent=0A= + arguments are passed on the stack. The called function will pop the=20=0A= + arguments off the stack. If the number of arguments is variable all=0A= + arguments are pushed on the stack.=0A= +=20=0A= @item cdecl=0A= @cindex functions that do pop the argument stack on the 386=0A= @opindex mrtd=0A= ------=_NextPart_000_004B_01C29A51.B5AB0DF0 Content-Type: text/plain; name="20021110-1.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="20021110-1.c" Content-length: 40 void __attribute__ ((fastcall)) f() { } ------=_NextPart_000_004B_01C29A51.B5AB0DF0 Content-Type: application/octet-stream; name="20021110-1.x" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="20021110-1.x" Content-length: 181 # Only mingw32 and cygwin on i386 have fastcall support=0A= if { !([istarget "i386-pc-mingw32*"] || [istarget "i386-pc-cygwin*"]) } {= =0A= return 1;=0A= }=0A= =0A= return 0;=0A= ------=_NextPart_000_004B_01C29A51.B5AB0DF0 Content-Type: text/plain; name="20021110-2.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="20021110-2.c" Content-length: 23 void _fastcall f() { } ------=_NextPart_000_004B_01C29A51.B5AB0DF0 Content-Type: application/octet-stream; name="20021110-2.x" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="20021110-2.x" Content-length: 181 # Only mingw32 and cygwin on i386 have fastcall support=0A= if { !([istarget "i386-pc-mingw32*"] || [istarget "i386-pc-cygwin*"]) } {= =0A= return 1;=0A= }=0A= =0A= return 0;=0A= ------=_NextPart_000_004B_01C29A51.B5AB0DF0 Content-Type: text/plain; name="20021110-3.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="20021110-3.c" Content-length: 24 void __fastcall f() { } ------=_NextPart_000_004B_01C29A51.B5AB0DF0 Content-Type: application/octet-stream; name="20021110-3.x" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="20021110-3.x" Content-length: 181 # Only mingw32 and cygwin on i386 have fastcall support=0A= if { !([istarget "i386-pc-mingw32*"] || [istarget "i386-pc-cygwin*"]) } {= =0A= return 1;=0A= }=0A= =0A= return 0;=0A= ------=_NextPart_000_004B_01C29A51.B5AB0DF0 Content-Type: text/plain; name="20021110-4.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="20021110-4.c" Content-length: 58 int __attribute__ ((fastcall)) f(int x, int y, int z) { } ------=_NextPart_000_004B_01C29A51.B5AB0DF0 Content-Type: application/octet-stream; name="20021110-4.x" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="20021110-4.x" Content-length: 181 # Only mingw32 and cygwin on i386 have fastcall support=0A= if { !([istarget "i386-pc-mingw32*"] || [istarget "i386-pc-cygwin*"]) } {= =0A= return 1;=0A= }=0A= =0A= return 0;=0A= ------=_NextPart_000_004B_01C29A51.B5AB0DF0--