现在的位置: 首页 > 综合 > 正文

gcc [patch i386]: Enable ms_abi/sysv_abi and add testcases(linux平台 调试、调用windows编译的obj文件)

2017年10月31日 ⁄ 综合 ⁄ 共 5377字 ⁄ 字号 评论关闭

[patch i386]: Enable ms_abi/sysv_abi and add testcases
From: Jan Hubicka
To: Kai Tietz
Cc: gcc-patches at gcc dot gnu dot org, Jan Hubicka
Date: Thu, 12 Jun 2008 14:49:07 +0200
Subject: Re: [patch i386]: Enable ms_abi/sysv_abi and add testcases
References:
--------------------------------------------------------------------------------
> Hi,
>
> This patch enables the new function attributes sysv_abi and ms_abi for
> i386 attribute based calling convention switch for x86_64 and w64.
> The test are just executed for x86_64-*-linux*, because the va_list
> arguments are at the moment not compatible for variable-argument calls
> from w64 to x86_64.
>
> Index: gcc/gcc/testsuite/gcc.dg/callabi/callabi.h
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/callabi/callabi.h
> @@ -0,0 +1,22 @@
> +/* First the default target definition. */
> +#ifndef __GNUC_VA_LIST
> +#define __GNUC_VA_LIST
> + typedef __builtin_va_list __gnuc_va_list;
> +#endif
> +
> +#ifndef _VA_LIST_DEFINED
> +#define _VA_LIST_DEFINED
> + typedef __gnuc_va_list va_list;
> +#endif
> +
> +#define __va_copy(d,s) __builtin_va_copy(d,s)
> +#define __va_start(v,l) __builtin_va_start(v,l)
> +#define __va_arg(v,l) __builtin_va_arg(v,l)
> +#define __va_end(v) __builtin_va_end(v)
You can't just include stdarg here to get those defined?
I am bit confused here, since the ms_abi define va_list as a pointer,
while sysv_abi va_list is array. I would expect that in order to write
va_list operations in alien ABI, we would need different type of va_list
used, that would probably imply exporting new set of builtins or make
them polymorphic?
Honza
> +
> +#define CALLABI_NATIVE
> +#ifdef _WIN64
> +#define CALLABI_CROSS __attribute__ ((sysv_abi))
> +#else
> +#define CALLABI_CROSS __attribute__ ((ms_abi))
> +#endif
> / No newline at end of file
> Index: gcc/gcc/config/i386/i386.c
> ===================================================================
> --- gcc.orig/gcc/config/i386/i386.c
> +++ gcc/gcc/config/i386/i386.c
> @@ -23049,6 +23049,58 @@ x86_order_regs_for_local_alloc (void)
> reg_alloc_order [pos++] = 0;
> }
>
> +/* Handle a "ms_abi" or "sysv" attribute; arguments as in
> + struct attribute_spec.handler. */
> +static tree
> +ix86_handle_abi_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
> + && 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 only available for 64-bit",
> + IDENTIFIER_POINTER (name));
> + *no_add_attrs = true;
> + return NULL_TREE;
> + }
> +
> + /* Can combine regparm with all attributes but fastcall. */
> + if (is_attribute_p ("ms_abi", name))
> + {
> + tree cst;
> +
> + if (lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (*node)))
> + {
> + error ("ms_abi and sysv_abi attributes are not compatible");
> + }
> +
> + return NULL_TREE;
> + }
> + else if (is_attribute_p ("sysv_abi", name))
> + {
> + tree cst;
> +
> + if (lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (*node)))
> + {
> + error ("ms_abi and sysv_abi attributes are not compatible");
> + }
> +
> + return NULL_TREE;
> + }
> +
> + return NULL_TREE;
> +}
> +
> /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
> struct attribute_spec.handler. */
> static tree
> @@ -25858,6 +25910,10 @@ static const struct attribute_spec ix86_
> #ifdef SUBTARGET_ATTRIBUTE_TABLE
> SUBTARGET_ATTRIBUTE_TABLE,
> #endif
> + /* ms_abi and sysv_abi calling convention function attributes. */
> + { "ms_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
> + { "sysv_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
> + /* End element. */
> { NULL, 0, 0, false, false, false, NULL }
> };
>
> Index: gcc/gcc/testsuite/gcc.dg/callabi/vaarg-1.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/callabi/vaarg-1.c
> @@ -0,0 +1,47 @@
> +/* Test for cross x86_64<->w64 abi va_list calls.
> +*/
> +/* Origin: Kai Tietz */
> +/* { dg-do run { target { x86_64-*-linux* } } } */
> +/* { dg-options "-std=gnu99" } */
> +#include "callabi.h"
> +
> +extern __SIZE_TYPE__ strlen (const char *);
> +extern int sprintf (char *,const char *, ...);
> +extern void abort (void);
> +
> +static
> +void CALLABI_CROSS vdo_cpy (char *s, va_list argp)
> +{
> + __SIZE_TYPE__ len;
> + char *r = s;
> + char *e;
> + *r = 0;
> + for (;;) {
> + e = __va_arg (argp,char *);
> + if (*e == 0) break;
> + sprintf (r," %s", e);
> + r += strlen (r);
> + }
> +}
> +
> +static
> +void CALLABI_CROSS do_cpy (char *s, ...)
> +{
> + va_list argp;
> + __va_start (argp, s);
> + vdo_cpy (s, argp);
> + __va_end (argp);
> +}
> +
> +int main ()
> +{
> + char s[256];
> +
> + do_cpy (s, "1","2","3","4", "5", "6", "7", "");
> +
> + if (s[0] != '1' || s[1] !='2' || s[2] != '3' || s[3] != '4'
> + || s[4] != '5' || s[5] != '6' || s[6] != '7' || s[7] != 0)
> + abort ();
> +
> + return 0;
> +}
> Index: gcc/gcc/testsuite/gcc.dg/callabi/func-1.c
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/gcc.dg/callabi/func-1.c
> @@ -0,0 +1,40 @@
> +/* Test for cross x86_64<->w64 abi standard calls.
> +*/
> +/* Origin: Kai Tietz */
> +/* { dg-do run { target { x86_64-*-linux* } } } */
> +/* { dg-options "-std=gnu99" } */
> +#include "callabi.h"
> +
> +extern void abort (void);
> +
> +long double
> +CALLABI_CROSS func_cross (long double a, double b, float c, long d, int e,
> + char f)
> +{
> + long double ret;
> + ret = a + (long double) b + (long double) c;
> + ret *= (long double) (d + (long) e);
> + if (f>0)
> + ret += func_cross (a,b,c,d,e,-f);
> + return ret;
> +}
> +
> +long double
> +CALLABI_NATIVE func_native (long double a, double b, float c, long d, int e,
> + char f)
> +{
> + long double ret;
> + ret = a + (long double) b + (long double) c;
> + ret *= (long double) (d + (long) e);
> + if (f>0)
> + ret += func_native (a,b,c,d,e,-f);
> + return ret;
> +}
> +
> +int main ()
> +{
> + if (func_cross (1.0,2.0,3.0,1,2,3)
> + != func_native (1.0,2.0,3.0,1,2,3))
> + abort ();
> + return 0;
> +}
> / No newline at end of file
> =

抱歉!评论已关闭.