summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorktietz <ktietz@138bc75d-0d04-0410-961f-82ee72b054a4>2010-04-09 08:58:00 +0000
committerktietz <ktietz@138bc75d-0d04-0410-961f-82ee72b054a4>2010-04-09 08:58:00 +0000
commit538adab1509c5f81f1ea6138874711c7f8e1d2a5 (patch)
treef27eae49df0a1d17560380b81541562295afd47c
parent5a84efd3f60af101e802bef5ecc817b315eecc71 (diff)
downloadgcc-538adab1509c5f81f1ea6138874711c7f8e1d2a5.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158155 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/config/i386/cygming.h2
-rw-r--r--gcc/config/i386/i386.c77
-rw-r--r--gcc/config/i386/i386.h3
-rw-r--r--gcc/doc/extend.texi12
5 files changed, 107 insertions, 6 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 <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
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index 5e9ccb2add4..a726bb4455e 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -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 \
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
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 0f133593ad8..4b83370c9a6 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -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. */
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 78d90930f59..0e499ccd136 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -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