diff mbox

[i386] : Set for method-functions default calling-convention to thiscall for 32-bit msabi

Message ID AANLkTikjPQhTQG3fgmt+yy=h6hMn-hB0Q7GhSnhosLNH@mail.gmail.com
State New
Headers show

Commit Message

Kai Tietz April 1, 2011, 6:10 p.m. UTC
2011/4/1 Nathan Froyd <froydnj@codesourcery.com>:
> On Fri, Apr 01, 2011 at 07:39:13PM +0200, Kai Tietz wrote:
>> this patch sets for c++ methods, which are not stdarg ones, the
>> default calling-convention to thiscall for ms_abi 32-bit, as vendor
>> specific compiler does.
>
> I think it might be worthwhile to pull this pattern:
>
>> @@ -5500,7 +5524,8 @@ ix86_function_regparm (const_tree type,
>>    if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
>>      return 2;
>>
>> -  if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (type)))
>> +  if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (type))
>> +      || ix86_is_msabi_thiscall (type))
>
> into a separate function.?  That function could also be used for
> negative tests like this one:
>
>> @@ -9799,7 +9826,8 @@ find_drap_reg (void)
>>         && !lookup_attribute ("fastcall",
>>                               TYPE_ATTRIBUTES (TREE_TYPE (decl)))
>>         && !lookup_attribute ("thiscall",
>> -                             TYPE_ATTRIBUTES (TREE_TYPE (decl))))
>> +                             TYPE_ATTRIBUTES (TREE_TYPE (decl)))
>> +       && ! ix86_is_msabi_thiscall (TREE_TYPE (decl)))
>
> WDYT?
>
> -Nathan
>

Nathan, good idea. I modified patch for this.

ChangeLog

2011-04-01  Kai Tietz

	* i386.c (ix86_is_msabi_thiscall): New helper function.
	(ix86_is_type_thiscall): New helper function.
	(ix86_comp_type_attributes): Handle thiscall for method-functions
	special.
	(init_cumulative_args): Likewise.
	(find_drap_reg): Likewise.
	(ix86_static_chain): Likewise.
	(x86_this_parameter): Likewise.
	(x86_output_mi_thunk): Likewise.

Regards,
Kai

Comments

Richard Henderson April 1, 2011, 6:20 p.m. UTC | #1
On 04/01/2011 11:10 AM, Kai Tietz wrote:
> 	* i386.c (ix86_is_msabi_thiscall): New helper function.
> 	(ix86_is_type_thiscall): New helper function.
> 	(ix86_comp_type_attributes): Handle thiscall for method-functions
> 	special.
> 	(init_cumulative_args): Likewise.
> 	(find_drap_reg): Likewise.
> 	(ix86_static_chain): Likewise.
> 	(x86_this_parameter): Likewise.
> 	(x86_output_mi_thunk): Likewise.

Ok.


r~
diff mbox

Patch

Index: gcc/gcc/config/i386/i386.c
===================================================================
--- gcc.orig/gcc/config/i386/i386.c	2011-04-01 18:26:53.207236300 +0200
+++ gcc/gcc/config/i386/i386.c	2011-04-01 20:08:15.344145300 +0200
@@ -5436,6 +5436,33 @@  ix86_handle_cconv_attribute (tree *node,
   return NULL_TREE;
 }
 
+/* This function checks if the method-function has default __thiscall
+   calling-convention for 32-bit msabi.
+   It returns true if TYPE is of kind METHOD_TYPE, no stdarg function,
+   and the MS_ABI 32-bit is used.  Otherwise it returns false.  */
+
+static bool
+ix86_is_msabi_thiscall (const_tree type)
+{
+  if (TARGET_64BIT || ix86_function_type_abi (type) != MS_ABI
+      || TREE_CODE (type) != METHOD_TYPE || stdarg_p (type))
+    return false;
+  return true;
+}
+
+/* This function checks if the thiscall attribute is set for the TYPE,
+   or if it is an method-type with default thiscall convention.
+   It returns true if function match, otherwise false is returned.  */
+
+static bool
+ix86_is_type_thiscall (const_tree type)
+{
+  if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (type))
+      || ix86_is_msabi_thiscall (type))
+    return true;
+  return false;
+}
+
 /* Return 0 if the attributes for two types are incompatible, 1 if they
    are compatible, and 2 if they are nearly compatible (which causes a
    warning to be generated).  */
