diff options
author | Casper S. Hornstrup <chorns@users.sourceforge.net> | 2002-12-19 22:00:33 +0000 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2002-12-19 14:00:33 -0800 |
commit | e91f04de4bb14746e48091a26234c87287e73163 (patch) | |
tree | 21891e9229467b063b2f39b501b4c0fe4d386c1e /gcc/config/i386/winnt.c | |
parent | 61138bb628f5774e6877f2a336db898c28677a14 (diff) | |
download | gcc-e91f04de4bb14746e48091a26234c87287e73163.zip gcc-e91f04de4bb14746e48091a26234c87287e73163.tar.gz gcc-e91f04de4bb14746e48091a26234c87287e73163.tar.bz2 |
i386.c (ix86_handle_cdecl_attribute): Check for attributes incompatible with fastcall attribute.
* config/i386/i386.c (ix86_handle_cdecl_attribute): Check for
attributes incompatible with fastcall attribute.
(ix86_handle_regparm_attribute): Likewise.
* config/i386/i386.c (ix86_comp_type_attributes): Check for mismatched
fastcall types.
* 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). Add __imp_ prefix in
i386_pe_output_labelref rather than here.
(gen_fastcall_suffix): New function. Decorates a label name with the
fastcall prefix (@) and the stdcall suffix.
(i386_pe_encode_section_info): Call gen_fastcall_suffix() if a symbol
has a fastcall attribute.
(i386_pe_output_labelref): New function. Outputs a label reference.
* 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.
(DLL_IMPORT_EXPORT_PREFIX): Redefine as '#'.
(FASTCALL_PREFIX): Define as '@'.
* config/i386/mingw32.h (TARGET_OS_CPP_BUILTINS): Add fastcall
attributes.
* doc/extend.texi: Add documentation of fastcall attribute.
* testsuite/gcc.dg/i386-fastcall-1.c: New.
Co-Authored-By: Danny Smith <dannysmith@users.sourceforge.net>
Co-Authored-By: Eric Kohl <ekohl@rz-online.de>
From-SVN: r60337
Diffstat (limited to 'gcc/config/i386/winnt.c')
-rw-r--r-- | gcc/config/i386/winnt.c | 97 |
1 files changed, 90 insertions, 7 deletions
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index bc2527a..89dd007 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA. */ static tree associated_type PARAMS ((tree)); const char * gen_stdcall_suffix PARAMS ((tree)); +const char * gen_fastcall_suffix PARAMS ((tree)); int i386_pe_dllexport_p PARAMS ((tree)); int i386_pe_dllimport_p PARAMS ((tree)); void i386_pe_mark_dllexport PARAMS ((tree)); @@ -315,8 +316,8 @@ i386_pe_mark_dllimport (decl) return; } - newname = alloca (strlen (oldname) + 11); - sprintf (newname, "%ci._imp__%s", DLL_IMPORT_EXPORT_PREFIX, oldname); + newname = alloca (strlen (oldname) + 4); + sprintf (newname, "%ci.%s", DLL_IMPORT_EXPORT_PREFIX, oldname); /* We pass newname through get_identifier to ensure it has a unique address. RTL processing can sometimes peek inside the symbol ref @@ -334,6 +335,43 @@ i386_pe_mark_dllimport (decl) } /* Return string which is the former assembler name modified with a + prefix consisting of FASTCALL_PREFIX and a suffix consisting of an + atsign (@) followed by the number of bytes of arguments. */ + +const char * +gen_fastcall_suffix (decl) + tree decl; +{ + int total = 0; + + const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + char *newsym; + + if (TYPE_ARG_TYPES (TREE_TYPE (decl))) + if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl)))) + == void_type_node) + { + tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl)); + + while (TREE_VALUE (formal_type) != void_type_node) + { + int parm_size + = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type))); + /* Must round up to include padding. This is done the same + way as in store_one_arg. */ + parm_size = ((parm_size + PARM_BOUNDARY - 1) + / PARM_BOUNDARY * PARM_BOUNDARY); + total += parm_size; + formal_type = TREE_CHAIN (formal_type); + } + } + + newsym = xmalloc (strlen (asmname) + 11); + sprintf (newsym, "%c%s@%d", FASTCALL_PREFIX, asmname, total/BITS_PER_UNIT); + return IDENTIFIER_POINTER (get_identifier (newsym)); +} + +/* Return string which is the former assembler name modified with a suffix consisting of an atsign (@) followed by the number of bytes of arguments */ @@ -389,10 +427,16 @@ i386_pe_encode_section_info (decl, first) } if (TREE_CODE (decl) == FUNCTION_DECL) - if (lookup_attribute ("stdcall", - TYPE_ATTRIBUTES (TREE_TYPE (decl)))) - XEXP (DECL_RTL (decl), 0) = - gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl)); + { + if (lookup_attribute ("stdcall", + TYPE_ATTRIBUTES (TREE_TYPE (decl)))) + XEXP (DECL_RTL (decl), 0) = + gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl)); + else if (lookup_attribute ("fastcall", + TYPE_ATTRIBUTES (TREE_TYPE (decl)))) + XEXP (DECL_RTL (decl), 0) = + gen_rtx (SYMBOL_REF, Pmode, gen_fastcall_suffix (decl)); + } /* Mark the decl so we can tell from the rtl whether the object is dllexport'd or dllimport'd. */ @@ -426,7 +470,8 @@ i386_pe_encode_section_info (decl, first) } } -/* Strip only the leading encoding, leaving the stdcall suffix. */ +/* Strip only the leading encoding, leaving the stdcall suffix and fastcall + prefix if it exists. */ const char * i386_pe_strip_name_encoding (str) @@ -455,6 +500,44 @@ i386_pe_strip_name_encoding_full (str) return name; } +/* 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). */ + +void i386_pe_output_labelref (stream, name) + FILE *stream; + const char *name; +{ + char prefix[4]; + + sprintf (prefix, "%ci.", DLL_IMPORT_EXPORT_PREFIX); + if (strncmp (name, prefix, strlen (prefix)) == 0) + { + if (name[3] == FASTCALL_PREFIX) + { + fprintf (stream, "__imp_%s", + i386_pe_strip_name_encoding (name)); + } + else + { + fprintf (stream, "__imp__%s", + i386_pe_strip_name_encoding (name)); + } + } + else if ((name[0] == FASTCALL_PREFIX) + || ((name[0] == DLL_IMPORT_EXPORT_PREFIX) + && (name[3] == FASTCALL_PREFIX))) + { + fprintf (stream, "%s", + i386_pe_strip_name_encoding (name)); + } + else + { + fprintf (stream, "%s%s", USER_LABEL_PREFIX, + i386_pe_strip_name_encoding (name)); + } +} + void i386_pe_unique_section (decl, reloc) tree decl; |