OSDN Git Service

2010-04-09 Kai Tietz <kai.tietz@onevision.com>
authorktietz <ktietz@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Apr 2010 08:58:00 +0000 (08:58 +0000)
committerktietz <ktietz@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Apr 2010 08:58:00 +0000 (08:58 +0000)
        * 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
gcc/config/i386/cygming.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/doc/extend.texi

index 23377d1..37e496b 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 5e9ccb2..a726bb4 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 5387fae..f65220c 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 0f13359..4b83370 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 78d9093..0e499cc 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