1
#ifndef _VACALL_R_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,
14
/* These definitions are adjusted by `configure' automatically. */
69
/* Calling convention */
70
/* Define if using pcc non-reentrant struct return convention */
71
#undef __PCC_STRUCT_RETURN__
72
/* Define if small structs are returned in registers */
73
#define __SMALL_STRUCT_RETURN__ 1
74
/* Define if floating-point results are returned in the integer registers */
75
#undef __IREG_FLOAT_RETURN__
77
/* gl_AC_TYPE_LONG_LONG */
78
/* Define if your compiler supports the 'long long' type. */
79
#ifndef HAVE_LONG_LONG
83
/* AC_C_CHAR_UNSIGNED */
84
#ifndef __CHAR_UNSIGNED__
85
#undef __CHAR_UNSIGNED__
88
/* End of definitions adjusted by `configure'. */
91
/* Max # words in argument-list and temporary structure storage.
93
#ifndef __VA_ALIST_WORDS
94
#define __VA_ALIST_WORDS 256
97
/* Determine the alignment of a type at compile time.
100
#define __VA_alignof __alignof__
102
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) /* SGI compiler */
103
#define __VA_alignof __builtin_alignof
105
#define __VA_offsetof(type,ident) ((unsigned long)&(((type*)0)->ident))
106
#define __VA_alignof(type) __VA_offsetof(struct { char __slot1; type __slot2; }, __slot2)
112
#if defined(__mipsn32__)
113
typedef long long __vaword;
115
typedef long __vaword;
138
enum __VA_alist_flags
141
/* how to return structs */
142
/* There are basically 3 ways to return structs:
143
* a. The called function returns a pointer to static data. Not reentrant.
144
* b. The caller passes the return structure address in a dedicated register
145
* or as a first (or last), invisible argument. The called function stores
147
* c. Like b, and the called function also returns the return structure
148
* address in the return value register. (This is not very distinguishable
150
* Independently of this,
151
* r. small structures (<= 4 or <= 8 bytes) may be returned in the return
152
* value register(s), or
153
* m. even small structures are passed in memory.
155
/* gcc-2.6.3 employs the following strategy:
156
* - If PCC_STATIC_STRUCT_RETURN is defined in the machine description
157
* it uses method a, else method c.
158
* - If flag_pcc_struct_return is set (either by -fpcc-struct-return or if
159
* DEFAULT_PCC_STRUCT_RETURN is defined to 1 in the machine description)
160
* it uses method m, else (either by -freg-struct-return or if
161
* DEFAULT_PCC_STRUCT_RETURN is defined to 0 in the machine description)
164
__VA_PCC_STRUCT_RETURN = 1<<0, /* a: need to copy the struct */
165
__VA_SMALL_STRUCT_RETURN = 1<<1, /* r: special case for small structs */
166
__VA_GCC_STRUCT_RETURN = 1<<2, /* consider 8 byte structs as small */
167
#if defined(__sparc__) && !defined(__sparc64__)
168
__VA_SUNCC_STRUCT_RETURN = 1<<3,
169
__VA_SUNPROCC_STRUCT_RETURN = 1<<4,
171
__VA_SUNCC_STRUCT_RETURN = 0,
172
__VA_SUNPROCC_STRUCT_RETURN = 0,
174
#if defined(__i386__)
175
__VA_NEXTGCC_STRUCT_RETURN = 1<<3,
176
__VA_MSVC_STRUCT_RETURN = 1<<4,
178
#if defined(__hppa__)
179
__VA_OLDGCC_STRUCT_RETURN = 1<<3,
181
/* the default way to return structs */
182
/* This choice here is based on the assumption that the function you are
183
* going to call has been compiled with the same compiler you are using to
185
* If you want to call functions with another struct returning convention,
186
* just #define __VA_STRUCT_RETURN ...
187
* before or after #including <vacall_r.h>.
189
#ifndef __VA_STRUCT_RETURN
191
#if defined(__sparc__) && !defined(__sparc64__) && defined(sun) && defined(__SUNPRO_C) /* SUNWspro cc */
192
__VA_SUNPROCC_STRUCT_RETURN,
194
#if defined(__PCC_STRUCT_RETURN__) /* defined through configure, see above */
195
__VA_PCC_STRUCT_RETURN,
197
#if defined(__SMALL_STRUCT_RETURN__) || defined(__mipsn32__) || defined(__mips64__) /* defined through configure, see above */
198
__VA_SMALL_STRUCT_RETURN |
200
#if defined(__GNUC__)
201
__VA_GCC_STRUCT_RETURN |
203
#if defined(__i386__) && defined(NeXT) && defined(__GNUC__) /* NeXT gcc-2.5.8 */
204
__VA_NEXTGCC_STRUCT_RETURN |
206
#if defined(__i386__) && defined(_MSC_VER) /* MSVC 4.0 */
207
__VA_MSVC_STRUCT_RETURN |
209
#if defined(__hppa__) && defined(__GNUC__) && (__GNUC__ < 3) && (__GNUC_MINOR__ < 7)
210
__VA_OLDGCC_STRUCT_RETURN |
217
/* how to return floats */
218
#if defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__))
219
__VA_SUNCC_FLOAT_RETURN = 1<<5,
221
#if defined(__m68k__)
222
__VA_FREG_FLOAT_RETURN = 1<<6,
224
/* the default way to return floats */
225
/* This choice here is based on the assumption that the function you are
226
* going to call has been compiled with the same compiler you are using to
228
* If you want to call functions with another float returning convention,
229
* just #define __VA_FLOAT_RETURN ...
230
* before or after #including <vacall_r.h>.
232
#ifndef __VA_FLOAT_RETURN
233
#if (defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__))) && !defined(__GNUC__) && defined(sun) && !defined(__SUNPRO_C) /* sun cc */
234
__VA_FLOAT_RETURN = __VA_SUNCC_FLOAT_RETURN,
235
#elif (defined(__m68k__) && !defined(__IREG_FLOAT_RETURN__))
236
__VA_FLOAT_RETURN = __VA_FREG_FLOAT_RETURN,
238
__VA_FLOAT_RETURN = 0,
242
/* how to pass structs */
243
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__)
244
__VA_SGICC_STRUCT_ARGS = 1<<7,
246
#if defined(__powerpc__) && !defined(__powerpc64__)
247
__VA_AIXCC_STRUCT_ARGS = 1<<7,
249
/* the default way to pass floats */
250
/* This choice here is based on the assumption that the function you are
251
* going to call has been compiled with the same compiler you are using to
253
* If you want to call functions with another float passing convention,
254
* just #define __VA_STRUCT_ARGS ...
255
* before or after #including <vacall_r.h>.
257
#ifndef __VA_STRUCT_ARGS
258
#if (defined(__mips__) || defined(__mipsn32__) || defined(__mips64__)) && !defined(__GNUC__) /* SGI mips cc */
259
__VA_STRUCT_ARGS = __VA_SGICC_STRUCT_ARGS,
261
#if defined(__powerpc__) && !defined(__powerpc64__) && defined(_AIX) && !defined(__GNUC__) /* AIX cc, xlc */
262
__VA_STRUCT_ARGS = __VA_AIXCC_STRUCT_ARGS,
264
__VA_STRUCT_ARGS = 0,
269
/* how to pass floats */
270
/* ANSI C compilers and GNU gcc pass floats as floats.
271
* K&R C compilers pass floats as doubles. We don't support them any more.
274
/* how to pass and return small integer arguments */
275
__VA_ANSI_INTEGERS = 0, /* no promotions */
276
__VA_TRADITIONAL_INTEGERS = 0, /* promote [u]char, [u]short to [u]int */
277
/* Fortunately these two methods are compatible. Our macros work with both. */
279
/* stack cleanup policy */
280
__VA_CDECL_CLEANUP = 0, /* caller pops args after return */
281
__VA_STDCALL_CLEANUP = 1<<9, /* callee pops args before return */
282
/* currently only supported on __i386__ */
284
__VA_CLEANUP = __VA_CDECL_CLEANUP,
287
/* These are for internal use only */
288
#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__)
289
__VA_REGISTER_STRUCT_RETURN = 1<<10,
291
#if defined(__mips__) && !defined(__mipsn32__)
292
__VA_FLOAT_1 = 1<<11,
293
__VA_FLOAT_2 = 1<<12,
295
#if defined(__mipsn32__) || defined(__mips64__)
296
__VA_REGISTER_FLOATSTRUCT_RETURN = 1<<13,
297
__VA_REGISTER_DOUBLESTRUCT_RETURN = 1<<14,
300
__VA_flag_for_broken_compilers_that_dont_like_trailing_commas
304
* Definition of the `va_alist' type.
308
/* some va_... macros need these flags */
310
/* current pointer into the argument array */
312
/* structure return pointer, return type, return type size */
316
#if defined(__i386__) || (defined(__powerpc__) && !defined(__powerpc64__) && defined(__MACH__) && defined(__APPLE__))
317
/* Filler word, needed if the numbers of words up to now in this structure */
318
/* is odd (because on MSVC, alignof(double) = 8, normally = 4; similarly, */
319
/* on MacOS X, the Apple compiler has alignof(double) = 8 whereas the */
320
/* standard GCC has alignof(double) = 4. */
323
/* temporary storage for return value */
327
unsigned char _uchar;
329
unsigned short _ushort;
333
unsigned long _ulong;
334
#if !(defined(__mips64__) || defined(__alpha__) || defined(__powerpc64__)) && defined(HAVE_LONG_LONG)
336
unsigned long long _ulonglong;
343
#if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__m88k__) || defined(__ia64__)
346
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__alpha__) || defined(__hppa__)
349
#if defined(__hppa__)
355
#if defined(__mips__) && !defined(__mipsn32__)
360
#if defined(__mipsn32__) || defined(__mips64__)
365
#if defined(__sparc64__)
370
#if defined(__powerpc__) || defined(__powerpc64__)
373
#if !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
379
#if defined(__s390__)
388
#if defined(__ia64__)
393
#if defined(__x86_64__)
396
__vaword* memiargptr;
401
typedef __va_alist* va_alist;
405
* Definition of the va_start_xxx macros.
407
#define __VA_START_FLAGS \
408
__VA_STRUCT_RETURN | __VA_FLOAT_RETURN | __VA_STRUCT_ARGS | __VA_CLEANUP
409
#define __va_start(LIST,RETTYPE) \
410
((LIST)->flags = __VA_START_FLAGS, \
411
(LIST)->rtype = (RETTYPE) \
413
#define va_start_void(LIST) __va_start(LIST,__VAvoid)
414
#define va_start_char(LIST) __va_start(LIST,__VAchar)
415
#define va_start_schar(LIST) __va_start(LIST,__VAschar)
416
#define va_start_uchar(LIST) __va_start(LIST,__VAuchar)
417
#define va_start_short(LIST) __va_start(LIST,__VAshort)
418
#define va_start_ushort(LIST) __va_start(LIST,__VAushort)
419
#define va_start_int(LIST) __va_start(LIST,__VAint)
420
#define va_start_uint(LIST) __va_start(LIST,__VAuint)
421
#define va_start_long(LIST) __va_start(LIST,__VAlong)
422
#define va_start_ulong(LIST) __va_start(LIST,__VAulong)
423
#define va_start_longlong(LIST) __va_start(LIST,__VAlonglong)
424
#define va_start_ulonglong(LIST) __va_start(LIST,__VAulonglong)
425
#define va_start_float(LIST) __va_start(LIST,__VAfloat)
426
#define va_start_double(LIST) __va_start(LIST,__VAdouble)
427
#define va_start_ptr(LIST,TYPE) __va_start(LIST,__VAvoidp)
430
* va_start_struct: Preparing structure return.
432
#define va_start_struct(LIST,TYPE,TYPE_SPLITTABLE) \
433
_va_start_struct(LIST,sizeof(TYPE),__VA_alignof(TYPE),TYPE_SPLITTABLE)
434
/* _va_start_struct() is like va_start_struct(), except that you pass
435
* the type's size and alignment instead of the type itself.
437
#define _va_start_struct(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
438
(__va_start(LIST,__VAstruct), \
439
(LIST)->rsize = (TYPE_SIZE), \
440
((LIST)->flags & __VA_SUNPROCC_STRUCT_RETURN \
441
? __va_start_struct2(LIST) \
442
: ((LIST)->flags & (__VA_PCC_STRUCT_RETURN | __VA_SUNCC_STRUCT_RETURN) \
443
? ((TYPE_SIZE) <= sizeof(__va_struct_buffer) || __va_error2(TYPE_SIZE), \
444
(LIST)->raddr = &__va_struct_buffer, \
447
: (((LIST)->flags & __VA_SMALL_STRUCT_RETURN) \
448
&& __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
449
? ((LIST)->raddr = &(LIST)->tmp, \
450
__va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
452
: __va_start_struct2(LIST) \
454
/* Determines whether a structure is returned in registers,
455
* depending on its size and its word-splittable flag.
457
#if (defined(__i386__) && defined(_WIN32))
458
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
459
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 \
460
|| ((TYPE_SIZE) == 8 \
461
&& (((LIST)->flags & __VA_MSVC_STRUCT_RETURN) \
462
|| ((TYPE_SPLITTABLE) \
463
&& ((LIST)->flags & __VA_GCC_STRUCT_RETURN) \
465
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
466
* and the struct will actually be returned in registers.
468
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
469
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
471
#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
472
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
473
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 \
474
|| ((TYPE_SIZE) == 8 && (TYPE_SPLITTABLE) \
475
&& ((LIST)->flags & __VA_GCC_STRUCT_RETURN) \
477
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
478
* and the struct will actually be returned in registers.
480
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
481
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
483
#if defined(__alpha__)
484
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
485
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8 \
486
|| ((TYPE_SIZE) == 16 && (TYPE_SPLITTABLE) \
487
&& ((LIST)->flags & __VA_GCC_STRUCT_RETURN) \
489
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
490
* and the struct will actually be returned in registers.
492
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
493
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
495
#if defined(__hppa__)
496
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
497
((LIST)->flags & __VA_OLDGCC_STRUCT_RETURN \
498
? ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4) \
499
: ((TYPE_SIZE) <= 8) \
501
/* Test both __VA_OLDGCC_STRUCT_RETURN and __VA_SMALL_STRUCT_RETURN at run time. */
502
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
505
#if defined(__mips__) && !defined(__mipsn32__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__m88k__)
506
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
507
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4)
508
/* Test __VA_SMALL_STRUCT_RETURN instead of __VA_REGISTER_STRUCT_RETURN. */
509
#if defined(__mips__) && !defined(__mipsn32__)
510
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
515
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
519
#if defined(__mipsn32__) || defined(__mips64__)
520
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
521
((LIST)->flags & __VA_GCC_STRUCT_RETURN \
522
? ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8) \
523
: ((TYPE_SIZE) <= 16) \
525
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
526
* and the struct will actually be returned in registers. Also turn on
527
* __VA_REGISTER_FLOATSTRUCT_RETURN or __VA_REGISTER_DOUBLESTRUCT_RETURN if
528
* the struct will be returned in floating-point registers.
530
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
531
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, \
532
(TYPE_ALIGN) == sizeof(float) && (TYPE_SPLITTABLE) \
533
&& ((TYPE_SIZE) == sizeof(float) || (TYPE_SIZE) == 2*sizeof(float)) \
534
&& ((LIST)->flags |= __VA_REGISTER_FLOATSTRUCT_RETURN), \
535
(TYPE_ALIGN) == sizeof(double) && (TYPE_SPLITTABLE) \
536
&& ((TYPE_SIZE) == sizeof(double) || (TYPE_SIZE) == 2*sizeof(double)) \
537
&& ((LIST)->flags |= __VA_REGISTER_DOUBLESTRUCT_RETURN), \
540
#if defined(__powerpc64__)
541
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
543
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
546
#if defined(__sparc64__) || defined(__ia64__)
547
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
549
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
550
* and the struct will actually be returned in registers.
552
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
553
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, \
556
#if defined(__x86_64__)
557
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
559
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
560
* and the struct will actually be returned in registers.
562
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
563
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, \
567
* Preparing structure return in memory.
569
#if defined(__i386__)
570
/* Return structure pointer is passed in a special register or as first arg. */
571
#define __va_start_struct2(LIST) \
572
((LIST)->flags & __VA_NEXTGCC_STRUCT_RETURN \
573
? ((LIST)->raddr = (LIST)->structraddr, 0) /* special register */ \
574
: ((LIST)->raddr = *(void* *)((LIST)->aptr), /* first arg */ \
575
(LIST)->aptr += sizeof(void*), \
579
#if defined(__alpha__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__) || defined(__s390__)
580
/* Return structure pointer is passed as first arg. */
581
#define __va_start_struct2(LIST) \
582
((LIST)->raddr = *(void* *)((LIST)->aptr), \
583
(LIST)->aptr += sizeof(void*), \
587
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__)
588
/* Return structure pointer is passed as first arg. */
589
#define __va_start_struct2(LIST) \
590
((LIST)->raddr = *(void* *)((LIST)->aptr), \
591
(LIST)->aptr += sizeof(void*), \
596
#if defined(__x86_64__)
597
/* Return structure pointer is passed as first arg. */
598
#define __va_start_struct2(LIST) \
599
((LIST)->raddr = (void *)(*(LIST)->memiargptr++), \
603
#if defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__m88k__) || defined(__ia64__)
604
/* Return structure pointer is passed in a special register. */
605
#define __va_start_struct2(LIST) \
606
((LIST)->raddr = (LIST)->structraddr, 0)
611
* Definition of the va_arg_xxx macros.
614
/* Padding of non-struct arguments. */
615
#define __va_argsize(TYPE_SIZE) \
616
(((TYPE_SIZE) + sizeof(__vaword)-1) & -(long)sizeof(__vaword))
617
#if defined(__i386__) || defined(__m68k__) || defined(__mips__) && !defined(__mipsn32__) || (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__)
619
/* small structures < 1 word are adjusted depending on compiler */
620
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
621
((LIST)->aptr += __va_argsize(TYPE_SIZE), \
622
(LIST)->aptr - __va_argsize(TYPE_SIZE) \
624
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
625
((LIST)->aptr += __va_argsize(TYPE_SIZE), \
626
(LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword) \
628
: __va_argsize(TYPE_SIZE) \
632
#if defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
634
/* small structures < 1 word are adjusted depending on compiler */
635
/* Also make sure we switch to the stack pointer after 8 args */
636
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
637
((((LIST)->onstack == 0 && (LIST)->aptr >= (long)&(LIST)->regarg[8]) \
638
? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0), \
639
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
640
(LIST)->aptr - __va_argsize(TYPE_SIZE) \
642
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
643
((((LIST)->onstack == 0 && (LIST)->aptr >= (long)&(LIST)->regarg[8]) \
644
? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0), \
645
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
646
(LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword) \
648
: __va_argsize(TYPE_SIZE) \
652
#if defined(__s390__)
654
/* small structures < 1 word are adjusted depending on compiler */
655
/* Also make sure we switch to the stack pointer after 5 args */
656
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
657
((((LIST)->onstack == 0 && (LIST)->aptr >= (long)&(LIST)->regarg[5]) \
658
? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0), \
659
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
660
(LIST)->aptr - __va_argsize(TYPE_SIZE) \
662
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
663
(((((LIST)->onstack == 0 && ((LIST)->aptr >= (long)&(LIST)->regarg[5])) \
664
|| ((TYPE_SIZE) > sizeof(__vaword) && (LIST)->aptr >= (long)&(LIST)->regarg[4])) \
665
? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0), \
666
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
667
(LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword) \
669
: __va_argsize(TYPE_SIZE) \
673
#if defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__)
675
/* small structures < 1 word are adjusted depending on compiler */
676
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
677
((LIST)->anum += __va_argsize(TYPE_SIZE)/sizeof(__vaword), \
678
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
679
(LIST)->aptr - __va_argsize(TYPE_SIZE) \
681
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
682
((LIST)->anum += __va_argsize(TYPE_SIZE)/sizeof(__vaword), \
683
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
684
(LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword) \
686
: __va_argsize(TYPE_SIZE) \
690
#if defined(__hppa__)
692
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
693
((LIST)->aptr = (LIST)->aptr - __va_argsize(TYPE_SIZE), \
694
((TYPE_SIZE) > 4 && ((LIST)->aptr &= -8)), \
697
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
698
((LIST)->aptr = (LIST)->aptr - __va_argsize(TYPE_SIZE), \
699
((TYPE_SIZE) > 4 && ((LIST)->aptr &= -8)), \
700
(LIST)->aptr + ((-(TYPE_SIZE)) & 3) \
703
#if defined(__i386__) || defined(__alpha__) || defined(__ia64__)
704
/* little endian -> small args < 1 word are adjusted to the left */
705
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
706
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)
708
#if defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__s390__)
709
/* big endian -> small args < 1 word are adjusted to the right */
710
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
711
__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)
713
#if defined(__mips__) && !defined(__mipsn32__)
714
/* big endian -> small args < 1 word are adjusted to the right */
715
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
716
((LIST)->anum++, __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN))
718
#if defined(__x86_64__)
719
/* the first 6 argument words are passed in registers */
720
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
721
((LIST)->memiargptr + ((TYPE_SIZE) + sizeof(__vaword)-1) / sizeof(__vaword) <= &(LIST)->iarg[6] \
722
? ((LIST)->memiargptr += ((TYPE_SIZE) + sizeof(__vaword)-1) / sizeof(__vaword), \
723
(LIST)->memiargptr - ((TYPE_SIZE) + sizeof(__vaword)-1) / sizeof(__vaword) \
725
: (void*)__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
728
#define __va_arg(LIST,TYPE) \
729
*(TYPE*)__va_arg_adjusted(LIST,sizeof(TYPE),__VA_alignof(TYPE))
731
/* Integer arguments. */
733
#define va_arg_char(LIST) __va_arg(LIST,char)
734
#define va_arg_schar(LIST) __va_arg(LIST,signed char)
735
#define va_arg_uchar(LIST) __va_arg(LIST,unsigned char)
736
#define va_arg_short(LIST) __va_arg(LIST,short)
737
#define va_arg_ushort(LIST) __va_arg(LIST,unsigned short)
738
#define va_arg_int(LIST) __va_arg(LIST,int)
739
#define va_arg_uint(LIST) __va_arg(LIST,unsigned int)
740
#define va_arg_long(LIST) __va_arg(LIST,long)
741
#define va_arg_ulong(LIST) __va_arg(LIST,unsigned long)
743
#if defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__powerpc64__) || defined(__ia64__) || defined(__x86_64__)
744
/* `long long' and `long' are identical. */
745
#define va_arg_longlong va_arg_long
746
#define va_arg_ulonglong va_arg_ulong
747
#elif defined(__mipsn32__)
748
/* `long long' fits in __vaword. */
749
#define va_arg_longlong(LIST) __va_arg(LIST,long long)
750
#define va_arg_ulonglong(LIST) __va_arg(LIST,unsigned long long)
751
#elif defined(__i386__) || defined(__m68k__) || defined(__mips__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__arm__) || defined(__powerpc__) || defined(__m88k__) || defined(__convex__) || defined(__s390__)
752
/* `long long's are passed embedded on the arg stack. */
753
#define va_arg_longlong(LIST) __va_arg_longlong(LIST,long long)
754
#define va_arg_ulonglong(LIST) __va_arg_longlong(LIST,unsigned long long)
755
#if defined(__i386__) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__)
756
/* `long long's are (at most) word-aligned. */
757
#define __va_arg_longlong(LIST,TYPE) __va_arg(LIST,TYPE)
759
#if defined(__mips__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__)
760
/* `long long's have alignment 8. */
761
#define __va_arg_longlong(LIST,TYPE) \
762
((LIST)->aptr = (((LIST)->aptr+__VA_alignof(TYPE)-1) & -(long)__VA_alignof(TYPE)), \
765
#if (defined(__sparc__) && !defined(__sparc64__)) || defined(__s390__)
766
/* Within the arg stack, the alignment is only 4, not 8. */
767
/* Beware against unaligned accesses! */
768
#define __va_arg_longlong(LIST,TYPE) \
769
((LIST)->tmp._words[0] = ((__vaword*)((LIST)->aptr))[0], \
770
(LIST)->tmp._words[1] = ((__vaword*)((LIST)->aptr))[1], \
771
(LIST)->aptr += sizeof(TYPE), \
772
(TYPE)((LIST)->tmp._longlong) \
775
#if defined(__hppa__)
776
/* `long long's have alignment 8. */
777
#define __va_arg_longlong(LIST,TYPE) \
778
((LIST)->aptr = ((LIST)->aptr & -(long)__VA_alignof(TYPE)), \
783
/* Floating point arguments. */
785
#if defined(__i386__) || defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__alpha__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__)
786
#define __va_align_double(LIST)
788
#if defined(__mips__) && !defined(__mipsn32__) || defined(__m88k__)
789
/* __VA_alignof(double) > sizeof(__vaword) */
790
#define __va_align_double(LIST) \
791
(LIST)->aptr = ((LIST)->aptr + sizeof(double)-1) & -(long)sizeof(double),
793
#if defined(__hppa__)
794
#define __va_align_double(LIST) \
795
(LIST)->aptr = (LIST)->aptr & -(long)sizeof(double),
798
#if defined(__sparc__) && !defined(__sparc64__)
799
/* Beware against unaligned `double' accesses! */
800
#define va_arg_double(LIST) \
801
(__va_align_double(LIST) \
802
(LIST)->tmp._words[0] = ((__vaword*)((LIST)->aptr))[0], \
803
(LIST)->tmp._words[1] = ((__vaword*)((LIST)->aptr))[1], \
804
(LIST)->aptr += sizeof(double), \
805
(LIST)->tmp._double \
808
#if defined(__alpha__)
809
/* The first 6 floating point registers have been stored in another place. */
810
#define va_arg_double(LIST) \
811
(((LIST)->aptr += sizeof(double)) <= (LIST)->memargptr \
812
? *(double*)((LIST)->aptr - sizeof(double) - 6*sizeof(double)) \
813
: *(double*)((LIST)->aptr - sizeof(double)) \
815
#define va_arg_float(LIST) \
816
(((LIST)->aptr += sizeof(double)) <= (LIST)->memargptr \
817
? /* The first 6 args have been put into memory by "stt" instructions */\
818
/* (see vacall-alpha.s!). Therefore load them as doubles. */ \
819
/* When viewed as floats, the value will be the correct one. */ \
820
(float)*(double*)((LIST)->aptr - sizeof(double) - 6*sizeof(double)) \
821
: /* These args have been put into memory by "sts" instructions, */ \
822
/* therefore load them as floats. */ \
823
*(float*)((LIST)->aptr - sizeof(double)) \
826
#if defined(__hppa__)
827
/* The first 4 float registers and the first 2 double registers are stored
830
#if 1 /* gcc-2.5.2 passes these args in general registers! A bug, I think. */
831
#define va_arg_float(LIST) \
832
(*(float*)((LIST)->aptr -= sizeof(float)))
833
#define va_arg_double(LIST) \
834
(__va_align_double(LIST) \
835
*(double*)((LIST)->aptr -= sizeof(double)) \
837
#else /* this would be correct if the args were passed in float registers. */
838
#define va_arg_float(LIST) \
839
(((LIST)->aptr -= sizeof(float)) >= (LIST)->memargptr \
840
? /* The first 4 float args are stored separately. */ \
841
*(float*)((LIST)->aptr + (LIST)->farg_offset) \
842
: *(float*)((LIST)->aptr) \
844
#define va_arg_double(LIST) \
845
(__va_align_double(LIST) \
846
(((LIST)->aptr -= sizeof(double)) >= (LIST)->memargptr \
847
? /* The first 2 double args are stored separately. */ \
848
*(double*)((LIST)->aptr + (LIST)->darg_offset) \
849
: *(double*)((LIST)->aptr) \
853
#if defined(__mips__) && !defined(__mipsn32__)
854
/* The first 0,1,2 registers are stored elsewhere if they are floating-point
857
#define va_arg_float(LIST) \
858
((LIST)->aptr += sizeof(float), \
861
? ((LIST)->flags |= __VA_FLOAT_1, (LIST)->farg[0]) \
862
: ((LIST)->anum == 2 && ((LIST)->flags & __VA_FLOAT_1) \
863
? (/* (LIST)->flags |= __VA_FLOAT_2, */ (LIST)->farg[1]) \
864
: *(float*)((LIST)->aptr - sizeof(float)) \
866
#define va_arg_double(LIST) \
867
(__va_align_double(LIST) \
868
(LIST)->aptr += sizeof(double), \
871
? ((LIST)->flags |= __VA_FLOAT_1, (LIST)->darg[0]) \
872
: ((LIST)->anum == 2 && ((LIST)->flags & __VA_FLOAT_1) \
873
? (/* (LIST)->flags |= __VA_FLOAT_2, */ (LIST)->darg[1]) \
874
: *(double*)((LIST)->aptr - sizeof(double)) \
877
#if defined(__mipsn32__) || defined(__mips64__)
878
/* The first 0,..,8 registers are stored elsewhere if they are floating-point
881
#define va_arg_float(LIST) \
882
(__va_align_double(LIST) \
883
(LIST)->aptr += sizeof(double), \
884
(++(LIST)->anum <= 8 \
885
? (LIST)->farg[(LIST)->anum - 1] \
886
: *(float*)((LIST)->aptr - sizeof(double)) \
888
#define va_arg_double(LIST) \
889
(__va_align_double(LIST) \
890
(LIST)->aptr += sizeof(double), \
891
(++(LIST)->anum <= 8 \
892
? (LIST)->darg[(LIST)->anum - 1] \
893
: *(double*)((LIST)->aptr - sizeof(double)) \
896
#if defined(__sparc64__)
897
/* The first 0,..,16 registers are stored elsewhere if they are floating-point
900
#define va_arg_float(LIST) \
901
(__va_align_double(LIST) \
902
(LIST)->aptr += sizeof(double), \
903
(++(LIST)->anum <= 16 \
904
? (LIST)->farg[(LIST)->anum - 1] \
905
: *(float*)((LIST)->aptr - sizeof(double)) \
907
#define va_arg_double(LIST) \
908
(__va_align_double(LIST) \
909
(LIST)->aptr += sizeof(double), \
910
(++(LIST)->anum <= 16 \
911
? (LIST)->darg[(LIST)->anum - 1] \
912
: *(double*)((LIST)->aptr - sizeof(double)) \
915
#if defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
916
/* The first 13 floating-point args have been stored elsewhere. */
917
#define va_arg_float(LIST) \
918
((LIST)->aptr += sizeof(float), \
919
((LIST)->memfargptr < &(LIST)->farg[13] \
920
? (float) *((LIST)->memfargptr++) \
921
: *(float*)((LIST)->aptr - sizeof(float)) \
923
#define va_arg_double(LIST) \
924
(__va_align_double(LIST) \
925
(LIST)->aptr += sizeof(double), \
926
((LIST)->memfargptr < &(LIST)->farg[13] \
927
? *((LIST)->memfargptr++) \
928
: *(double*)((LIST)->aptr - sizeof(double)) \
931
#if defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
932
/* The first 8 floating-point args have been stored elsewhere. */
933
#define va_arg_float(LIST) \
934
((LIST)->memfargptr < &(LIST)->farg[8] \
935
? (float) *((LIST)->memfargptr++) \
936
: ((LIST)->aptr = ((LIST)->onstack == 0 \
937
? ((LIST)->onstack=1, (LIST)->saptr) \
940
(LIST)->aptr += sizeof(float), \
941
*(float*)((LIST)->aptr - sizeof(float)) \
943
#define va_arg_double(LIST) \
944
((LIST)->memfargptr < &(LIST)->farg[8] \
945
? *((LIST)->memfargptr++) \
946
: ((LIST)->aptr = ((LIST)->onstack == 0 \
947
? ((LIST)->onstack=1, (LIST)->saptr) \
950
__va_align_double(LIST) \
951
(LIST)->aptr += sizeof(double), \
952
*(double*)((LIST)->aptr - sizeof(double)) \
955
#if defined(__powerpc64__)
956
/* The first 13 floating-point args have been stored elsewhere. */
957
#define va_arg_float(LIST) \
958
((LIST)->aptr += sizeof(__vaword), \
959
((LIST)->memfargptr < &(LIST)->farg[13] \
960
? (float) *((LIST)->memfargptr++) \
961
: *(float*)((LIST)->aptr - sizeof(float)) \
963
#define va_arg_double(LIST) \
964
(__va_align_double(LIST) \
965
(LIST)->aptr += sizeof(double), \
966
((LIST)->memfargptr < &(LIST)->farg[13] \
967
? *((LIST)->memfargptr++) \
968
: *(double*)((LIST)->aptr - sizeof(double)) \
971
#if defined(__s390__)
972
/* The first 2 floating-point args have been stored elsewhere. */
973
#define va_arg_float(LIST) \
974
((LIST)->memfargptr < &(LIST)->farg[2] \
975
? (LIST)->memdargptr++, (float) *((LIST)->memfargptr++) \
976
: ((LIST)->aptr = ((LIST)->onstack == 0 \
977
? ((LIST)->onstack=1, (LIST)->saptr) \
980
(LIST)->aptr += sizeof(float), \
981
*(float*)((LIST)->aptr - sizeof(float)) \
983
#define va_arg_double(LIST) \
984
((LIST)->memdargptr < &(LIST)->darg[2] \
985
? (LIST)->memfargptr++, *((LIST)->memdargptr++) \
986
: ((LIST)->aptr = ((LIST)->onstack == 0 \
987
? ((LIST)->onstack=1, (LIST)->saptr) \
990
__va_align_double(LIST) \
991
(LIST)->aptr += sizeof(double), \
992
*(double*)((LIST)->aptr - sizeof(double)) \
995
#if defined(__ia64__)
996
/* The first 8 floating-point args have been stored elsewhere. */
997
#define va_arg_float(LIST) \
998
((LIST)->aptr += sizeof(__vaword), \
999
((LIST)->memfargptr < &(LIST)->farg[8] \
1000
? (float) *((LIST)->memfargptr++) \
1001
: *(float*)((LIST)->aptr - sizeof(__vaword)) \
1003
#define va_arg_double(LIST) \
1004
(__va_align_double(LIST) \
1005
(LIST)->aptr += sizeof(double), \
1006
((LIST)->memfargptr < &(LIST)->farg[8] \
1007
? *((LIST)->memfargptr++) \
1008
: *(double*)((LIST)->aptr - sizeof(double)) \
1011
#if defined(__x86_64__)
1012
/* The first 8 floating-point args have been stored elsewhere. */
1013
#define va_arg_float(LIST) \
1014
((LIST)->memfargptr < &(LIST)->farg[8] \
1015
? ((LIST)->memfargptr++, \
1016
*(float*)((LIST)->memfargptr - 1) \
1018
: ((LIST)->aptr += sizeof(__vaword), \
1019
*(float*)((LIST)->aptr - sizeof(__vaword)) \
1021
#define va_arg_double(LIST) \
1022
((LIST)->memfargptr < &(LIST)->farg[8] \
1023
? *(LIST)->memfargptr++ \
1024
: ((LIST)->aptr += sizeof(__vaword), \
1025
*(double*)((LIST)->aptr - sizeof(__vaword)) \
1028
#ifndef va_arg_float
1029
#define va_arg_float(LIST) __va_arg(LIST,float)
1031
#ifndef va_arg_double
1032
#define va_arg_double(LIST) \
1033
(__va_align_double(LIST) __va_arg(LIST,double))
1036
/* Pointer arguments. */
1037
#define va_arg_ptr(LIST,TYPE) __va_arg(LIST,TYPE)
1039
/* Structure arguments. */
1040
#define va_arg_struct(LIST,TYPE) \
1041
*(TYPE*)__va_arg_struct(LIST,sizeof(TYPE),__VA_alignof(TYPE))
1042
/* _va_arg_struct() is like va_arg_struct(), except that you pass the type's
1043
* size and alignment instead of the type and get the value's address instead
1044
* of the value itself.
1046
#define _va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1047
(void*)__va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)
1048
/* Structure argument alignment. */
1049
#if defined(__i386__) && defined(_MSC_VER)
1050
/* In MSVC, doubles inside structures have alignment 8, i.e.
1051
* __VA_alignof(double) = 8, but doubles (and also structures containing
1052
* doubles) are passed on the stack with alignment 4. Looks really weird.
1054
#define __va_struct_alignment(TYPE_ALIGN) \
1055
((TYPE_ALIGN) <= 4 ? (TYPE_ALIGN) : 4)
1057
#define __va_struct_alignment(TYPE_ALIGN) \
1060
#define __va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1061
(LIST)->aptr = ((LIST)->aptr + __va_struct_alignment(TYPE_ALIGN)-1) & -(long)__va_struct_alignment(TYPE_ALIGN),
1062
#if defined(__i386__) || defined(__m68k__) || defined(__alpha__) || defined(__arm__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__x86_64__)
1063
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1064
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1065
__va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1068
#if defined(__mips__) && !defined(__mipsn32__)
1069
/* small structures < 1 word are adjusted depending on compiler */
1070
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1071
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1072
((LIST)->flags & __VA_SGICC_STRUCT_ARGS \
1073
? /* SGI MIPS cc passes small structures left-adjusted, although big-endian! */\
1074
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1075
: /* SGI MIPS gcc passes small structures within the first four words left- \
1076
* adjusted, for compatibility with cc. But structures in memory are passed \
1077
* right-adjusted!! See gcc-2.6.3/config/mips/mips.c:function_arg(). \
1079
((LIST)->aptr < (LIST)->memargptr \
1080
? __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1081
: __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1084
#if defined(__mipsn32__) || defined(__mips64__)
1085
/* small structures < 1 word are adjusted depending on compiler */
1086
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1087
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1088
((LIST)->flags & __VA_SGICC_STRUCT_ARGS \
1089
? /* SGI MIPS cc passes small structures left-adjusted, although big-endian! */\
1090
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1091
: /* SGI MIPS gcc passes small structures right-adjusted. */ \
1092
__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1095
#if defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
1096
/* small structures < 1 word are adjusted depending on compiler */
1097
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1098
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1099
((LIST)->flags & __VA_AIXCC_STRUCT_ARGS \
1100
? /* AIX cc and xlc pass small structures left-adjusted, although big-endian! */\
1101
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1102
: /* gcc passes small structures right-adjusted. */ \
1103
__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1106
#if defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
1107
/* Structures are passed as pointers to caller-made local copies. */
1108
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1109
va_arg_ptr(LIST,void*)
1111
#if defined(__sparc__) && !defined(__sparc64__)
1112
/* Structures are passed as pointers to caller-made local copies. */
1113
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1114
va_arg_ptr(LIST,void*)
1116
#if defined(__sparc64__)
1117
/* Small structures are passed left-adjusted, although big-endian! */
1118
/* Big structures are passed as pointers to caller-made local copies. */
1119
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1120
((TYPE_SIZE) <= 16 \
1121
? (__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1122
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)) \
1123
: va_arg_ptr(LIST,void*) \
1126
#if defined(__s390__)
1127
/* Structures <= 8 bytes are passed as embedded copies on the arg stack.
1128
* Big structures are passed as pointers to caller-made local copies.
1130
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1131
((TYPE_SIZE) != 1 && (TYPE_SIZE) != 2 && (TYPE_SIZE) != 4 && (TYPE_SIZE) != 8 \
1132
? va_arg_ptr(LIST,void*) \
1133
: (void*)__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1136
#if defined(__hppa__)
1137
/* Structures <= 8 bytes are passed as embedded copies on the arg stack.
1138
* Big structures are passed as pointers to caller-made local copies.
1140
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1142
? va_arg_ptr(LIST,void*) \
1143
: /* FIXME: gcc-2.6.3 passes structures <= 4 bytes in memory left-adjusted! ?? */\
1144
(void*)__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1147
#if defined(__ia64__)
1148
/* Types larger than a word have 2-word alignment. */
1149
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1150
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1151
((TYPE_SIZE) > sizeof(__vaword) && (((__vaword*)(LIST)->aptr - (LIST)->saptr) & 1) ? (LIST)->aptr += sizeof(__vaword) : 0), \
1152
__va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1158
* Definition of the va_return_xxx macros.
1160
#define __va_return(LIST,RETTYPE) \
1161
(((LIST)->rtype == (RETTYPE)) || __va_error1((LIST)->rtype,RETTYPE))
1162
#define va_return_void(LIST) \
1163
__va_return(LIST,__VAvoid)
1164
#define va_return_char(LIST,VAL) \
1165
(__va_return(LIST,__VAchar), (LIST)->tmp._char = (VAL))
1166
#define va_return_schar(LIST,VAL) \
1167
(__va_return(LIST,__VAschar), (LIST)->tmp._schar = (VAL))
1168
#define va_return_uchar(LIST,VAL) \
1169
(__va_return(LIST,__VAuchar), (LIST)->tmp._uchar = (VAL))
1170
#define va_return_short(LIST,VAL) \
1171
(__va_return(LIST,__VAshort), (LIST)->tmp._short = (VAL))
1172
#define va_return_ushort(LIST,VAL) \
1173
(__va_return(LIST,__VAushort), (LIST)->tmp._ushort = (VAL))
1174
#define va_return_int(LIST,VAL) \
1175
(__va_return(LIST,__VAint), (LIST)->tmp._int = (VAL))
1176
#define va_return_uint(LIST,VAL) \
1177
(__va_return(LIST,__VAuint), (LIST)->tmp._uint = (VAL))
1178
#define va_return_long(LIST,VAL) \
1179
(__va_return(LIST,__VAlong), (LIST)->tmp._long = (VAL))
1180
#define va_return_ulong(LIST,VAL) \
1181
(__va_return(LIST,__VAulong), (LIST)->tmp._ulong = (VAL))
1182
#if defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__powerpc64__) || defined(__ia64__) || defined(__x86_64__)
1183
#define va_return_longlong(LIST,VAL) \
1184
(__va_return(LIST,__VAlonglong), (LIST)->tmp._long = (VAL))
1185
#define va_return_ulonglong(LIST,VAL) \
1186
(__va_return(LIST,__VAulonglong), (LIST)->tmp._ulong = (VAL))
1188
#define va_return_longlong(LIST,VAL) \
1189
(__va_return(LIST,__VAlonglong), (LIST)->tmp._longlong = (VAL))
1190
#define va_return_ulonglong(LIST,VAL) \
1191
(__va_return(LIST,__VAulonglong), (LIST)->tmp._ulonglong = (VAL))
1193
#define va_return_float(LIST,VAL) \
1194
(__va_return(LIST,__VAfloat), (LIST)->tmp._float = (VAL))
1195
#define va_return_double(LIST,VAL) \
1196
(__va_return(LIST,__VAdouble), (LIST)->tmp._double = (VAL))
1197
#define va_return_ptr(LIST,TYPE,VAL) \
1198
(__va_return(LIST,__VAvoidp), (LIST)->tmp._ptr = (void*)(TYPE)(VAL))
1199
#define va_return_struct(LIST,TYPE,VAL) \
1200
(__va_return(LIST,__VAstruct), *(TYPE*)((LIST)->raddr) = (VAL))
1201
#define _va_return_struct(LIST,TYPE_SIZE,TYPE_ALIGN,VAL_ADDR) \
1202
(__va_return(LIST,__VAstruct), \
1203
__structcpy((void*)((LIST)->raddr),VAL_ADDR,TYPE_SIZE,TYPE_ALIGN) \
1207
/* Determine whether a struct type is word-splittable, i.e. whether each of
1208
* its components fit into a register.
1209
* The entire computation is done at compile time.
1211
#define va_word_splittable_1(slot1) \
1212
(__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword))
1213
#define va_word_splittable_2(slot1,slot2) \
1214
((__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword)) \
1215
&& (__va_offset2(slot1,slot2)/sizeof(__vaword) == (__va_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__vaword)) \
1217
#define va_word_splittable_3(slot1,slot2,slot3) \
1218
((__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword)) \
1219
&& (__va_offset2(slot1,slot2)/sizeof(__vaword) == (__va_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__vaword)) \
1220
&& (__va_offset3(slot1,slot2,slot3)/sizeof(__vaword) == (__va_offset3(slot1,slot2,slot3)+sizeof(slot3)-1)/sizeof(__vaword)) \
1222
#define va_word_splittable_4(slot1,slot2,slot3,slot4) \
1223
((__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword)) \
1224
&& (__va_offset2(slot1,slot2)/sizeof(__vaword) == (__va_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__vaword)) \
1225
&& (__va_offset3(slot1,slot2,slot3)/sizeof(__vaword) == (__va_offset3(slot1,slot2,slot3)+sizeof(slot3)-1)/sizeof(__vaword)) \
1226
&& (__va_offset4(slot1,slot2,slot3,slot4)/sizeof(__vaword) == (__va_offset4(slot1,slot2,slot3,slot4)+sizeof(slot4)-1)/sizeof(__vaword)) \
1228
#define __va_offset1(slot1) \
1230
#define __va_offset2(slot1,slot2) \
1231
((__va_offset1(slot1)+sizeof(slot1)+__VA_alignof(slot2)-1) & -(long)__VA_alignof(slot2))
1232
#define __va_offset3(slot1,slot2,slot3) \
1233
((__va_offset2(slot1,slot2)+sizeof(slot2)+__VA_alignof(slot3)-1) & -(long)__VA_alignof(slot3))
1234
#define __va_offset4(slot1,slot2,slot3,slot4) \
1235
((__va_offset3(slot1,slot2,slot3)+sizeof(slot3)+__VA_alignof(slot4)-1) & -(long)__VA_alignof(slot4))
1239
* Miscellaneous declarations.
1242
extern "C" void __vacall_r (); /* the return type is variable, not void! */
1244
extern void __vacall_r (); /* the return type is variable, not void! */
1246
extern int __va_error1 (enum __VAtype, enum __VAtype);
1247
extern int __va_error2 (unsigned int);
1248
extern void __structcpy (void* dest, const void* src, unsigned long size, unsigned long alignment);
1249
typedef union { __vaword room[__VA_ALIST_WORDS]; double align; } __va_struct_buffer_t;
1250
extern __va_struct_buffer_t __va_struct_buffer;
1253
#endif /* _VACALL_R_H */