cygming.h (TARGET_OS_CPP_BUILTINS): Add __thiscall and _thiscall as predefined macros.

2010-04-09  Kai Tietz  <kai.tietz@onevision.com>

        * config/i386/cygming.h (TARGET_OS_CPP_BUILTINS): Add
        __thiscall and _thiscall as predefined macros.
        * config/i386/i386.c (ix86_handle_cconv_attribute): Add
        thiscall attribute handling.
        (ix86_comp_type_attributes): Likewise.
        (ix86_function_regparm): Likewise.
        (ix86_return_pops_args): Likewise.
        (init_cumulative_args): Likewise.
        (find_drap_reg): Likewise.
        (ix86_static_chain): Likewise.
        (x86_this_parameter): Likewise.
        (x86_output_mi_thunk): Likewise.
        (ix86_attribute_table): Add description for thiscall attribute.
        * config/i386/i386.h (ix86_args): Adjust comment for member
        fastcall.
        * doc/extend.texi: Add documentation for thiscall.

From-SVN: r158155
This commit is contained in:
Kai Tietz 2010-04-09 08:58:00 +00:00 committed by Kai Tietz
parent c688a8b0d7
commit 3e65f25191
5 changed files with 107 additions and 6 deletions

View File

@ -1,3 +1,22 @@
2010-04-09 Kai Tietz <kai.tietz@onevision.com>
* config/i386/cygming.h (TARGET_OS_CPP_BUILTINS): Add
__thiscall and _thiscall as predefined macros.
* config/i386/i386.c (ix86_handle_cconv_attribute): Add
thiscall attribute handling.
(ix86_comp_type_attributes): Likewise.
(ix86_function_regparm): Likewise.
(ix86_return_pops_args): Likewise.
(init_cumulative_args): Likewise.
(find_drap_reg): Likewise.
(ix86_static_chain): Likewise.
(x86_this_parameter): Likewise.
(x86_output_mi_thunk): Likewise.
(ix86_attribute_table): Add description for thiscall attribute.
* config/i386/i386.h (ix86_args): Adjust comment for member
fastcall.
* doc/extend.texi: Add documentation for thiscall.
2010-04-09 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c++/28584

View File

