This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] 2nd try: Add sseregparm function attribute for x86
Richard Henderson wrote:
> On Thu, Jun 09, 2005 at 12:03:50AM +0200, Richard Guenther wrote:
>
>>+ /* Handle a "sseregparm" attribute;
>>+ arguments as in struct attribute_spec.handler. */
>>+ static tree
>>+ ix86_handle_sseregparm_attribute (tree *node, tree name,
>>+ tree args ATTRIBUTE_UNUSED,
>>+ int flags ATTRIBUTE_UNUSED,
>>+ bool *no_add_attrs)
>>+ {
>>+ if (TREE_CODE (*node) != FUNCTION_TYPE
>>+ && TREE_CODE (*node) != METHOD_TYPE)
>>+ {
>>+ warning (OPT_Wattributes, "%qs attribute only applies to functions",
>>+ IDENTIFIER_POINTER (name));
>>+ *no_add_attrs = true;
>>+ }
>>+
>>+ return NULL_TREE;
>
>
> This needs to handle all the other calling conventions, and rejecting
> combinations that don't make sense. I guess this could be paired with
> regparm or fastcall, since sseregparm doesn't say anything about integer
> data, but it certainly can't be paired with cdecl or stdcall.
Btw., why do you think it cannot be paired with cdecl or stdcall? From
the documentation these affect only who's going to pop the argument
stack, and this could still be applied to remaining integer arguments.
If all these combinations work is another question, though. I.e. my
current attribute handling function looks like the attached one.
Richard.
/* Handle "cdecl", "stdcall", "fastcall", "regparm" and "sseregparm"
calling convention attributes;
arguments as in struct attribute_spec.handler. */
static tree
ix86_handle_cconv_attribute (tree *node, tree name,
tree args,
int flags ATTRIBUTE_UNUSED,
bool *no_add_attrs)
{
if (TREE_CODE (*node) != FUNCTION_TYPE
&& TREE_CODE (*node) != METHOD_TYPE
&& TREE_CODE (*node) != FIELD_DECL
&& TREE_CODE (*node) != TYPE_DECL)
{
warning (OPT_Wattributes, "%qs attribute only applies to functions",
IDENTIFIER_POINTER (name));
*no_add_attrs = true;
return NULL_TREE;
}
if (TARGET_64BIT)
{
warning (OPT_Wattributes, "%qs attribute ignored",
IDENTIFIER_POINTER (name));
*no_add_attrs = true;
return NULL_TREE;
}
/* Can combine fastcall with stdcall (redundant) and sseregparm. */
if (is_attribute_p ("fastcall", name))
{
if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (*node)))
{
error ("fastcall and cdecl attributes are not compatible");
}
if (lookup_attribute ("regparm", TYPE_ATTRIBUTES (*node)))
{
error ("fastcall and regparm attributes are not compatible");
}
}
/* Can combine stdcall with fastcall (redundant), regparm and
sseregparm. */
else if (is_attribute_p ("stdcall", name))
{
if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (*node)))
{
error ("stdcall and cdecl attributes are not compatible");
}
}
/* Can combine cdecl with regparm and sseregparm. */
else if (is_attribute_p ("cdecl", name))
{
if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (*node)))
{
error ("stdcall and cdecl attributes are not compatible");
}
if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
{
error ("fastcall and cdecl attributes are not compatible");
}
}
/* Can combine sseregparm with all attributes. */
else if (is_attribute_p ("sseregparm", name))
;
/* Can combine regparm with all attributes but fastcall. */
else if (is_attribute_p ("regparm", name))
{
tree cst;
if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
{
error ("fastcall and regparm attributes are not compatible");
}
cst = TREE_VALUE (args);
if (TREE_CODE (cst) != INTEGER_CST)
{
warning (OPT_Wattributes,
"%qs attribute requires an integer constant argument",
IDENTIFIER_POINTER (name));
*no_add_attrs = true;
}
else if (compare_tree_int (cst, REGPARM_MAX) > 0)
{
warning (OPT_Wattributes, "argument to %qs attribute larger than %d",
IDENTIFIER_POINTER (name), REGPARM_MAX);
*no_add_attrs = true;
}
}
return NULL_TREE;
}