1
#ifndef _VACALL_H /*-*- C -*-*/
5
* Copyright 1995-2006 Bruno Haible, <bruno@clisp.org>
7
* This is free software distributed under the GNU General Public Licence
8
* described in the file COPYING. Contact the author if you don't have this
9
* or can't live with it. There is ABSOLUTELY NO WARRANTY, explicit or implied,
13
#if !defined(LIBFFCALL_VERSION)
14
# define LIBFFCALL_VERSION 0x010B
17
/* These definitions are adjusted by `configure' automatically. */
72
/* Calling convention */
73
/* Define if using pcc non-reentrant struct return convention */
74
#undef __PCC_STRUCT_RETURN__
75
/* Define if small structs are returned in registers */
76
#define __SMALL_STRUCT_RETURN__ 1
77
/* Define if floating-point results are returned in the integer registers */
78
#undef __IREG_FLOAT_RETURN__
80
/* AC_TYPE_LONG_LONG */
81
/* Define if your compiler supports the 'long long' type. */
82
#ifndef HAVE_LONG_LONG_INT
83
#undef HAVE_LONG_LONG_INT
86
/* AC_C_CHAR_UNSIGNED */
87
#ifndef __CHAR_UNSIGNED__
88
#undef __CHAR_UNSIGNED__
91
/* End of definitions adjusted by `configure'. */
94
/* Max # words in argument-list and temporary structure storage.
96
#ifndef __VA_ALIST_WORDS
97
#define __VA_ALIST_WORDS 256
100
/* Determine the alignment of a type at compile time.
102
#if defined(__GNUC__)
103
#define __VA_alignof __alignof__
105
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) /* SGI compiler */
106
#define __VA_alignof __builtin_alignof
108
#define __VA_offsetof(type,ident) ((unsigned long)&(((type*)0)->ident))
109
#define __VA_alignof(type) __VA_offsetof(struct { char __slot1; type __slot2; }, __slot2)
115
#if defined(__mipsn32__)
116
typedef long long __vaword;
118
typedef long __vaword;
141
enum __VA_alist_flags
144
/* how to return structs */
145
/* There are basically 3 ways to return structs:
146
* a. The called function returns a pointer to static data. Not reentrant.
147
* b. The caller passes the return structure address in a dedicated register
148
* or as a first (or last), invisible argument. The called function stores
150
* c. Like b, and the called function also returns the return structure
151
* address in the return value register. (This is not very distinguishable
153
* Independently of this,
154
* r. small structures (<= 4 or <= 8 bytes) may be returned in the return
155
* value register(s), or
156
* m. even small structures are passed in memory.
158
/* gcc-2.6.3 employs the following strategy:
159
* - If PCC_STATIC_STRUCT_RETURN is defined in the machine description
160
* it uses method a, else method c.
161
* - If flag_pcc_struct_return is set (either by -fpcc-struct-return or if
162
* DEFAULT_PCC_STRUCT_RETURN is defined to 1 in the machine description)
163
* it uses method m, else (either by -freg-struct-return or if
164
* DEFAULT_PCC_STRUCT_RETURN is defined to 0 in the machine description)
167
__VA_PCC_STRUCT_RETURN = 1<<0, /* a: need to copy the struct */
168
__VA_SMALL_STRUCT_RETURN = 1<<1, /* r: special case for small structs */
169
__VA_GCC_STRUCT_RETURN = 1<<2, /* consider 8 byte structs as small */
170
#if defined(__sparc__) && !defined(__sparc64__)
171
__VA_SUNCC_STRUCT_RETURN = 1<<3,
172
__VA_SUNPROCC_STRUCT_RETURN = 1<<4,
174
__VA_SUNCC_STRUCT_RETURN = 0,
175
__VA_SUNPROCC_STRUCT_RETURN = 0,
177
#if defined(__i386__)
178
__VA_NEXTGCC_STRUCT_RETURN = 1<<3,
179
__VA_MSVC_STRUCT_RETURN = 1<<4,
181
#if defined(__hppa__)
182
__VA_OLDGCC_STRUCT_RETURN = 1<<3,
184
/* the default way to return structs */
185
/* This choice here is based on the assumption that the function you are
186
* going to call has been compiled with the same compiler you are using to
188
* If you want to call functions with another struct returning convention,
189
* just #define __VA_STRUCT_RETURN ...
190
* before or after #including <vacall.h>.
192
#ifndef __VA_STRUCT_RETURN
194
#if defined(__sparc__) && !defined(__sparc64__) && defined(sun) && defined(__SUNPRO_C) /* SUNWspro cc */
195
__VA_SUNPROCC_STRUCT_RETURN,
197
#if defined(__PCC_STRUCT_RETURN__) /* defined through configure, see above */
198
__VA_PCC_STRUCT_RETURN,
200
#if defined(__SMALL_STRUCT_RETURN__) || defined(__mipsn32__) || defined(__mips64__) || defined(__ARMEL__)/* defined through configure, see above */
201
__VA_SMALL_STRUCT_RETURN |
203
#if defined(__GNUC__)
204
__VA_GCC_STRUCT_RETURN |
206
#if defined(__i386__) && defined(NeXT) && defined(__GNUC__) /* NeXT gcc-2.5.8 */
207
__VA_NEXTGCC_STRUCT_RETURN |
209
#if defined(__i386__) && defined(_MSC_VER) /* MSVC 4.0 */
210
__VA_MSVC_STRUCT_RETURN |
212
#if defined(__hppa__) && defined(__GNUC__) && (__GNUC__ < 3) && (__GNUC_MINOR__ < 7)
213
__VA_OLDGCC_STRUCT_RETURN |
220
/* how to return floats */
221
#if defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__))
222
__VA_SUNCC_FLOAT_RETURN = 1<<5,
224
#if defined(__m68k__)
225
__VA_FREG_FLOAT_RETURN = 1<<6,
227
/* the default way to return floats */
228
/* This choice here is based on the assumption that the function you are
229
* going to call has been compiled with the same compiler you are using to
231
* If you want to call functions with another float returning convention,
232
* just #define __VA_FLOAT_RETURN ...
233
* before or after #including <vacall.h>.
235
#ifndef __VA_FLOAT_RETURN
236
#if (defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__))) && !defined(__GNUC__) && defined(sun) && !defined(__SUNPRO_C) /* sun cc */
237
__VA_FLOAT_RETURN = __VA_SUNCC_FLOAT_RETURN,
238
#elif (defined(__m68k__) && !defined(__IREG_FLOAT_RETURN__))
239
__VA_FLOAT_RETURN = __VA_FREG_FLOAT_RETURN,
241
__VA_FLOAT_RETURN = 0,
245
/* how to pass structs */
246
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__)
247
__VA_SGICC_STRUCT_ARGS = 1<<7,
249
#if defined(__powerpc__) && !defined(__powerpc64__)
250
__VA_AIXCC_STRUCT_ARGS = 1<<7,
252
/* the default way to pass floats */
253
/* This choice here is based on the assumption that the function you are
254
* going to call has been compiled with the same compiler you are using to
256
* If you want to call functions with another float passing convention,
257
* just #define __VA_STRUCT_ARGS ...
258
* before or after #including <vacall.h>.
260
#ifndef __VA_STRUCT_ARGS
261
#if (defined(__mips__) || defined(__mipsn32__) || defined(__mips64__)) && !defined(__GNUC__) /* SGI mips cc */
262
__VA_STRUCT_ARGS = __VA_SGICC_STRUCT_ARGS,
264
#if defined(__powerpc__) && !defined(__powerpc64__) && defined(_AIX) && !defined(__GNUC__) /* AIX cc, xlc */
265
__VA_STRUCT_ARGS = __VA_AIXCC_STRUCT_ARGS,
267
__VA_STRUCT_ARGS = 0,
272
/* how to pass floats */
273
/* ANSI C compilers and GNU gcc pass floats as floats.
274
* K&R C compilers pass floats as doubles. We don't support them any more.
276
__VA_ANSI_FLOAT_ARGS = 0, /* pass floats as floats */
278
/* how to pass and return small integer arguments */
279
__VA_ANSI_INTEGERS = 0, /* no promotions */
280
__VA_TRADITIONAL_INTEGERS = 0, /* promote [u]char, [u]short to [u]int */
281
/* Fortunately these two methods are compatible. Our macros work with both. */
283
/* stack cleanup policy */
284
__VA_CDECL_CLEANUP = 0, /* caller pops args after return */
285
__VA_STDCALL_CLEANUP = 1<<9, /* callee pops args before return */
286
/* currently only supported on __i386__ */
288
__VA_CLEANUP = __VA_CDECL_CLEANUP,
291
/* These are for internal use only */
292
#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__)
293
__VA_REGISTER_STRUCT_RETURN = 1<<10,
295
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)
296
__VA_FLOAT_1 = 1<<11,
297
__VA_FLOAT_2 = 1<<12,
299
#if defined(__mipsn32__) || defined(__mips64__)
300
__VA_REGISTER_FLOATSTRUCT_RETURN = 1<<13,
301
__VA_REGISTER_DOUBLESTRUCT_RETURN = 1<<14,
304
__VA_flag_for_broken_compilers_that_dont_like_trailing_commas
308
* Definition of the `va_alist' type.
312
/* some va_... macros need these flags */
314
/* current pointer into the argument array */
316
/* structure return pointer, return type, return type size */
320
#if defined(__i386__) || (defined(__powerpc__) && !defined(__powerpc64__) && defined(__MACH__) && defined(__APPLE__))
321
/* Filler word, needed if the numbers of words up to now in this structure */
322
/* is odd (because on MSVC, alignof(double) = 8, normally = 4; similarly, */
323
/* on MacOS X, the Apple compiler has alignof(double) = 8 whereas the */
324
/* standard GCC has alignof(double) = 4. */
327
/* temporary storage for return value */
331
unsigned char _uchar;
333
unsigned short _ushort;
337
unsigned long _ulong;
338
#if !(defined(__mips64__) || defined(__alpha__) || defined(__powerpc64__)) && defined(HAVE_LONG_LONG_INT)
340
unsigned long long _ulonglong;
347
#if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__m88k__) || defined(__ia64__)
350
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__alpha__) || defined(__hppa__)
353
#if defined(__hppa__)
359
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)
364
#if defined(__mipsn32__) || defined(__mips64__)
369
#if defined(__sparc64__)
374
#if defined(__powerpc__) || defined(__powerpc64__)
377
#if !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
383
#if defined(__s390__)
392
#if defined(__ia64__)
397
#if defined(__x86_64__)
400
__vaword* memiargptr;
405
typedef __va_alist* va_alist;
409
* Definition of the va_start_xxx macros.
411
#define __VA_START_FLAGS \
412
__VA_STRUCT_RETURN | __VA_FLOAT_RETURN | __VA_STRUCT_ARGS | __VA_CLEANUP
413
#define __va_start(LIST,RETTYPE) \
414
((LIST)->flags = __VA_START_FLAGS, \
415
(LIST)->rtype = (RETTYPE) \
417
#define va_start_void(LIST) __va_start(LIST,__VAvoid)
418
#define va_start_char(LIST) __va_start(LIST,__VAchar)
419
#define va_start_schar(LIST) __va_start(LIST,__VAschar)
420
#define va_start_uchar(LIST) __va_start(LIST,__VAuchar)
421
#define va_start_short(LIST) __va_start(LIST,__VAshort)
422
#define va_start_ushort(LIST) __va_start(LIST,__VAushort)
423
#define va_start_int(LIST) __va_start(LIST,__VAint)
424
#define va_start_uint(LIST) __va_start(LIST,__VAuint)
425
#define va_start_long(LIST) __va_start(LIST,__VAlong)
426
#define va_start_ulong(LIST) __va_start(LIST,__VAulong)
427
#define va_start_longlong(LIST) __va_start(LIST,__VAlonglong)
428
#define va_start_ulonglong(LIST) __va_start(LIST,__VAulonglong)
429
#define va_start_float(LIST) __va_start(LIST,__VAfloat)
430
#define va_start_double(LIST) __va_start(LIST,__VAdouble)
431
#define va_start_ptr(LIST,TYPE) __va_start(LIST,__VAvoidp)
434
* va_start_struct: Preparing structure return.
436
#define va_start_struct(LIST,TYPE,TYPE_SPLITTABLE) \
437
_va_start_struct(LIST,sizeof(TYPE),__VA_alignof(TYPE),TYPE_SPLITTABLE)
438
/* _va_start_struct() is like va_start_struct(), except that you pass
439
* the type's size and alignment instead of the type itself.
441
#define _va_start_struct(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
442
(__va_start(LIST,__VAstruct), \
443
(LIST)->rsize = (TYPE_SIZE), \
444
((LIST)->flags & __VA_SUNPROCC_STRUCT_RETURN \
445
? __va_start_struct2(LIST) \
446
: ((LIST)->flags & (__VA_PCC_STRUCT_RETURN | __VA_SUNCC_STRUCT_RETURN) \
447
? ((TYPE_SIZE) <= sizeof(__va_struct_buffer) || __va_error2(TYPE_SIZE), \
448
(LIST)->raddr = &__va_struct_buffer, \
451
: (((LIST)->flags & __VA_SMALL_STRUCT_RETURN) \
452
&& __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
453
? ((LIST)->raddr = &(LIST)->tmp, \
454
__va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
456
: __va_start_struct2(LIST) \
458
/* Determines whether a structure is returned in registers,
459
* depending on its size and its word-splittable flag.
461
#if (defined(__i386__) && defined(_WIN32))
462
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
463
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 \
464
|| ((TYPE_SIZE) == 8 \
465
&& (((LIST)->flags & __VA_MSVC_STRUCT_RETURN) \
466
|| ((TYPE_SPLITTABLE) \
467
&& ((LIST)->flags & __VA_GCC_STRUCT_RETURN) \
469
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
470
* and the struct will actually be returned in registers.
472
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
473
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
475
#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || (defined(__arm__) && !defined(__ARMEL__)) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
476
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
477
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 \
478
|| ((TYPE_SIZE) == 8 && (TYPE_SPLITTABLE) \
479
&& ((LIST)->flags & __VA_GCC_STRUCT_RETURN) \
481
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
482
* and the struct will actually be returned in registers.
484
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
485
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
488
#if defined(__ARMEL__)
489
/* structs of size 3 also will be returned in register */
490
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
492
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
493
* and the struct will actually be returned in registers.
495
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
496
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
498
#if defined(__alpha__)
499
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
500
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8 \
501
|| ((TYPE_SIZE) == 16 && (TYPE_SPLITTABLE) \
502
&& ((LIST)->flags & __VA_GCC_STRUCT_RETURN) \
504
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
505
* and the struct will actually be returned in registers.
507
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
508
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
510
#if defined(__hppa__)
511
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
512
((LIST)->flags & __VA_OLDGCC_STRUCT_RETURN \
513
? ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4) \
514
: ((TYPE_SIZE) <= 8) \
516
/* Test both __VA_OLDGCC_STRUCT_RETURN and __VA_SMALL_STRUCT_RETURN at run time. */
517
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
520
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__m88k__)
521
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
522
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4)
523
/* Test __VA_SMALL_STRUCT_RETURN instead of __VA_REGISTER_STRUCT_RETURN. */
524
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)
525
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
530
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
534
#if defined(__mipsn32__) || defined(__mips64__)
535
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
536
((LIST)->flags & __VA_GCC_STRUCT_RETURN \
537
? ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8) \
538
: ((TYPE_SIZE) <= 16) \
540
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
541
* and the struct will actually be returned in registers. Also turn on
542
* __VA_REGISTER_FLOATSTRUCT_RETURN or __VA_REGISTER_DOUBLESTRUCT_RETURN if
543
* the struct will be returned in floating-point registers.
545
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
546
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, \
547
(TYPE_ALIGN) == sizeof(float) && (TYPE_SPLITTABLE) \
548
&& ((TYPE_SIZE) == sizeof(float) || (TYPE_SIZE) == 2*sizeof(float)) \
549
&& ((LIST)->flags |= __VA_REGISTER_FLOATSTRUCT_RETURN), \
550
(TYPE_ALIGN) == sizeof(double) && (TYPE_SPLITTABLE) \
551
&& ((TYPE_SIZE) == sizeof(double) || (TYPE_SIZE) == 2*sizeof(double)) \
552
&& ((LIST)->flags |= __VA_REGISTER_DOUBLESTRUCT_RETURN), \
555
#if defined(__powerpc64__)
556
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
558
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
561
#if defined(__sparc64__) || defined(__ia64__)
562
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
564
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
565
* and the struct will actually be returned in registers.
567
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
568
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, \
571
#if defined(__x86_64__)
572
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
574
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
575
* and the struct will actually be returned in registers.
577
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
578
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, \
582
* Preparing structure return in memory.
584
#if defined(__i386__)
585
/* Return structure pointer is passed in a special register or as first arg. */
586
#define __va_start_struct2(LIST) \
587
((LIST)->flags & __VA_NEXTGCC_STRUCT_RETURN \
588
? ((LIST)->raddr = (LIST)->structraddr, 0) /* special register */ \
589
: ((LIST)->raddr = *(void* *)((LIST)->aptr), /* first arg */ \
590
(LIST)->aptr += sizeof(void*), \
594
#if defined(__alpha__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__) || defined(__s390__)
595
/* Return structure pointer is passed as first arg. */
596
#define __va_start_struct2(LIST) \
597
((LIST)->raddr = *(void* *)((LIST)->aptr), \
598
(LIST)->aptr += sizeof(void*), \
602
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__)
603
/* Return structure pointer is passed as first arg. */
604
#define __va_start_struct2(LIST) \
605
((LIST)->raddr = *(void* *)((LIST)->aptr), \
606
(LIST)->aptr += sizeof(void*), \
611
#if defined(__x86_64__)
612
/* Return structure pointer is passed as first arg. */
613
#define __va_start_struct2(LIST) \
614
((LIST)->raddr = (void *)(*(LIST)->memiargptr++), \
618
#if defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__m88k__) || defined(__ia64__)
619
/* Return structure pointer is passed in a special register. */
620
#define __va_start_struct2(LIST) \
621
((LIST)->raddr = (LIST)->structraddr, 0)
626
* Definition of the va_arg_xxx macros.
629
/* Padding of non-struct arguments. */
630
#define __va_argsize(TYPE_SIZE) \
631
(((TYPE_SIZE) + sizeof(__vaword)-1) & -(long)sizeof(__vaword))
632
#if defined(__i386__) || defined(__m68k__) || (defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__alpha__) || defined(__arm__) || (defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__)
634
/* small structures < 1 word are adjusted depending on compiler */
635
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
636
((LIST)->aptr += __va_argsize(TYPE_SIZE), \
637
(LIST)->aptr - __va_argsize(TYPE_SIZE) \
639
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
640
((LIST)->aptr += __va_argsize(TYPE_SIZE), \
641
(LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword) \
643
: __va_argsize(TYPE_SIZE) \
647
#if defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
649
/* small structures < 1 word are adjusted depending on compiler */
650
/* Also make sure we switch to the stack pointer after 8 args */
651
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
652
((((LIST)->onstack == 0 && (LIST)->aptr >= (long)&(LIST)->regarg[8]) \
653
? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0), \
654
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
655
(LIST)->aptr - __va_argsize(TYPE_SIZE) \
657
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
658
((((LIST)->onstack == 0 && (LIST)->aptr >= (long)&(LIST)->regarg[8]) \
659
? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0), \
660
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
661
(LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword) \
663
: __va_argsize(TYPE_SIZE) \
667
#if defined(__s390__)
669
/* small structures < 1 word are adjusted depending on compiler */
670
/* Also make sure we switch to the stack pointer after 5 args */
671
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
672
((((LIST)->onstack == 0 && (LIST)->aptr >= (long)&(LIST)->regarg[5]) \
673
? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0), \
674
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
675
(LIST)->aptr - __va_argsize(TYPE_SIZE) \
677
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
678
(((((LIST)->onstack == 0 && ((LIST)->aptr >= (long)&(LIST)->regarg[5])) \
679
|| ((TYPE_SIZE) > sizeof(__vaword) && (LIST)->aptr >= (long)&(LIST)->regarg[4])) \
680
? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0), \
681
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
682
(LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword) \
684
: __va_argsize(TYPE_SIZE) \
688
#if defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__)
690
/* small structures < 1 word are adjusted depending on compiler */
691
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
692
((LIST)->anum += __va_argsize(TYPE_SIZE)/sizeof(__vaword), \
693
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
694
(LIST)->aptr - __va_argsize(TYPE_SIZE) \
696
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
697
((LIST)->anum += __va_argsize(TYPE_SIZE)/sizeof(__vaword), \
698
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
699
(LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword) \
701
: __va_argsize(TYPE_SIZE) \
705
#if defined(__hppa__)
707
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
708
((LIST)->aptr = (LIST)->aptr - __va_argsize(TYPE_SIZE), \
709
((TYPE_SIZE) > 4 && ((LIST)->aptr &= -8)), \
712
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
713
((LIST)->aptr = (LIST)->aptr - __va_argsize(TYPE_SIZE), \
714
((TYPE_SIZE) > 4 && ((LIST)->aptr &= -8)), \
715
(LIST)->aptr + ((-(TYPE_SIZE)) & 3) \
718
#if defined(__i386__) || defined(__alpha__) || defined(__ia64__) || defined(__ARMEL__)
719
/* little endian -> small args < 1 word are adjusted to the left */
720
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
721
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)
723
#if defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || (defined(__arm__) && !defined(__ARMEL__)) || defined(__powerpc__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__s390__)
724
/* big endian -> small args < 1 word are adjusted to the right */
725
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
726
__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)
728
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)
729
/* big endian -> small args < 1 word are adjusted to the right */
730
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
731
((LIST)->anum++, __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN))
733
#if defined(__x86_64__)
734
/* the first 6 argument words are passed in registers */
735
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
736
((LIST)->memiargptr + ((TYPE_SIZE) + sizeof(__vaword)-1) / sizeof(__vaword) <= &(LIST)->iarg[6] \
737
? ((LIST)->memiargptr += ((TYPE_SIZE) + sizeof(__vaword)-1) / sizeof(__vaword), \
738
(LIST)->memiargptr - ((TYPE_SIZE) + sizeof(__vaword)-1) / sizeof(__vaword) \
740
: (void*)__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
743
#define __va_arg(LIST,TYPE) \
744
*(TYPE*)__va_arg_adjusted(LIST,sizeof(TYPE),__VA_alignof(TYPE))
746
/* Integer arguments. */
748
#define va_arg_char(LIST) __va_arg(LIST,char)
749
#define va_arg_schar(LIST) __va_arg(LIST,signed char)
750
#define va_arg_uchar(LIST) __va_arg(LIST,unsigned char)
751
#define va_arg_short(LIST) __va_arg(LIST,short)
752
#define va_arg_ushort(LIST) __va_arg(LIST,unsigned short)
753
#define va_arg_int(LIST) __va_arg(LIST,int)
754
#define va_arg_uint(LIST) __va_arg(LIST,unsigned int)
755
#define va_arg_long(LIST) __va_arg(LIST,long)
756
#define va_arg_ulong(LIST) __va_arg(LIST,unsigned long)
758
#if defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__powerpc64__) || defined(__ia64__) || defined(__x86_64__)
759
/* `long long' and `long' are identical. */
760
#define va_arg_longlong va_arg_long
761
#define va_arg_ulonglong va_arg_ulong
762
#elif defined(__mipsn32__)
763
/* `long long' fits in __vaword. */
764
#define va_arg_longlong(LIST) __va_arg(LIST,long long)
765
#define va_arg_ulonglong(LIST) __va_arg(LIST,unsigned long long)
766
#elif defined(__i386__) || defined(__m68k__) || defined(__mips__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__arm__) || defined(__powerpc__) || defined(__m88k__) || defined(__convex__) || defined(__s390__)
767
/* `long long's are passed embedded on the arg stack. */
768
#define va_arg_longlong(LIST) __va_arg_longlong(LIST,long long)
769
#define va_arg_ulonglong(LIST) __va_arg_longlong(LIST,unsigned long long)
770
#if defined(__i386__) || defined(__m68k__) || (defined(__arm__) && !defined(__ARMEL__)) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__)
771
/* `long long's are (at most) word-aligned. */
772
#define __va_arg_longlong(LIST,TYPE) __va_arg(LIST,TYPE)
774
#if defined(__mips__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__) || defined(__ARMEL__)
775
/* `long long's have alignment 8. */
776
#define __va_arg_longlong(LIST,TYPE) \
777
((LIST)->aptr = (((LIST)->aptr+__VA_alignof(TYPE)-1) & -(long)__VA_alignof(TYPE)), \
780
#if (defined(__sparc__) && !defined(__sparc64__)) || defined(__s390__)
781
/* Within the arg stack, the alignment is only 4, not 8. */
782
/* Beware against unaligned accesses! */
783
#define __va_arg_longlong(LIST,TYPE) \
784
((LIST)->tmp._words[0] = ((__vaword*)((LIST)->aptr))[0], \
785
(LIST)->tmp._words[1] = ((__vaword*)((LIST)->aptr))[1], \
786
(LIST)->aptr += sizeof(TYPE), \
787
(TYPE)((LIST)->tmp._longlong) \
790
#if defined(__hppa__)
791
/* `long long's have alignment 8. */
792
#define __va_arg_longlong(LIST,TYPE) \
793
((LIST)->aptr = ((LIST)->aptr & -(long)__VA_alignof(TYPE)), \
798
/* Floating point arguments. */
800
#if defined(__i386__) || defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__alpha__) || (defined(__arm__) && !defined(__ARMEL__)) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__)
801
#define __va_align_double(LIST)
803
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__) || defined(__m88k__) || defined(__ARMEL__)
804
/* __VA_alignof(double) > sizeof(__vaword) */
805
#define __va_align_double(LIST) \
806
(LIST)->aptr = ((LIST)->aptr + sizeof(double)-1) & -(long)sizeof(double),
808
#if defined(__hppa__)
809
#define __va_align_double(LIST) \
810
(LIST)->aptr = (LIST)->aptr & -(long)sizeof(double),
813
#if defined(__sparc__) && !defined(__sparc64__)
814
/* Beware against unaligned `double' accesses! */
815
#define va_arg_double(LIST) \
816
(__va_align_double(LIST) \
817
(LIST)->tmp._words[0] = ((__vaword*)((LIST)->aptr))[0], \
818
(LIST)->tmp._words[1] = ((__vaword*)((LIST)->aptr))[1], \
819
(LIST)->aptr += sizeof(double), \
820
(LIST)->tmp._double \
823
#if defined(__alpha__)
824
/* The first 6 floating point registers have been stored in another place. */
825
#define va_arg_double(LIST) \
826
(((LIST)->aptr += sizeof(double)) <= (LIST)->memargptr \
827
? *(double*)((LIST)->aptr - sizeof(double) - 6*sizeof(double)) \
828
: *(double*)((LIST)->aptr - sizeof(double)) \
830
#define va_arg_float(LIST) \
831
(((LIST)->aptr += sizeof(double)) <= (LIST)->memargptr \
832
? /* The first 6 args have been put into memory by "stt" instructions */\
833
/* (see vacall-alpha.s!). Therefore load them as doubles. */ \
834
/* When viewed as floats, the value will be the correct one. */ \
835
(float)*(double*)((LIST)->aptr - sizeof(double) - 6*sizeof(double)) \
836
: /* These args have been put into memory by "sts" instructions, */ \
837
/* therefore load them as floats. */ \
838
*(float*)((LIST)->aptr - sizeof(double)) \
841
#if defined(__hppa__)
842
/* The first 4 float registers and the first 2 double registers are stored
845
#if 1 /* gcc-2.5.2 passes these args in general registers! A bug, I think. */
846
#define va_arg_float(LIST) \
847
(*(float*)((LIST)->aptr -= sizeof(float)))
848
#define va_arg_double(LIST) \
849
(__va_align_double(LIST) \
850
*(double*)((LIST)->aptr -= sizeof(double)) \
852
#else /* this would be correct if the args were passed in float registers. */
853
#define va_arg_float(LIST) \
854
(((LIST)->aptr -= sizeof(float)) >= (LIST)->memargptr \
855
? /* The first 4 float args are stored separately. */ \
856
*(float*)((LIST)->aptr + (LIST)->farg_offset) \
857
: *(float*)((LIST)->aptr) \
859
#define va_arg_double(LIST) \
860
(__va_align_double(LIST) \
861
(((LIST)->aptr -= sizeof(double)) >= (LIST)->memargptr \
862
? /* The first 2 double args are stored separately. */ \
863
*(double*)((LIST)->aptr + (LIST)->darg_offset) \
864
: *(double*)((LIST)->aptr) \
868
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)
869
/* The first 0,1,2 registers are stored elsewhere if they are floating-point
872
#define va_arg_float(LIST) \
873
((LIST)->aptr += sizeof(float), \
876
? ((LIST)->flags |= __VA_FLOAT_1, (LIST)->farg[0]) \
877
: ((LIST)->anum == 2 && ((LIST)->flags & __VA_FLOAT_1) \
878
? (/* (LIST)->flags |= __VA_FLOAT_2, */ (LIST)->farg[1]) \
879
: *(float*)((LIST)->aptr - sizeof(float)) \
881
#define va_arg_double(LIST) \
882
(__va_align_double(LIST) \
883
(LIST)->aptr += sizeof(double), \
886
? ((LIST)->flags |= __VA_FLOAT_1, (LIST)->darg[0]) \
887
: ((LIST)->anum == 2 && ((LIST)->flags & __VA_FLOAT_1) \
888
? (/* (LIST)->flags |= __VA_FLOAT_2, */ (LIST)->darg[1]) \
889
: *(double*)((LIST)->aptr - sizeof(double)) \
892
#if defined(__mipsn32__) || defined(__mips64__)
893
/* The first 0,..,8 registers are stored elsewhere if they are floating-point
896
#define va_arg_float(LIST) \
897
(__va_align_double(LIST) \
898
(LIST)->aptr += sizeof(double), \
899
(++(LIST)->anum <= 8 \
900
? (LIST)->farg[(LIST)->anum - 1] \
901
: *(float*)((LIST)->aptr - sizeof(double)) \
903
#define va_arg_double(LIST) \
904
(__va_align_double(LIST) \
905
(LIST)->aptr += sizeof(double), \
906
(++(LIST)->anum <= 8 \
907
? (LIST)->darg[(LIST)->anum - 1] \
908
: *(double*)((LIST)->aptr - sizeof(double)) \
911
#if defined(__sparc64__)
912
/* The first 0,..,16 registers are stored elsewhere if they are floating-point
915
#define va_arg_float(LIST) \
916
(__va_align_double(LIST) \
917
(LIST)->aptr += sizeof(double), \
918
(++(LIST)->anum <= 16 \
919
? (LIST)->farg[(LIST)->anum - 1] \
920
: *(float*)((LIST)->aptr - sizeof(double)) \
922
#define va_arg_double(LIST) \
923
(__va_align_double(LIST) \
924
(LIST)->aptr += sizeof(double), \
925
(++(LIST)->anum <= 16 \
926
? (LIST)->darg[(LIST)->anum - 1] \
927
: *(double*)((LIST)->aptr - sizeof(double)) \
930
#if defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
931
/* The first 13 floating-point args have been stored elsewhere. */
932
#define va_arg_float(LIST) \
933
((LIST)->aptr += sizeof(float), \
934
((LIST)->memfargptr < &(LIST)->farg[13] \
935
? (float) *((LIST)->memfargptr++) \
936
: *(float*)((LIST)->aptr - sizeof(float)) \
938
#define va_arg_double(LIST) \
939
(__va_align_double(LIST) \
940
(LIST)->aptr += sizeof(double), \
941
((LIST)->memfargptr < &(LIST)->farg[13] \
942
? *((LIST)->memfargptr++) \
943
: *(double*)((LIST)->aptr - sizeof(double)) \
946
#if defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
947
/* The first 8 floating-point args have been stored elsewhere. */
948
#define va_arg_float(LIST) \
949
((LIST)->memfargptr < &(LIST)->farg[8] \
950
? (float) *((LIST)->memfargptr++) \
951
: ((LIST)->aptr = ((LIST)->onstack == 0 \
952
? ((LIST)->onstack=1, (LIST)->saptr) \
955
(LIST)->aptr += sizeof(float), \
956
*(float*)((LIST)->aptr - sizeof(float)) \
958
#define va_arg_double(LIST) \
959
((LIST)->memfargptr < &(LIST)->farg[8] \
960
? *((LIST)->memfargptr++) \
961
: ((LIST)->aptr = ((LIST)->onstack == 0 \
962
? ((LIST)->onstack=1, (LIST)->saptr) \
965
__va_align_double(LIST) \
966
(LIST)->aptr += sizeof(double), \
967
*(double*)((LIST)->aptr - sizeof(double)) \
970
#if defined(__powerpc64__)
971
/* The first 13 floating-point args have been stored elsewhere. */
972
#define va_arg_float(LIST) \
973
((LIST)->aptr += sizeof(__vaword), \
974
((LIST)->memfargptr < &(LIST)->farg[13] \
975
? (float) *((LIST)->memfargptr++) \
976
: *(float*)((LIST)->aptr - sizeof(float)) \
978
#define va_arg_double(LIST) \
979
(__va_align_double(LIST) \
980
(LIST)->aptr += sizeof(double), \
981
((LIST)->memfargptr < &(LIST)->farg[13] \
982
? *((LIST)->memfargptr++) \
983
: *(double*)((LIST)->aptr - sizeof(double)) \
986
#if defined(__s390__)
987
/* The first 2 floating-point args have been stored elsewhere. */
988
#define va_arg_float(LIST) \
989
((LIST)->memfargptr < &(LIST)->farg[2] \
990
? (LIST)->memdargptr++, (float) *((LIST)->memfargptr++) \
991
: ((LIST)->aptr = ((LIST)->onstack == 0 \
992
? ((LIST)->onstack=1, (LIST)->saptr) \
995
(LIST)->aptr += sizeof(float), \
996
*(float*)((LIST)->aptr - sizeof(float)) \
998
#define va_arg_double(LIST) \
999
((LIST)->memdargptr < &(LIST)->darg[2] \
1000
? (LIST)->memfargptr++, *((LIST)->memdargptr++) \
1001
: ((LIST)->aptr = ((LIST)->onstack == 0 \
1002
? ((LIST)->onstack=1, (LIST)->saptr) \
1005
__va_align_double(LIST) \
1006
(LIST)->aptr += sizeof(double), \
1007
*(double*)((LIST)->aptr - sizeof(double)) \
1010
#if defined(__ia64__)
1011
/* The first 8 floating-point args have been stored elsewhere. */
1012
#define va_arg_float(LIST) \
1013
((LIST)->aptr += sizeof(__vaword), \
1014
((LIST)->memfargptr < &(LIST)->farg[8] \
1015
? (float) *((LIST)->memfargptr++) \
1016
: *(float*)((LIST)->aptr - sizeof(__vaword)) \
1018
#define va_arg_double(LIST) \
1019
(__va_align_double(LIST) \
1020
(LIST)->aptr += sizeof(double), \
1021
((LIST)->memfargptr < &(LIST)->farg[8] \
1022
? *((LIST)->memfargptr++) \
1023
: *(double*)((LIST)->aptr - sizeof(double)) \
1026
#if defined(__x86_64__)
1027
/* The first 8 floating-point args have been stored elsewhere. */
1028
#define va_arg_float(LIST) \
1029
((LIST)->memfargptr < &(LIST)->farg[8] \
1030
? ((LIST)->memfargptr++, \
1031
*(float*)((LIST)->memfargptr - 1) \
1033
: ((LIST)->aptr += sizeof(__vaword), \
1034
*(float*)((LIST)->aptr - sizeof(__vaword)) \
1036
#define va_arg_double(LIST) \
1037
((LIST)->memfargptr < &(LIST)->farg[8] \
1038
? *(LIST)->memfargptr++ \
1039
: ((LIST)->aptr += sizeof(__vaword), \
1040
*(double*)((LIST)->aptr - sizeof(__vaword)) \
1043
#ifndef va_arg_float
1044
#define va_arg_float(LIST) __va_arg(LIST,float)
1046
#ifndef va_arg_double
1047
#define va_arg_double(LIST) \
1048
(__va_align_double(LIST) __va_arg(LIST,double))
1051
/* Pointer arguments. */
1052
#define va_arg_ptr(LIST,TYPE) __va_arg(LIST,TYPE)
1054
/* Structure arguments. */
1055
#define va_arg_struct(LIST,TYPE) \
1056
*(TYPE*)__va_arg_struct(LIST,sizeof(TYPE),__VA_alignof(TYPE))
1057
/* _va_arg_struct() is like va_arg_struct(), except that you pass the type's
1058
* size and alignment instead of the type and get the value's address instead
1059
* of the value itself.
1061
#define _va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1062
(void*)__va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)
1063
/* Structure argument alignment. */
1064
#if defined(__i386__) && defined(_MSC_VER)
1065
/* In MSVC, doubles inside structures have alignment 8, i.e.
1066
* __VA_alignof(double) = 8, but doubles (and also structures containing
1067
* doubles) are passed on the stack with alignment 4. Looks really weird.
1069
#define __va_struct_alignment(TYPE_ALIGN) \
1070
((TYPE_ALIGN) <= 4 ? (TYPE_ALIGN) : 4)
1072
#define __va_struct_alignment(TYPE_ALIGN) \
1075
#define __va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1076
(LIST)->aptr = ((LIST)->aptr + __va_struct_alignment(TYPE_ALIGN)-1) & -(long)__va_struct_alignment(TYPE_ALIGN),
1077
#if defined(__i386__) || defined(__m68k__) || defined(__alpha__) || defined(__arm__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__x86_64__)
1078
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1079
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1080
__va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1083
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)
1084
/* small structures < 1 word are adjusted depending on compiler */
1085
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1086
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1087
((LIST)->flags & __VA_SGICC_STRUCT_ARGS \
1088
? /* SGI MIPS cc passes small structures left-adjusted, although big-endian! */\
1089
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1090
: /* SGI MIPS gcc passes small structures within the first four words left- \
1091
* adjusted, for compatibility with cc. But structures in memory are passed \
1092
* right-adjusted!! See gcc-2.6.3/config/mips/mips.c:function_arg(). \
1094
((LIST)->aptr < (LIST)->memargptr \
1095
? __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1096
: __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1099
#if defined(__mipsn32__) || defined(__mips64__)
1100
/* small structures < 1 word are adjusted depending on compiler */
1101
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1102
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1103
((LIST)->flags & __VA_SGICC_STRUCT_ARGS \
1104
? /* SGI MIPS cc passes small structures left-adjusted, although big-endian! */\
1105
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1106
: /* SGI MIPS gcc passes small structures right-adjusted. */ \
1107
__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1110
#if defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
1111
/* small structures < 1 word are adjusted depending on compiler */
1112
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1113
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1114
((LIST)->flags & __VA_AIXCC_STRUCT_ARGS \
1115
? /* AIX cc and xlc pass small structures left-adjusted, although big-endian! */\
1116
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1117
: /* gcc passes small structures right-adjusted. */ \
1118
__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1121
#if defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
1122
/* Structures are passed as pointers to caller-made local copies. */
1123
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1124
va_arg_ptr(LIST,void*)
1126
#if defined(__sparc__) && !defined(__sparc64__)
1127
/* Structures are passed as pointers to caller-made local copies. */
1128
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1129
va_arg_ptr(LIST,void*)
1131
#if defined(__sparc64__)
1132
/* Small structures are passed left-adjusted, although big-endian! */
1133
/* Big structures are passed as pointers to caller-made local copies. */
1134
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1135
((TYPE_SIZE) <= 16 \
1136
? (__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1137
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)) \
1138
: va_arg_ptr(LIST,void*) \
1141
#if defined(__s390__)
1142
/* Structures <= 8 bytes are passed as embedded copies on the arg stack.
1143
* Big structures are passed as pointers to caller-made local copies.
1145
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1146
((TYPE_SIZE) != 1 && (TYPE_SIZE) != 2 && (TYPE_SIZE) != 4 && (TYPE_SIZE) != 8 \
1147
? va_arg_ptr(LIST,void*) \
1148
: (void*)__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1151
#if defined(__hppa__)
1152
/* Structures <= 8 bytes are passed as embedded copies on the arg stack.
1153
* Big structures are passed as pointers to caller-made local copies.
1155
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1157
? va_arg_ptr(LIST,void*) \
1158
: /* FIXME: gcc-2.6.3 passes structures <= 4 bytes in memory left-adjusted! ?? */\
1159
(void*)__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1162
#if defined(__ia64__)
1163
/* Types larger than a word have 2-word alignment. */
1164
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1165
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1166
((TYPE_SIZE) > sizeof(__vaword) && (((__vaword*)(LIST)->aptr - (LIST)->saptr) & 1) ? (LIST)->aptr += sizeof(__vaword) : 0), \
1167
__va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1173
* Definition of the va_return_xxx macros.
1175
#define __va_return(LIST,RETTYPE) \
1176
(((LIST)->rtype == (RETTYPE)) || __va_error1((LIST)->rtype,RETTYPE))
1177
#define va_return_void(LIST) \
1178
__va_return(LIST,__VAvoid)
1179
#define va_return_char(LIST,VAL) \
1180
(__va_return(LIST,__VAchar), (LIST)->tmp._char = (VAL))
1181
#define va_return_schar(LIST,VAL) \
1182
(__va_return(LIST,__VAschar), (LIST)->tmp._schar = (VAL))
1183
#define va_return_uchar(LIST,VAL) \
1184
(__va_return(LIST,__VAuchar), (LIST)->tmp._uchar = (VAL))
1185
#define va_return_short(LIST,VAL) \
1186
(__va_return(LIST,__VAshort), (LIST)->tmp._short = (VAL))
1187
#define va_return_ushort(LIST,VAL) \
1188
(__va_return(LIST,__VAushort), (LIST)->tmp._ushort = (VAL))
1189
#define va_return_int(LIST,VAL) \
1190
(__va_return(LIST,__VAint), (LIST)->tmp._int = (VAL))
1191
#define va_return_uint(LIST,VAL) \
1192
(__va_return(LIST,__VAuint), (LIST)->tmp._uint = (VAL))
1193
#define va_return_long(LIST,VAL) \
1194
(__va_return(LIST,__VAlong), (LIST)->tmp._long = (VAL))
1195
#define va_return_ulong(LIST,VAL) \
1196
(__va_return(LIST,__VAulong), (LIST)->tmp._ulong = (VAL))
1197
#if defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__powerpc64__) || defined(__ia64__) || defined(__x86_64__)
1198
#define va_return_longlong(LIST,VAL) \
1199
(__va_return(LIST,__VAlonglong), (LIST)->tmp._long = (VAL))
1200
#define va_return_ulonglong(LIST,VAL) \
1201
(__va_return(LIST,__VAulonglong), (LIST)->tmp._ulong = (VAL))
1203
#define va_return_longlong(LIST,VAL) \
1204
(__va_return(LIST,__VAlonglong), (LIST)->tmp._longlong = (VAL))
1205
#define va_return_ulonglong(LIST,VAL) \
1206
(__va_return(LIST,__VAulonglong), (LIST)->tmp._ulonglong = (VAL))
1208
#define va_return_float(LIST,VAL) \
1209
(__va_return(LIST,__VAfloat), (LIST)->tmp._float = (VAL))
1210
#define va_return_double(LIST,VAL) \
1211
(__va_return(LIST,__VAdouble), (LIST)->tmp._double = (VAL))
1212
#define va_return_ptr(LIST,TYPE,VAL) \
1213
(__va_return(LIST,__VAvoidp), (LIST)->tmp._ptr = (void*)(TYPE)(VAL))
1214
#define va_return_struct(LIST,TYPE,VAL) \
1215
(__va_return(LIST,__VAstruct), *(TYPE*)((LIST)->raddr) = (VAL))
1216
#define _va_return_struct(LIST,TYPE_SIZE,TYPE_ALIGN,VAL_ADDR) \
1217
(__va_return(LIST,__VAstruct), \
1218
__structcpy((void*)((LIST)->raddr),VAL_ADDR,TYPE_SIZE,TYPE_ALIGN) \
1222
/* Determine whether a struct type is word-splittable, i.e. whether each of
1223
* its components fit into a register.
1224
* The entire computation is done at compile time.
1226
#define va_word_splittable_1(slot1) \
1227
(__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword))
1228
#define va_word_splittable_2(slot1,slot2) \
1229
((__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword)) \
1230
&& (__va_offset2(slot1,slot2)/sizeof(__vaword) == (__va_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__vaword)) \
1232
#define va_word_splittable_3(slot1,slot2,slot3) \
1233
((__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword)) \
1234
&& (__va_offset2(slot1,slot2)/sizeof(__vaword) == (__va_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__vaword)) \
1235
&& (__va_offset3(slot1,slot2,slot3)/sizeof(__vaword) == (__va_offset3(slot1,slot2,slot3)+sizeof(slot3)-1)/sizeof(__vaword)) \
1237
#define va_word_splittable_4(slot1,slot2,slot3,slot4) \
1238
((__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword)) \
1239
&& (__va_offset2(slot1,slot2)/sizeof(__vaword) == (__va_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__vaword)) \
1240
&& (__va_offset3(slot1,slot2,slot3)/sizeof(__vaword) == (__va_offset3(slot1,slot2,slot3)+sizeof(slot3)-1)/sizeof(__vaword)) \
1241
&& (__va_offset4(slot1,slot2,slot3,slot4)/sizeof(__vaword) == (__va_offset4(slot1,slot2,slot3,slot4)+sizeof(slot4)-1)/sizeof(__vaword)) \
1243
#define __va_offset1(slot1) \
1245
#define __va_offset2(slot1,slot2) \
1246
((__va_offset1(slot1)+sizeof(slot1)+__VA_alignof(slot2)-1) & -(long)__VA_alignof(slot2))
1247
#define __va_offset3(slot1,slot2,slot3) \
1248
((__va_offset2(slot1,slot2)+sizeof(slot2)+__VA_alignof(slot3)-1) & -(long)__VA_alignof(slot3))
1249
#define __va_offset4(slot1,slot2,slot3,slot4) \
1250
((__va_offset3(slot1,slot2,slot3)+sizeof(slot3)+__VA_alignof(slot4)-1) & -(long)__VA_alignof(slot4))
1254
* Miscellaneous declarations.
1257
extern "C" void (*vacall) (); /* the return type is variable, not void! */
1259
extern void (*vacall) (); /* the return type is variable, not void! */
1261
extern void (* vacall_function) (va_alist);
1262
extern int __va_error1 (enum __VAtype, enum __VAtype);
1263
extern int __va_error2 (unsigned int);
1264
extern void __structcpy (void* dest, const void* src, unsigned long size, unsigned long alignment);
1265
typedef union { __vaword room[__VA_ALIST_WORDS]; double align; } __va_struct_buffer_t;
1266
extern __va_struct_buffer_t __va_struct_buffer;
1269
#endif /* _VACALL_H */