From: Kai Tietz Date: Mon, 11 Apr 2011 17:44:04 +0000 (+0200) Subject: re PR target/9601 (-mrtd switch/stdcall attribute raises warnings for __buitltin... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b8ce4e945b396bc6db1da17d54d8a024ad5d7edb;p=gcc.git re PR target/9601 (-mrtd switch/stdcall attribute raises warnings for __buitltin functions) 2011-04-11 Kai Tietz PR target/9601 PR target/11772 * config/i386/i386-protos.h (ix86_get_callcvt): New prototype. * config/i386/i386.c (ix86_handle_cconv_attribute): Adjust comment. (ix86_is_msabi_thiscall): Removed. (ix86_is_type_thiscall): Likewise. (ix86_get_callcvt): New function. (ix86_comp_type_attributes): Simplify check. (ix86_function_regparm): Use ix86_get_callcvt for calling convention attribute checks. (ix86_return_pops_args): Likewise. (ix86_static_chain): Likewise. (x86_this_parameter): Likewise. (x86_output_mi_thunk): Likewise. (ix86_function_type_abi): Optimize check for types without attributes. * config/i386/i386.h (IX86_CALLCVT_CDECL, IX86_CALLCVT_STDCALL, IX86_CALLCVT_FASTCALL, IX86_CALLCVT_THISCALL, IX86_CALLCVT_REGPARM, IX86_CALLCVT_SSEREGPARM): New macros to represent calling convention by flag-values. (IX86_BASE_CALLCVT): Helper macro. * config/i386/netware.c (i386_nlm_maybe_mangle_decl_assembler_name): Use ix86_get_callcvt for calling convention attribute checks and avoid symbol-decoration for stdcall in TARGET_RTD case. * config/i386/winnt.c (i386_pe_maybe_mangle_decl_assembler_name): Likewise. (gen_stdcall_or_fastcall_suffix): Adjust ident and use DECL_ORIGIN for declaration. From-SVN: r172268 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 80e8c3bf025..36ca4804b12 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,34 @@ +2011-04-11 Kai Tietz + + PR target/9601 + PR target/11772 + * config/i386/i386-protos.h (ix86_get_callcvt): New prototype. + * config/i386/i386.c (ix86_handle_cconv_attribute): Adjust + comment. + (ix86_is_msabi_thiscall): Removed. + (ix86_is_type_thiscall): Likewise. + (ix86_get_callcvt): New function. + (ix86_comp_type_attributes): Simplify check. + (ix86_function_regparm): Use ix86_get_callcvt for calling + convention attribute checks. + (ix86_return_pops_args): Likewise. + (ix86_static_chain): Likewise. + (x86_this_parameter): Likewise. + (x86_output_mi_thunk): Likewise. + (ix86_function_type_abi): Optimize check for types without attributes. + * config/i386/i386.h (IX86_CALLCVT_CDECL, IX86_CALLCVT_STDCALL, + IX86_CALLCVT_FASTCALL, IX86_CALLCVT_THISCALL, IX86_CALLCVT_REGPARM, + IX86_CALLCVT_SSEREGPARM): New macros to represent calling convention + by flag-values. + (IX86_BASE_CALLCVT): Helper macro. + * config/i386/netware.c (i386_nlm_maybe_mangle_decl_assembler_name): + Use ix86_get_callcvt for calling convention attribute checks and avoid + symbol-decoration for stdcall in TARGET_RTD case. + * config/i386/winnt.c (i386_pe_maybe_mangle_decl_assembler_name): + Likewise. + (gen_stdcall_or_fastcall_suffix): Adjust ident and use DECL_ORIGIN + for declaration. + 2011-04-11 Uros Bizjak * config/i386/sse.md (VI_128): New mode iterator. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 4f90b502167..4b34e411808 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -191,6 +191,8 @@ extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *); extern tree ix86_handle_selectany_attribute (tree *, tree, tree, int, bool *); extern int x86_field_alignment (tree, int); extern tree ix86_valid_target_attribute_tree (tree); +extern unsigned int ix86_get_callcvt (const_tree); + #endif extern rtx ix86_tls_get_addr (void); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index cd47ba75f94..62187021e8a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5312,7 +5312,7 @@ ix86_handle_cconv_attribute (tree *node, tree name, return NULL_TREE; } - /* Can combine regparm with all attributes but fastcall. */ + /* Can combine regparm with all attributes but fastcall, and thiscall. */ if (is_attribute_p ("regparm", name)) { tree cst; @@ -5436,38 +5436,54 @@ ix86_handle_cconv_attribute (tree *node, tree name, 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. */ +/* This function determines from TYPE the calling-convention. */ -static bool -ix86_is_msabi_thiscall (const_tree type) +unsigned int +ix86_get_callcvt (const_tree type) { - if (TARGET_64BIT || ix86_function_type_abi (type) != MS_ABI - || TREE_CODE (type) != METHOD_TYPE || stdarg_p (type)) - return false; - /* Check for different calling-conventions. */ - if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (type)) - || lookup_attribute ("stdcall", TYPE_ATTRIBUTES (type)) - || lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)) - || lookup_attribute ("regparm", TYPE_ATTRIBUTES (type)) - || lookup_attribute ("sseregparm", TYPE_ATTRIBUTES (type))) - return false; - return true; -} + unsigned int ret = 0; + bool is_stdarg; + tree attrs; -/* 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. */ + if (TARGET_64BIT) + return IX86_CALLCVT_CDECL; -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; + attrs = TYPE_ATTRIBUTES (type); + if (attrs != NULL_TREE) + { + if (lookup_attribute ("cdecl", attrs)) + ret |= IX86_CALLCVT_CDECL; + else if (lookup_attribute ("stdcall", attrs)) + ret |= IX86_CALLCVT_STDCALL; + else if (lookup_attribute ("fastcall", attrs)) + ret |= IX86_CALLCVT_FASTCALL; + else if (lookup_attribute ("thiscall", attrs)) + ret |= IX86_CALLCVT_THISCALL; + + /* Regparam isn't allowed for thiscall and fastcall. */ + if ((ret & (IX86_CALLCVT_THISCALL | IX86_CALLCVT_FASTCALL)) == 0) + { + if (lookup_attribute ("regparm", attrs)) + ret |= IX86_CALLCVT_REGPARM; + if (lookup_attribute ("sseregparm", attrs)) + ret |= IX86_CALLCVT_SSEREGPARM; + } + + if (IX86_BASE_CALLCVT(ret) != 0) + return ret; + } + + is_stdarg = stdarg_p (type); + if (TARGET_RTD && !is_stdarg) + return IX86_CALLCVT_STDCALL | ret; + + if (ret != 0 + || is_stdarg + || TREE_CODE (type) != METHOD_TYPE + || ix86_function_type_abi (type) != MS_ABI) + return IX86_CALLCVT_CDECL | ret; + + return IX86_CALLCVT_THISCALL; } /* Return 0 if the attributes for two types are incompatible, 1 if they @@ -5477,43 +5493,18 @@ ix86_is_type_thiscall (const_tree type) static int ix86_comp_type_attributes (const_tree type1, const_tree type2) { - /* Check for mismatch of non-default calling convention. */ - bool is_thiscall = ix86_is_msabi_thiscall (type1); - const char *const rtdstr = TARGET_RTD ? (is_thiscall ? "thiscall" : "cdecl") : "stdcall"; + unsigned int ccvt1, ccvt2; if (TREE_CODE (type1) != FUNCTION_TYPE && TREE_CODE (type1) != METHOD_TYPE) return 1; - /* Check for mismatched fastcall/regparm types. */ - if ((!lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type1)) - != !lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type2))) - || (ix86_function_regparm (type1, NULL) - != ix86_function_regparm (type2, NULL))) - return 0; - - /* Check for mismatched sseregparm types. */ - if (!lookup_attribute ("sseregparm", TYPE_ATTRIBUTES (type1)) - != !lookup_attribute ("sseregparm", TYPE_ATTRIBUTES (type2))) + ccvt1 = ix86_get_callcvt (type1); + ccvt2 = ix86_get_callcvt (type2); + if (ccvt1 != ccvt2) return 0; - - /* Check for mismatched thiscall types. */ - 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)) - != !lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type2))) + if (ix86_function_regparm (type1, NULL) + != ix86_function_regparm (type2, NULL)) return 0; return 1; @@ -5528,23 +5519,26 @@ ix86_function_regparm (const_tree type, const_tree decl) { tree attr; int regparm; + unsigned int ccvt; if (TARGET_64BIT) return (ix86_function_type_abi (type) == SYSV_ABI ? X86_64_REGPARM_MAX : X86_64_MS_REGPARM_MAX); - + ccvt = ix86_get_callcvt (type); regparm = ix86_regparm; - attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type)); - if (attr) + + if ((ccvt & IX86_CALLCVT_REGPARM) != 0) { - regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))); - return regparm; + attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type)); + if (attr) + { + regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))); + return regparm; + } } - - if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type))) + else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0) return 2; - - if (ix86_is_type_thiscall (type)) + else if ((ccvt & IX86_CALLCVT_THISCALL) != 0) return 1; /* Use register calling convention for local functions when possible. */ @@ -5695,27 +5689,18 @@ ix86_keep_aggregate_return_pointer (tree fntype) static int ix86_return_pops_args (tree fundecl, tree funtype, int size) { - int rtd; + unsigned int ccvt; /* None of the 64-bit ABIs pop arguments. */ if (TARGET_64BIT) return 0; - rtd = TARGET_RTD && (!fundecl || TREE_CODE (fundecl) != IDENTIFIER_NODE); + ccvt = ix86_get_callcvt (funtype); - /* Cdecl functions override -mrtd, and never pop the stack. */ - if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) - { - /* 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)) - || ix86_is_type_thiscall (funtype)) - rtd = 1; - - if (rtd && ! stdarg_p (funtype)) - return size; - } + if ((ccvt & (IX86_CALLCVT_STDCALL | IX86_CALLCVT_FASTCALL + | IX86_CALLCVT_THISCALL)) != 0 + && ! stdarg_p (funtype)) + return size; /* Lose any fake structure return argument if it is passed on the stack. */ if (aggregate_value_p (TREE_TYPE (funtype), fundecl) @@ -5818,7 +5803,7 @@ ix86_reg_parm_stack_space (const_tree fndecl) enum calling_abi ix86_function_type_abi (const_tree fntype) { - if (fntype != NULL) + if (fntype != NULL_TREE && TYPE_ATTRIBUTES (fntype) != NULL_TREE) { enum calling_abi abi = ix86_abi; if (abi == SYSV_ABI) @@ -6048,12 +6033,13 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */ else look for regparm information. */ if (fntype) { - if (ix86_is_type_thiscall (fntype)) + unsigned int ccvt = ix86_get_callcvt (fntype); + if ((ccvt & IX86_CALLCVT_THISCALL) != 0) { cum->nregs = 1; cum->fastcall = 1; /* Same first register as in fastcall. */ } - else if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype))) + else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0) { cum->nregs = 2; cum->fastcall = 1; @@ -9839,13 +9825,13 @@ find_drap_reg (void) /* Reuse static chain register if it isn't used for parameter passing. */ - if (ix86_function_regparm (TREE_TYPE (decl), decl) <= 2 - && !lookup_attribute ("fastcall", - TYPE_ATTRIBUTES (TREE_TYPE (decl))) - && !ix86_is_type_thiscall (TREE_TYPE (decl))) - return CX_REG; - else - return DI_REG; + if (ix86_function_regparm (TREE_TYPE (decl), decl) <= 2) + { + unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (decl)); + if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) == 0) + return CX_REG; + } + return DI_REG; } } @@ -23283,20 +23269,19 @@ ix86_static_chain (const_tree fndecl, bool incoming_p) else { tree fntype; + unsigned int ccvt; + /* By default in 32-bit mode we use ECX to pass the static chain. */ regno = CX_REG; fntype = TREE_TYPE (fndecl); - if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype))) + ccvt = ix86_get_callcvt (fntype); + if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) != 0) { /* Fastcall functions use ecx/edx for arguments, which leaves - us with EAX for the static chain. */ - regno = AX_REG; - } - else if (ix86_is_type_thiscall (fntype)) - { - /* Thiscall functions use ecx for arguments, which leaves - us with EAX for the static chain. */ + us with EAX for the static chain. + Thiscall functions use ecx for arguments, which also + leaves us with EAX for the static chain. */ regno = AX_REG; } else if (ix86_function_regparm (fntype, fndecl) == 3) @@ -29847,10 +29832,11 @@ x86_this_parameter (tree function) if (nregs > 0 && !stdarg_p (type)) { int regno; + unsigned int ccvt = ix86_get_callcvt (type); - if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type))) + if ((ccvt & IX86_CALLCVT_FASTCALL) != 0) regno = aggr ? DX_REG : CX_REG; - else if (ix86_is_type_thiscall (type)) + else if ((ccvt & IX86_CALLCVT_THISCALL) != 0) { regno = CX_REG; if (aggr) @@ -29967,9 +29953,8 @@ x86_output_mi_thunk (FILE *file, else { int tmp_regno = CX_REG; - if (lookup_attribute ("fastcall", - TYPE_ATTRIBUTES (TREE_TYPE (function))) - || ix86_is_type_thiscall (TREE_TYPE (function))) + unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (function)); + if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) != 0) tmp_regno = AX_REG; tmp = gen_rtx_REG (SImode, tmp_regno); } diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index c7f3bd4dc6d..511429a727a 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2368,6 +2368,18 @@ extern void debug_dispatch_window (int); ((VALUE) = GET_MODE_BITSIZE (MODE), TARGET_BMI) +/* Flags returned by ix86_get_callcvt (). */ +#define IX86_CALLCVT_CDECL 0x1 +#define IX86_CALLCVT_STDCALL 0x2 +#define IX86_CALLCVT_FASTCALL 0x4 +#define IX86_CALLCVT_THISCALL 0x8 +#define IX86_CALLCVT_REGPARM 0x10 +#define IX86_CALLCVT_SSEREGPARM 0x20 + +#define IX86_BASE_CALLCVT(FLAGS) \ + ((FLAGS) & (IX86_CALLCVT_CDECL | IX86_CALLCVT_STDCALL \ + | IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) + /* Local variables: version-control: t diff --git a/gcc/config/i386/netware.c b/gcc/config/i386/netware.c index 2232dbf6e51..80f26f88aec 100644 --- a/gcc/config/i386/netware.c +++ b/gcc/config/i386/netware.c @@ -148,12 +148,20 @@ i386_nlm_maybe_mangle_decl_assembler_name (tree decl, tree id) { tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl)); tree new_id; + unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (decl)); - if (lookup_attribute ("stdcall", type_attributes)) - new_id = gen_stdcall_or_fastcall_decoration (decl, id, '_'); - else if (lookup_attribute ("fastcall", type_attributes)) + if ((ccvt & IX86_CALLCVT_STDCALL) != 0) + { + if (TARGET_RTD) + /* If we are using -mrtd emit undecorated symbol and let linker + do the proper resolving. */ + return NULL_TREE; + new_id = gen_stdcall_or_fastcall_decoration (decl, id, '_'); + } + else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0) new_id = gen_stdcall_or_fastcall_decoration (decl, id, FASTCALL_PREFIX); - else if ((new_id = lookup_attribute ("regparm", type_attributes))) + else if ((cvt & IX86_CALLCVT_REGPARM) != 0 + && (new_id = lookup_attribute ("regparm", type_attributes))) new_id = gen_regparm_prefix (decl, id, TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (new_id)))); else diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index 169832fd36a..8e7043f1fe5 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -170,7 +170,7 @@ gen_stdcall_or_fastcall_suffix (tree decl, tree id, bool fastcall) HOST_WIDE_INT total = 0; const char *old_str = IDENTIFIER_POINTER (id != NULL_TREE ? id : DECL_NAME (decl)); char *new_str, *p; - tree type = TREE_TYPE (decl); + tree type = TREE_TYPE (DECL_ORIGIN (decl)); tree arg; function_args_iterator args_iter; @@ -202,7 +202,8 @@ gen_stdcall_or_fastcall_suffix (tree decl, tree id, bool fastcall) / parm_boundary_bytes * parm_boundary_bytes); total += parm_size; } - } + } + /* Assume max of 8 base 10 digits in the suffix. */ p = new_str = XALLOCAVEC (char, 1 + strlen (old_str) + 1 + 8 + 1); if (fastcall) @@ -222,10 +223,16 @@ i386_pe_maybe_mangle_decl_assembler_name (tree decl, tree id) if (TREE_CODE (decl) == FUNCTION_DECL) { - tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl)); - if (lookup_attribute ("stdcall", type_attributes)) - new_id = gen_stdcall_or_fastcall_suffix (decl, id, false); - else if (lookup_attribute ("fastcall", type_attributes)) + unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (decl)); + if ((ccvt & IX86_CALLCVT_STDCALL) != 0) + { + if (TARGET_RTD) + /* If we are using -mrtd emit undecorated symbol and let linker + do the proper resolving. */ + return NULL_TREE; + new_id = gen_stdcall_or_fastcall_suffix (decl, id, false); + } + else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0) new_id = gen_stdcall_or_fastcall_suffix (decl, id, true); }