1
#ifndef _avcall_h /*-*- C -*-*/
4
Copyright 1993 Bill Triggs, <Bill.Triggs@inrialpes.fr>
6
Copyright 1995-2006 Bruno Haible, <bruno@clisp.org>
8
This is free software distributed under the GNU General Public
9
Licence described in the file COPYING. Contact the author if
10
you don't have this or can't live with it. There is ABSOLUTELY
11
NO WARRANTY, explicit or implied, on this software.
13
/*----------------------------------------------------------------------
14
av_call() foreign function interface.
16
Varargs-style macros to build a C argument list incrementally
17
and call a function on it.
18
----------------------------------------------------------------------*/
21
/* These definitions are adjusted by `configure' automatically. */
76
/* Calling convention */
77
/* Define if using pcc non-reentrant struct return convention */
78
#undef __PCC_STRUCT_RETURN__
79
/* Define if small structs are returned in registers */
80
#define __SMALL_STRUCT_RETURN__ 1
81
/* Define if floating-point results are returned in the integer registers */
82
#undef __IREG_FLOAT_RETURN__
84
/* gl_AC_TYPE_LONG_LONG */
85
/* Define if your compiler supports the 'long long' type. */
88
/* End of definitions adjusted by `configure'. */
91
/* Max # words in argument-list and temporary structure storage.
93
#ifndef __AV_ALIST_WORDS
94
#define __AV_ALIST_WORDS 256
97
/* Determine the alignment of a type at compile time.
100
#define __AV_alignof __alignof__
102
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) /* SGI compiler */
103
#define __AV_alignof __builtin_alignof
105
#define __AV_offsetof(type,ident) ((unsigned long)&(((type*)0)->ident))
106
#define __AV_alignof(type) __AV_offsetof(struct { char __slot1; type __slot2; }, __slot2)
112
#if defined(__mipsn32__)
113
typedef long long __avword;
115
typedef long __avword;
139
enum __AV_alist_flags
142
/* how to return structs */
143
/* There are basically 3 ways to return structs:
144
* a. The called function returns a pointer to static data. Not reentrant.
145
* b. The caller passes the return structure address in a dedicated register
146
* or as a first (or last), invisible argument. The called function stores
148
* c. Like b, and the called function also returns the return structure
149
* address in the return value register. (This is not very distinguishable
151
* Independently of this,
152
* r. small structures (<= 4 or <= 8 bytes) may be returned in the return
153
* value register(s), or
154
* m. even small structures are passed in memory.
156
/* gcc-2.6.3 employs the following strategy:
157
* - If PCC_STATIC_STRUCT_RETURN is defined in the machine description
158
* it uses method a, else method c.
159
* - If flag_pcc_struct_return is set (either by -fpcc-struct-return or if
160
* DEFAULT_PCC_STRUCT_RETURN is defined to 1 in the machine description)
161
* it uses method m, else (either by -freg-struct-return or if
162
* DEFAULT_PCC_STRUCT_RETURN is defined to 0 in the machine description)
165
__AV_PCC_STRUCT_RETURN = 1<<0, /* a: need to copy the struct */
166
__AV_SMALL_STRUCT_RETURN = 1<<1, /* r: special case for small structs */
167
__AV_GCC_STRUCT_RETURN = 1<<2, /* consider 8 byte structs as small */
168
#if defined(__sparc__) && !defined(__sparc64__)
169
__AV_SUNCC_STRUCT_RETURN = 1<<3,
170
__AV_SUNPROCC_STRUCT_RETURN = 1<<4,
172
#if defined(__i386__)
173
__AV_NEXTGCC_STRUCT_RETURN = 1<<3,
174
__AV_MSVC_STRUCT_RETURN = 1<<4,
176
#if defined(__hppa__)
177
__AV_OLDGCC_STRUCT_RETURN = 1<<3,
179
/* the default way to return structs */
180
/* This choice here is based on the assumption that the function you are
181
* going to call has been compiled with the same compiler you are using to
183
* If you want to call functions with another struct returning convention,
184
* just #define __AV_STRUCT_RETURN ...
185
* before or after #including <avcall.h>.
187
#ifndef __AV_STRUCT_RETURN
189
#if defined(__sparc__) && !defined(__sparc64__) && defined(sun) && defined(__SUNPRO_C) /* SUNWspro cc */
190
__AV_SUNPROCC_STRUCT_RETURN,
192
#if defined(__PCC_STRUCT_RETURN__) /* defined through configure, see above */
193
__AV_PCC_STRUCT_RETURN,
195
#if defined(__SMALL_STRUCT_RETURN__) || defined(__mipsn32__) || defined(__mips64__) /* defined through configure, see above */
196
__AV_SMALL_STRUCT_RETURN |
198
#if defined(__GNUC__)
199
__AV_GCC_STRUCT_RETURN |
201
#if defined(__i386__) && defined(NeXT) && defined(__GNUC__) /* NeXT gcc-2.5.8 */
202
__AV_NEXTGCC_STRUCT_RETURN |
204
#if defined(__i386__) && defined(_MSC_VER) /* MSVC 4.0 */
205
__AV_MSVC_STRUCT_RETURN |
207
#if defined(__hppa__) && defined(__GNUC__) && (__GNUC__ < 3) && (__GNUC_MINOR__ < 7)
208
__AV_OLDGCC_STRUCT_RETURN |
215
/* how to return floats */
216
#if defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__))
217
__AV_SUNCC_FLOAT_RETURN = 1<<5,
219
#if defined(__m68k__)
220
__AV_FREG_FLOAT_RETURN = 1<<6,
222
/* the default way to return floats */
223
/* This choice here is based on the assumption that the function you are
224
* going to call has been compiled with the same compiler you are using to
226
* If you want to call functions with another float returning convention,
227
* just #define __AV_FLOAT_RETURN ...
228
* before or after #including <avcall.h>.
230
#ifndef __AV_FLOAT_RETURN
231
#if (defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__))) && !defined(__GNUC__) && defined(sun) && !defined(__SUNPRO_C) /* sun cc */
232
__AV_FLOAT_RETURN = __AV_SUNCC_FLOAT_RETURN,
233
#elif (defined(__m68k__) && !defined(__IREG_FLOAT_RETURN__))
234
__AV_FLOAT_RETURN = __AV_FREG_FLOAT_RETURN,
236
__AV_FLOAT_RETURN = 0,
240
/* how to pass structs */
241
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__)
242
__AV_SGICC_STRUCT_ARGS = 1<<7,
244
#if defined(__powerpc__) && !defined(__powerpc64__)
245
__AV_AIXCC_STRUCT_ARGS = 1<<7,
247
/* the default way to pass floats */
248
/* This choice here is based on the assumption that the function you are
249
* going to call has been compiled with the same compiler you are using to
251
* If you want to call functions with another float passing convention,
252
* just #define __AV_STRUCT_ARGS ...
253
* before or after #including <avcall.h>.
255
#ifndef __AV_STRUCT_ARGS
256
#if (defined(__mips__) || defined(__mipsn32__) || defined(__mips64__)) && !defined(__GNUC__) /* SGI mips cc */
257
__AV_STRUCT_ARGS = __AV_SGICC_STRUCT_ARGS,
259
#if defined(__powerpc__) && !defined(__powerpc64__) && defined(_AIX) && !defined(__GNUC__) /* AIX cc, xlc */
260
__AV_STRUCT_ARGS = __AV_AIXCC_STRUCT_ARGS,
262
__AV_STRUCT_ARGS = 0,
267
/* how to pass floats */
268
/* ANSI C compilers and GNU gcc pass floats as floats.
269
* K&R C compilers pass floats as doubles. We don't support them any more.
272
/* how to pass and return small integer arguments */
273
__AV_ANSI_INTEGERS = 0, /* no promotions */
274
__AV_TRADITIONAL_INTEGERS = 0, /* promote [u]char, [u]short to [u]int */
275
/* Fortunately these two methods are compatible. Our macros work with both. */
277
/* stack cleanup policy */
278
__AV_CDECL_CLEANUP = 0, /* caller pops args after return */
279
__AV_STDCALL_CLEANUP = 0, /* callee pops args before return */
280
/* currently only supported on __i386__ */
282
__AV_CLEANUP = __AV_CDECL_CLEANUP,
285
/* These are for internal use only */
286
#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__)
287
__AV_REGISTER_STRUCT_RETURN = 1<<9,
289
#if defined(__mips__) && !defined(__mipsn32__)
290
__AV_FLOAT_1 = 1<<10,
291
__AV_FLOAT_2 = 1<<11,
294
__AV_flag_for_broken_compilers_that_dont_like_trailing_commas
299
/* function to be called */
301
/* some av_... macros need these flags */
303
/* return type, address for the result */
307
/* current pointer into the args[] array */
309
#if defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || (defined(__powerpc__) && !defined(__powerpc64__) && !defined(_AIX) && !(defined(__MACH__) && defined(__APPLE__))) || defined(__s390__)
310
/* limit pointer into the args[] array */
313
#if defined(__i386__) && 0
314
/* Filler word, needed if the numbers of words up to now in this structure */
315
/* is odd (because on MSVC, alignof(double) = 8, normally = 4). */
318
#if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__arm__) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
319
/* temporary storage, used to split doubles into two words */
322
#if defined(__sparc__) && !defined(__sparc64__) && defined(HAVE_LONG_LONG)
328
#if defined(__x86_64__)
329
/* store the integer arguments in an extra array */
333
#if defined(__mips__) && !defined(__mipsn32__)
334
/* store the floating-point arguments in an extra array */
338
#if defined(__mipsn32__) || defined(__mips64__)
339
/* store the floating-point arguments in an extra array */
340
int anum; /* redundant: (LIST).aptr = &(LIST).args[(LIST).anum] */
341
unsigned int farg_mask; /* bitmask of those entries in farg[] which have a value */
342
unsigned int darg_mask; /* bitmask of those entries in args[] which have a double value */
345
#if defined(__sparc64__)
346
/* store the floating-point arguments in an extra array */
347
int anum; /* redundant: (LIST).aptr = &(LIST).args[(LIST).anum] */
348
unsigned int farg_mask; /* bitmask of those entries in farg[] which have a value */
349
unsigned int darg_mask; /* bitmask of those entries in args[] which have a double value */
351
#if defined(__ia64__) || defined(__x86_64__)
352
/* store the floating-point arguments in an extra array */
356
__avword args[__AV_ALIST_WORDS]; /* sizeof(double)-aligned */
357
#if defined(__powerpc__) || defined(__powerpc64__)
358
/* store the floating-point arguments in an extra array */
362
#if defined(__s390__)
363
/* store the floating-point arguments in an extra array */
375
/* store the arguments passed in registers in an extra array */
376
__avword regargs[8+7];
380
/* The limit for the pointer into the args[] array. */
381
#if defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || (defined(__powerpc__) && !defined(__powerpc64__) && !defined(_AIX) && !(defined(__MACH__) && defined(__APPLE__))) || defined(__s390)
382
#define __av_eptr(LIST) ((LIST).eptr)
384
#define __av_eptr(LIST) (&(LIST).args[__AV_ALIST_WORDS])
387
/* Delayed overflow detection */
388
#if defined(__hppa__)
389
#define av_overflown(LIST) ((LIST).aptr < __av_eptr(LIST))
391
#define av_overflown(LIST) ((LIST).aptr > __av_eptr(LIST))
396
* av_start_<type> macros which specify the return type
399
#define __AV_START_FLAGS \
400
__AV_STRUCT_RETURN | __AV_FLOAT_RETURN | __AV_STRUCT_ARGS | __AV_CLEANUP
402
#define __av_start(LIST,FUNC,RADDR,RETTYPE) \
403
((LIST).func = (__avword(*)())(FUNC), \
404
(LIST).raddr = (void*)(RADDR), \
405
(LIST).rtype = (RETTYPE), \
407
(LIST).flags = __AV_START_FLAGS)
409
#if defined(__i386__) || defined(__m68k__) || defined(__alpha__) || defined(__arm__) || defined(__m88k__) || defined(__convex__)
410
#define __av_start1(LIST) \
411
(LIST).aptr = &(LIST).args[0],
413
#if defined(__mips__) && !defined(__mipsn32__)
414
#define __av_start1(LIST) \
416
(LIST).aptr = &(LIST).args[0],
418
#if defined(__mipsn32__) || defined(__mips64__)
419
#define __av_start1(LIST) \
421
(LIST).farg_mask = 0, \
422
(LIST).darg_mask = 0, \
423
(LIST).aptr = &(LIST).args[0],
425
#if defined(__sparc__) && !defined(__sparc64__)
426
#define __av_start1(LIST) \
427
(LIST).aptr = &(LIST).args[0], \
428
(LIST).eptr = &(LIST).args[__AV_ALIST_WORDS],
430
#if defined(__sparc64__)
431
#define __av_start1(LIST) \
433
(LIST).farg_mask = 0, \
434
(LIST).darg_mask = 0, \
435
(LIST).aptr = &(LIST).args[0], \
436
(LIST).eptr = &(LIST).args[__AV_ALIST_WORDS],
438
#if defined(__hppa__)
439
#define __av_start1(LIST) \
440
(LIST).aptr = &(LIST).args[__AV_ALIST_WORDS], \
441
(LIST).eptr = &(LIST).args[0],
443
#if defined(__powerpc__) || defined(__powerpc64__)
444
#if defined(__powerpc64__) || defined(_AIX) || (defined(__MACH__) && defined(__APPLE__))
445
#define __av_start1(LIST) \
446
(LIST).aptr = &(LIST).args[0], \
447
(LIST).faptr = &(LIST).fargs[0],
449
#define __av_start1(LIST) \
450
(LIST).aptr = &(LIST).args[0], \
451
(LIST).faptr = &(LIST).fargs[0], \
452
(LIST).eptr = &(LIST).args[__AV_ALIST_WORDS],
455
#if defined(__s390__)
456
#define __av_start1(LIST) \
457
(LIST).aptr = &(LIST).args[0], \
458
(LIST).fargwords = 0, \
459
(LIST).faptr = &(LIST).fargs[0], \
460
(LIST).daptr = &(LIST).dargs[0], \
461
(LIST).fargsusedptr = &(LIST).fargsused[0], \
462
(LIST).dargsusedptr = &(LIST).dargsused[0], \
463
(LIST).eptr = &(LIST).args[__AV_ALIST_WORDS],
465
#if defined(__ia64__)
466
#define __av_start1(LIST) \
467
(LIST).aptr = &(LIST).args[0], \
468
(LIST).faptr = &(LIST).fargs[0],
470
#if defined(__x86_64__)
471
#define __av_start1(LIST) \
472
(LIST).aptr = &(LIST).args[0], \
473
(LIST).iaptr = &(LIST).iargs[0], \
474
(LIST).faptr = &(LIST).fargs[0],
477
#define av_start_void(LIST,FUNC) __av_start(LIST,FUNC,0, __AVvoid)
478
#define av_start_char(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVchar)
479
#define av_start_schar(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVschar)
480
#define av_start_uchar(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVuchar)
481
#define av_start_short(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVshort)
482
#define av_start_ushort(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVushort)
483
#define av_start_int(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVint)
484
#define av_start_uint(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVuint)
485
#define av_start_long(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVlong)
486
#define av_start_ulong(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVulong)
487
#define av_start_longlong(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVlonglong)
488
#define av_start_ulonglong(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVulonglong)
489
#define av_start_float(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVfloat)
490
#define av_start_double(LIST,FUNC,RADDR) __av_start(LIST,FUNC,RADDR,__AVdouble)
491
#define av_start_ptr(LIST,FUNC,TYPE,RADDR) __av_start(LIST,FUNC,RADDR,__AVvoidp)
493
#define av_start_struct(LIST,FUNC,TYPE,TYPE_SPLITTABLE,RADDR) \
494
_av_start_struct(LIST,FUNC,sizeof(TYPE),TYPE_SPLITTABLE,RADDR)
495
#define _av_start_struct(LIST,FUNC,TYPE_SIZE,TYPE_SPLITTABLE,RADDR) \
496
(__av_start(LIST,FUNC,RADDR,__AVstruct), \
497
(LIST).rsize = TYPE_SIZE, \
498
__av_start_struct1(LIST,TYPE_SIZE,TYPE_SPLITTABLE), \
501
#define __av_start_struct1(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
502
((LIST).flags & __AV_PCC_STRUCT_RETURN \
503
? /* pcc struct return convention: \
504
* called function returns pointer to value, we'll copy its contents afterwards. \
507
: __av_start_struct2(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
509
#if (defined(__sparc__) && !defined(__sparc64__)) || defined(__m88k__)
510
/* Return structure pointer is passed in a special register.
512
#define __av_start_struct2(LIST,TYPE_SIZE,TYPE_SPLITTABLE) 0
514
#define __av_start_struct2(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
515
(((LIST).flags & __AV_SMALL_STRUCT_RETURN) \
516
&& __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
517
? /* <= Word-sized structures are returned in a register. */ \
518
__av_start_struct3(LIST) \
519
: __av_start_struct4(LIST,TYPE_SIZE) \
521
/* Determines whether a structure is returned in registers,
522
* depending on its size and its word-splittable flag.
524
#if (defined(__i386__) && defined(_WIN32))
525
#define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
526
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 \
527
|| ((TYPE_SIZE) == 8 \
528
&& (((LIST).flags & __AV_MSVC_STRUCT_RETURN) \
529
|| ((TYPE_SPLITTABLE) \
530
&& ((LIST).flags & __AV_GCC_STRUCT_RETURN) \
532
/* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set
533
* and the struct will actually be returned in registers.
535
#define __av_start_struct3(LIST) \
536
((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
538
#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
539
#define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
540
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 \
541
|| ((TYPE_SIZE) == 8 && (TYPE_SPLITTABLE) \
542
&& ((LIST).flags & __AV_GCC_STRUCT_RETURN) \
544
/* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set
545
* and the struct will actually be returned in registers.
547
#define __av_start_struct3(LIST) \
548
((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
550
#if defined(__alpha__)
551
#define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
552
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8 \
553
|| ((TYPE_SIZE) == 16 && (TYPE_SPLITTABLE) \
554
&& ((LIST).flags & __AV_GCC_STRUCT_RETURN) \
556
/* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set
557
* and the struct will actually be returned in registers.
559
#define __av_start_struct3(LIST) \
560
((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
562
#if defined(__hppa__)
563
#define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
564
((LIST).flags & __AV_OLDGCC_STRUCT_RETURN \
565
? ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4) \
566
: ((TYPE_SIZE) <= 8) \
568
/* Test both __AV_OLDGCC_STRUCT_RETURN and __AV_SMALL_STRUCT_RETURN at run time. */
569
#define __av_start_struct3(LIST) \
572
#if defined(__mips__) && !defined(__mipsn32__)
573
#define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
574
((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4)
575
/* Test __AV_SMALL_STRUCT_RETURN instead of __AV_REGISTER_STRUCT_RETURN. */
576
#define __av_start_struct3(LIST) \
579
#if defined(__mipsn32__) || defined(__mips64__)
580
#define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
581
((LIST).flags & __AV_GCC_STRUCT_RETURN \
582
? ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8) \
583
: ((TYPE_SIZE) <= 16) \
585
/* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set
586
* and the struct will actually be returned in registers.
588
#define __av_start_struct3(LIST) \
589
((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
591
#if defined(__powerpc64__)
592
#define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
594
#define __av_start_struct3(LIST) \
597
#if defined(__sparc64__) || defined(__ia64__)
598
#define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
600
/* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set
601
* and the struct will actually be returned in registers.
603
#define __av_start_struct3(LIST) \
604
((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
606
#if defined(__x86_64__)
607
#define __av_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE) \
609
/* Turn on __AV_REGISTER_STRUCT_RETURN if __AV_SMALL_STRUCT_RETURN was set
610
* and the struct will actually be returned in registers.
612
#define __av_start_struct3(LIST) \
613
((LIST).flags |= __AV_REGISTER_STRUCT_RETURN, 0)
615
#if defined(__i386__)
616
/* Return structure pointer is passed in a special register or as first arg. */
617
#define __av_start_struct4(LIST,TYPE_SIZE) \
618
((LIST).flags & __AV_NEXTGCC_STRUCT_RETURN \
619
? 0 /* special register */ \
620
: (*(LIST).aptr++ = (__avword)((LIST).raddr), 0) /* first arg */ \
623
#if defined(__m68k__) || defined(__hppa__) || defined(__ia64__)
624
/* Return structure pointer is passed in a special register.
626
#define __av_start_struct4(LIST,TYPE_SIZE) 0
628
/* Return structure pointer is passed as first arg.
630
#if defined(__alpha__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__) || defined(__s390__)
631
#define __av_start_struct4(LIST,TYPE_SIZE) \
632
(*(LIST).aptr++ = (__avword)((LIST).raddr), 0)
634
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__)
635
#define __av_start_struct4(LIST,TYPE_SIZE) \
636
(*(LIST).aptr++ = (__avword)((LIST).raddr), \
641
#if defined(__x86_64__)
642
#define __av_start_struct4(LIST,TYPE_SIZE) \
643
(*(LIST).iaptr++ = (__avword)((LIST).raddr), 0)
649
* av_<type> macros which specify the argument and its type
653
* scalar argument types
656
#if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__alpha__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__)
657
/* Floats and all integer types are passed as words,
658
* doubles as two words.
660
#define __av_word(LIST,VAL) \
661
(++(LIST).aptr > __av_eptr(LIST) \
662
? -1 : ((LIST).aptr[-1] = (__avword)(VAL), 0))
664
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__)
665
/* Most things are passed as integers:
667
#define __av_word(LIST,VAL) \
668
(++(LIST).aptr > __av_eptr(LIST) \
669
? -1 : ((LIST).anum++, (LIST).aptr[-1] = (__avword)(VAL), 0))
671
#if defined(__hppa__)
672
/* Floats and all integer types are passed as words,
673
* doubles as two words.
675
#define __av_word(LIST,VAL) \
676
(--(LIST).aptr < __av_eptr(LIST) \
677
? -1 : (*(LIST).aptr = (__avword)(VAL), 0))
680
/* Some arguments are passed in registers. Query the macro AV_ARG_REGNUM.
681
* This should really be an argument to __av_word.
683
#undef __av_word /**/
684
#define __av_word(LIST,VAL) \
685
((AV_ARG_REGNUM) >= 0 \
686
? ((AV_ARG_REGNUM) < 8+7 \
687
? -1 : ((LIST).regargs[(AV_ARG_REGNUM)] = (__avword)(VAL), 0)) \
688
: (++(LIST).aptr > __av_eptr(LIST) \
689
? -1 : ((LIST).aptr[-1] = (__avword)(VAL), 0)))
692
/* integer argument types */
694
#if defined(__x86_64__)
695
/* The first 6 integer arguments are passed in registers. */
696
#define av_long(LIST,VAL) \
697
((LIST).iaptr < &(LIST).iargs[6] \
698
? (*(LIST).iaptr++ = (long)(VAL), 0) \
699
: __av_word(LIST,(long)(VAL)))
701
#define av_long(LIST,VAL) __av_word(LIST,(long)(VAL))
704
#if defined(__x86_64__)
705
/* The first 6 integer arguments are passed in registers. */
706
#define av_ulong(LIST,VAL) \
707
((LIST).iaptr < &(LIST).iargs[6] \
708
? (*(LIST).iaptr++ = (unsigned long)(VAL), 0) \
709
: __av_word(LIST,(unsigned long)(VAL)))
711
#define av_ulong(LIST,VAL) __av_word(LIST,(unsigned long)(VAL))
714
#if defined(__x86_64__)
715
/* The first 6 integer arguments are passed in registers. */
716
#define av_ptr(LIST,TYPE,VAL) \
717
((LIST).iaptr < &(LIST).iargs[6] \
718
? (*(LIST).iaptr++ = (__avword)(TYPE)(VAL), 0) \
719
: __av_word(LIST,(TYPE)(VAL)))
721
#define av_ptr(LIST,TYPE,VAL) __av_word(LIST,(TYPE)(VAL))
724
#define av_char av_long
725
#define av_schar av_long
726
#define av_short av_long
727
#define av_int av_long
728
#define av_uchar av_ulong
729
#define av_ushort av_ulong
730
#define av_uint av_ulong
732
#if defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__powerpc64__) || defined(__ia64__) || defined(__x86_64__)
733
/* `long long' and `long' are identical. */
734
#define av_longlong av_long
735
#define av_ulonglong av_ulong
736
#elif defined(__mipsn32__)
737
/* `long long' fits in __avword. */
738
#define av_longlong __av_word
739
#define av_ulonglong(LIST,VAL) __av_word(LIST,(unsigned long long)(VAL))
740
#elif defined(__i386__) || defined(__m68k__) || defined(__mips__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__arm__) || defined(__powerpc__) || defined(__m88k__) || defined(__convex__) || defined(__s390__)
741
/* `long long's are passed embedded on the arg stack. */
742
#define av_longlong(LIST,VAL) __av_longlong(LIST,long long,VAL)
743
#define av_ulonglong(LIST,VAL) __av_longlong(LIST,unsigned long long,VAL)
744
#if defined(__i386__) || defined(__m68k__) || defined(__arm__) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__)
745
/* `long long's are (at most) word-aligned. */
746
#define __av_longlong(LIST,TYPE,VAL) \
747
(((LIST).aptr += sizeof(TYPE)/sizeof(__avword)) > __av_eptr(LIST) \
748
? -1 : (((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0))
750
#if defined(__mips__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__) || defined(__s390__)
751
/* `long long's have alignment 8. */
752
#if defined(__mips__)
753
#define __av_longlong(LIST,TYPE,VAL) \
754
(((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(TYPE)+__AV_alignof(TYPE)-1) & -(long)__AV_alignof(TYPE))) > __av_eptr(LIST) \
755
? -1 : ((LIST).anum++, ((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0))
757
#if defined(__sparc__) && !defined(__sparc64__)
758
/* Within the arg stack, the alignment is only 4, not 8. */
759
/* This assumes sizeof(long long) == 2*sizeof(__avword). */
760
#define __av_longlong(LIST,TYPE,VAL) \
761
(((LIST).aptr += sizeof(TYPE)/sizeof(__avword)) > __av_eptr(LIST) \
763
((LIST).tmp._longlong = (TYPE)(VAL), \
764
(LIST).aptr[-2] = (LIST).tmp.words[0], \
765
(LIST).aptr[-1] = (LIST).tmp.words[1], \
768
#if defined(__hppa__)
769
#define __av_longlong(LIST,TYPE,VAL) \
770
(((LIST).aptr = (__avword*)(((__avword)(LIST).aptr & -(long)__AV_alignof(TYPE)) - sizeof(TYPE))) < __av_eptr(LIST) \
771
? -1 : (*(TYPE*)(LIST).aptr = (TYPE)(VAL), 0))
773
#if (defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__)
774
#define __av_longlong(LIST,TYPE,VAL) \
775
(((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(TYPE)+__AV_alignof(TYPE)-1) & -(long)__AV_alignof(TYPE))) > __av_eptr(LIST) \
776
? -1 : (((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0))
778
#if defined(__s390__)
779
#define __av_longlong(LIST,TYPE,VAL) \
780
(((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(TYPE)+__AV_alignof(TYPE)-1) & -(long)__AV_alignof(TYPE))) > __av_eptr(LIST) \
782
(((LIST).aptr - (LIST).args - (LIST).fargwords == 4 ? ++(LIST).aptr,0 : 0), \
783
(((TYPE*)(LIST).aptr)[-1] = (TYPE)(VAL), 0)))
788
/* floating-point argument types */
790
#if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__arm__) || defined(__convex__)
792
#define av_float(LIST,VAL) \
793
(++(LIST).aptr > __av_eptr(LIST) \
794
? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), 0))
796
/* This assumes sizeof(double) == 2*sizeof(__avword). */
797
#define av_double(LIST,VAL) \
798
(((LIST).aptr += 2) > __av_eptr(LIST) \
800
((LIST).tmp._double = (double)(VAL), \
801
(LIST).aptr[-2] = (LIST).tmp.words[0], \
802
(LIST).aptr[-1] = (LIST).tmp.words[1], \
807
#if defined(__mips__) && !defined(__mipsn32__)
809
/* Up to 2 leading float or double non-varargs args can be passed in
810
* float registers, but we also push them into the corresponding int
811
* registers in case of varargs. For doubles we need to align the aptr
812
* to an even boundary.
814
#define av_float(LIST,VAL) \
815
(++(LIST).aptr > __av_eptr(LIST) \
816
? -1 : ((++(LIST).anum == 1 \
817
? ((LIST).flags |= __AV_FLOAT_1, \
818
((float*)(LIST).floatarg)[1] = ((float*)(LIST).aptr)[-1] = (float)(VAL))\
819
: (LIST).anum == 2 && ((LIST).flags & __AV_FLOAT_1) \
820
? ((LIST).flags |= __AV_FLOAT_2, \
821
((float*)(LIST).floatarg)[3] = ((float*)(LIST).aptr)[-1] = (float)(VAL))\
822
: (*(float*)&(LIST).aptr[-1] = (float)(VAL))), \
825
#define av_double(LIST,VAL) \
826
(((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+15)&-8)) \
828
? -1 : ((++(LIST).anum == 1 \
829
? ((LIST).flags |= __AV_FLOAT_1, \
830
(LIST).floatarg[0] = ((double*)(LIST).aptr)[-1] = (double)(VAL))\
831
: (LIST).anum == 2 && ((LIST).flags & __AV_FLOAT_1) \
832
? ((LIST).flags |= __AV_FLOAT_2, \
833
(LIST).floatarg[1] = ((double*)(LIST).aptr)[-1] = (double)(VAL))\
834
: (((double*)(LIST).aptr)[-1] = (double)(VAL))), \
839
#if defined(__mipsn32__) || defined(__mips64__)
841
/* Up to 8 leading float or double non-varargs args can be passed in
842
* float registers, but we also push them into the corresponding int
843
* registers in case of varargs.
845
#define av_float(LIST,VAL) \
846
((LIST).aptr >= __av_eptr(LIST) \
847
? -1 : (((LIST).anum < 8 \
848
? ((LIST).farg_mask |= (1 << (LIST).anum), \
849
(LIST).farg[(LIST).anum] = *(float*)(LIST).aptr = (float)(VAL)) \
850
: (*(float*)(LIST).aptr = (float)(VAL))), \
855
#define av_double(LIST,VAL) \
856
((LIST).aptr >= __av_eptr(LIST) \
857
? -1 : (((LIST).anum < 8 && ((LIST).darg_mask |= (1 << (LIST).anum))), \
858
*(double*)(LIST).aptr = (double)(VAL), \
865
#if defined(__sparc64__)
867
/* Up to 16 leading float or double non-varargs args can be passed in
868
* float registers, but we also push them into the corresponding int
869
* registers in case of varargs.
871
#define av_float(LIST,VAL) \
872
((LIST).aptr >= __av_eptr(LIST) \
873
? -1 : (((LIST).anum < 16 && ((LIST).farg_mask |= (1 << (LIST).anum))), \
874
(*(float*)(LIST).aptr = (float)(VAL)), \
879
#define av_double(LIST,VAL) \
880
((LIST).aptr >= __av_eptr(LIST) \
881
? -1 : (((LIST).anum < 16 && ((LIST).darg_mask |= (1 << (LIST).anum))), \
882
*(double*)(LIST).aptr = (double)(VAL), \
889
#if defined(__alpha__)
891
#define av_double(LIST,VAL) \
892
(++(LIST).aptr > __av_eptr(LIST) \
893
? -1 : (((double*)(LIST).aptr)[-1] = (double)(VAL), 0))
895
#define av_float(LIST,VAL) \
896
(++(LIST).aptr > __av_eptr(LIST) \
898
: (((LIST).aptr > &(LIST).args[6] \
899
? /* These args will be fetched from memory using "lds" instructions */ \
900
/* therefore store them as floats */ \
901
(*(float*)((LIST).aptr-1) = (float)(VAL)) \
902
: /* The first 6 args will be put into registers by "ldt" instructions */ \
903
/* (see avcall-alpha.c!). Therefore store them as doubles. */ \
904
/* When viewed as floats, the value will be the correct one. */\
905
(*(double*)((LIST).aptr-1) = (double)(float)(VAL)) \
910
#if defined(__hppa__)
912
#define av_float(LIST,VAL) \
913
(--(LIST).aptr < __av_eptr(LIST) \
914
? -1 : (*(float*)(LIST).aptr = (float)(VAL), 0))
916
#define av_double(LIST,VAL) \
917
(((LIST).aptr = (__avword*)(((long)(LIST).aptr-sizeof(double)) & -(long)sizeof(double))) \
919
? -1 : (*(double*)(LIST).aptr = (double)(VAL), 0))
923
#if defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
925
/* Up to 13 float or double non-varargs args can be passed in
926
* float registers, but we also push them into the corresponding int
927
* registers in case of varargs.
930
#define av_float(LIST,VAL) \
931
(++(LIST).aptr > __av_eptr(LIST) \
932
? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), \
933
(LIST).faptr < &(LIST).fargs[13] && \
934
(*(LIST).faptr++ = (double)(float)(VAL)), \
937
#define av_double(LIST,VAL) \
938
(((LIST).aptr += 2) > __av_eptr(LIST) \
940
((LIST).tmp._double = (double)(VAL), \
941
(LIST).aptr[-2] = (LIST).tmp.words[0], \
942
(LIST).aptr[-1] = (LIST).tmp.words[1], \
943
(LIST).faptr < &(LIST).fargs[13] && \
944
(*(LIST).faptr++ = (LIST).tmp._double), \
949
#if defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
951
/* Up to 8 float or double non-varargs args can be passed in
952
* float registers, without occupying space in the general registers.
955
#define av_float(LIST,VAL) \
956
((LIST).faptr < &(LIST).fargs[8] \
957
? ((*(LIST).faptr++ = (double)(float)(VAL)), 0) \
958
: (++(LIST).aptr > __av_eptr(LIST) \
959
? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), 0)))
961
#define av_double(LIST,VAL) \
962
((LIST).faptr < &(LIST).fargs[8] \
963
? ((*(LIST).faptr++ = (double)(VAL)), 0) \
964
: (((LIST).aptr += 2) > __av_eptr(LIST) \
966
((LIST).tmp._double = (double)(VAL), \
967
(LIST).aptr[-2] = (LIST).tmp.words[0], \
968
(LIST).aptr[-1] = (LIST).tmp.words[1], \
973
#if defined(__powerpc64__)
975
/* Up to 13 float or double non-varargs args can be passed in
976
* float registers, but we also push them into the corresponding int
977
* registers in case of varargs.
980
#define av_float(LIST,VAL) \
981
(++(LIST).aptr > __av_eptr(LIST) \
982
? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), \
983
(LIST).faptr < &(LIST).fargs[13] && \
984
(*(LIST).faptr++ = (double)(float)(VAL)), \
987
#define av_double(LIST,VAL) \
988
(++(LIST).aptr > __av_eptr(LIST) \
989
? -1 : (((double*)(LIST).aptr)[-1] = (double)(VAL), \
990
(LIST).faptr < &(LIST).fargs[13] && \
991
(*(LIST).faptr++ = (double)(VAL)), \
996
#if defined(__s390__)
998
/* Up to 2 float or double non-varargs args can be passed in
999
* float registers, without occupying space in the general registers.
1002
#define av_float(LIST,VAL) \
1003
((LIST).faptr < &(LIST).fargs[2] \
1004
? (LIST).daptr++, *(LIST).fargsusedptr++ = 1, *(LIST).dargsusedptr++ = 0, ((*(LIST).faptr++ = (float)(VAL)), 0) \
1005
: (++(LIST).aptr > __av_eptr(LIST) \
1006
? -1 : ((LIST).fargwords++, ((float*)(LIST).aptr)[-1] = (float)(VAL), 0)))
1008
#define av_double(LIST,VAL) \
1009
((LIST).daptr < &(LIST).dargs[2] \
1010
? (LIST).faptr++, *(LIST).dargsusedptr++ = 1, *(LIST).fargsusedptr++ = 0, ((*(LIST).daptr++ = (double)(VAL)), 0) \
1011
: (((LIST).aptr += 2) > __av_eptr(LIST) \
1013
((LIST).fargwords+=2, (LIST).tmp._double = (double)(VAL), \
1014
(LIST).aptr[-2] = (LIST).tmp.words[0], \
1015
(LIST).aptr[-1] = (LIST).tmp.words[1], \
1020
#if defined(__m88k__)
1022
#define av_float(LIST,VAL) \
1023
(++(LIST).aptr > __av_eptr(LIST) \
1024
? -1 : (((float*)(LIST).aptr)[-1] = (float)(VAL), 0))
1026
#define av_double(LIST,VAL) \
1027
(((LIST).aptr = (__avword*)(((long)(LIST).aptr+sizeof(double)+sizeof(double)-1) & -(long)sizeof(double))) \
1029
? -1 : (((double*)(LIST).aptr)[-1] = (double)(VAL), 0))
1033
#if defined(__ia64__)
1035
/* Up to 8 leading float or double non-varargs args can be passed in
1036
* float registers, but we also push them into the corresponding int
1037
* registers in case of varargs.
1039
#define av_float(LIST,VAL) \
1040
((LIST).aptr >= __av_eptr(LIST) \
1041
? -1 : ((*(float*)(LIST).aptr = (float)(VAL)), \
1042
((LIST).faptr < &(LIST).fargs[8] && (*(LIST).faptr = *(float*)(LIST).aptr, (LIST).faptr++)), \
1046
#define av_double(LIST,VAL) \
1047
((LIST).aptr >= __av_eptr(LIST) \
1048
? -1 : (*(double*)(LIST).aptr = (double)(VAL), \
1049
((LIST).faptr < &(LIST).fargs[8] && (*(LIST).faptr = *(double*)(LIST).aptr, (LIST).faptr++)), \
1055
#if defined(__x86_64__)
1057
/* Up to 8 leading float or double args can be passed in float registers.
1059
#define av_float(LIST,VAL) \
1060
((LIST).faptr < &(LIST).fargs[8] \
1061
? (*(LIST).faptr = 0.0, *(float*)(LIST).faptr = (float)(VAL), \
1064
: ((LIST).aptr >= __av_eptr(LIST) \
1065
? -1 : ((*(float*)(LIST).aptr = (float)(VAL)), \
1069
#define av_double(LIST,VAL) \
1070
((LIST).faptr < &(LIST).fargs[8] \
1071
? (*(LIST).faptr = (double)(VAL), \
1074
: ((LIST).aptr >= __av_eptr(LIST) \
1075
? -1 : ((*(double*)(LIST).aptr = (double)(VAL)), \
1082
* structure argument types
1085
#define av_struct(LIST,TYPE,VAL) \
1086
__av_struct(LIST,TYPE,sizeof(TYPE),__AV_alignof(TYPE),__av_struct_assign,VAL)
1087
#define __av_struct_assign(TYPE,TYPE_SIZE,TYPE_ALIGN,PLACE,VAL) \
1088
*(TYPE*)(PLACE) = (VAL)
1089
/* _av_struct() is like av_struct(), except that you pass the type's size and alignment
1090
* and the value's address instead of the type and the value themselves.
1092
#define _av_struct(LIST,TYPE_SIZE,TYPE_ALIGN,VAL_ADDR) \
1093
__av_struct(LIST,unknown,TYPE_SIZE,TYPE_ALIGN,__av_struct_copy,VAL_ADDR)
1094
#define __av_struct_copy(TYPE,TYPE_SIZE,TYPE_ALIGN,PLACE,VAL_ADDR) \
1095
__structcpy(PLACE,VAL_ADDR,TYPE_SIZE,TYPE_ALIGN)
1096
/* Structure argument alignment. */
1097
#if defined(__i386__) && defined(_MSC_VER)
1098
/* In MSVC, doubles inside structures have alignment 8, i.e.
1099
* __AV_alignof(double) = 8, but doubles (and also structures containing
1100
* doubles) are passed on the stack with alignment 4. Looks really weird.
1102
#define __av_struct_alignment(TYPE_ALIGN) \
1103
((TYPE_ALIGN) <= 4 ? (TYPE_ALIGN) : 4)
1105
#define __av_struct_alignment(TYPE_ALIGN) \
1108
#if defined(__i386__) || defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__alpha__) || (defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__powerpc64__) || defined(__m88k__) || defined(__ia64__) || defined(__s390__)
1109
/* Structures are passed as fully aligned structures on the arg stack.
1110
* We align the aptr, store the structure, then fill to word alignment.
1111
* Single-small-integer structures are NOT promoted to integers and have
1112
* different alignment.
1114
/* little endian -> small structures < 1 word are adjusted to the left */
1115
#if defined(__i386__) || defined(__alpha__) || defined(__x86_64__)
1116
#define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1118
(__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+__av_struct_alignment(TYPE_ALIGN)-1) & -(long)__av_struct_alignment(TYPE_ALIGN)))\
1120
? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
1121
(LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),\
1124
#if defined(__ia64__)
1125
/* Types larger than a word have 2-word alignment. */
1126
#define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1127
((LIST).aptr = (__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+__av_struct_alignment(TYPE_ALIGN)-1) & -(long)__av_struct_alignment(TYPE_ALIGN)), \
1128
((TYPE_SIZE) > sizeof(__avword) && (((LIST).aptr - &(LIST).args[0]) & 1) ? ++(LIST).aptr : 0), \
1129
((LIST).aptr > __av_eptr(LIST) \
1130
? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
1131
(LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),\
1134
/* small structures < 1 word are adjusted depending on compiler */
1135
#if defined(__mips__) && !defined(__mipsn32__)
1136
#define __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1138
(__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)))\
1140
? -1 : (++(LIST).anum, \
1141
ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
1142
(LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),\
1144
#define __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1146
(__avword*)(((((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN))\
1147
+sizeof(__avword)-1) & -(long)sizeof(__avword))) \
1149
? -1 : (++(LIST).anum, \
1150
ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
1152
#define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1153
((LIST).flags & __AV_SGICC_STRUCT_ARGS \
1154
? /* SGI MIPS cc passes small structures left-adjusted, although big-endian! */\
1155
__av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1156
: /* SGI MIPS gcc passes small structures within the first four words left- \
1157
* adjusted, for compatibility with cc. But structures in memory are passed \
1158
* right-adjusted!! See gcc-2.6.3/config/mips/mips.c:function_arg(). \
1160
((LIST).aptr < &(LIST).args[4] \
1161
? __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1162
: __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)))
1164
#if defined(__mipsn32__) || defined(__mips64__)
1165
/* When a structure is passed (partially) in registers, it is passed in the
1166
* integer registers, except that doubles within the structure are passed in
1167
* the floating point registers. Instead of distinguishing these cases, we
1168
* always pass the structure in both the integer and the floating point
1171
#define __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1173
(__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)))\
1175
? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
1176
(LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),\
1177
((LIST).anum < 8 && ((LIST).darg_mask |= (-1 << (LIST).anum))), \
1178
(LIST).anum += (((((TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)) + sizeof(__avword)-1) & -(long)sizeof(__avword))/sizeof(__avword),\
1179
(LIST).darg_mask &= (1 << ((LIST).anum < 8 ? (LIST).anum : 8)) - 1, \
1181
#define __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1183
(__avword*)(((((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN))\
1184
+sizeof(__avword)-1) & -(long)sizeof(__avword))) \
1186
? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
1187
((LIST).anum < 8 && ((LIST).darg_mask |= (-1 << (LIST).anum))), \
1188
(LIST).anum += (((((TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)) + sizeof(__avword)-1) & -(long)sizeof(__avword))/sizeof(__avword),\
1189
(LIST).darg_mask &= (1 << ((LIST).anum < 8 ? (LIST).anum : 8)) - 1, \
1191
#define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1192
((LIST).flags & __AV_SGICC_STRUCT_ARGS \
1193
? /* SGI MIPS cc passes small structures left-adjusted, although big-endian! */\
1194
__av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1195
: /* SGI MIPS gcc passes small structures right-adjusted. */ \
1196
__av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL))
1198
#if defined(__powerpc__) || defined(__powerpc64__)
1199
#define __av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)\
1201
(__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)))\
1203
? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
1204
(LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),\
1206
#define __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)\
1208
(__avword*)(((((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN))\
1209
+sizeof(__avword)-1) & -(long)sizeof(__avword))) \
1211
? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
1213
#if !defined(__powerpc64__)
1214
#define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1215
((LIST).flags & __AV_AIXCC_STRUCT_ARGS \
1216
? /* AIX cc and xlc pass small structures left-adjusted, although big-endian! */\
1217
__av_struct_leftadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1218
: /* gcc passes small structures right-adjusted. */ \
1219
__av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL))
1221
#if defined(__powerpc64__)
1222
#define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1223
__av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)
1226
#if defined(__s390__)
1227
#define __av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)\
1229
(__avword*)(((((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN))\
1230
+sizeof(__avword)-1) & -(long)sizeof(__avword))) \
1232
? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
1234
#define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1235
((TYPE_SIZE) != 1 && (TYPE_SIZE) != 2 && (TYPE_SIZE) != 4 && (TYPE_SIZE) != 8 \
1237
> ((LIST).eptr = (__avword*)((long)(LIST).eptr - (((TYPE_SIZE)+7)&-8)))\
1239
(ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)(LIST).eptr,VAL), \
1240
(LIST).aptr[-1] = (__avword)(LIST).eptr, \
1242
: (((TYPE_SIZE) == 8 && (LIST).aptr - (LIST).args - (LIST).fargwords == 4 ? ++(LIST).aptr,0 : 0), \
1243
__av_struct_rightadjusted(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL)))
1245
/* big endian -> small structures < 1 word are adjusted to the right */
1246
#if defined(__m88k__)
1247
#define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1249
(__avword*)(((((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN))\
1250
+sizeof(__avword)-1) & -(long)sizeof(__avword))) \
1252
? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
1256
#if defined(__m68k__) || defined(__arm__) || defined(__convex__)
1257
/* Structures are passed as embedded copies on the arg stack.
1259
#define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1260
(((LIST).aptr = (__avword*)(((long)(LIST).aptr+(TYPE_SIZE)+sizeof(__avword)-1) & -(long)sizeof(__avword))) \
1262
? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
1265
#if (defined(__sparc__) && !defined(__sparc64__)) || (defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__))))
1266
/* Structures are passed as pointers to caller-made local copies. We
1267
* grab space for the copies from the end of the argument list space
1268
* and always use maximal (double) alignment.
1270
#define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1272
> ((LIST).eptr = (__avword*)((long)(LIST).eptr - (((TYPE_SIZE)+7)&-8)))\
1274
(ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)(LIST).eptr,VAL), \
1275
(LIST).aptr[-1] = (__avword)(LIST).eptr, \
1278
#if defined(__sparc64__)
1279
/* Structures <= 16 bytes are passed as embedded copies on the arg stack,
1280
* left-adjusted (although big-endian!).
1281
* When a structure is passed (partially) in registers, it is passed in the
1282
* integer registers, except that floats and doubles within the structure
1283
* are passed in the floating point registers. Instead of distinguishing
1284
* these cases, we always pass the structure in both the integer and the
1285
* floating point registers.
1286
* Big structures are passed as pointers to caller-made local copies.
1287
* FIXME: Shouldn't (LIST).anum be incremented in sync with (LIST).aptr ?
1289
#define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1292
> ((LIST).eptr = (__avword*)((long)(LIST).eptr - (((TYPE_SIZE)+7)&-8)))\
1294
(ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)(LIST).eptr,VAL), \
1295
(LIST).aptr[-1] = (__avword)(LIST).eptr, \
1298
(__avword*)(((__avword)(LIST).aptr+(TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)))\
1300
? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr-(TYPE_SIZE)),VAL),\
1301
(LIST).aptr = (__avword*)(((__avword)(LIST).aptr+sizeof(__avword)-1) & -(long)sizeof(__avword)),\
1303
&& ((LIST).farg_mask |= (-1 << (LIST).anum), \
1304
(LIST).darg_mask |= (-1 << (LIST).anum))), \
1305
(LIST).anum += (((((TYPE_SIZE)+(TYPE_ALIGN)-1) & -(long)(TYPE_ALIGN)) + sizeof(__avword)-1) & -(long)sizeof(__avword))/sizeof(__avword),\
1306
(LIST).farg_mask &= (1 << ((LIST).anum < 16 ? (LIST).anum : 16)) - 1, \
1307
(LIST).darg_mask &= (1 << ((LIST).anum < 16 ? (LIST).anum : 16)) - 1, \
1310
#if defined(__hppa__)
1311
/* Structures <= 8 bytes are passed as embedded copies on the arg stack.
1312
* Big structures are passed as pointers to caller-made local copies.
1314
#define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1317
< ((LIST).eptr = (__avword*)((long)(LIST).eptr + (((TYPE_SIZE) + 7) & -8))) \
1319
: (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((long)(LIST).eptr - (((TYPE_SIZE) + 7) & -8)), VAL), \
1320
*(LIST).aptr = (__avword)((long)(LIST).eptr - (((TYPE_SIZE) + 7) & -8)), \
1322
: ((TYPE_SIZE) > 4 \
1323
? (((LIST).aptr = (__avword*)((((long)(LIST).aptr & -8) - (long)(TYPE_SIZE)) & -8)) \
1325
? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)(LIST).aptr,VAL), 0)) \
1326
: /* FIXME: gcc-2.6.3 passes structures <= 4 bytes in memory left-adjusted! ?? */\
1327
(((LIST).aptr = (__avword*)(((long)(LIST).aptr & -4) - (long)(TYPE_SIZE))) \
1329
? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)(LIST).aptr,VAL), \
1330
(LIST).aptr = (__avword*)((long)(LIST).aptr & -4), \
1333
#if defined(__x86_64__)
1334
/* Structures <= 16 bytes can be passed in integer or floating-point registers
1335
if there is enough room for the whole number of words needed by the structure
1336
in the corresponding iargs/fargs block. We can't distinguish the two cases
1337
and support only passing in integer registers. Other structures are passed
1338
on the arg stack. */
1339
#define __av_struct(LIST,TYPE,TYPE_SIZE,TYPE_ALIGN,ASSIGN,VAL) \
1340
((LIST).iaptr + ((TYPE_SIZE) + sizeof(__avword)-1) / sizeof(__avword) <= &(LIST).iargs[6] \
1341
? (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)(LIST).iaptr,VAL), \
1342
(LIST).iaptr += ((TYPE_SIZE) + sizeof(__avword)-1) / sizeof(__avword), \
1344
: ((LIST).aptr = (__avword*)((__avword)(LIST).aptr + (((TYPE_SIZE)+__av_struct_alignment(TYPE_ALIGN)-1) & -(long)__av_struct_alignment(TYPE_ALIGN))), \
1345
((LIST).aptr > __av_eptr(LIST) \
1346
? -1 : (ASSIGN(TYPE,TYPE_SIZE,TYPE_ALIGN,(void*)((__avword)(LIST).aptr - (((TYPE_SIZE)+__av_struct_alignment(TYPE_ALIGN)-1) & -(long)__av_struct_alignment(TYPE_ALIGN))),VAL),\
1351
* calling the function
1354
#define av_call(LIST) __builtin_avcall(&(LIST))
1356
/* Determine whether a struct type is word-splittable, i.e. whether each of
1357
* its components fit into a register.
1358
* The entire computation is done at compile time.
1360
#define av_word_splittable_1(slot1) \
1361
(__av_offset1(slot1)/sizeof(__avword) == (__av_offset1(slot1)+sizeof(slot1)-1)/sizeof(__avword))
1362
#define av_word_splittable_2(slot1,slot2) \
1363
((__av_offset1(slot1)/sizeof(__avword) == (__av_offset1(slot1)+sizeof(slot1)-1)/sizeof(__avword)) \
1364
&& (__av_offset2(slot1,slot2)/sizeof(__avword) == (__av_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__avword)) \
1366
#define av_word_splittable_3(slot1,slot2,slot3) \
1367
((__av_offset1(slot1)/sizeof(__avword) == (__av_offset1(slot1)+sizeof(slot1)-1)/sizeof(__avword)) \
1368
&& (__av_offset2(slot1,slot2)/sizeof(__avword) == (__av_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__avword)) \
1369
&& (__av_offset3(slot1,slot2,slot3)/sizeof(__avword) == (__av_offset3(slot1,slot2,slot3)+sizeof(slot3)-1)/sizeof(__avword)) \
1371
#define av_word_splittable_4(slot1,slot2,slot3,slot4) \
1372
((__av_offset1(slot1)/sizeof(__avword) == (__av_offset1(slot1)+sizeof(slot1)-1)/sizeof(__avword)) \
1373
&& (__av_offset2(slot1,slot2)/sizeof(__avword) == (__av_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__avword)) \
1374
&& (__av_offset3(slot1,slot2,slot3)/sizeof(__avword) == (__av_offset3(slot1,slot2,slot3)+sizeof(slot3)-1)/sizeof(__avword)) \
1375
&& (__av_offset4(slot1,slot2,slot3,slot4)/sizeof(__avword) == (__av_offset4(slot1,slot2,slot3,slot4)+sizeof(slot4)-1)/sizeof(__avword)) \
1377
#define __av_offset1(slot1) \
1379
#define __av_offset2(slot1,slot2) \
1380
((__av_offset1(slot1)+sizeof(slot1)+__AV_alignof(slot2)-1) & -(long)__AV_alignof(slot2))
1381
#define __av_offset3(slot1,slot2,slot3) \
1382
((__av_offset2(slot1,slot2)+sizeof(slot2)+__AV_alignof(slot3)-1) & -(long)__AV_alignof(slot3))
1383
#define __av_offset4(slot1,slot2,slot3,slot4) \
1384
((__av_offset3(slot1,slot2,slot3)+sizeof(slot3)+__AV_alignof(slot4)-1) & -(long)__AV_alignof(slot4))
1387
* Miscellaneous declarations.
1390
extern int __builtin_avcall (av_alist* l);
1391
extern void __structcpy (void* dest, const void* src, unsigned long size, unsigned long alignment);
1393
#endif /*_avcall_h */