@@ -1,11 +1,11 @@ #ifndef _avcall_h /*-*- C -*-*/ #define _avcall_h /** Copyright 1993 Bill Triggs, - Copyright 1995-2004 Bruno Haible, + Copyright 1995-2006 Bruno Haible, This is free software distributed under the GNU General Public Licence described in the file COPYING. Contact the author if you don't have this or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied, on this software. @@ -15,10 +15,13 @@ Varargs-style macros to build a C argument list incrementally and call a function on it. ----------------------------------------------------------------------*/ +#if !defined(LIBFFCALL_VERSION) +# define LIBFFCALL_VERSION @LIBFFCALL_VERSION@ +#endif /* These definitions are adjusted by `configure' automatically. */ /* CPU */ #ifndef __i386__ @@ -49,12 +52,15 @@ #undef __hppa__ #endif #ifndef __arm__ #undef __arm__ #endif -#ifndef __rs6000__ -#undef __rs6000__ +#ifndef __powerpc__ +#undef __powerpc__ +#endif +#ifndef __powerpc64__ +#undef __powerpc64__ #endif #ifndef __s390__ #undef __s390__ #endif #ifndef __m88k__ @@ -76,13 +82,13 @@ /* Define if small structs are returned in registers */ #define __SMALL_STRUCT_RETURN__ 1 /* Define if floating-point results are returned in the integer registers */ #undef __IREG_FLOAT_RETURN__ -/* CL_LONGLONG */ -/* Define if your compiler supports the `long long' type. */ -#undef HAVE_LONGLONG +/* AC_TYPE_LONG_LONG */ +/* Define if your compiler supports the 'long long' type. */ +#undef HAVE_LONG_LONG_INT /* End of definitions adjusted by `configure'. */ /* Max # words in argument-list and temporary structure storage. @@ -185,18 +191,13 @@ __AV_STRUCT_RETURN = #if defined(__sparc__) && !defined(__sparc64__) && defined(sun) && defined(__SUNPRO_C) /* SUNWspro cc */ __AV_SUNPROCC_STRUCT_RETURN, #else #if defined(__PCC_STRUCT_RETURN__) /* defined through configure, see above */ - __AV_PCC_STRUCT_RETURN | -#if defined(__sparc__) && !defined(__sparc64__) && defined(sun) && !(defined(__STDC__) || defined(__GNUC__)) /* sun cc */ - __AV_SUNCC_STRUCT_RETURN, -#else - 0, -#endif -#else -#if defined(__SMALL_STRUCT_RETURN__) || defined(__mipsn32__) || defined(__mips64__) /* defined through configure, see above */ + __AV_PCC_STRUCT_RETURN, +#else +#if defined(__SMALL_STRUCT_RETURN__) || defined(__mipsn32__) || defined(__mips64__) || defined(__ARMEL__) /* defined through configure, see above */ __AV_SMALL_STRUCT_RETURN | #endif #if defined(__GNUC__) __AV_GCC_STRUCT_RETURN | #endif @@ -241,11 +242,11 @@ /* how to pass structs */ #if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) __AV_SGICC_STRUCT_ARGS = 1<<7, #endif -#if defined(__rs6000__) +#if defined(__powerpc__) && !defined(__powerpc64__) __AV_AIXCC_STRUCT_ARGS = 1<<7, #endif /* the default way to pass floats */ /* This choice here is based on the assumption that the function you are * going to call has been compiled with the same compiler you are using to @@ -256,62 +257,27 @@ */ #ifndef __AV_STRUCT_ARGS #if (defined(__mips__) || defined(__mipsn32__) || defined(__mips64__)) && !defined(__GNUC__) /* SGI mips cc */ __AV_STRUCT_ARGS = __AV_SGICC_STRUCT_ARGS, #else -#if defined(__rs6000__) && defined(_AIX) && !defined(__GNUC__) /* AIX cc, xlc */ +#if defined(__powerpc__) && !defined(__powerpc64__) && defined(_AIX) && !defined(__GNUC__) /* AIX cc, xlc */ __AV_STRUCT_ARGS = __AV_AIXCC_STRUCT_ARGS, #else __AV_STRUCT_ARGS = 0, #endif #endif #endif /* how to pass floats */ /* ANSI C compilers and GNU gcc pass floats as floats. - * K&R C compilers pass floats as doubles. - * (Except some compilers like SGI MIPS "cc" and "cc -cckr" if a prototype is - * known for the called functions. But to compile a program with prototypes, - * "cc -ansi" is better anyway. - */ - __AV_ANSI_FLOAT_ARGS = 0, /* pass floats as floats */ - __AV_TRADITIONAL_FLOAT_ARGS = 1<<8, /* pass floats as doubles */ - /* the default way to pass floats */ - /* This choice here is based on the assumption that the function you are - * going to call has been compiled with the same compiler you are using to - * include this file. - * If you want to call functions with another float passing convention, - * just #define __AV_FLOAT_ARGS ... - * before or after #including . - */ -#ifndef __AV_FLOAT_ARGS -#if defined(__STDC__) || defined(__GNUC__) /* what about hppa "cc -Aa" ?? */ - __AV_FLOAT_ARGS = __AV_ANSI_FLOAT_ARGS, -#else - __AV_FLOAT_ARGS = __AV_TRADITIONAL_FLOAT_ARGS, -#endif -#endif + * K&R C compilers pass floats as doubles. We don't support them any more. + */ /* how to pass and return small integer arguments */ __AV_ANSI_INTEGERS = 0, /* no promotions */ __AV_TRADITIONAL_INTEGERS = 0, /* promote [u]char, [u]short to [u]int */ /* Fortunately these two methods are compatible. Our macros work with both. */ - /* the default way to pass and return small integer arguments */ - /* This choice here is based on the assumption that the function you are - * going to call has been compiled with the same compiler you are using to - * include this file. - * If you want to call functions with another float passing convention, - * just #define __AV_INTEGERS ... - * before or after #including . - */ -#ifndef __AV_INTEGERS -#if defined(__STDC__) || defined(__GNUC__) - __AV_INTEGERS = __AV_ANSI_INTEGERS, -#else - __AV_INTEGERS = __AV_TRADITIONAL_INTEGERS, -#endif -#endif /* stack cleanup policy */ __AV_CDECL_CLEANUP = 0, /* caller pops args after return */ __AV_STDCALL_CLEANUP = 0, /* callee pops args before return */ /* currently only supported on __i386__ */ @@ -318,16 +284,18 @@ #ifndef __AV_CLEANUP __AV_CLEANUP = __AV_CDECL_CLEANUP, #endif /* These are for internal use only */ -#if defined(__i386__) || defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__arm__) || defined(__rs6000__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__) +#if defined(__i386__) || defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__arm__) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__) __AV_REGISTER_STRUCT_RETURN = 1<<9, #endif -#if defined(__mips__) && !defined(__mipsn32__) +#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__) __AV_FLOAT_1 = 1<<10, __AV_FLOAT_2 = 1<<11, + __AV_DOUBLE_1 = 1<<12, + __AV_DOUBLE_2 = 1<<13, #endif __AV_flag_for_broken_compilers_that_dont_like_trailing_commas }; @@ -341,24 +309,24 @@ void* raddr; enum __AVtype rtype; unsigned long rsize; /* current pointer into the args[] array */ __avword* aptr; -#if defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || (defined(__rs6000__) && !defined(_AIX) && !(defined(__MACH__) && defined(__APPLE__))) || defined(__s390__) +#if defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || (defined(__powerpc__) && !defined(__powerpc64__) && !defined(_AIX) && !(defined(__MACH__) && defined(__APPLE__))) || defined(__s390__) /* limit pointer into the args[] array */ __avword* eptr; #endif #if defined(__i386__) && 0 /* Filler word, needed if the numbers of words up to now in this structure */ /* is odd (because on MSVC, alignof(double) = 8, normally = 4). */ __avword filler1; #endif -#if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__arm__) || defined(__rs6000__) || defined(__convex__) || defined(__s390__) +#if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__arm__) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__) /* temporary storage, used to split doubles into two words */ union { double _double; -#if defined(__sparc__) && !defined(__sparc64__) && defined(HAVE_LONGLONG) +#if defined(__sparc__) && !defined(__sparc64__) && defined(HAVE_LONG_LONG_INT) long long _longlong; #endif __avword words[2]; } tmp; #endif @@ -365,14 +333,15 @@ #if defined(__x86_64__) /* store the integer arguments in an extra array */ __avword* iaptr; __avword iargs[6]; #endif -#if defined(__mips__) && !defined(__mipsn32__) +#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__) /* store the floating-point arguments in an extra array */ int anum; - double floatarg[2]; + float floatarg[2]; + double doublearg[2]; #endif #if defined(__mipsn32__) || defined(__mips64__) /* store the floating-point arguments in an extra array */ int anum; /* redundant: (LIST).aptr = &(LIST).args[(LIST).anum] */ unsigned int farg_mask; /* bitmask of those entries in farg[] which have a value */ @@ -389,11 +358,11 @@ /* store the floating-point arguments in an extra array */ double* faptr; double fargs[8]; #endif __avword args[__AV_ALIST_WORDS]; /* sizeof(double)-aligned */ -#if defined(__rs6000__) +#if defined(__powerpc__) || defined(__powerpc64__) /* store the floating-point arguments in an extra array */ double* faptr; double fargs[13]; #endif #if defined(__s390__) @@ -413,11 +382,11 @@ __avword regargs[8+7]; #endif } av_alist; /* The limit for the pointer into the args[] array. */ -#if defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || (defined(__rs6000__) && !defined(_AIX) && !(defined(__MACH__) && defined(__APPLE__))) || defined(__s390) +#if defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || (defined(__powerpc__) && !defined(__powerpc64__) && !defined(_AIX) && !(defined(__MACH__) && defined(__APPLE__))) || defined(__s390) #define __av_eptr(LIST) ((LIST).eptr) #else #define __av_eptr(LIST) (&(LIST).args[__AV_ALIST_WORDS]) #endif @@ -432,11 +401,11 @@ /* * av_start_ macros which specify the return type */ #define __AV_START_FLAGS \ - __AV_STRUCT_RETURN | __AV_FLOAT_RETURN | __AV_STRUCT_ARGS | __AV_FLOAT_ARGS | __AV_INTEGERS | __AV_CLEANUP + __AV_STRUCT_RETURN | __AV_FLOAT_RETURN | __AV_STRUCT_ARGS | __AV_CLEANUP #define __av_start(LIST,FUNC,RADDR,RETTYPE) \ ((LIST).func = (__avword(*)())(FUNC), \ (LIST).raddr = (void*)(RADDR), \ (LIST).rtype = (RETTYPE), \ @@ -445,11 +414,11 @@ #if defined(__i386__) || defined(__m68k__) || defined(__alpha__) || defined(__arm__) || defined(__m88k__) || defined(__convex__) #define __av_start1(LIST) \ (LIST).aptr = &(LIST).args[0], #endif -#if defined(__mips__) && !defined(__mipsn32__) +#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__) #define __av_start1(LIST) \ (LIST).anum = 0, \ (LIST).aptr = &(LIST).args[0], #endif #if defined(__mipsn32__) || defined(__mips64__) @@ -475,12 +444,12 @@ #if defined(__hppa__) #define __av_start1(LIST) \ (LIST).aptr = &(LIST).args[__AV_ALIST_WORDS], \ (LIST).eptr = &(LIST).args[0], #endif -#if defined(__rs6000__) -#if defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)) +#if defined(__powerpc__) || defined(__powerpc64__) +#if defined(__powerpc64__) || defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)) #define __av_start1(LIST) \ (LIST).aptr = &(LIST).args[0], \ (LIST).faptr = &(LIST).fargs[0], #else #define __av_start1(LIST) \ @@ -570,11 +539,11 @@ * and the struct will actually be returned in registers. */ #define __av_start_struct3(LIST) \ ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0) #endif -#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || defined(__arm__) || defined(__rs6000__) || defined(__convex__) || defined(__s390__) +#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || (defined(__arm__) && !defined(__ARMEL__)) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__) #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \ ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 \ || ((TYPE_SIZE) == 8 && (TYPE_SPLITTABLE) \ && ((LIST).flags & __AV_GCC_STRUCT_RETURN) \ ) ) @@ -582,10 +551,18 @@ * and the struct will actually be returned in registers. */ #define __av_start_struct3(LIST) \ ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0) #endif + +#if defined(__ARMEL__) +#define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \ + ((TYPE_SIZE) <= 4) +#define __av_start_struct3(LIST) \ + ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0) +#endif + #if defined(__alpha__) #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \ ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8 \ || ((TYPE_SIZE) == 16 && (TYPE_SPLITTABLE) \ && ((LIST).flags & __AV_GCC_STRUCT_RETURN) \ @@ -604,11 +581,11 @@ ) /* Test both __AV_OLDGCC_STRUCT_RETURN and __AV_SMALL_STRUCT_RETURN at run time. */ #define __av_start_struct3(LIST) \ 0 #endif -#if defined(__mips__) && !defined(__mipsn32__) +#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__) #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \ ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4) /* Test __AV_SMALL_STRUCT_RETURN instead of __AV_REGISTER_STRUCT_RETURN. */ #define __av_start_struct3(LIST) \ 0 @@ -622,10 +599,16 @@ /* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set * and the struct will actually be returned in registers. */ #define __av_start_struct3(LIST) \ ((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0) +#endif +#if defined(__powerpc64__) +#define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \ + 0 +#define __av_start_struct3(LIST) \ + 0 #endif #if defined(__sparc64__) || defined(__ia64__) #define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \ ((TYPE_SIZE) <= 32) /* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set @@ -656,11 +639,11 @@ */ #define __av_start_struct4(LIST,TYPE_SIZE) 0 #endif /* Return structure pointer is passed as first arg. */ -#if defined(__alpha__) || defined(__arm__) || defined(__rs6000__) || defined(__convex__) || defined(__s390__) +#if defined(__alpha__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__) || defined(__s390__) #define __av_start_struct4(LIST,TYPE_SIZE) \ (*(LIST).aptr++ = (__avword)((LIST).raddr), 0) #endif #if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__) #define __av_start_struct4(LIST,TYPE_SIZE) \ @@ -682,11 +665,11 @@ /* * scalar argument types */ -#if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__alpha__) || defined(__arm__) || defined(__rs6000__) || defined(__m88k__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__) +#if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__alpha__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__) /* Floats and all integer types are passed as words, * doubles as two words. */ #define __av_word(LIST,VAL) \ (++(LIST).aptr > __av_eptr(LIST) \ @@ -758,29 +741,36 @@ #define av_int av_long #define av_uchar av_ulong #define av_ushort av_ulong #define av_uint av_ulong -#if defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__ia64__) || defined(__x86_64__) +#if defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__powerpc64__) || defined(__ia64__) || defined(__x86_64__) /* `long long' and `long' are identical. */ #define av_longlong av_long #define av_ulonglong av_ulong #elif defined(__mipsn32__) /* `long long' fits in __avword. */ #define av_longlong __av_word #define av_ulonglong(LIST,VAL) __av_word(LIST,(unsigned long long)(VAL)) -#elif defined(__i386__) || defined(__m68k__) || defined(__mips__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__arm__) || defined(__rs6000__) || defined(__m88k__) || defined(__convex__) || defined(__s390__) +#elif defined(__i386__) || defined(__m68k__) || (defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__arm__) || defined(__powerpc__) || defined(__m88k__) || defined(__convex__) || defined(__s390__) /* `long long's are passed embedded on the arg stack. */ #define av_longlong(LIST,VAL) __av_longlong(LIST,long long,VAL) #define av_ulonglong(LIST,VAL) __av_longlong(LIST,unsigned long long,VAL) -#if defined(__i386__) || defined(__m68k__) || defined(__arm__) || (defined(__rs6000__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__) +#if defined(__i386__) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__) +#if defined(__ARMEL__) +/* `long long's are 8 bytes aligned on ARM. */ +#define __av_longlong(LIST,TYPE,VAL) \ + (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(TYPE)+__AV_alignof(TYPE)-1) & -(long)__AV_alignof(TYPE))) > __av_eptr(LIST) \ + ? -1 : (((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0)) +#else /* `long long's are (at most) word-aligned. */ #define __av_longlong(LIST,TYPE,VAL) \ (((LIST).aptr += sizeof(TYPE)/sizeof(__avword)) > __av_eptr(LIST) \ ? -1 : (((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0)) #endif -#if defined(__mips__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || (defined(__rs6000__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__) || defined(__s390__) +#endif +#if defined(__mips__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__) || defined(__s390__) /* `long long's have alignment 8. */ #if defined(__mips__) #define __av_longlong(LIST,TYPE,VAL) \ (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(TYPE)+__AV_alignof(TYPE)-1) & -(long)__AV_alignof(TYPE))) > __av_eptr(LIST) \ ? -1 : ((LIST).anum++, ((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0)) @@ -799,11 +789,11 @@ #if defined(__hppa__) #define __av_longlong(LIST,TYPE,VAL) \ (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr & -(long)__AV_alignof(TYPE)) - sizeof(TYPE))) < __av_eptr(LIST) \ ? -1 : (*(TYPE*)(LIST).aptr = (TYPE)(VAL), 0)) #endif -#if (defined(__rs6000__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__) +#if (defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__) #define __av_longlong(LIST,TYPE,VAL) \ (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(TYPE)+__AV_alignof(TYPE)-1) & -(long)__AV_alignof(TYPE))) > __av_eptr(LIST) \ ? -1 : (((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0)) #endif #if defined(__s390__) @@ -816,59 +806,65 @@ #endif #endif /* floating-point argument types */ -#define av_float(LIST,VAL) \ - ((LIST).flags & __AV_TRADITIONAL_FLOAT_ARGS \ - ? av_double(LIST,(float)(VAL)) \ - : __av_float(LIST,VAL)) - #if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__arm__) || defined(__convex__) -#define __av_float(LIST,VAL) \ +#define av_float(LIST,VAL) \ (++(LIST).aptr > __av_eptr(LIST) \ ? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), 0)) +#if defined(__ARMEL__) +/* Almost identical normal case, but we must align location */ +#define av_double(LIST,VAL) \ + (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+15)&-8)) \ + > __av_eptr(LIST) \ + ? -1 : \ + ((LIST).tmp._double = (double)(VAL), \ + (LIST).aptr[-2] = (LIST).tmp.words[0], \ + (LIST).aptr[-1] = (LIST).tmp.words[1], \ + 0)) +#else /* This assumes sizeof(double) == 2*sizeof(__avword). */ #define av_double(LIST,VAL) \ (((LIST).aptr += 2) > __av_eptr(LIST) \ ? -1 : \ ((LIST).tmp._double = (double)(VAL), \ (LIST).aptr[-2] = (LIST).tmp.words[0], \ (LIST).aptr[-1] = (LIST).tmp.words[1], \ 0)) - +#endif #endif -#if defined(__mips__) && !defined(__mipsn32__) +#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__) /* Up to 2 leading float or double non-varargs args can be passed in * float registers, but we also push them into the corresponding int * registers in case of varargs. For doubles we need to align the aptr * to an even boundary. */ -#define __av_float(LIST,VAL) \ +#define av_float(LIST,VAL) \ (++(LIST).aptr > __av_eptr(LIST) \ ? -1 : ((++(LIST).anum == 1 \ ? ((LIST).flags |= __AV_FLOAT_1, \ - ((float*)(LIST).floatarg)[1] = ((float*)(LIST).aptr)[-1] = (float)(VAL))\ - : (LIST).anum == 2 && ((LIST).flags & __AV_FLOAT_1) \ + (LIST).floatarg[0] = ((float*)(LIST).aptr)[-1] = (float)(VAL))\ + : (LIST).anum == 2 && (((LIST).flags & __AV_FLOAT_1) || ((LIST).flags & __AV_DOUBLE_1))\ ? ((LIST).flags |= __AV_FLOAT_2, \ - ((float*)(LIST).floatarg)[3] = ((float*)(LIST).aptr)[-1] = (float)(VAL))\ - : (*(float*)&(LIST).aptr[-1] = (float)(VAL))), \ + (LIST).floatarg[1] = ((float*)(LIST).aptr)[-1] = (float)(VAL))\ + : (((float*)(LIST).aptr)[-1] = (float)(VAL))), \ 0)) #define av_double(LIST,VAL) \ (((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+15)&-8)) \ > __av_eptr(LIST) \ ? -1 : ((++(LIST).anum == 1 \ - ? ((LIST).flags |= __AV_FLOAT_1, \ - (LIST).floatarg[0] = ((double*)(LIST).aptr)[-1] = (double)(VAL))\ - : (LIST).anum == 2 && ((LIST).flags & __AV_FLOAT_1) \ - ? ((LIST).flags |= __AV_FLOAT_2, \ - (LIST).floatarg[1] = ((double*)(LIST).aptr)[-1] = (double)(VAL))\ + ? ((LIST).flags |= __AV_DOUBLE_1, \ + (LIST).doublearg[0] = ((double*)(LIST).aptr)[-1] = (double)(VAL))\ + : (LIST).anum == 2 && (((LIST).flags & __AV_FLOAT_1) || ((LIST).flags & __AV_DOUBLE_1))\ + ? ((LIST).flags |= __AV_DOUBLE_2, \ + (LIST).doublearg[1] = ((double*)(LIST).aptr)[-1] = (double)(VAL))\ : (((double*)(LIST).aptr)[-1] = (double)(VAL))), \ 0)) #endif @@ -876,11 +872,11 @@ /* Up to 8 leading float or double non-varargs args can be passed in * float registers, but we also push them into the corresponding int * registers in case of varargs. */ -#define __av_float(LIST,VAL) \ +#define av_float(LIST,VAL) \ ((LIST).aptr >= __av_eptr(LIST) \ ? -1 : (((LIST).anum < 8 \ ? ((LIST).farg_mask |= (1 << (LIST).anum), \ (LIST).farg[(LIST).anum] = *(float*)(LIST).aptr = (float)(VAL)) \ : (*(float*)(LIST).aptr = (float)(VAL))), \ @@ -902,11 +898,11 @@ /* Up to 16 leading float or double non-varargs args can be passed in * float registers, but we also push them into the corresponding int * registers in case of varargs. */ -#define __av_float(LIST,VAL) \ +#define av_float(LIST,VAL) \ ((LIST).aptr >= __av_eptr(LIST) \ ? -1 : (((LIST).anum < 16 && ((LIST).farg_mask |= (1 << (LIST).anum))), \ (*(float*)(LIST).aptr = (float)(VAL)), \ (LIST).anum++, \ (LIST).aptr++, \ @@ -926,11 +922,11 @@ #define av_double(LIST,VAL) \ (++(LIST).aptr > __av_eptr(LIST) \ ? -1 : (((double*)(LIST).aptr)[-1] = (double)(VAL), 0)) -#define __av_float(LIST,VAL) \ +#define av_float(LIST,VAL) \ (++(LIST).aptr > __av_eptr(LIST) \ ? -1 \ : (((LIST).aptr > &(LIST).args[6] \ ? /* These args will be fetched from memory using "lds" instructions */ \ /* therefore store them as floats */ \ @@ -943,11 +939,11 @@ #endif #if defined(__hppa__) -#define __av_float(LIST,VAL) \ +#define av_float(LIST,VAL) \ (--(LIST).aptr < __av_eptr(LIST) \ ? -1 : (*(float*)(LIST).aptr = (float)(VAL), 0)) #define av_double(LIST,VAL) \ (((LIST).aptr = (__avword*)(((long)(LIST).aptr-sizeof(double)) & -(long)sizeof(double))) \ @@ -954,18 +950,18 @@ < __av_eptr(LIST) \ ? -1 : (*(double*)(LIST).aptr = (double)(VAL), 0)) #endif -#if defined(__rs6000__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__))) +#if defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__))) /* Up to 13 float or double non-varargs args can be passed in * float registers, but we also push them into the corresponding int * registers in case of varargs. */ -#define __av_float(LIST,VAL) \ +#define av_float(LIST,VAL) \ (++(LIST).aptr > __av_eptr(LIST) \ ? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), \ (LIST).faptr < &(LIST).fargs[13] && \ (*(LIST).faptr++ = (double)(float)(VAL)), \ 0)) @@ -980,17 +976,17 @@ (*(LIST).faptr++ = (LIST).tmp._double), \ 0)) #endif -#if defined(__rs6000__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__))) +#if defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__))) /* Up to 8 float or double non-varargs args can be passed in * float registers, without occupying space in the general registers. */ -#define __av_float(LIST,VAL) \ +#define av_float(LIST,VAL) \ ((LIST).faptr < &(LIST).fargs[8] \ ? ((*(LIST).faptr++ = (double)(float)(VAL)), 0) \ : (++(LIST).aptr > __av_eptr(LIST) \ ? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), 0))) @@ -1003,18 +999,41 @@ (LIST).aptr[-2] = (LIST).tmp.words[0], \ (LIST).aptr[-1] = (LIST).tmp.words[1], \ 0))) #endif + +#if defined(__powerpc64__) + +/* Up to 13 float or double non-varargs args can be passed in + * float registers, but we also push them into the corresponding int + * registers in case of varargs. + */ + +#define av_float(LIST,VAL) \ + (++(LIST).aptr > __av_eptr(LIST) \ + ? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), \ + (LIST).faptr < &(LIST).fargs[13] && \ + (*(LIST).faptr++ = (double)(float)(VAL)), \ + 0)) + +#define av_double(LIST,VAL) \ + (++(LIST).aptr > __av_eptr(LIST) \ + ? -1 : (((double*)(LIST).aptr)[-1] = (double)(VAL), \ + (LIST).faptr < &(LIST).fargs[13] && \ + (*(LIST).faptr++ = (double)(VAL)), \ + 0)) + +#endif #if defined(__s390__) /* Up to 2 float or double non-varargs args can be passed in * float registers, without occupying space in the general registers. */ -#define __av_float(LIST,VAL) \ +#define av_float(LIST,VAL) \ ((LIST).faptr < &(LIST).fargs[2] \ ? (LIST).daptr++, *(LIST).fargsusedptr++ = 1, *(LIST).dargsusedptr++ = 0, ((*(LIST).faptr++ = (float)(VAL)), 0) \ : (++(LIST).aptr > __av_eptr(LIST) \ ? -1 : ((LIST).fargwords++, ((float*)(LIST).aptr)[-1] = (float)(VAL), 0))) @@ -1030,11 +1049,11 @@ #endif #if defined(__m88k__) -#define __av_float(LIST,VAL) \ +#define av_float(LIST,VAL) \ (++(LIST).aptr > __av_eptr(LIST) \ ? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), 0)) #define av_double(LIST,VAL) \ (((LIST).aptr = (__avword*)(((long)(LIST).aptr+sizeof(double)+sizeof(double)-1) & -(long)sizeof(double))) \ @@ -1047,11 +1066,11 @@ /* Up to 8 leading float or double non-varargs args can be passed in * float registers, but we also push them into the corresponding int * registers in case of varargs. */ -#define __av_float(LIST,VAL) \ +#define av_float(LIST,VAL) \ ((LIST).aptr >= __av_eptr(LIST) \ ? -1 : ((*(float*)(LIST).aptr = (float)(VAL)), \ ((LIST).faptr < &(LIST).fargs[8] && (*(LIST).faptr = *(float*)(LIST).aptr, (LIST).faptr++)), \ (LIST).aptr++, \ 0)) @@ -1067,11 +1086,11 @@ #if defined(__x86_64__) /* Up to 8 leading float or double args can be passed in float registers. */ -#define __av_float(LIST,VAL) \ +#define av_float(LIST,VAL) \ ((LIST).faptr < &(LIST).fargs[8] \ ? (*(LIST).faptr = 0.0, *(float*)(LIST).faptr = (float)(VAL), \ (LIST).faptr++, \ 0) \ : ((LIST).aptr >= __av_eptr(LIST) \ @@ -1116,27 +1135,27 @@ ((TYPE_ALIGN) <= 4 ? (TYPE_ALIGN) : 4) #else #define __av_struct_alignment(TYPE_ALIGN) \ (TYPE_ALIGN) #endif -#if defined(__i386__) || defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__alpha__) || (defined(__rs6000__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__) || defined(__ia64__) || defined(__s390__) +#if defined(__i386__) || defined(__mips__) || defined(__ARMEL__) || defined(__mipsn32__) || defined(__mips64__) || defined(__alpha__) || (defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__powerpc64__) || defined(__m88k__) || defined(__ia64__) || defined(__s390__) /* Structures are passed as fully aligned structures on the arg stack. * We align the aptr, store the structure, then fill to word alignment. * Single-small-integer structures are NOT promoted to integers and have * different alignment. */ /* little endian -> small structures < 1 word are adjusted to the left */ -#if defined(__i386__) || defined(__alpha__) || defined(__x86_64__) +#if defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__ARMEL__) || (defined(__ia64__) && defined(__GNUC__) && (__GNUC__ >= 3)) #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \ (((LIST).aptr = \ (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+__av_struct_alignment(TYPE_ALIGN)-1) & -(long)__av_struct_alignment(TYPE_ALIGN)))\ > __av_eptr(LIST) \ ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\ (LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),\ 0)) #endif -#if defined(__ia64__) +#if defined(__ia64__) && (!defined(__GNUC__) || (__GNUC__ < 3)) /* Types larger than a word have 2-word alignment. */ #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \ ((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+__av_struct_alignment(TYPE_ALIGN)-1) & -(long)__av_struct_alignment(TYPE_ALIGN)), \ ((TYPE_SIZE) > sizeof(__avword) && (((LIST).aptr - &(LIST).args[0]) & 1) ? ++(LIST).aptr : 0), \ ((LIST).aptr > __av_eptr(LIST) \ @@ -1143,11 +1162,11 @@ ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\ (LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),\ 0))) #endif /* small structures < 1 word are adjusted depending on compiler */ -#if defined(__mips__) && !defined(__mipsn32__) +#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__) #define __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \ (((LIST).aptr = \ (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)))\ > __av_eptr(LIST) \ ? -1 : (++(LIST).anum, \ @@ -1206,11 +1225,11 @@ ? /* SGI MIPS cc passes small structures left-adjusted, although big-endian! */\ __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \ : /* SGI MIPS gcc passes small structures right-adjusted. */ \ __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)) #endif -#if defined(__rs6000__) +#if defined(__powerpc__) || defined(__powerpc64__) #define __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)\ (((LIST).aptr = \ (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)))\ > __av_eptr(LIST) \ ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\ @@ -1221,16 +1240,22 @@ (__avword*)(((((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN))\ +sizeof(__avword)-1) & -(long)sizeof(__avword))) \ > __av_eptr(LIST) \ ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\ 0)) +#if !defined(__powerpc64__) #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \ ((LIST).flags & __AV_AIXCC_STRUCT_ARGS \ ? /* AIX cc and xlc pass small structures left-adjusted, although big-endian! */\ __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \ : /* gcc passes small structures right-adjusted. */ \ __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)) +#endif +#if defined(__powerpc64__) +#define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \ + __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) +#endif #endif #if defined(__s390__) #define __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)\ (((LIST).aptr = \ (__avword*)(((((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN))\ @@ -1258,20 +1283,20 @@ > __av_eptr(LIST) \ ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\ 0)) #endif #endif -#if defined(__m68k__) || defined(__arm__) || defined(__convex__) +#if defined(__m68k__) || (defined(__arm__) && !defined(__ARMEL__)) || defined(__convex__) /* Structures are passed as embedded copies on the arg stack. */ #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \ (((LIST).aptr = (__avword*)(((long)(LIST).aptr+(TYPE_SIZE)+sizeof(__avword)-1) & -(long)sizeof(__avword))) \ > __av_eptr(LIST) \ ? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\ 0)) #endif -#if (defined(__sparc__) && !defined(__sparc64__)) || (defined(__rs6000__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) +#if (defined(__sparc__) && !defined(__sparc64__)) || (defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) /* Structures are passed as pointers to caller-made local copies. We * grab space for the copies from the end of the argument list space * and always use maximal (double) alignment. */ #define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \ @@ -1392,14 +1417,9 @@ /* * Miscellaneous declarations. */ -#if defined(__STDC__) || defined(__GNUC__) || defined(__cplusplus) extern int __builtin_avcall (av_alist* l); -extern void __structcpy (void* dest, void* src, unsigned long size, unsigned long alignment); -#else -extern int __builtin_avcall (); -extern void __structcpy (); -#endif +extern void __structcpy (void* dest, const void* src, unsigned long size, unsigned long alignment); #endif /*_avcall_h */