@@ -5444,7 +5471,8 @@  static int
 ix86_comp_type_attributes (const_tree type1, const_tree type2)
 {
   /* Check for mismatch of non-default calling convention.  */
-  const char *const rtdstr = TARGET_RTD ? "cdecl" : "stdcall";
+  bool is_thiscall = ix86_is_msabi_thiscall (type1);
+  const char *const rtdstr = TARGET_RTD ? (is_thiscall ? "thiscall" : "cdecl") : "stdcall";
 
   if (TREE_CODE (type1) != FUNCTION_TYPE
       && TREE_CODE (type1) != METHOD_TYPE)
@@ -5463,9 +5491,18 @@  ix86_comp_type_attributes (const_tree ty
     return 0;
 
   /* Check for mismatched thiscall types.  */
-  if (!lookup_attribute ("thiscall", TYPE_ATTRIBUTES (type1))
-      != !lookup_attribute ("thiscall", TYPE_ATTRIBUTES (type2)))
-    return 0;
+  if (is_thiscall && !TARGET_RTD)
+    {
+      if (!lookup_attribute ("cdecl", TYPE_ATTRIBUTES (type1))
+	  != !lookup_attribute ("cdecl", TYPE_ATTRIBUTES (type2)))
+	return 0;
+    }
+  else if (!is_thiscall || TARGET_RTD)
+    {
+      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))
@@ -5500,7 +5537,7 @@  ix86_function_regparm (const_tree type,
   if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
     return 2;
 
-  if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (type)))
+  if (ix86_is_type_thiscall (type))
     return 1;
 
   /* Use register calling convention for local functions when possible.  */
@@ -5666,7 +5703,7 @@  ix86_return_pops_args (tree fundecl, tre
          variable args.  */
       if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype))
 	  || lookup_attribute ("fastcall", TYPE_ATTRIBUTES (funtype))
-          || lookup_attribute ("thiscall", TYPE_ATTRIBUTES (funtype)))
+          || ix86_is_type_thiscall (funtype))
 	rtd = 1;
 
       if (rtd && ! stdarg_p (funtype))
@@ -6004,7 +6041,7 @@  init_cumulative_args (CUMULATIVE_ARGS *c
 	 else look for regparm information.  */
       if (fntype)
 	{
-	  if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (fntype)))
+	  if (ix86_is_type_thiscall (fntype))
 	    {
 	      cum->nregs = 1;
 	      cum->fastcall = 1; /* Same first register as in fastcall.  */
@@ -9798,8 +9835,7 @@  find_drap_reg (void)
       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))))
+	  && !ix86_is_type_thiscall (TREE_TYPE (decl)))
 	return CX_REG;
       else
 	return DI_REG;
@@ -23249,7 +23285,7 @@  ix86_static_chain (const_tree fndecl, bo
 	     us with EAX for the static chain.  */
 	  regno = AX_REG;
 	}
-      else if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (fntype)))
+      else if (ix86_is_type_thiscall (fntype))
 	{
 	  /* Thiscall functions use ecx for arguments, which leaves
 	     us with EAX for the static chain.  */
@@ -29806,7 +29842,7 @@  x86_this_parameter (tree function)
 
       if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
 	regno = aggr ? DX_REG : CX_REG;
-      else if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (type)))
+      else if (ix86_is_type_thiscall (type))
         {
 	  regno = CX_REG;
 	  if (aggr)
@@ -29925,8 +29961,7 @@  x86_output_mi_thunk (FILE *file,
 	  int tmp_regno = CX_REG;
 	  if (lookup_attribute ("fastcall",
 				TYPE_ATTRIBUTES (TREE_TYPE (function)))
-	      || lookup_attribute ("thiscall",
-				   TYPE_ATTRIBUTES (TREE_TYPE (function))))
+	      || ix86_is_type_thiscall (TREE_TYPE (function)))
 	    tmp_regno = AX_REG;
 	  tmp = gen_rtx_REG (SImode, tmp_regno);
 	}