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,
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
#undef __SMALL_STRUCT_RETURN__
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.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.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.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.
273
__VA_ANSI_FLOAT_ARGS = 0, /* pass floats as floats */
275
/* how to pass and return small integer arguments */
276
__VA_ANSI_INTEGERS = 0, /* no promotions */
277
__VA_TRADITIONAL_INTEGERS = 0, /* promote [u]char, [u]short to [u]int */
278
/* Fortunately these two methods are compatible. Our macros work with both. */
280
/* stack cleanup policy */
281
__VA_CDECL_CLEANUP = 0, /* caller pops args after return */
282
__VA_STDCALL_CLEANUP = 1<<9, /* callee pops args before return */
283
/* currently only supported on __i386__ */
285
__VA_CLEANUP = __VA_CDECL_CLEANUP,
288
/* These are for internal use only */
289
#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__)
290
__VA_REGISTER_STRUCT_RETURN = 1<<10,
292
#if defined(__mips__) && !defined(__mipsn32__)
293
__VA_FLOAT_1 = 1<<11,
294
__VA_FLOAT_2 = 1<<12,
296
#if defined(__mipsn32__) || defined(__mips64__)
297
__VA_REGISTER_FLOATSTRUCT_RETURN = 1<<13,
298
__VA_REGISTER_DOUBLESTRUCT_RETURN = 1<<14,
301
__VA_flag_for_broken_compilers_that_dont_like_trailing_commas
305
* Definition of the `va_alist' type.
309
/* some va_... macros need these flags */
311
/* current pointer into the argument array */
313
/* structure return pointer, return type, return type size */
317
#if defined(__i386__) || (defined(__powerpc__) && !defined(__powerpc64__) && defined(__MACH__) && defined(__APPLE__))
318
/* Filler word, needed if the numbers of words up to now in this structure */
319
/* is odd (because on MSVC, alignof(double) = 8, normally = 4; similarly, */
320
/* on MacOS X, the Apple compiler has alignof(double) = 8 whereas the */
321
/* standard GCC has alignof(double) = 4. */
324
/* temporary storage for return value */
328
unsigned char _uchar;
330
unsigned short _ushort;
334
unsigned long _ulong;
335
#if !(defined(__mips64__) || defined(__alpha__) || defined(__powerpc64__)) && defined(HAVE_LONG_LONG)
337
unsigned long long _ulonglong;
344
#if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__m88k__) || defined(__ia64__)
347
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__alpha__) || defined(__hppa__)
350
#if defined(__hppa__)
356
#if defined(__mips__) && !defined(__mipsn32__)
361
#if defined(__mipsn32__) || defined(__mips64__)
366
#if defined(__sparc64__)
371
#if defined(__powerpc__) || defined(__powerpc64__)
374
#if !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
380
#if defined(__s390__)
389
#if defined(__ia64__)
394
#if defined(__x86_64__)
397
__vaword* memiargptr;
402
typedef __va_alist* va_alist;
406
* Definition of the va_start_xxx macros.
408
#define __VA_START_FLAGS \
409
__VA_STRUCT_RETURN | __VA_FLOAT_RETURN | __VA_STRUCT_ARGS | __VA_CLEANUP
410
#define __va_start(LIST,RETTYPE) \
411
((LIST)->flags = __VA_START_FLAGS, \
412
(LIST)->rtype = (RETTYPE) \
414
#define va_start_void(LIST) __va_start(LIST,__VAvoid)
415
#define va_start_char(LIST) __va_start(LIST,__VAchar)
416
#define va_start_schar(LIST) __va_start(LIST,__VAschar)
417
#define va_start_uchar(LIST) __va_start(LIST,__VAuchar)
418
#define va_start_short(LIST) __va_start(LIST,__VAshort)
419
#define va_start_ushort(LIST) __va_start(LIST,__VAushort)
420
#define va_start_int(LIST) __va_start(LIST,__VAint)
421
#define va_start_uint(LIST) __va_start(LIST,__VAuint)
422
#define va_start_long(LIST) __va_start(LIST,__VAlong)
423
#define va_start_ulong(LIST) __va_start(LIST,__VAulong)
424
#define va_start_longlong(LIST) __va_start(LIST,__VAlonglong)
425
#define va_start_ulonglong(LIST) __va_start(LIST,__VAulonglong)
426
#define va_start_float(LIST) __va_start(LIST,__VAfloat)
427
#define va_start_double(LIST) __va_start(LIST,__VAdouble)
428
#define va_start_ptr(LIST,TYPE) __va_start(LIST,__VAvoidp)
431
* va_start_struct: Preparing structure return.
433
#define va_start_struct(LIST,TYPE,TYPE_SPLITTABLE) \
434
_va_start_struct(LIST,sizeof(TYPE),__VA_alignof(TYPE),TYPE_SPLITTABLE)
435
/* _va_start_struct() is like va_start_struct(), except that you pass
436
* the type's size and alignment instead of the type itself.
438
#define _va_start_struct(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
439
(__va_start(LIST,__VAstruct), \
440
(LIST)->rsize = (TYPE_SIZE), \
441
((LIST)->flags & __VA_SUNPROCC_STRUCT_RETURN \
442
? __va_start_struct2(LIST) \
443
: ((LIST)->flags & (__VA_PCC_STRUCT_RETURN | __VA_SUNCC_STRUCT_RETURN) \
444
? ((TYPE_SIZE) <= sizeof(__va_struct_buffer) || __va_error2(TYPE_SIZE), \
445
(LIST)->raddr = &__va_struct_buffer, \
448
: (((LIST)->flags & __VA_SMALL_STRUCT_RETURN) \
449
&& __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
450
? ((LIST)->raddr = &(LIST)->tmp, \
451
__va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
453
: __va_start_struct2(LIST) \
455
/* Determines whether a structure is returned in registers,
456
* depending on its size and its word-splittable flag.
458
#if (defined(__i386__) && defined(_WIN32))
459
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
460
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 \
461
|| ((TYPE_SIZE) == 8 \
462
&& (((LIST)->flags & __VA_MSVC_STRUCT_RETURN) \
463
|| ((TYPE_SPLITTABLE) \
464
&& ((LIST)->flags & __VA_GCC_STRUCT_RETURN) \
466
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
467
* and the struct will actually be returned in registers.
469
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
470
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
472
#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
473
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
474
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 \
475
|| ((TYPE_SIZE) == 8 && (TYPE_SPLITTABLE) \
476
&& ((LIST)->flags & __VA_GCC_STRUCT_RETURN) \
478
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
479
* and the struct will actually be returned in registers.
481
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
482
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
484
#if defined(__alpha__)
485
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
486
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8 \
487
|| ((TYPE_SIZE) == 16 && (TYPE_SPLITTABLE) \
488
&& ((LIST)->flags & __VA_GCC_STRUCT_RETURN) \
490
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
491
* and the struct will actually be returned in registers.
493
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
494
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
496
#if defined(__hppa__)
497
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
498
((LIST)->flags & __VA_OLDGCC_STRUCT_RETURN \
499
? ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4) \
500
: ((TYPE_SIZE) <= 8) \
502
/* Test both __VA_OLDGCC_STRUCT_RETURN and __VA_SMALL_STRUCT_RETURN at run time. */
503
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
506
#if defined(__mips__) && !defined(__mipsn32__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__m88k__)
507
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
508
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4)
509
/* Test __VA_SMALL_STRUCT_RETURN instead of __VA_REGISTER_STRUCT_RETURN. */
510
#if defined(__mips__) && !defined(__mipsn32__)
511
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
516
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
520
#if defined(__mipsn32__) || defined(__mips64__)
521
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
522
((LIST)->flags & __VA_GCC_STRUCT_RETURN \
523
? ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8) \
524
: ((TYPE_SIZE) <= 16) \
526
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
527
* and the struct will actually be returned in registers. Also turn on
528
* __VA_REGISTER_FLOATSTRUCT_RETURN or __VA_REGISTER_DOUBLESTRUCT_RETURN if
529
* the struct will be returned in floating-point registers.
531
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
532
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, \
533
(TYPE_ALIGN) == sizeof(float) && (TYPE_SPLITTABLE) \
534
&& ((TYPE_SIZE) == sizeof(float) || (TYPE_SIZE) == 2*sizeof(float)) \
535
&& ((LIST)->flags |= __VA_REGISTER_FLOATSTRUCT_RETURN), \
536
(TYPE_ALIGN) == sizeof(double) && (TYPE_SPLITTABLE) \
537
&& ((TYPE_SIZE) == sizeof(double) || (TYPE_SIZE) == 2*sizeof(double)) \
538
&& ((LIST)->flags |= __VA_REGISTER_DOUBLESTRUCT_RETURN), \
541
#if defined(__powerpc64__)
542
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
544
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
547
#if defined(__sparc64__) || defined(__ia64__)
548
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
550
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
551
* and the struct will actually be returned in registers.
553
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
554
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, \
557
#if defined(__x86_64__)
558
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
560
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
561
* and the struct will actually be returned in registers.
563
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
564
((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, \
568
* Preparing structure return in memory.
570
#if defined(__i386__)
571
/* Return structure pointer is passed in a special register or as first arg. */
572
#define __va_start_struct2(LIST) \
573
((LIST)->flags & __VA_NEXTGCC_STRUCT_RETURN \
574
? ((LIST)->raddr = (LIST)->structraddr, 0) /* special register */ \
575
: ((LIST)->raddr = *(void* *)((LIST)->aptr), /* first arg */ \
576
(LIST)->aptr += sizeof(void*), \
580
#if defined(__alpha__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__) || defined(__s390__)
581
/* Return structure pointer is passed as first arg. */
582
#define __va_start_struct2(LIST) \
583
((LIST)->raddr = *(void* *)((LIST)->aptr), \
584
(LIST)->aptr += sizeof(void*), \
588
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__)
589
/* Return structure pointer is passed as first arg. */
590
#define __va_start_struct2(LIST) \
591
((LIST)->raddr = *(void* *)((LIST)->aptr), \
592
(LIST)->aptr += sizeof(void*), \
597
#if defined(__x86_64__)
598
/* Return structure pointer is passed as first arg. */
599
#define __va_start_struct2(LIST) \
600
((LIST)->raddr = (void *)(*(LIST)->memiargptr++), \
604
#if defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__m88k__) || defined(__ia64__)
605
/* Return structure pointer is passed in a special register. */
606
#define __va_start_struct2(LIST) \
607
((LIST)->raddr = (LIST)->structraddr, 0)
612
* Definition of the va_arg_xxx macros.
615
/* Padding of non-struct arguments. */
616
#define __va_argsize(TYPE_SIZE) \
617
(((TYPE_SIZE) + sizeof(__vaword)-1) & -(long)sizeof(__vaword))
618
#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__)
620
/* small structures < 1 word are adjusted depending on compiler */
621
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
622
((LIST)->aptr += __va_argsize(TYPE_SIZE), \
623
(LIST)->aptr - __va_argsize(TYPE_SIZE) \
625
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
626
((LIST)->aptr += __va_argsize(TYPE_SIZE), \
627
(LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword) \
629
: __va_argsize(TYPE_SIZE) \
633
#if defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
635
/* small structures < 1 word are adjusted depending on compiler */
636
/* Also make sure we switch to the stack pointer after 8 args */
637
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
638
((((LIST)->onstack == 0 && (LIST)->aptr >= (long)&(LIST)->regarg[8]) \
639
? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0), \
640
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
641
(LIST)->aptr - __va_argsize(TYPE_SIZE) \
643
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
644
((((LIST)->onstack == 0 && (LIST)->aptr >= (long)&(LIST)->regarg[8]) \
645
? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0), \
646
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
647
(LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword) \
649
: __va_argsize(TYPE_SIZE) \
653
#if defined(__s390__)
655
/* small structures < 1 word are adjusted depending on compiler */
656
/* Also make sure we switch to the stack pointer after 5 args */
657
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
658
((((LIST)->onstack == 0 && (LIST)->aptr >= (long)&(LIST)->regarg[5]) \
659
? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0), \
660
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
661
(LIST)->aptr - __va_argsize(TYPE_SIZE) \
663
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
664
(((((LIST)->onstack == 0 && ((LIST)->aptr >= (long)&(LIST)->regarg[5])) \
665
|| ((TYPE_SIZE) > sizeof(__vaword) && (LIST)->aptr >= (long)&(LIST)->regarg[4])) \
666
? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0), \
667
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
668
(LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword) \
670
: __va_argsize(TYPE_SIZE) \
674
#if defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__)
676
/* small structures < 1 word are adjusted depending on compiler */
677
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
678
((LIST)->anum += __va_argsize(TYPE_SIZE)/sizeof(__vaword), \
679
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
680
(LIST)->aptr - __va_argsize(TYPE_SIZE) \
682
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
683
((LIST)->anum += __va_argsize(TYPE_SIZE)/sizeof(__vaword), \
684
(LIST)->aptr += __va_argsize(TYPE_SIZE), \
685
(LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword) \
687
: __va_argsize(TYPE_SIZE) \
691
#if defined(__hppa__)
693
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
694
((LIST)->aptr = (LIST)->aptr - __va_argsize(TYPE_SIZE), \
695
((TYPE_SIZE) > 4 && ((LIST)->aptr &= -8)), \
698
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
699
((LIST)->aptr = (LIST)->aptr - __va_argsize(TYPE_SIZE), \
700
((TYPE_SIZE) > 4 && ((LIST)->aptr &= -8)), \
701
(LIST)->aptr + ((-(TYPE_SIZE)) & 3) \
704
#if defined(__i386__) || defined(__alpha__) || defined(__ia64__)
705
/* little endian -> small args < 1 word are adjusted to the left */
706
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
707
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)
709
#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__)
710
/* big endian -> small args < 1 word are adjusted to the right */
711
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
712
__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)
714
#if defined(__mips__) && !defined(__mipsn32__)
715
/* big endian -> small args < 1 word are adjusted to the right */
716
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
717
((LIST)->anum++, __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN))
719
#if defined(__x86_64__)
720
/* the first 6 argument words are passed in registers */
721
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
722
((LIST)->memiargptr + ((TYPE_SIZE) + sizeof(__vaword)-1) / sizeof(__vaword) <= &(LIST)->iarg[6] \
723
? ((LIST)->memiargptr += ((TYPE_SIZE) + sizeof(__vaword)-1) / sizeof(__vaword), \
724
(LIST)->memiargptr - ((TYPE_SIZE) + sizeof(__vaword)-1) / sizeof(__vaword) \
726
: (void*)__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
729
#define __va_arg(LIST,TYPE) \
730
*(TYPE*)__va_arg_adjusted(LIST,sizeof(TYPE),__VA_alignof(TYPE))
732
/* Integer arguments. */
734
#define va_arg_char(LIST) __va_arg(LIST,char)
735
#define va_arg_schar(LIST) __va_arg(LIST,signed char)
736
#define va_arg_uchar(LIST) __va_arg(LIST,unsigned char)
737
#define va_arg_short(LIST) __va_arg(LIST,short)
738
#define va_arg_ushort(LIST) __va_arg(LIST,unsigned short)
739
#define va_arg_int(LIST) __va_arg(LIST,int)
740
#define va_arg_uint(LIST) __va_arg(LIST,unsigned int)
741
#define va_arg_long(LIST) __va_arg(LIST,long)
742
#define va_arg_ulong(LIST) __va_arg(LIST,unsigned long)
744
#if defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__powerpc64__) || defined(__ia64__) || defined(__x86_64__)
745
/* `long long' and `long' are identical. */
746
#define va_arg_longlong va_arg_long
747
#define va_arg_ulonglong va_arg_ulong
748
#elif defined(__mipsn32__)
749
/* `long long' fits in __vaword. */
750
#define va_arg_longlong(LIST) __va_arg(LIST,long long)
751
#define va_arg_ulonglong(LIST) __va_arg(LIST,unsigned long long)
752
#elif defined(__i386__) || defined(__m68k__) || defined(__mips__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__arm__) || defined(__powerpc__) || defined(__m88k__) || defined(__convex__) || defined(__s390__)
753
/* `long long's are passed embedded on the arg stack. */
754
#define va_arg_longlong(LIST) __va_arg_longlong(LIST,long long)
755
#define va_arg_ulonglong(LIST) __va_arg_longlong(LIST,unsigned long long)
756
#if defined(__i386__) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__)
757
/* `long long's are (at most) word-aligned. */
758
#define __va_arg_longlong(LIST,TYPE) __va_arg(LIST,TYPE)
760
#if defined(__mips__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__)
761
/* `long long's have alignment 8. */
762
#define __va_arg_longlong(LIST,TYPE) \
763
((LIST)->aptr = (((LIST)->aptr+__VA_alignof(TYPE)-1) & -(long)__VA_alignof(TYPE)), \
766
#if (defined(__sparc__) && !defined(__sparc64__)) || defined(__s390__)
767
/* Within the arg stack, the alignment is only 4, not 8. */
768
/* Beware against unaligned accesses! */
769
#define __va_arg_longlong(LIST,TYPE) \
770
((LIST)->tmp._words[0] = ((__vaword*)((LIST)->aptr))[0], \
771
(LIST)->tmp._words[1] = ((__vaword*)((LIST)->aptr))[1], \
772
(LIST)->aptr += sizeof(TYPE), \
773
(TYPE)((LIST)->tmp._longlong) \
776
#if defined(__hppa__)
777
/* `long long's have alignment 8. */
778
#define __va_arg_longlong(LIST,TYPE) \
779
((LIST)->aptr = ((LIST)->aptr & -(long)__VA_alignof(TYPE)), \
784
/* Floating point arguments. */
786
#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__)
787
#define __va_align_double(LIST)
789
#if defined(__mips__) && !defined(__mipsn32__) || defined(__m88k__)
790
/* __VA_alignof(double) > sizeof(__vaword) */
791
#define __va_align_double(LIST) \
792
(LIST)->aptr = ((LIST)->aptr + sizeof(double)-1) & -(long)sizeof(double),
794
#if defined(__hppa__)
795
#define __va_align_double(LIST) \
796
(LIST)->aptr = (LIST)->aptr & -(long)sizeof(double),
799
#if defined(__sparc__) && !defined(__sparc64__)
800
/* Beware against unaligned `double' accesses! */
801
#define va_arg_double(LIST) \
802
(__va_align_double(LIST) \
803
(LIST)->tmp._words[0] = ((__vaword*)((LIST)->aptr))[0], \
804
(LIST)->tmp._words[1] = ((__vaword*)((LIST)->aptr))[1], \
805
(LIST)->aptr += sizeof(double), \
806
(LIST)->tmp._double \
809
#if defined(__alpha__)
810
/* The first 6 floating point registers have been stored in another place. */
811
#define va_arg_double(LIST) \
812
(((LIST)->aptr += sizeof(double)) <= (LIST)->memargptr \
813
? *(double*)((LIST)->aptr - sizeof(double) - 6*sizeof(double)) \
814
: *(double*)((LIST)->aptr - sizeof(double)) \
816
#define va_arg_float(LIST) \
817
(((LIST)->aptr += sizeof(double)) <= (LIST)->memargptr \
818
? /* The first 6 args have been put into memory by "stt" instructions */\
819
/* (see vacall-alpha.s!). Therefore load them as doubles. */ \
820
/* When viewed as floats, the value will be the correct one. */ \
821
(float)*(double*)((LIST)->aptr - sizeof(double) - 6*sizeof(double)) \
822
: /* These args have been put into memory by "sts" instructions, */ \
823
/* therefore load them as floats. */ \
824
*(float*)((LIST)->aptr - sizeof(double)) \
827
#if defined(__hppa__)
828
/* The first 4 float registers and the first 2 double registers are stored
831
#if 1 /* gcc-2.5.2 passes these args in general registers! A bug, I think. */
832
#define va_arg_float(LIST) \
833
(*(float*)((LIST)->aptr -= sizeof(float)))
834
#define va_arg_double(LIST) \
835
(__va_align_double(LIST) \
836
*(double*)((LIST)->aptr -= sizeof(double)) \
838
#else /* this would be correct if the args were passed in float registers. */
839
#define va_arg_float(LIST) \
840
(((LIST)->aptr -= sizeof(float)) >= (LIST)->memargptr \
841
? /* The first 4 float args are stored separately. */ \
842
*(float*)((LIST)->aptr + (LIST)->farg_offset) \
843
: *(float*)((LIST)->aptr) \
845
#define va_arg_double(LIST) \
846
(__va_align_double(LIST) \
847
(((LIST)->aptr -= sizeof(double)) >= (LIST)->memargptr \
848
? /* The first 2 double args are stored separately. */ \
849
*(double*)((LIST)->aptr + (LIST)->darg_offset) \
850
: *(double*)((LIST)->aptr) \
854
#if defined(__mips__) && !defined(__mipsn32__)
855
/* The first 0,1,2 registers are stored elsewhere if they are floating-point
858
#define va_arg_float(LIST) \
859
((LIST)->aptr += sizeof(float), \
862
? ((LIST)->flags |= __VA_FLOAT_1, (LIST)->farg[0]) \
863
: ((LIST)->anum == 2 && ((LIST)->flags & __VA_FLOAT_1) \
864
? (/* (LIST)->flags |= __VA_FLOAT_2, */ (LIST)->farg[1]) \
865
: *(float*)((LIST)->aptr - sizeof(float)) \
867
#define va_arg_double(LIST) \
868
(__va_align_double(LIST) \
869
(LIST)->aptr += sizeof(double), \
872
? ((LIST)->flags |= __VA_FLOAT_1, (LIST)->darg[0]) \
873
: ((LIST)->anum == 2 && ((LIST)->flags & __VA_FLOAT_1) \
874
? (/* (LIST)->flags |= __VA_FLOAT_2, */ (LIST)->darg[1]) \
875
: *(double*)((LIST)->aptr - sizeof(double)) \
878
#if defined(__mipsn32__) || defined(__mips64__)
879
/* The first 0,..,8 registers are stored elsewhere if they are floating-point
882
#define va_arg_float(LIST) \
883
(__va_align_double(LIST) \
884
(LIST)->aptr += sizeof(double), \
885
(++(LIST)->anum <= 8 \
886
? (LIST)->farg[(LIST)->anum - 1] \
887
: *(float*)((LIST)->aptr - sizeof(double)) \
889
#define va_arg_double(LIST) \
890
(__va_align_double(LIST) \
891
(LIST)->aptr += sizeof(double), \
892
(++(LIST)->anum <= 8 \
893
? (LIST)->darg[(LIST)->anum - 1] \
894
: *(double*)((LIST)->aptr - sizeof(double)) \
897
#if defined(__sparc64__)
898
/* The first 0,..,16 registers are stored elsewhere if they are floating-point
901
#define va_arg_float(LIST) \
902
(__va_align_double(LIST) \
903
(LIST)->aptr += sizeof(double), \
904
(++(LIST)->anum <= 16 \
905
? (LIST)->farg[(LIST)->anum - 1] \
906
: *(float*)((LIST)->aptr - sizeof(double)) \
908
#define va_arg_double(LIST) \
909
(__va_align_double(LIST) \
910
(LIST)->aptr += sizeof(double), \
911
(++(LIST)->anum <= 16 \
912
? (LIST)->darg[(LIST)->anum - 1] \
913
: *(double*)((LIST)->aptr - sizeof(double)) \
916
#if defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
917
/* The first 13 floating-point args have been stored elsewhere. */
918
#define va_arg_float(LIST) \
919
((LIST)->aptr += sizeof(float), \
920
((LIST)->memfargptr < &(LIST)->farg[13] \
921
? (float) *((LIST)->memfargptr++) \
922
: *(float*)((LIST)->aptr - sizeof(float)) \
924
#define va_arg_double(LIST) \
925
(__va_align_double(LIST) \
926
(LIST)->aptr += sizeof(double), \
927
((LIST)->memfargptr < &(LIST)->farg[13] \
928
? *((LIST)->memfargptr++) \
929
: *(double*)((LIST)->aptr - sizeof(double)) \
932
#if defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
933
/* The first 8 floating-point args have been stored elsewhere. */
934
#define va_arg_float(LIST) \
935
((LIST)->memfargptr < &(LIST)->farg[8] \
936
? (float) *((LIST)->memfargptr++) \
937
: ((LIST)->aptr = ((LIST)->onstack == 0 \
938
? ((LIST)->onstack=1, (LIST)->saptr) \
941
(LIST)->aptr += sizeof(float), \
942
*(float*)((LIST)->aptr - sizeof(float)) \
944
#define va_arg_double(LIST) \
945
((LIST)->memfargptr < &(LIST)->farg[8] \
946
? *((LIST)->memfargptr++) \
947
: ((LIST)->aptr = ((LIST)->onstack == 0 \
948
? ((LIST)->onstack=1, (LIST)->saptr) \
951
__va_align_double(LIST) \
952
(LIST)->aptr += sizeof(double), \
953
*(double*)((LIST)->aptr - sizeof(double)) \
956
#if defined(__powerpc64__)
957
/* The first 13 floating-point args have been stored elsewhere. */
958
#define va_arg_float(LIST) \
959
((LIST)->aptr += sizeof(__vaword), \
960
((LIST)->memfargptr < &(LIST)->farg[13] \
961
? (float) *((LIST)->memfargptr++) \
962
: *(float*)((LIST)->aptr - sizeof(float)) \
964
#define va_arg_double(LIST) \
965
(__va_align_double(LIST) \
966
(LIST)->aptr += sizeof(double), \
967
((LIST)->memfargptr < &(LIST)->farg[13] \
968
? *((LIST)->memfargptr++) \
969
: *(double*)((LIST)->aptr - sizeof(double)) \
972
#if defined(__s390__)
973
/* The first 2 floating-point args have been stored elsewhere. */
974
#define va_arg_float(LIST) \
975
((LIST)->memfargptr < &(LIST)->farg[2] \
976
? (LIST)->memdargptr++, (float) *((LIST)->memfargptr++) \
977
: ((LIST)->aptr = ((LIST)->onstack == 0 \
978
? ((LIST)->onstack=1, (LIST)->saptr) \
981
(LIST)->aptr += sizeof(float), \
982
*(float*)((LIST)->aptr - sizeof(float)) \
984
#define va_arg_double(LIST) \
985
((LIST)->memdargptr < &(LIST)->darg[2] \
986
? (LIST)->memfargptr++, *((LIST)->memdargptr++) \
987
: ((LIST)->aptr = ((LIST)->onstack == 0 \
988
? ((LIST)->onstack=1, (LIST)->saptr) \
991
__va_align_double(LIST) \
992
(LIST)->aptr += sizeof(double), \
993
*(double*)((LIST)->aptr - sizeof(double)) \
996
#if defined(__ia64__)
997
/* The first 8 floating-point args have been stored elsewhere. */
998
#define va_arg_float(LIST) \
999
((LIST)->aptr += sizeof(__vaword), \
1000
((LIST)->memfargptr < &(LIST)->farg[8] \
1001
? (float) *((LIST)->memfargptr++) \
1002
: *(float*)((LIST)->aptr - sizeof(__vaword)) \
1004
#define va_arg_double(LIST) \
1005
(__va_align_double(LIST) \
1006
(LIST)->aptr += sizeof(double), \
1007
((LIST)->memfargptr < &(LIST)->farg[8] \
1008
? *((LIST)->memfargptr++) \
1009
: *(double*)((LIST)->aptr - sizeof(double)) \
1012
#if defined(__x86_64__)
1013
/* The first 8 floating-point args have been stored elsewhere. */
1014
#define va_arg_float(LIST) \
1015
((LIST)->memfargptr < &(LIST)->farg[8] \
1016
? ((LIST)->memfargptr++, \
1017
*(float*)((LIST)->memfargptr - 1) \
1019
: ((LIST)->aptr += sizeof(__vaword), \
1020
*(float*)((LIST)->aptr - sizeof(__vaword)) \
1022
#define va_arg_double(LIST) \
1023
((LIST)->memfargptr < &(LIST)->farg[8] \
1024
? *(LIST)->memfargptr++ \
1025
: ((LIST)->aptr += sizeof(__vaword), \
1026
*(double*)((LIST)->aptr - sizeof(__vaword)) \
1029
#ifndef va_arg_float
1030
#define va_arg_float(LIST) __va_arg(LIST,float)
1032
#ifndef va_arg_double
1033
#define va_arg_double(LIST) \
1034
(__va_align_double(LIST) __va_arg(LIST,double))
1037
/* Pointer arguments. */
1038
#define va_arg_ptr(LIST,TYPE) __va_arg(LIST,TYPE)
1040
/* Structure arguments. */
1041
#define va_arg_struct(LIST,TYPE) \
1042
*(TYPE*)__va_arg_struct(LIST,sizeof(TYPE),__VA_alignof(TYPE))
1043
/* _va_arg_struct() is like va_arg_struct(), except that you pass the type's
1044
* size and alignment instead of the type and get the value's address instead
1045
* of the value itself.
1047
#define _va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1048
(void*)__va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)
1049
/* Structure argument alignment. */
1050
#if defined(__i386__) && defined(_MSC_VER)
1051
/* In MSVC, doubles inside structures have alignment 8, i.e.
1052
* __VA_alignof(double) = 8, but doubles (and also structures containing
1053
* doubles) are passed on the stack with alignment 4. Looks really weird.
1055
#define __va_struct_alignment(TYPE_ALIGN) \
1056
((TYPE_ALIGN) <= 4 ? (TYPE_ALIGN) : 4)
1058
#define __va_struct_alignment(TYPE_ALIGN) \
1061
#define __va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1062
(LIST)->aptr = ((LIST)->aptr + __va_struct_alignment(TYPE_ALIGN)-1) & -(long)__va_struct_alignment(TYPE_ALIGN),
1063
#if defined(__i386__) || defined(__m68k__) || defined(__alpha__) || defined(__arm__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__x86_64__)
1064
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1065
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1066
__va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1069
#if defined(__mips__) && !defined(__mipsn32__)
1070
/* small structures < 1 word are adjusted depending on compiler */
1071
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1072
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1073
((LIST)->flags & __VA_SGICC_STRUCT_ARGS \
1074
? /* SGI MIPS cc passes small structures left-adjusted, although big-endian! */\
1075
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1076
: /* SGI MIPS gcc passes small structures within the first four words left- \
1077
* adjusted, for compatibility with cc. But structures in memory are passed \
1078
* right-adjusted!! See gcc-2.6.3/config/mips/mips.c:function_arg(). \
1080
((LIST)->aptr < (LIST)->memargptr \
1081
? __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1082
: __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1085
#if defined(__mipsn32__) || defined(__mips64__)
1086
/* small structures < 1 word are adjusted depending on compiler */
1087
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1088
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1089
((LIST)->flags & __VA_SGICC_STRUCT_ARGS \
1090
? /* SGI MIPS cc passes small structures left-adjusted, although big-endian! */\
1091
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1092
: /* SGI MIPS gcc passes small structures right-adjusted. */ \
1093
__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1096
#if defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
1097
/* small structures < 1 word are adjusted depending on compiler */
1098
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1099
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1100
((LIST)->flags & __VA_AIXCC_STRUCT_ARGS \
1101
? /* AIX cc and xlc pass small structures left-adjusted, although big-endian! */\
1102
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1103
: /* gcc passes small structures right-adjusted. */ \
1104
__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1107
#if defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
1108
/* Structures are passed as pointers to caller-made local copies. */
1109
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1110
va_arg_ptr(LIST,void*)
1112
#if defined(__sparc__) && !defined(__sparc64__)
1113
/* Structures are passed as pointers to caller-made local copies. */
1114
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1115
va_arg_ptr(LIST,void*)
1117
#if defined(__sparc64__)
1118
/* Small structures are passed left-adjusted, although big-endian! */
1119
/* Big structures are passed as pointers to caller-made local copies. */
1120
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1121
((TYPE_SIZE) <= 16 \
1122
? (__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1123
__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)) \
1124
: va_arg_ptr(LIST,void*) \
1127
#if defined(__s390__)
1128
/* Structures <= 8 bytes are passed as embedded copies on the arg stack.
1129
* Big structures are passed as pointers to caller-made local copies.
1131
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1132
((TYPE_SIZE) != 1 && (TYPE_SIZE) != 2 && (TYPE_SIZE) != 4 && (TYPE_SIZE) != 8 \
1133
? va_arg_ptr(LIST,void*) \
1134
: (void*)__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1137
#if defined(__hppa__)
1138
/* Structures <= 8 bytes are passed as embedded copies on the arg stack.
1139
* Big structures are passed as pointers to caller-made local copies.
1141
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1143
? va_arg_ptr(LIST,void*) \
1144
: /* FIXME: gcc-2.6.3 passes structures <= 4 bytes in memory left-adjusted! ?? */\
1145
(void*)__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1148
#if defined(__ia64__)
1149
/* Types larger than a word have 2-word alignment. */
1150
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1151
(__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN) \
1152
((TYPE_SIZE) > sizeof(__vaword) && (((__vaword*)(LIST)->aptr - (LIST)->saptr) & 1) ? (LIST)->aptr += sizeof(__vaword) : 0), \
1153
__va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN) \
1159
* Definition of the va_return_xxx macros.
1161
#define __va_return(LIST,RETTYPE) \
1162
(((LIST)->rtype == (RETTYPE)) || __va_error1((LIST)->rtype,RETTYPE))
1163
#define va_return_void(LIST) \
1164
__va_return(LIST,__VAvoid)
1165
#define va_return_char(LIST,VAL) \
1166
(__va_return(LIST,__VAchar), (LIST)->tmp._char = (VAL))
1167
#define va_return_schar(LIST,VAL) \
1168
(__va_return(LIST,__VAschar), (LIST)->tmp._schar = (VAL))
1169
#define va_return_uchar(LIST,VAL) \
1170
(__va_return(LIST,__VAuchar), (LIST)->tmp._uchar = (VAL))
1171
#define va_return_short(LIST,VAL) \
1172
(__va_return(LIST,__VAshort), (LIST)->tmp._short = (VAL))
1173
#define va_return_ushort(LIST,VAL) \
1174
(__va_return(LIST,__VAushort), (LIST)->tmp._ushort = (VAL))
1175
#define va_return_int(LIST,VAL) \
1176
(__va_return(LIST,__VAint), (LIST)->tmp._int = (VAL))
1177
#define va_return_uint(LIST,VAL) \
1178
(__va_return(LIST,__VAuint), (LIST)->tmp._uint = (VAL))
1179
#define va_return_long(LIST,VAL) \
1180
(__va_return(LIST,__VAlong), (LIST)->tmp._long = (VAL))
1181
#define va_return_ulong(LIST,VAL) \
1182
(__va_return(LIST,__VAulong), (LIST)->tmp._ulong = (VAL))
1183
#if defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__powerpc64__) || defined(__ia64__) || defined(__x86_64__)
1184
#define va_return_longlong(LIST,VAL) \
1185
(__va_return(LIST,__VAlonglong), (LIST)->tmp._long = (VAL))
1186
#define va_return_ulonglong(LIST,VAL) \
1187
(__va_return(LIST,__VAulonglong), (LIST)->tmp._ulong = (VAL))
1189
#define va_return_longlong(LIST,VAL) \
1190
(__va_return(LIST,__VAlonglong), (LIST)->tmp._longlong = (VAL))
1191
#define va_return_ulonglong(LIST,VAL) \
1192
(__va_return(LIST,__VAulonglong), (LIST)->tmp._ulonglong = (VAL))
1194
#define va_return_float(LIST,VAL) \
1195
(__va_return(LIST,__VAfloat), (LIST)->tmp._float = (VAL))
1196
#define va_return_double(LIST,VAL) \
1197
(__va_return(LIST,__VAdouble), (LIST)->tmp._double = (VAL))
1198
#define va_return_ptr(LIST,TYPE,VAL) \
1199
(__va_return(LIST,__VAvoidp), (LIST)->tmp._ptr = (void*)(TYPE)(VAL))
1200
#define va_return_struct(LIST,TYPE,VAL) \
1201
(__va_return(LIST,__VAstruct), *(TYPE*)((LIST)->raddr) = (VAL))
1202
#define _va_return_struct(LIST,TYPE_SIZE,TYPE_ALIGN,VAL_ADDR) \
1203
(__va_return(LIST,__VAstruct), \
1204
__structcpy((void*)((LIST)->raddr),VAL_ADDR,TYPE_SIZE,TYPE_ALIGN) \
1208
/* Determine whether a struct type is word-splittable, i.e. whether each of
1209
* its components fit into a register.
1210
* The entire computation is done at compile time.
1212
#define va_word_splittable_1(slot1) \
1213
(__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword))
1214
#define va_word_splittable_2(slot1,slot2) \
1215
((__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword)) \
1216
&& (__va_offset2(slot1,slot2)/sizeof(__vaword) == (__va_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__vaword)) \
1218
#define va_word_splittable_3(slot1,slot2,slot3) \
1219
((__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword)) \
1220
&& (__va_offset2(slot1,slot2)/sizeof(__vaword) == (__va_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__vaword)) \
1221
&& (__va_offset3(slot1,slot2,slot3)/sizeof(__vaword) == (__va_offset3(slot1,slot2,slot3)+sizeof(slot3)-1)/sizeof(__vaword)) \
1223
#define va_word_splittable_4(slot1,slot2,slot3,slot4) \
1224
((__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword)) \
1225
&& (__va_offset2(slot1,slot2)/sizeof(__vaword) == (__va_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__vaword)) \
1226
&& (__va_offset3(slot1,slot2,slot3)/sizeof(__vaword) == (__va_offset3(slot1,slot2,slot3)+sizeof(slot3)-1)/sizeof(__vaword)) \
1227
&& (__va_offset4(slot1,slot2,slot3,slot4)/sizeof(__vaword) == (__va_offset4(slot1,slot2,slot3,slot4)+sizeof(slot4)-1)/sizeof(__vaword)) \
1229
#define __va_offset1(slot1) \
1231
#define __va_offset2(slot1,slot2) \
1232
((__va_offset1(slot1)+sizeof(slot1)+__VA_alignof(slot2)-1) & -(long)__VA_alignof(slot2))
1233
#define __va_offset3(slot1,slot2,slot3) \
1234
((__va_offset2(slot1,slot2)+sizeof(slot2)+__VA_alignof(slot3)-1) & -(long)__VA_alignof(slot3))
1235
#define __va_offset4(slot1,slot2,slot3,slot4) \
1236
((__va_offset3(slot1,slot2,slot3)+sizeof(slot3)+__VA_alignof(slot4)-1) & -(long)__VA_alignof(slot4))
1240
* Miscellaneous declarations.
1243
extern "C" void (*vacall) (); /* the return type is variable, not void! */
1245
extern void (*vacall) (); /* the return type is variable, not void! */
1247
extern void (* vacall_function) (va_alist);
1248
extern int __va_error1 (enum __VAtype, enum __VAtype);
1249
extern int __va_error2 (unsigned int);
1250
extern void __structcpy (void* dest, const void* src, unsigned long size, unsigned long alignment);
1251
typedef union { __vaword room[__VA_ALIST_WORDS]; double align; } __va_struct_buffer_t;
1252
extern __va_struct_buffer_t __va_struct_buffer;
1255
#endif /* _VACALL_H */