]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
cygming.h (TARGET_OS_CPP_BUILTINS): Add __thiscall and _thiscall as predefined macros.
authorKai Tietz <kai.tietz@onevision.com>
Fri, 9 Apr 2010 08:58:00 +0000 (08:58 +0000)
committerKai Tietz <ktietz@gcc.gnu.org>
Fri, 9 Apr 2010 08:58:00 +0000 (10:58 +0200)
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

gcc/ChangeLog
gcc/config/i386/cygming.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/doc/extend.texi

index 23377d1d760ffcc7b570e43d6d32d066a9faaf36..37e496bc799857847be1a8467871d4c4572dd01c 100644 (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
index 5e9ccb2add4282dc34f704981ca97eed80741fce..a726bb4455e9891759f07a968240d7ea566a7cea 100644 (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  \
index 5387fae6259cc382cf7fdeb538e9f6395401f96d..f65220c29112341f6f05b859e3d9d9cc36cd31eb 100644 (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
index 0f133593ad8ca389b3bbced5289154ab26d8722c..4b83370c9a614919705a5193644342606e7041da 100644 (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.  */
index 78d90930f5968efbdb6937af9532e63d3aa84c81..0e499ccd1367afab836b75d4d7b52d1b26be94c9 100644 (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