Hello Christian, Thank you for sending me the header file. It turns out the same file exists in my Linux machine too. I'll try to implement va_arg support for PowerPC in next release(5.15.54). However, I do not have PowerPC , so please debug by yourself. We need several iteration debugging this. I'd appreciate your cooperation. Masaharu Goto ----- Original Message ----- From: "cstrato" <cstrato@aon.at> To: "Masaharu Goto" <MXJ02154@nifty.ne.jp> Cc: "Jiri Masik" <masik@fzu.cz>; <roottalk@pcroot.cern.ch> Sent: Friday, August 23, 2002 4:03 AM Subject: Re: Support of variable arguments: Re: [ROOT] Form on Alpha OSF > Dear Masaharu > > Thank you for your extensive answer. > Enclosed I have attached the stdarg.h and va-ppc.h files > for the Mac/IBM/PowerPC platform. It would be great, if > CINT could support this platform. > > Thank you > Christian > > > Masaharu Goto wrote: > > > Hello Jiri and Christian, > > > > Support for variable arguments (between compiled code and interpreter) > > depends on stack data alignment of specific CPU architecture. So far, > > I investigated Intel, HP-PA and Sparc. It turned out passing class/struct > > object as value is a fundamental problem in HP-PA and Sparc. For those > > CPUs, only fundamental type arguments can be passed. Intel architecture > > is fine for passing class/struct object as value. I am not sure for > > Mac/PowerPC platform. > > > > This is implemented in following locations in Cint source code. > > > > G__ci.h line 1608-1633 > > Define macro for turning on/off the vaarg feature depending on > > computer architecture. > > > > src/size.c line 1258-1266 > > Implements vaarg byte alignment. You can add implementation > > for other platforms if you'd like. Normally, vaarg alignment rule is > > described in include/stdarg.h and in va_arg() macro. This macro > > is a really complicated beast, however, if you try hard, it tells you > > how variable arguments are implemented in your compiler. > > > > Probably, I can tell you a little more about Mac/PowerPC if you > > send me include/stdarg.h. > > > > Thank you > > Masaharu Goto > > > > ----- Original Message ----- > > From: "cstrato" <cstrato@aon.at> > > To: "Jiri Masik" <masik@fzu.cz> > > Cc: <roottalk@pcroot.cern.ch> > > Sent: Thursday, August 22, 2002 4:00 AM > > Subject: Support of variable arguments: Re: [ROOT] Form on Alpha OSF > > > > > > > >>Dear Rooters > >> > >>I am, too, missing support for variable arguments on the Mac, > >>i.e. the PowerPC platform. > >>Does anyone know if support is planned in the future? > >> > >>Best regards > >>Christian > >>_._._._._._._._._._._._._._._._ > >>C.h.i.s.t.i.a.n S.t.r.a.t.o.w.a > >>V.i.e.n.n.a A.u.s.t.r.i.a > >>_._._._._._._._._._._._._._._._ > >> > >> > >>Jiri Masik wrote: > >> > >> > >>>Thomas Bretz <tbretz@astro.uni-wuerzburg.de> writes: > >>> > >>> > >>> > >>>>Hi, > >>>> > >>>>what's the reason, that Form is not supported on Alphas in the > >>>> > > interpreter? > > > >>>>Thomas. > >>>> > >>>> > >>>Hi Thomas, > >>> > >>>Form relies on the implementation of variable arguments functions in > >>>Cint which is currently done only for Linux on ia32 and Win32 I think. > >>>You can do grep -r G__VAARG * in Root tree to get an idea what is > >>>needed. > >>> > >>>cheers > >>> Jiri > >>> > >>> > >>> > >>> > >> > > > > > > > > ---------------------------------------------------------------------------- ---- > /* stdarg.h for GNU. > Note that the type used in va_arg is supposed to match the > actual type **after default promotions**. > Thus, va_arg (..., short) is not valid. */ > > #ifndef _STDARG_H > #ifndef _ANSI_STDARG_H_ > #ifndef __need___va_list > #define _STDARG_H > #define _ANSI_STDARG_H_ > #endif /* not __need___va_list */ > #undef __need___va_list > > #ifdef __clipper__ > #include "va-clipper.h" > #else > #ifdef __m88k__ > #include "va-m88k.h" > #else > #ifdef __i860__ > #include "va-i860.h" > #else > #ifdef __hppa__ > #include "va-pa.h" > #else > #ifdef __mips__ > #include "va-mips.h" > #else > #ifdef __sparc__ > #include "va-sparc.h" > #else > #ifdef __i960__ > #include "va-i960.h" > #else > #ifdef __alpha__ > #include "va-alpha.h" > #else > #if defined (__H8300__) || defined (__H8300H__) || defined (__H8300S__) > #include "va-h8300.h" > #else > #if defined (_AIX) || (defined (__ppc__) && defined (__APPLE__)) || (defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32))) > #include "va-ppc.h" > #else > #ifdef __arc__ > #include "va-arc.h" > #else > #ifdef __M32R__ > #include "va-m32r.h" > #else > #ifdef __sh__ > #include "va-sh.h" > #else > #ifdef __mn10300__ > #include "va-mn10300.h" > #else > #ifdef __mn10200__ > #include "va-mn10200.h" > #else > #ifdef __v850__ > #include "va-v850.h" > #else > #if defined (_TMS320C4x) || defined (_TMS320C3x) > #include <va-c4x.h> > #else > > /* Define __gnuc_va_list. */ > > #ifndef __GNUC_VA_LIST > #define __GNUC_VA_LIST > #if defined(__svr4__) || defined(_AIX) || defined(_M_UNIX) || defined(__NetBSD__) > typedef char *__gnuc_va_list; > #else > typedef void *__gnuc_va_list; > #endif > #endif > > /* Define the standard macros for the user, > if this invocation was from the user program. */ > #ifdef _STDARG_H > > /* Amount of space required in an argument list for an arg of type TYPE. > TYPE may alternatively be an expression whose type is used. */ > > #if defined(sysV68) > #define __va_rounded_size(TYPE) \ > (((sizeof (TYPE) + sizeof (short) - 1) / sizeof (short)) * sizeof (short)) > #elif defined(_AIX) > #define __va_rounded_size(TYPE) \ > (((sizeof (TYPE) + sizeof (long) - 1) / sizeof (long)) * sizeof (long)) > #else > #define __va_rounded_size(TYPE) \ > (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) > #endif > > #define va_start(AP, LASTARG) \ > (AP = ((__gnuc_va_list) __builtin_next_arg (LASTARG))) > > #undef va_end > void va_end (__gnuc_va_list); /* Defined in libgcc.a */ > #define va_end(AP) ((void)0) > > /* We cast to void * and then to TYPE * because this avoids > a warning about increasing the alignment requirement. */ > > #if (defined (__arm__) && ! defined (__ARMEB__)) || defined (__i386__) || defined (__i860__) || defined (__ns32000__) || defined (__vax__) > /* This is for little-endian machines; small args are padded upward. */ > #define va_arg(AP, TYPE) \ > (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \ > *((TYPE *) (void *) ((char *) (AP) - __va_rounded_size (TYPE)))) > #else /* big-endian */ > /* This is for big-endian machines; small args are padded downward. */ > #define va_arg(AP, TYPE) \ > (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \ > *((TYPE *) (void *) ((char *) (AP) \ > - ((sizeof (TYPE) < __va_rounded_size (char) \ > ? sizeof (TYPE) : __va_rounded_size (TYPE)))))) > #endif /* big-endian */ > > /* Copy __gnuc_va_list into another variable of this type. */ > #define __va_copy(dest, src) (dest) = (src) > > #endif /* _STDARG_H */ > > #endif /* not TMS320C3x or TMS320C4x */ > #endif /* not v850 */ > #endif /* not mn10200 */ > #endif /* not mn10300 */ > #endif /* not sh */ > #endif /* not m32r */ > #endif /* not arc */ > #endif /* not powerpc with V.4 calling sequence */ > #endif /* not h8300 */ > #endif /* not alpha */ > #endif /* not i960 */ > #endif /* not sparc */ > #endif /* not mips */ > #endif /* not hppa */ > #endif /* not i860 */ > #endif /* not m88k */ > #endif /* not clipper */ > > #ifdef _STDARG_H > /* Define va_list, if desired, from __gnuc_va_list. */ > /* We deliberately do not define va_list when called from > stdio.h, because ANSI C says that stdio.h is not supposed to define > va_list. stdio.h needs to have access to that data type, > but must not use that name. It should use the name __gnuc_va_list, > which is safe because it is reserved for the implementation. */ > > #ifdef _HIDDEN_VA_LIST /* On OSF1, this means varargs.h is "half-loaded". */ > #undef _VA_LIST > #endif > > #ifdef _BSD_VA_LIST > #undef _BSD_VA_LIST > #endif > > #if defined(__svr4__) || (defined(_SCO_DS) && !defined(__VA_LIST)) > /* SVR4.2 uses _VA_LIST for an internal alias for va_list, > so we must avoid testing it and setting it here. > SVR4 uses _VA_LIST as a flag in stdarg.h, but we should > have no conflict with that. */ > #ifndef _VA_LIST_ > #define _VA_LIST_ > #ifdef __i860__ > #ifndef _VA_LIST > #define _VA_LIST va_list > #endif > #endif /* __i860__ */ > typedef __gnuc_va_list va_list; > #ifdef _SCO_DS > #define __VA_LIST > #endif > #endif /* _VA_LIST_ */ > #else /* not __svr4__ || _SCO_DS */ > > /* The macro _VA_LIST_ is the same thing used by this file in Ultrix. > But on BSD NET2 we must not test or define or undef it. > (Note that the comments in NET 2's ansi.h > are incorrect for _VA_LIST_--see stdio.h!) */ > #if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT) > /* The macro _VA_LIST_DEFINED is used in Windows NT 3.5 */ > #ifndef _VA_LIST_DEFINED > /* The macro _VA_LIST is used in SCO Unix 3.2. */ > #ifndef _VA_LIST > /* The macro _VA_LIST_T_H is used in the Bull dpx2 */ > #ifndef _VA_LIST_T_H > typedef __gnuc_va_list va_list; > #endif /* not _VA_LIST_T_H */ > #endif /* not _VA_LIST */ > #endif /* not _VA_LIST_DEFINED */ > #if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__)) > #define _VA_LIST_ > #endif > #ifndef _VA_LIST > #define _VA_LIST > #endif > #ifndef _VA_LIST_DEFINED > #define _VA_LIST_DEFINED > #endif > #ifndef _VA_LIST_T_H > #define _VA_LIST_T_H > #endif > > #endif /* not _VA_LIST_, except on certain systems */ > > #endif /* not __svr4__ */ > > #endif /* _STDARG_H */ > > #endif /* not _ANSI_STDARG_H_ */ > #endif /* not _STDARG_H */ > ---------------------------------------------------------------------------- ---- > /* GNU C varargs support for the PowerPC with either the Apple/AIX, V.4 or Windows NT calling sequences */ > > #if defined(_AIX) || defined (__APPLE__) > /* AIX support */ > /* Define __gnuc_va_list. */ > > #ifndef __GNUC_VA_LIST > #define __GNUC_VA_LIST > typedef char *__gnuc_va_list; > #endif > > /* If this is for internal libc use, don't define anything but > __gnuc_va_list. */ > #if defined (_STDARG_H) || defined (_VARARGS_H) > > #ifdef _STDARG_H /* stdarg.h support */ > > /* Calling __builtin_next_arg gives the proper error message if LASTARG is > not indeed the last argument. */ > #define va_start(AP, LASTARG) \ > (AP = ((__gnuc_va_list) __builtin_next_arg (LASTARG))) > > #else /* varargs.h support */ > > /* In GCC version 2, we want an ellipsis at the end of the declaration > of the argument list. GCC version 1 can't parse it. */ > > #if __GNUC__ > 1 > #define __va_ellipsis ... > #else > #define __va_ellipsis > #endif > > /* These macros implement traditional (non-ANSI) varargs > for GNU C. */ > > #define va_alist __builtin_va_alist > /* The ... causes current_function_varargs to be set in cc1. */ > #define va_dcl int __builtin_va_alist; __va_ellipsis > > #define va_start(AP) AP=(char *) &__builtin_va_alist > > #endif /* _STDARG_H */ > > #undef va_end > void va_end (__gnuc_va_list); /* Defined in libgcc.a */ > #define va_end(AP) ((void)0) > > /* We cast to void * and then to TYPE * because this avoids > a warning about increasing the alignment requirement. */ > > #define __va_rounded_size(TYPE) ((sizeof (TYPE) + 3) & ~3) > #define __va_align(AP, TYPE) \ > ((((unsigned long)(AP)) + ((__alignof__ (TYPE) == 16) ? 15 : 3)) \ > & ~((__alignof__ (TYPE) == 16) ? 15 : 3)) > > #define va_arg(AP,TYPE) \ > ( *(TYPE *) (void *) ((AP = (char *) (__va_align(AP, TYPE) \ > + __va_rounded_size(TYPE))) \ > - __va_rounded_size(TYPE))) > > /* Copy __gnuc_va_list into another variable of this type. */ > #define __va_copy(dest, src) (dest) = (src) > > #endif /* _STDARG_H */ > > > #else > #ifndef _WIN32 > /* System V.4 support */ > /* Define __gnuc_va_list. */ > > #ifndef __GNUC_VA_LIST > #define __GNUC_VA_LIST > > #ifndef _SYS_VA_LIST_H > #define _SYS_VA_LIST_H /* Solaris sys/va_list.h */ > > /* Solaris decided to rename overflow_arg_area to input_arg_area, > so handle it via a macro. */ > #define __va_overflow(AP) (AP)->overflow_arg_area > > /* Note that the names in this structure are in the user's namespace, but > that the V.4 abi explicitly states that these names should be used. */ > typedef struct __va_list_tag { > unsigned char gpr; /* index into the array of 8 GPRs stored in the > register save area gpr=0 corresponds to r3, > gpr=1 to r4, etc. */ > unsigned char fpr; /* index into the array of 8 FPRs stored in the > register save area fpr=0 corresponds to f1, > fpr=1 to f2, etc. */ > char *overflow_arg_area; /* location on stack that holds the next > overflow argument */ > char *reg_save_area; /* where r3:r10 and f1:f8, if saved are stored */ > } __va_list[1], __gnuc_va_list[1]; > > #else /* _SYS_VA_LIST */ > > typedef __va_list __gnuc_va_list; > #define __va_overflow(AP) (AP)->input_arg_area > > #endif /* not _SYS_VA_LIST */ > #endif /* not __GNUC_VA_LIST */ > > /* If this is for internal libc use, don't define anything but > __gnuc_va_list. */ > #if defined (_STDARG_H) || defined (_VARARGS_H) > > /* Register save area located below the frame pointer */ > #ifndef __VA_PPC_H__ > #define __VA_PPC_H__ > typedef struct { > long __gp_save[8]; /* save area for GP registers */ > double __fp_save[8]; /* save area for FP registers */ > } __va_regsave_t; > > /* Macros to access the register save area */ > /* We cast to void * and then to TYPE * because this avoids > a warning about increasing the alignment requirement. */ > #define __VA_FP_REGSAVE(AP,OFS,TYPE) \ > ((TYPE *) (void *) (&(((__va_regsave_t *) \ > (AP)->reg_save_area)->__fp_save[OFS]))) > > #define __VA_GP_REGSAVE(AP,OFS,TYPE) \ > ((TYPE *) (void *) (&(((__va_regsave_t *) \ > (AP)->reg_save_area)->__gp_save[OFS]))) > > /* Common code for va_start for both varargs and stdarg. This depends > on the format of rs6000_args in rs6000.h. The fields used are: > > #0 GWORDS # words used for GP registers > #1 FREGNO next available FP register > #2 NARGS_PROTOTYPE # args left in the current prototype > #3 ORIG_NARGS original value of NARGS_PROTOTYPE > #4 VARARGS_OFFSET offset from frame pointer of varargs area */ > > #define __va_gwords __builtin_args_info (0) > #define __va_fregno __builtin_args_info (1) > #define __va_nargs __builtin_args_info (2) > #define __va_orig_nargs __builtin_args_info (3) > #define __va_varargs_offset __builtin_args_info (4) > > #define __va_start_common(AP, LASTARG, FAKE) \ > __extension__ ({ \ > register int __gwords = __va_gwords - FAKE; \ > \ > (AP)->gpr = (__gwords < 8) ? __gwords : 8; \ > (AP)->fpr = __va_fregno - 33; \ > (AP)->reg_save_area = (((char *) __builtin_frame_address (0)) \ > + __va_varargs_offset); \ > __va_overflow(AP) = __builtin_next_arg(LASTARG) - FAKE * sizeof (int); \ > (void)0; \ > }) > > #ifdef _STDARG_H /* stdarg.h support */ > > /* Calling __builtin_next_arg gives the proper error message if LASTARG is > not indeed the last argument. */ > #define va_start(AP,LASTARG) __va_start_common (AP, LASTARG, 0) > > #else /* varargs.h support */ > > #define va_start(AP) __va_start_common (AP, __va_1st_arg, 1) > #define va_alist __va_1st_arg > #define va_dcl register int va_alist; ... > > #endif /* _STDARG_H */ > > #ifdef _SOFT_FLOAT > #define __va_float_p(TYPE) 0 > #else > #define __va_float_p(TYPE) (__builtin_classify_type(*(TYPE *)0) == 8) > #endif > > #define __va_vector_p(TYPE) (__builtin_classify_type(*(TYPE *)0) == -2) > > #define __va_longlong_p(TYPE) \ > ((__builtin_classify_type(*(TYPE *)0) == 1) && (sizeof(TYPE) == 8)) > > #define __va_aggregate_p(TYPE) (__builtin_classify_type(*(TYPE *)0) >= 12) > #define __va_size(TYPE) ((sizeof(TYPE) + sizeof (long) - 1) / sizeof (long)) > > /* This symbol isn't defined. It is used to flag type promotion violations > at link time. We can only do this when optimizing. Use __builtin_trap > instead of abort so that we don't require a prototype for abort. > > __builtin_trap stuff is not available on the gcc-2.95 branch, so we just > avoid calling it for now. */ > > #ifdef __OPTIMIZE__ > extern void __va_arg_type_violation(void) __attribute__((__noreturn__)); > #else > #define __va_arg_type_violation() > #endif > > #define va_arg(AP,TYPE) \ > __extension__ (*({ \ > register TYPE *__ptr; \ > \ > if (__va_vector_p (TYPE)) \ > { \ > __va_overflow(AP) = (char*)(((long)(__va_overflow(AP)) + 15) & ~15); \ > __ptr = (TYPE *) (void *) (__va_overflow(AP)); \ > __va_overflow(AP) += __va_size (TYPE) * sizeof (long); \ > } \ > else \ > if (__va_float_p (TYPE) && sizeof (TYPE) < 16) \ > { \ > unsigned char __fpr = (AP)->fpr; \ > if (__fpr < 8) \ > { \ > __ptr = __VA_FP_REGSAVE (AP, __fpr, TYPE); \ > (AP)->fpr = __fpr + 1; \ > } \ > else if (sizeof (TYPE) == 8) \ > { \ > unsigned long __addr = (unsigned long) (__va_overflow (AP)); \ > __ptr = (TYPE *)((__addr + 7) & -8); \ > __va_overflow (AP) = (char *)(__ptr + 1); \ > } \ > else \ > { \ > /* float is promoted to double. */ \ > __va_arg_type_violation (); \ > } \ > } \ > \ > /* Aggregates and long doubles are passed by reference. */ \ > else if (__va_aggregate_p (TYPE) || __va_float_p (TYPE)) \ > { \ > unsigned char __gpr = (AP)->gpr; \ > if (__gpr < 8) \ > { \ > __ptr = * __VA_GP_REGSAVE (AP, __gpr, TYPE *); \ > (AP)->gpr = __gpr + 1; \ > } \ > else \ > { \ > TYPE **__pptr = (TYPE **) (__va_overflow (AP)); \ > __ptr = * __pptr; \ > __va_overflow (AP) = (char *) (__pptr + 1); \ > } \ > } \ > \ > /* Only integrals remaining. */ \ > else \ > { \ > /* longlong is aligned. */ \ > if (sizeof (TYPE) == 8) \ > { \ > unsigned char __gpr = (AP)->gpr; \ > if (__gpr < 7) \ > { \ > __gpr += __gpr & 1; \ > __ptr = __VA_GP_REGSAVE (AP, __gpr, TYPE); \ > (AP)->gpr = __gpr + 2; \ > } \ > else \ > { \ > unsigned long __addr = (unsigned long) (__va_overflow (AP)); \ > __ptr = (TYPE *)((__addr + 7) & -8); \ > (AP)->gpr = 8; \ > __va_overflow (AP) = (char *)(__ptr + 1); \ > } \ > } \ > else if (sizeof (TYPE) == 4) \ > { \ > unsigned char __gpr = (AP)->gpr; \ > if (__gpr < 8) \ > { \ > __ptr = __VA_GP_REGSAVE (AP, __gpr, TYPE); \ > (AP)->gpr = __gpr + 1; \ > } \ > else \ > { \ > __ptr = (TYPE *) __va_overflow (AP); \ > __va_overflow (AP) = (char *)(__ptr + 1); \ > } \ > } \ > else \ > { \ > /* Everything else was promoted to int. */ \ > __va_arg_type_violation (); \ > } \ > } \ > __ptr; \ > })) > > #define va_end(AP) ((void)0) > > /* Copy __gnuc_va_list into another variable of this type. */ > #define __va_copy(dest, src) *(dest) = *(src) > > #endif /* __VA_PPC_H__ */ > #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */ > > > #else > /* Windows NT */ > /* Define __gnuc_va_list. */ > > #ifndef __GNUC_VA_LIST > #define __GNUC_VA_LIST > typedef char *__gnuc_va_list; > #endif /* not __GNUC_VA_LIST */ > > /* If this is for internal libc use, don't define anything but > __gnuc_va_list. */ > #if defined (_STDARG_H) || defined (_VARARGS_H) > > #define __va_start_common(AP, LASTARG, FAKE) \ > ((__builtin_saveregs ()), ((AP) = ((char *) &LASTARG) + __va_rounded_size (AP)), 0) > > #ifdef _STDARG_H /* stdarg.h support */ > > /* Calling __builtin_next_arg gives the proper error message if LASTARG is > not indeed the last argument. */ > #define va_start(AP,LASTARG) \ > (__builtin_saveregs (), \ > (AP) = __builtin_next_arg (LASTARG), \ > 0) > > #else /* varargs.h support */ > > #define va_start(AP) \ > (__builtin_saveregs (), \ > (AP) = __builtin_next_arg (__va_1st_arg) - sizeof (int), \ > 0) > > #define va_alist __va_1st_arg > #define va_dcl register int __va_1st_arg; ... > > #endif /* _STDARG_H */ > > #define __va_rounded_size(TYPE) ((sizeof (TYPE) + 3) & ~3) > #define __va_align(AP, TYPE) \ > ((((unsigned long)(AP)) + ((sizeof (TYPE) >= 8) ? 7 : 3)) \ > & ~((sizeof (TYPE) >= 8) ? 7 : 3)) > > #define va_arg(AP,TYPE) \ > ( *(TYPE *)((AP = (char *) (__va_align(AP, TYPE) \ > + __va_rounded_size(TYPE))) \ > - __va_rounded_size(TYPE))) > > #define va_end(AP) ((void)0) > > /* Copy __gnuc_va_list into another variable of this type. */ > #define __va_copy(dest, src) (dest) = (src) > > #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */ > #endif /* Windows NT */ > #endif /* not _AIX */ >
This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:51:05 MET