@ -79,11 +79,13 @@ along with GCC; see the file COPYING3. If not see
builtin_assert ("system=winnt"); \
builtin_define ("__stdcall=__attribute__((__stdcall__))"); \
builtin_define ("__fastcall=__attribute__((__fastcall__))"); \
builtin_define ("__thiscall=__attribute__((__thiscall__))"); \
builtin_define ("__cdecl=__attribute__((__cdecl__))"); \
if (!flag_iso) \
{ \
builtin_define ("_stdcall=__attribute__((__stdcall__))"); \
builtin_define ("_fastcall=__attribute__((__fastcall__))"); \
builtin_define ("_thiscall=__attribute__((__thiscall__))"); \
builtin_define ("_cdecl=__attribute__((__cdecl__))"); \
} \
/* Even though linkonce works with static libs, this is needed \

View File

@ -4395,8 +4395,8 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
return true;
}
/* Handle "cdecl", "stdcall", "fastcall", "regparm" and "sseregparm"
calling convention attributes;
/* Handle "cdecl", "stdcall", "fastcall", "regparm", "thiscall",
and "sseregparm" calling convention attributes;
arguments as in struct attribute_spec.handler. */
static tree
@ -4426,6 +4426,11 @@ ix86_handle_cconv_attribute (tree *node, tree name,
error ("fastcall and regparm attributes are not compatible");
}
if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (*node)))
{
error ("regparam and thiscall attributes are not compatible");
}
cst = TREE_VALUE (args);
if (TREE_CODE (cst) != INTEGER_CST)
{
@ -4471,6 +4476,10 @@ ix86_handle_cconv_attribute (tree *node, tree name,
{
error ("fastcall and regparm attributes are not compatible");
}
if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (*node)))
{
error ("fastcall and thiscall attributes are not compatible");
}
}
/* Can combine stdcall with fastcall (redundant), regparm and
@ -4485,6 +4494,10 @@ ix86_handle_cconv_attribute (tree *node, tree name,
{
error ("stdcall and fastcall attributes are not compatible");
}
if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (*node)))
{
error ("stdcall and thiscall attributes are not compatible");
}
}
/* Can combine cdecl with regparm and sseregparm. */
@ -4498,6 +4511,28 @@ ix86_handle_cconv_attribute (tree *node, tree name,
{
error ("fastcall and cdecl attributes are not compatible");
}
if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (*node)))
{
error ("cdecl and thiscall attributes are not compatible");
}
}
else if (is_attribute_p ("thiscall", name))
{
if (TREE_CODE (*node) != METHOD_TYPE && pedantic)
warning (OPT_Wattributes, "%qE attribute is used for none class-method",
name);
if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (*node)))
{
error ("stdcall and thiscall attributes are not compatible");
}
if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
{
error ("fastcall and thiscall attributes are not compatible");
}
if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (*node)))
{
error ("cdecl and thiscall attributes are not compatible");
}
}
/* Can combine sseregparm with all attributes. */
@ -4531,6 +4566,11 @@ ix86_comp_type_attributes (const_tree type1, const_tree type2)
!= !lookup_attribute ("sseregparm", TYPE_ATTRIBUTES (type2)))
return 0;
/* Check for mismatched thiscall types. */
if (!lookup_attribute ("thiscall", TYPE_ATTRIBUTES (type1))
!= !lookup_attribute ("thiscall", TYPE_ATTRIBUTES (type2)))
return 0;
/* Check for mismatched return types (cdecl vs stdcall). */
if (!lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type1))
!= !lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type2)))
@ -4564,6 +4604,9 @@ ix86_function_regparm (const_tree type, const_tree decl)
if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
return 2;
if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (type)))
return 1;
/* Use register calling convention for local functions when possible. */
if (decl
&& TREE_CODE (decl) == FUNCTION_DECL
@ -4701,7 +4744,8 @@ ix86_return_pops_args (tree fundecl, tree funtype, int size)
/* Stdcall and fastcall functions will pop the stack if not
variable args. */
if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype))
|| lookup_attribute ("fastcall", TYPE_ATTRIBUTES (funtype)))
|| lookup_attribute ("fastcall", TYPE_ATTRIBUTES (funtype))
|| lookup_attribute ("thiscall", TYPE_ATTRIBUTES (funtype)))
rtd = 1;
if (rtd && ! stdarg_p (funtype))
@ -4964,7 +5008,12 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
else look for regparm information. */
if (fntype)
{
if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype)))
if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (fntype)))
{
cum->nregs = 1;
cum->fastcall = 1; /* Same first register as in fastcall. */
}
else if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype)))
{
cum->nregs = 2;
cum->fastcall = 1;
@ -8303,6 +8352,8 @@ find_drap_reg (void)
passing. */
if (ix86_function_regparm (TREE_TYPE (decl), decl) <= 2
&& !lookup_attribute ("fastcall",
TYPE_ATTRIBUTES (TREE_TYPE (decl)))
&& !lookup_attribute ("thiscall",
TYPE_ATTRIBUTES (TREE_TYPE (decl))))
return CX_REG;
else
@ -20157,6 +20208,12 @@ ix86_static_chain (const_tree fndecl, bool incoming_p)
us with EAX for the static chain. */
regno = AX_REG;
}
else if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (fntype)))
{
/* Thiscall functions use ecx for arguments, which leaves
us with EAX for the static chain. */
regno = AX_REG;
}
else if (ix86_function_regparm (fntype, fndecl) == 3)
{
/* For regparm 3, we have no free call-clobbered registers in
@ -26124,6 +26181,11 @@ x86_this_parameter (tree function)
if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
regno = aggr ? DX_REG : CX_REG;
/* ???: To be verified. It is not absolutely clear how aggregates
have to be treated for thiscall. We assume that they are
identical to fastcall. */
else if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (type)))
regno = aggr ? DX_REG : CX_REG;
else
{
regno = AX_REG;
@ -26235,7 +26297,9 @@ x86_output_mi_thunk (FILE *file,
{
int tmp_regno = CX_REG;
if (lookup_attribute ("fastcall",
TYPE_ATTRIBUTES (TREE_TYPE (function))))
TYPE_ATTRIBUTES (TREE_TYPE (function)))
|| lookup_attribute ("thiscall",
TYPE_ATTRIBUTES (TREE_TYPE (function))))
tmp_regno = AX_REG;
tmp = gen_rtx_REG (SImode, tmp_regno);
}
@ -28975,6 +29039,9 @@ static const struct attribute_spec ix86_attribute_table[] =
/* Fastcall attribute says callee is responsible for popping arguments
if they are not variable. */
{ "fastcall", 0, 0, false, true, true, ix86_handle_cconv_attribute },
/* Thiscall attribute says callee is responsible for popping arguments
if they are not variable. */
{ "thiscall", 0, 0, false, true, true, ix86_handle_cconv_attribute },
/* Cdecl attribute says the callee is a normal C declaration */
{ "cdecl", 0, 0, false, true, true, ix86_handle_cconv_attribute },
/* Regparm attribute specifies how many integer arguments are to be

View File

@ -1580,7 +1580,8 @@ typedef struct ix86_args {
int words; /* # words passed so far */
int nregs; /* # registers available for passing */
int regno; /* next available register number */
int fastcall; /* fastcall calling convention is used */
int fastcall; /* fastcall or thiscall calling convention
is used */
int sse_words; /* # sse words passed so far */
int sse_nregs; /* # sse registers available for passing */
int warn_avx; /* True when we want to warn about AVX ABI. */

View File

@ -2323,6 +2323,18 @@ 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.
@item thiscall
@cindex functions that pop the argument stack on the 386
On the Intel 386, the @code{thiscall} attribute causes the compiler to
pass the first argument (if of integral type) in the register ECX.
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.
The @code{thiscall} attribute is intended for C++ non-static member functions.
As gcc extension this calling convention can be used for C-functions
and for static member methods.
@item format (@var{archetype}, @var{string-index}, @var{first-to-check})
@cindex @code{format} function attribute
@opindex Wformat