From 2b4c4ba72e9d18ae01a20c9b95f70868b6d338e3 Mon Sep 17 00:00:00 2001 From: ktietz Date: Fri, 9 Apr 2010 08:58:00 +0000 Subject: [PATCH 1/1] 2010-04-09 Kai Tietz * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158155 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 19 +++++++++++++ gcc/config/i386/i386.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 23377d1d760..37e496bc799 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2010-04-09 Kai Tietz + + * 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 PR c++/28584 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 5387fae6259..f65220c2911 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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 -- 2.11.0