From patchwork Fri Apr 1 18:10:21 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kai Tietz X-Patchwork-Id: 89315 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 72B62B6F97 for ; Sat, 2 Apr 2011 05:10:31 +1100 (EST) Received: (qmail 2453 invoked by alias); 1 Apr 2011 18:10:29 -0000 Received: (qmail 2443 invoked by uid 22791); 1 Apr 2011 18:10:27 -0000 X-SWARE-Spam-Status: No, hits=-1.0 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, RFC_ABUSE_POST X-Spam-Check-By: sourceware.org Received: from mail-qy0-f182.google.com (HELO mail-qy0-f182.google.com) (209.85.216.182) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 01 Apr 2011 18:10:22 +0000 Received: by qyk27 with SMTP id 27so2954680qyk.20 for ; Fri, 01 Apr 2011 11:10:21 -0700 (PDT) MIME-Version: 1.0 Received: by 10.229.0.75 with SMTP id 11mr3720120qca.94.1301681421196; Fri, 01 Apr 2011 11:10:21 -0700 (PDT) Received: by 10.229.97.206 with HTTP; Fri, 1 Apr 2011 11:10:21 -0700 (PDT) In-Reply-To: <20110401174309.GT23480@codesourcery.com> References: <20110401174309.GT23480@codesourcery.com> Date: Fri, 1 Apr 2011 20:10:21 +0200 Message-ID: Subject: Re: [patch i386]: Set for method-functions default calling-convention to thiscall for 32-bit msabi From: Kai Tietz To: Nathan Froyd Cc: GCC Patches , Richard Henderson X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 2011/4/1 Nathan Froyd : > 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 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); }