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

[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 > =

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值