~ubuntu-branches/debian/squeeze/ffcall/squeeze

« back to all changes in this revision

Viewing changes to vacall/vacall.h.msvc

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Egger
  • Date: 2010-06-26 15:29:30 UTC
  • mfrom: (5.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20100626152930-c09y01gk3szcnykn
Tags: 1.10+cvs20100619-2
Ship to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef _VACALL_H                               /*-*- C -*-*/
 
2
#define _VACALL_H
 
3
 
 
4
/*
 
5
 * Copyright 1995-2006 Bruno Haible, <bruno@clisp.org>
 
6
 *
 
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,
 
10
 * on this software.
 
11
 */
 
12
 
 
13
#if !defined(LIBFFCALL_VERSION)
 
14
# define LIBFFCALL_VERSION 0x010B
 
15
#endif
 
16
 
 
17
/* These definitions are adjusted by `configure' automatically. */
 
18
 
 
19
/* CPU */
 
20
#ifndef __i386__
 
21
#define __i386__ 1
 
22
#endif
 
23
#ifndef __m68k__
 
24
#undef __m68k__
 
25
#endif
 
26
#ifndef __mips__
 
27
#undef __mips__
 
28
#endif
 
29
#ifndef __mipsn32__
 
30
#undef __mipsn32__
 
31
#endif
 
32
#ifndef __mips64__
 
33
#undef __mips64__
 
34
#endif
 
35
#ifndef __sparc__
 
36
#undef __sparc__
 
37
#endif
 
38
#ifndef __sparc64__
 
39
#undef __sparc64__
 
40
#endif
 
41
#ifndef __alpha__
 
42
#undef __alpha__
 
43
#endif
 
44
#ifndef __hppa__
 
45
#undef __hppa__
 
46
#endif
 
47
#ifndef __arm__
 
48
#undef __arm__
 
49
#endif
 
50
#ifndef __powerpc__
 
51
#undef __powerpc__
 
52
#endif
 
53
#ifndef __powerpc64__
 
54
#undef __powerpc64__
 
55
#endif
 
56
#ifndef __s390__
 
57
#undef __s390__
 
58
#endif
 
59
#ifndef __m88k__
 
60
#undef __m88k__
 
61
#endif
 
62
#ifndef __convex__
 
63
#undef __convex__
 
64
#endif
 
65
#ifndef __ia64__
 
66
#undef __ia64__
 
67
#endif
 
68
#ifndef __x86_64__
 
69
#undef __x86_64__
 
70
#endif
 
71
 
 
72
/* Calling convention */
 
73
/* Define if using pcc non-reentrant struct return convention */
 
74
#undef __PCC_STRUCT_RETURN__
 
75
/* Define if small structs are returned in registers */
 
76
#define __SMALL_STRUCT_RETURN__ 1
 
77
/* Define if floating-point results are returned in the integer registers */
 
78
#undef __IREG_FLOAT_RETURN__
 
79
 
 
80
/* AC_TYPE_LONG_LONG */
 
81
/* Define if your compiler supports the 'long long' type. */
 
82
#ifndef HAVE_LONG_LONG_INT
 
83
#undef HAVE_LONG_LONG_INT
 
84
#endif
 
85
 
 
86
/* AC_C_CHAR_UNSIGNED */
 
87
#ifndef __CHAR_UNSIGNED__
 
88
#undef __CHAR_UNSIGNED__
 
89
#endif
 
90
 
 
91
/* End of definitions adjusted by `configure'. */
 
92
 
 
93
 
 
94
/* Max # words in argument-list and temporary structure storage.
 
95
 */
 
96
#ifndef __VA_ALIST_WORDS
 
97
#define __VA_ALIST_WORDS  256
 
98
#endif
 
99
 
 
100
/* Determine the alignment of a type at compile time.
 
101
 */
 
102
#if defined(__GNUC__)
 
103
#define __VA_alignof __alignof__
 
104
#else
 
105
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) /* SGI compiler */
 
106
#define __VA_alignof __builtin_alignof
 
107
#else
 
108
#define __VA_offsetof(type,ident)  ((unsigned long)&(((type*)0)->ident))
 
109
#define __VA_alignof(type)  __VA_offsetof(struct { char __slot1; type __slot2; }, __slot2)
 
110
#endif
 
111
#endif
 
112
 
 
113
/* C builtin types.
 
114
 */
 
115
#if defined(__mipsn32__)
 
116
typedef long long __vaword;
 
117
#else
 
118
typedef long __vaword;
 
119
#endif
 
120
 
 
121
enum __VAtype
 
122
{
 
123
  __VAvoid,
 
124
  __VAchar,
 
125
  __VAschar,
 
126
  __VAuchar,
 
127
  __VAshort,
 
128
  __VAushort,
 
129
  __VAint,
 
130
  __VAuint,
 
131
  __VAlong,
 
132
  __VAulong,
 
133
  __VAlonglong,
 
134
  __VAulonglong,
 
135
  __VAfloat,
 
136
  __VAdouble,
 
137
  __VAvoidp,
 
138
  __VAstruct
 
139
};
 
140
 
 
141
enum __VA_alist_flags
 
142
{
 
143
 
 
144
  /* how to return structs */
 
145
  /* There are basically 3 ways to return structs:
 
146
   * a. The called function returns a pointer to static data. Not reentrant.
 
147
   * b. The caller passes the return structure address in a dedicated register
 
148
   *    or as a first (or last), invisible argument. The called function stores
 
149
   *    its result there.
 
150
   * c. Like b, and the called function also returns the return structure
 
151
   *    address in the return value register. (This is not very distinguishable
 
152
   *    from b.)
 
153
   * Independently of this,
 
154
   * r. small structures (<= 4 or <= 8 bytes) may be returned in the return
 
155
   *    value register(s), or
 
156
   * m. even small structures are passed in memory.
 
157
   */
 
158
  /* gcc-2.6.3 employs the following strategy:
 
159
   *   - If PCC_STATIC_STRUCT_RETURN is defined in the machine description
 
160
   *     it uses method a, else method c.
 
161
   *   - If flag_pcc_struct_return is set (either by -fpcc-struct-return or if
 
162
   *     DEFAULT_PCC_STRUCT_RETURN is defined to 1 in the machine description)
 
163
   *     it uses method m, else (either by -freg-struct-return or if
 
164
   *     DEFAULT_PCC_STRUCT_RETURN is defined to 0 in the machine description)
 
165
   *     method r.
 
166
   */
 
167
  __VA_PCC_STRUCT_RETURN        = 1<<0, /* a: need to copy the struct */
 
168
  __VA_SMALL_STRUCT_RETURN      = 1<<1, /* r: special case for small structs */
 
169
  __VA_GCC_STRUCT_RETURN        = 1<<2, /* consider 8 byte structs as small */
 
170
#if defined(__sparc__) && !defined(__sparc64__)
 
171
  __VA_SUNCC_STRUCT_RETURN      = 1<<3,
 
172
  __VA_SUNPROCC_STRUCT_RETURN   = 1<<4,
 
173
#else
 
174
  __VA_SUNCC_STRUCT_RETURN      = 0,
 
175
  __VA_SUNPROCC_STRUCT_RETURN   = 0,
 
176
#endif
 
177
#if defined(__i386__)
 
178
  __VA_NEXTGCC_STRUCT_RETURN    = 1<<3,
 
179
  __VA_MSVC_STRUCT_RETURN       = 1<<4,
 
180
#endif
 
181
#if defined(__hppa__)
 
182
  __VA_OLDGCC_STRUCT_RETURN     = 1<<3,
 
183
#endif
 
184
  /* the default way to return structs */
 
185
  /* This choice here is based on the assumption that the function you are
 
186
   * going to call has been compiled with the same compiler you are using to
 
187
   * include this file.
 
188
   * If you want to call functions with another struct returning convention,
 
189
   * just  #define __VA_STRUCT_RETURN ...
 
190
   * before or after #including <vacall.h>.
 
191
   */
 
192
#ifndef __VA_STRUCT_RETURN
 
193
  __VA_STRUCT_RETURN            =
 
194
#if defined(__sparc__) && !defined(__sparc64__) && defined(sun) && defined(__SUNPRO_C) /* SUNWspro cc */
 
195
                                  __VA_SUNPROCC_STRUCT_RETURN,
 
196
#else
 
197
#if defined(__PCC_STRUCT_RETURN__) /* defined through configure, see above */
 
198
                                  __VA_PCC_STRUCT_RETURN,
 
199
#else
 
200
#if defined(__SMALL_STRUCT_RETURN__) || defined(__mipsn32__) || defined(__mips64__) || defined(__ARMEL__)/* defined through configure, see above */
 
201
                                  __VA_SMALL_STRUCT_RETURN |
 
202
#endif
 
203
#if defined(__GNUC__)
 
204
                                  __VA_GCC_STRUCT_RETURN |
 
205
#endif
 
206
#if defined(__i386__) && defined(NeXT) && defined(__GNUC__) /* NeXT gcc-2.5.8 */
 
207
                                  __VA_NEXTGCC_STRUCT_RETURN |
 
208
#endif
 
209
#if defined(__i386__) && defined(_MSC_VER) /* MSVC 4.0 */
 
210
                                  __VA_MSVC_STRUCT_RETURN |
 
211
#endif
 
212
#if defined(__hppa__) && defined(__GNUC__) && (__GNUC__ < 3) && (__GNUC_MINOR__ < 7)
 
213
                                  __VA_OLDGCC_STRUCT_RETURN |
 
214
#endif
 
215
                                  0,
 
216
#endif
 
217
#endif
 
218
#endif
 
219
 
 
220
  /* how to return floats */
 
221
#if defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__))
 
222
  __VA_SUNCC_FLOAT_RETURN       = 1<<5,
 
223
#endif
 
224
#if defined(__m68k__)
 
225
  __VA_FREG_FLOAT_RETURN        = 1<<6,
 
226
#endif
 
227
  /* the default way to return floats */
 
228
  /* This choice here is based on the assumption that the function you are
 
229
   * going to call has been compiled with the same compiler you are using to
 
230
   * include this file.
 
231
   * If you want to call functions with another float returning convention,
 
232
   * just  #define __VA_FLOAT_RETURN ...
 
233
   * before or after #including <vacall.h>.
 
234
   */
 
235
#ifndef __VA_FLOAT_RETURN
 
236
#if (defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__))) && !defined(__GNUC__) && defined(sun) && !defined(__SUNPRO_C)  /* sun cc */
 
237
  __VA_FLOAT_RETURN             = __VA_SUNCC_FLOAT_RETURN,
 
238
#elif (defined(__m68k__) && !defined(__IREG_FLOAT_RETURN__))
 
239
  __VA_FLOAT_RETURN             = __VA_FREG_FLOAT_RETURN,
 
240
#else
 
241
  __VA_FLOAT_RETURN             = 0,
 
242
#endif
 
243
#endif
 
244
 
 
245
  /* how to pass structs */
 
246
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__)
 
247
  __VA_SGICC_STRUCT_ARGS        = 1<<7,
 
248
#endif
 
249
#if defined(__powerpc__) && !defined(__powerpc64__)
 
250
  __VA_AIXCC_STRUCT_ARGS        = 1<<7,
 
251
#endif
 
252
  /* the default way to pass floats */
 
253
  /* This choice here is based on the assumption that the function you are
 
254
   * going to call has been compiled with the same compiler you are using to
 
255
   * include this file.
 
256
   * If you want to call functions with another float passing convention,
 
257
   * just  #define __VA_STRUCT_ARGS ...
 
258
   * before or after #including <vacall.h>.
 
259
   */
 
260
#ifndef __VA_STRUCT_ARGS
 
261
#if (defined(__mips__) || defined(__mipsn32__) || defined(__mips64__)) && !defined(__GNUC__) /* SGI mips cc */
 
262
  __VA_STRUCT_ARGS              = __VA_SGICC_STRUCT_ARGS,
 
263
#else
 
264
#if defined(__powerpc__) && !defined(__powerpc64__) && defined(_AIX) && !defined(__GNUC__) /* AIX cc, xlc */
 
265
  __VA_STRUCT_ARGS              = __VA_AIXCC_STRUCT_ARGS,
 
266
#else
 
267
  __VA_STRUCT_ARGS              = 0,
 
268
#endif
 
269
#endif
 
270
#endif
 
271
 
 
272
  /* how to pass floats */
 
273
  /* ANSI C compilers and GNU gcc pass floats as floats.
 
274
   * K&R C compilers pass floats as doubles. We don't support them any more.
 
275
   */
 
276
  __VA_ANSI_FLOAT_ARGS          = 0,    /* pass floats as floats */
 
277
 
 
278
  /* how to pass and return small integer arguments */
 
279
  __VA_ANSI_INTEGERS            = 0, /* no promotions */
 
280
  __VA_TRADITIONAL_INTEGERS     = 0, /* promote [u]char, [u]short to [u]int */
 
281
  /* Fortunately these two methods are compatible. Our macros work with both. */
 
282
 
 
283
  /* stack cleanup policy */
 
284
  __VA_CDECL_CLEANUP            = 0, /* caller pops args after return */
 
285
  __VA_STDCALL_CLEANUP          = 1<<9, /* callee pops args before return */
 
286
                                     /* currently only supported on __i386__ */
 
287
#ifndef __VA_CLEANUP
 
288
  __VA_CLEANUP                  = __VA_CDECL_CLEANUP,
 
289
#endif
 
290
 
 
291
  /* These are for internal use only */
 
292
#if defined(__i386__) || defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__arm__) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__)
 
293
  __VA_REGISTER_STRUCT_RETURN   = 1<<10,
 
294
#endif
 
295
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)
 
296
  __VA_FLOAT_1                  = 1<<11,
 
297
  __VA_FLOAT_2                  = 1<<12,
 
298
#endif
 
299
#if defined(__mipsn32__) || defined(__mips64__)
 
300
  __VA_REGISTER_FLOATSTRUCT_RETURN      = 1<<13,
 
301
  __VA_REGISTER_DOUBLESTRUCT_RETURN     = 1<<14,
 
302
#endif
 
303
 
 
304
  __VA_flag_for_broken_compilers_that_dont_like_trailing_commas
 
305
};
 
306
 
 
307
/*
 
308
 * Definition of the `va_alist' type.
 
309
 */
 
310
typedef struct
 
311
{
 
312
  /* some va_... macros need these flags */
 
313
  int            flags;
 
314
  /* current pointer into the argument array */
 
315
  unsigned long  aptr;
 
316
  /* structure return pointer, return type, return type size */
 
317
  void*          raddr;
 
318
  enum __VAtype  rtype;
 
319
  unsigned long  rsize;
 
320
#if defined(__i386__) || (defined(__powerpc__) && !defined(__powerpc64__) && defined(__MACH__) && defined(__APPLE__))
 
321
  /* Filler word, needed if the numbers of words up to now in this structure */
 
322
  /* is odd (because on MSVC, alignof(double) = 8, normally = 4; similarly,  */
 
323
  /* on MacOS X, the Apple compiler has alignof(double) = 8 whereas the      */
 
324
  /* standard GCC has alignof(double) = 4.                                   */
 
325
  __vaword       filler1;
 
326
#endif
 
327
  /* temporary storage for return value */
 
328
  union {
 
329
    char                _char;
 
330
    signed char         _schar;
 
331
    unsigned char       _uchar;
 
332
    short               _short;
 
333
    unsigned short      _ushort;
 
334
    int                 _int;
 
335
    unsigned int        _uint;
 
336
    long                _long;
 
337
    unsigned long       _ulong;
 
338
#if !(defined(__mips64__) || defined(__alpha__) || defined(__powerpc64__)) && defined(HAVE_LONG_LONG_INT)
 
339
    long long           _longlong;
 
340
    unsigned long long  _ulonglong;
 
341
#endif
 
342
    float               _float;
 
343
    double              _double;
 
344
    void*               _ptr;
 
345
    __vaword            _words[2];
 
346
  }              tmp;
 
347
#if defined(__i386__) || defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__m88k__) || defined(__ia64__)
 
348
  void*          structraddr;
 
349
#endif
 
350
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__alpha__) || defined(__hppa__)
 
351
  long           memargptr;
 
352
#endif
 
353
#if defined(__hppa__)
 
354
  long           farg_offset;
 
355
  long           darg_offset;
 
356
  float          farg[4];
 
357
  double         darg[2];
 
358
#endif
 
359
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)
 
360
  int            anum;
 
361
  float          farg[2];
 
362
  double         darg[2];
 
363
#endif
 
364
#if defined(__mipsn32__) || defined(__mips64__)
 
365
  int            anum;
 
366
  float          farg[8];
 
367
  double         darg[8];
 
368
#endif
 
369
#if defined(__sparc64__)
 
370
  int            anum;
 
371
  float          farg[16];
 
372
  double         darg[16];
 
373
#endif
 
374
#if defined(__powerpc__) || defined(__powerpc64__)
 
375
  double*        memfargptr;
 
376
  double         farg[13];
 
377
#if !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
 
378
  __vaword       regarg[8];
 
379
  unsigned long  saptr;
 
380
  int            onstack;
 
381
#endif
 
382
#endif
 
383
#if defined(__s390__)
 
384
  float*         memfargptr;
 
385
  double*        memdargptr;
 
386
  float          farg[2];
 
387
  double         darg[2];
 
388
  __vaword       regarg[5];
 
389
  unsigned long  saptr;
 
390
  int            onstack;
 
391
#endif
 
392
#if defined(__ia64__)
 
393
  __vaword*      saptr;
 
394
  double*        memfargptr;
 
395
  double         farg[8];
 
396
#endif
 
397
#if defined(__x86_64__)
 
398
  double*        memfargptr;
 
399
  double         farg[8];
 
400
  __vaword*      memiargptr;
 
401
  __vaword       iarg[6];
 
402
#endif
 
403
} __va_alist;
 
404
 
 
405
typedef __va_alist* va_alist;
 
406
 
 
407
 
 
408
/*
 
409
 * Definition of the va_start_xxx macros.
 
410
 */
 
411
#define __VA_START_FLAGS  \
 
412
  __VA_STRUCT_RETURN | __VA_FLOAT_RETURN | __VA_STRUCT_ARGS | __VA_CLEANUP
 
413
#define __va_start(LIST,RETTYPE)  \
 
414
  ((LIST)->flags = __VA_START_FLAGS,                                    \
 
415
   (LIST)->rtype = (RETTYPE)                                            \
 
416
  )
 
417
#define va_start_void(LIST)      __va_start(LIST,__VAvoid)
 
418
#define va_start_char(LIST)      __va_start(LIST,__VAchar)
 
419
#define va_start_schar(LIST)     __va_start(LIST,__VAschar)
 
420
#define va_start_uchar(LIST)     __va_start(LIST,__VAuchar)
 
421
#define va_start_short(LIST)     __va_start(LIST,__VAshort)
 
422
#define va_start_ushort(LIST)    __va_start(LIST,__VAushort)
 
423
#define va_start_int(LIST)       __va_start(LIST,__VAint)
 
424
#define va_start_uint(LIST)      __va_start(LIST,__VAuint)
 
425
#define va_start_long(LIST)      __va_start(LIST,__VAlong)
 
426
#define va_start_ulong(LIST)     __va_start(LIST,__VAulong)
 
427
#define va_start_longlong(LIST)  __va_start(LIST,__VAlonglong)
 
428
#define va_start_ulonglong(LIST) __va_start(LIST,__VAulonglong)
 
429
#define va_start_float(LIST)     __va_start(LIST,__VAfloat)
 
430
#define va_start_double(LIST)    __va_start(LIST,__VAdouble)
 
431
#define va_start_ptr(LIST,TYPE)  __va_start(LIST,__VAvoidp)
 
432
 
 
433
/*
 
434
 * va_start_struct: Preparing structure return.
 
435
 */
 
436
#define va_start_struct(LIST,TYPE,TYPE_SPLITTABLE)  \
 
437
  _va_start_struct(LIST,sizeof(TYPE),__VA_alignof(TYPE),TYPE_SPLITTABLE)
 
438
/* _va_start_struct() is like va_start_struct(), except that you pass
 
439
 * the type's size and alignment instead of the type itself.
 
440
 */
 
441
#define _va_start_struct(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
 
442
  (__va_start(LIST,__VAstruct),                                         \
 
443
   (LIST)->rsize = (TYPE_SIZE),                                         \
 
444
   ((LIST)->flags & __VA_SUNPROCC_STRUCT_RETURN                         \
 
445
    ? __va_start_struct2(LIST)                                          \
 
446
    : ((LIST)->flags & (__VA_PCC_STRUCT_RETURN | __VA_SUNCC_STRUCT_RETURN) \
 
447
       ? ((TYPE_SIZE) <= sizeof(__va_struct_buffer) || __va_error2(TYPE_SIZE), \
 
448
          (LIST)->raddr = &__va_struct_buffer,                          \
 
449
          0                                                             \
 
450
         )                                                              \
 
451
       : (((LIST)->flags & __VA_SMALL_STRUCT_RETURN)                    \
 
452
          && __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)     \
 
453
          ? ((LIST)->raddr = &(LIST)->tmp,                              \
 
454
             __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE) \
 
455
            )                                                           \
 
456
          : __va_start_struct2(LIST)                                    \
 
457
  ))  )  )
 
458
/* Determines whether a structure is returned in registers,
 
459
 * depending on its size and its word-splittable flag.
 
460
 */
 
461
#if (defined(__i386__) && defined(_WIN32))
 
462
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
 
463
  ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4             \
 
464
   || ((TYPE_SIZE) == 8                                                 \
 
465
       && (((LIST)->flags & __VA_MSVC_STRUCT_RETURN)                    \
 
466
           || ((TYPE_SPLITTABLE)                                        \
 
467
               && ((LIST)->flags & __VA_GCC_STRUCT_RETURN)              \
 
468
  )   )   )   )
 
469
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
 
470
 * and the struct will actually be returned in registers.
 
471
 */
 
472
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
 
473
  ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
 
474
#endif
 
475
#if (defined(__i386__) && !defined(_WIN32)) || defined(__m68k__) || (defined(__arm__) && !defined(__ARMEL__)) || (defined(__powerpc__) && !defined(__powerpc64__)) || defined(__convex__) || defined(__s390__)
 
476
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
 
477
  ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4             \
 
478
   || ((TYPE_SIZE) == 8 && (TYPE_SPLITTABLE)                            \
 
479
       && ((LIST)->flags & __VA_GCC_STRUCT_RETURN)                      \
 
480
  )   )
 
481
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
 
482
 * and the struct will actually be returned in registers.
 
483
 */
 
484
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
 
485
  ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
 
486
#endif
 
487
 
 
488
#if defined(__ARMEL__)
 
489
/* structs of size 3 also will be returned in register */
 
490
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
 
491
    ((TYPE_SIZE) <= 4)
 
492
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
 
493
 * and the struct will actually be returned in registers.
 
494
 */
 
495
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
 
496
  ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
 
497
#endif
 
498
#if defined(__alpha__)
 
499
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
 
500
  ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8 \
 
501
   || ((TYPE_SIZE) == 16 && (TYPE_SPLITTABLE)                           \
 
502
       && ((LIST)->flags & __VA_GCC_STRUCT_RETURN)                      \
 
503
  )   )
 
504
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
 
505
 * and the struct will actually be returned in registers.
 
506
 */
 
507
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
 
508
  ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN, 0)
 
509
#endif
 
510
#if defined(__hppa__)
 
511
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
 
512
  ((LIST)->flags & __VA_OLDGCC_STRUCT_RETURN                            \
 
513
   ? ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4)         \
 
514
   : ((TYPE_SIZE) <= 8)                                                 \
 
515
  )
 
516
/* Test both __VA_OLDGCC_STRUCT_RETURN and __VA_SMALL_STRUCT_RETURN at run time. */
 
517
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
 
518
  0
 
519
#endif
 
520
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__m88k__)
 
521
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
 
522
  ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4)
 
523
/* Test __VA_SMALL_STRUCT_RETURN instead of __VA_REGISTER_STRUCT_RETURN. */
 
524
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)
 
525
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
 
526
  ((LIST)->anum++,                                                      \
 
527
   0                                                                    \
 
528
  )
 
529
#else
 
530
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
 
531
  0
 
532
#endif
 
533
#endif
 
534
#if defined(__mipsn32__) || defined(__mips64__)
 
535
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
 
536
  ((LIST)->flags & __VA_GCC_STRUCT_RETURN                               \
 
537
   ? ((TYPE_SIZE) == 1 || (TYPE_SIZE) == 2 || (TYPE_SIZE) == 4 || (TYPE_SIZE) == 8) \
 
538
   : ((TYPE_SIZE) <= 16)                                                \
 
539
  )
 
540
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
 
541
 * and the struct will actually be returned in registers. Also turn on
 
542
 * __VA_REGISTER_FLOATSTRUCT_RETURN or __VA_REGISTER_DOUBLESTRUCT_RETURN if
 
543
 * the struct will be returned in floating-point registers.
 
544
 */
 
545
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
 
546
  ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN,                                \
 
547
   (TYPE_ALIGN) == sizeof(float) && (TYPE_SPLITTABLE)                           \
 
548
    && ((TYPE_SIZE) == sizeof(float) || (TYPE_SIZE) == 2*sizeof(float))         \
 
549
    && ((LIST)->flags |= __VA_REGISTER_FLOATSTRUCT_RETURN),                     \
 
550
   (TYPE_ALIGN) == sizeof(double) && (TYPE_SPLITTABLE)                          \
 
551
    && ((TYPE_SIZE) == sizeof(double) || (TYPE_SIZE) == 2*sizeof(double))       \
 
552
    && ((LIST)->flags |= __VA_REGISTER_DOUBLESTRUCT_RETURN),                    \
 
553
   0)
 
554
#endif
 
555
#if defined(__powerpc64__)
 
556
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
 
557
  0
 
558
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
 
559
  0
 
560
#endif
 
561
#if defined(__sparc64__) || defined(__ia64__)
 
562
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
 
563
  ((TYPE_SIZE) <= 32)
 
564
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
 
565
 * and the struct will actually be returned in registers.
 
566
 */
 
567
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
 
568
  ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN,                                \
 
569
   0)
 
570
#endif
 
571
#if defined(__x86_64__)
 
572
#define __va_reg_struct_return(LIST,TYPE_SIZE,TYPE_SPLITTABLE)  \
 
573
  ((TYPE_SIZE) <= 16)
 
574
/* Turn on __VA_REGISTER_STRUCT_RETURN if __VA_SMALL_STRUCT_RETURN was set
 
575
 * and the struct will actually be returned in registers.
 
576
 */
 
577
#define __va_start_struct1(LIST,TYPE_SIZE,TYPE_ALIGN,TYPE_SPLITTABLE)  \
 
578
  ((LIST)->flags |= __VA_REGISTER_STRUCT_RETURN,                                \
 
579
   0)
 
580
#endif
 
581
/*
 
582
 * Preparing structure return in memory.
 
583
 */
 
584
#if defined(__i386__)
 
585
/* Return structure pointer is passed in a special register or as first arg. */
 
586
#define __va_start_struct2(LIST)  \
 
587
  ((LIST)->flags & __VA_NEXTGCC_STRUCT_RETURN                           \
 
588
   ? ((LIST)->raddr = (LIST)->structraddr, 0)    /* special register */ \
 
589
   : ((LIST)->raddr = *(void* *)((LIST)->aptr),         /* first arg */ \
 
590
      (LIST)->aptr += sizeof(void*),                                    \
 
591
      0                                                                 \
 
592
  )  )
 
593
#endif
 
594
#if defined(__alpha__) || defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__)  || defined(__s390__)
 
595
/* Return structure pointer is passed as first arg. */
 
596
#define __va_start_struct2(LIST)  \
 
597
  ((LIST)->raddr = *(void* *)((LIST)->aptr),                            \
 
598
   (LIST)->aptr += sizeof(void*),                                       \
 
599
   0                                                                    \
 
600
  )
 
601
#endif
 
602
#if defined(__mips__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__)
 
603
/* Return structure pointer is passed as first arg. */
 
604
#define __va_start_struct2(LIST)  \
 
605
  ((LIST)->raddr = *(void* *)((LIST)->aptr),                            \
 
606
   (LIST)->aptr += sizeof(void*),                                       \
 
607
   (LIST)->anum++,                                                      \
 
608
   0                                                                    \
 
609
  )
 
610
#endif
 
611
#if defined(__x86_64__)
 
612
/* Return structure pointer is passed as first arg. */
 
613
#define __va_start_struct2(LIST)  \
 
614
  ((LIST)->raddr = (void *)(*(LIST)->memiargptr++),                     \
 
615
   0                                                                    \
 
616
  )
 
617
#endif
 
618
#if defined(__m68k__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__m88k__) || defined(__ia64__)
 
619
/* Return structure pointer is passed in a special register. */
 
620
#define __va_start_struct2(LIST)  \
 
621
  ((LIST)->raddr = (LIST)->structraddr, 0)
 
622
#endif
 
623
 
 
624
 
 
625
/*
 
626
 * Definition of the va_arg_xxx macros.
 
627
 */
 
628
 
 
629
/* Padding of non-struct arguments. */
 
630
#define __va_argsize(TYPE_SIZE)  \
 
631
  (((TYPE_SIZE) + sizeof(__vaword)-1) & -(long)sizeof(__vaword))
 
632
#if defined(__i386__) || defined(__m68k__) || (defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__alpha__) || defined(__arm__) || (defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__)
 
633
/* args grow up */
 
634
/* small structures < 1 word are adjusted depending on compiler */
 
635
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
636
  ((LIST)->aptr += __va_argsize(TYPE_SIZE),                             \
 
637
   (LIST)->aptr - __va_argsize(TYPE_SIZE)                               \
 
638
  )
 
639
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
640
  ((LIST)->aptr += __va_argsize(TYPE_SIZE),                             \
 
641
   (LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword)                       \
 
642
                   ? (TYPE_SIZE)                                        \
 
643
                   : __va_argsize(TYPE_SIZE)                            \
 
644
                  )                                                     \
 
645
  )
 
646
#endif
 
647
#if defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
 
648
/* args grow up */
 
649
/* small structures < 1 word are adjusted depending on compiler */
 
650
/* Also make sure we switch to the stack pointer after 8 args */
 
651
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
652
  ((((LIST)->onstack == 0 && (LIST)->aptr >= (long)&(LIST)->regarg[8])  \
 
653
    ? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0),           \
 
654
   (LIST)->aptr += __va_argsize(TYPE_SIZE),                             \
 
655
   (LIST)->aptr - __va_argsize(TYPE_SIZE)                               \
 
656
  )
 
657
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
658
  ((((LIST)->onstack == 0 && (LIST)->aptr >= (long)&(LIST)->regarg[8])  \
 
659
    ? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0),           \
 
660
   (LIST)->aptr += __va_argsize(TYPE_SIZE),                             \
 
661
   (LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword)                       \
 
662
                   ? (TYPE_SIZE)                                        \
 
663
                   : __va_argsize(TYPE_SIZE)                            \
 
664
                  )                                                     \
 
665
  )
 
666
#endif
 
667
#if defined(__s390__)
 
668
/* args grow up */
 
669
/* small structures < 1 word are adjusted depending on compiler */
 
670
/* Also make sure we switch to the stack pointer after 5 args */
 
671
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
672
  ((((LIST)->onstack == 0 && (LIST)->aptr >= (long)&(LIST)->regarg[5])  \
 
673
    ? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0),           \
 
674
   (LIST)->aptr += __va_argsize(TYPE_SIZE),                             \
 
675
   (LIST)->aptr - __va_argsize(TYPE_SIZE)                               \
 
676
  )
 
677
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
678
  (((((LIST)->onstack == 0 && ((LIST)->aptr >= (long)&(LIST)->regarg[5])) \
 
679
   || ((TYPE_SIZE) > sizeof(__vaword) && (LIST)->aptr >= (long)&(LIST)->regarg[4])) \
 
680
    ? ((LIST)->onstack=1, (LIST)->aptr = (LIST)->saptr) : 0),           \
 
681
   (LIST)->aptr += __va_argsize(TYPE_SIZE),                             \
 
682
   (LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword)                       \
 
683
                   ? (TYPE_SIZE)                                        \
 
684
                   : __va_argsize(TYPE_SIZE)                            \
 
685
                  )                                                     \
 
686
  )
 
687
#endif
 
688
#if defined(__mipsn32__) || defined(__mips64__) || defined(__sparc64__)
 
689
/* args grow up */
 
690
/* small structures < 1 word are adjusted depending on compiler */
 
691
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
692
  ((LIST)->anum += __va_argsize(TYPE_SIZE)/sizeof(__vaword),            \
 
693
   (LIST)->aptr += __va_argsize(TYPE_SIZE),                             \
 
694
   (LIST)->aptr - __va_argsize(TYPE_SIZE)                               \
 
695
  )
 
696
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
697
  ((LIST)->anum += __va_argsize(TYPE_SIZE)/sizeof(__vaword),            \
 
698
   (LIST)->aptr += __va_argsize(TYPE_SIZE),                             \
 
699
   (LIST)->aptr - ((TYPE_SIZE) < sizeof(__vaword)                       \
 
700
                   ? (TYPE_SIZE)                                        \
 
701
                   : __va_argsize(TYPE_SIZE)                            \
 
702
                  )                                                     \
 
703
  )
 
704
#endif
 
705
#if defined(__hppa__)
 
706
/* args grow down */
 
707
#define __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
708
  ((LIST)->aptr = (LIST)->aptr - __va_argsize(TYPE_SIZE),               \
 
709
   ((TYPE_SIZE) > 4 && ((LIST)->aptr &= -8)),                           \
 
710
   (LIST)->aptr                                                         \
 
711
  )
 
712
#define __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
713
  ((LIST)->aptr = (LIST)->aptr - __va_argsize(TYPE_SIZE),               \
 
714
   ((TYPE_SIZE) > 4 && ((LIST)->aptr &= -8)),                           \
 
715
   (LIST)->aptr + ((-(TYPE_SIZE)) & 3)                                  \
 
716
  )
 
717
#endif
 
718
#if defined(__i386__) || defined(__alpha__) || defined(__ia64__) || defined(__ARMEL__)
 
719
/* little endian -> small args < 1 word are adjusted to the left */
 
720
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
721
  __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)
 
722
#endif
 
723
#if defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__hppa__) || (defined(__arm__) && !defined(__ARMEL__)) || defined(__powerpc__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__s390__)
 
724
/* big endian -> small args < 1 word are adjusted to the right */
 
725
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
726
  __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)
 
727
#endif
 
728
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)
 
729
/* big endian -> small args < 1 word are adjusted to the right */
 
730
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
731
  ((LIST)->anum++, __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN))
 
732
#endif
 
733
#if defined(__x86_64__)
 
734
/* the first 6 argument words are passed in registers */
 
735
#define __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
736
  ((LIST)->memiargptr + ((TYPE_SIZE) + sizeof(__vaword)-1) / sizeof(__vaword) <= &(LIST)->iarg[6] \
 
737
   ? ((LIST)->memiargptr += ((TYPE_SIZE) + sizeof(__vaword)-1) / sizeof(__vaword), \
 
738
      (LIST)->memiargptr - ((TYPE_SIZE) + sizeof(__vaword)-1) / sizeof(__vaword) \
 
739
     )                                                                  \
 
740
   : (void*)__va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)            \
 
741
  )
 
742
#endif
 
743
#define __va_arg(LIST,TYPE)  \
 
744
  *(TYPE*)__va_arg_adjusted(LIST,sizeof(TYPE),__VA_alignof(TYPE))
 
745
 
 
746
/* Integer arguments. */
 
747
 
 
748
#define va_arg_char(LIST)       __va_arg(LIST,char)
 
749
#define va_arg_schar(LIST)      __va_arg(LIST,signed char)
 
750
#define va_arg_uchar(LIST)      __va_arg(LIST,unsigned char)
 
751
#define va_arg_short(LIST)      __va_arg(LIST,short)
 
752
#define va_arg_ushort(LIST)     __va_arg(LIST,unsigned short)
 
753
#define va_arg_int(LIST)        __va_arg(LIST,int)
 
754
#define va_arg_uint(LIST)       __va_arg(LIST,unsigned int)
 
755
#define va_arg_long(LIST)       __va_arg(LIST,long)
 
756
#define va_arg_ulong(LIST)      __va_arg(LIST,unsigned long)
 
757
 
 
758
#if defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__powerpc64__) || defined(__ia64__) || defined(__x86_64__)
 
759
/* `long long' and `long' are identical. */
 
760
#define va_arg_longlong         va_arg_long
 
761
#define va_arg_ulonglong        va_arg_ulong
 
762
#elif defined(__mipsn32__)
 
763
/* `long long' fits in __vaword. */
 
764
#define va_arg_longlong(LIST)   __va_arg(LIST,long long)
 
765
#define va_arg_ulonglong(LIST)  __va_arg(LIST,unsigned long long)
 
766
#elif defined(__i386__) || defined(__m68k__) || defined(__mips__) || (defined(__sparc__) && !defined(__sparc64__)) || defined(__hppa__) || defined(__arm__) || defined(__powerpc__) || defined(__m88k__) || defined(__convex__) || defined(__s390__)
 
767
/* `long long's are passed embedded on the arg stack. */
 
768
#define va_arg_longlong(LIST)   __va_arg_longlong(LIST,long long)
 
769
#define va_arg_ulonglong(LIST)  __va_arg_longlong(LIST,unsigned long long)
 
770
#if defined(__i386__) || defined(__m68k__) || (defined(__arm__) && !defined(__ARMEL__)) || (defined(__powerpc__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__convex__)
 
771
/* `long long's are (at most) word-aligned. */
 
772
#define __va_arg_longlong(LIST,TYPE)    __va_arg(LIST,TYPE)
 
773
#endif
 
774
#if defined(__mips__) || (defined(__powerpc__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))) || defined(__m88k__) || defined(__ARMEL__)
 
775
/* `long long's have alignment 8. */
 
776
#define __va_arg_longlong(LIST,TYPE)                                    \
 
777
  ((LIST)->aptr = (((LIST)->aptr+__VA_alignof(TYPE)-1) & -(long)__VA_alignof(TYPE)), \
 
778
   __va_arg(LIST,TYPE))
 
779
#endif
 
780
#if (defined(__sparc__) && !defined(__sparc64__)) || defined(__s390__)
 
781
/* Within the arg stack, the alignment is only 4, not 8. */
 
782
/* Beware against unaligned accesses! */
 
783
#define __va_arg_longlong(LIST,TYPE)                                    \
 
784
  ((LIST)->tmp._words[0] = ((__vaword*)((LIST)->aptr))[0],              \
 
785
   (LIST)->tmp._words[1] = ((__vaword*)((LIST)->aptr))[1],              \
 
786
   (LIST)->aptr += sizeof(TYPE),                                        \
 
787
   (TYPE)((LIST)->tmp._longlong)                                        \
 
788
  )
 
789
#endif
 
790
#if defined(__hppa__)
 
791
/* `long long's have alignment 8. */
 
792
#define __va_arg_longlong(LIST,TYPE)                                    \
 
793
  ((LIST)->aptr = ((LIST)->aptr & -(long)__VA_alignof(TYPE)),           \
 
794
   __va_arg(LIST,TYPE))
 
795
#endif
 
796
#endif
 
797
 
 
798
/* Floating point arguments. */
 
799
 
 
800
#if defined(__i386__) || defined(__m68k__) || defined(__mipsn32__) || defined(__mips64__) || defined(__sparc__) || defined(__sparc64__) || defined(__alpha__) || (defined(__arm__) && !defined(__ARMEL__)) || defined(__powerpc__) || defined(__powerpc64__) || defined(__convex__) || defined(__ia64__) || defined(__x86_64__) || defined(__s390__)
 
801
#define __va_align_double(LIST)
 
802
#endif
 
803
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__) || defined(__m88k__) || defined(__ARMEL__)
 
804
/* __VA_alignof(double) > sizeof(__vaword) */
 
805
#define __va_align_double(LIST)  \
 
806
  (LIST)->aptr = ((LIST)->aptr + sizeof(double)-1) & -(long)sizeof(double),
 
807
#endif
 
808
#if defined(__hppa__)
 
809
#define __va_align_double(LIST)  \
 
810
  (LIST)->aptr = (LIST)->aptr & -(long)sizeof(double),
 
811
#endif
 
812
 
 
813
#if defined(__sparc__) && !defined(__sparc64__)
 
814
/* Beware against unaligned `double' accesses! */
 
815
#define va_arg_double(LIST)  \
 
816
  (__va_align_double(LIST)                                              \
 
817
   (LIST)->tmp._words[0] = ((__vaword*)((LIST)->aptr))[0],              \
 
818
   (LIST)->tmp._words[1] = ((__vaword*)((LIST)->aptr))[1],              \
 
819
   (LIST)->aptr += sizeof(double),                                      \
 
820
   (LIST)->tmp._double                                                  \
 
821
  )
 
822
#endif
 
823
#if defined(__alpha__)
 
824
/* The first 6 floating point registers have been stored in another place. */
 
825
#define va_arg_double(LIST)  \
 
826
  (((LIST)->aptr += sizeof(double)) <= (LIST)->memargptr                \
 
827
   ? *(double*)((LIST)->aptr - sizeof(double) - 6*sizeof(double))       \
 
828
   : *(double*)((LIST)->aptr - sizeof(double))                          \
 
829
  )
 
830
#define va_arg_float(LIST)  \
 
831
  (((LIST)->aptr += sizeof(double)) <= (LIST)->memargptr                \
 
832
   ? /* The first 6 args have been put into memory by "stt" instructions */\
 
833
     /* (see vacall-alpha.s!). Therefore load them as doubles. */       \
 
834
     /* When viewed as floats, the value will be the correct one. */    \
 
835
     (float)*(double*)((LIST)->aptr - sizeof(double) - 6*sizeof(double)) \
 
836
   : /* These args have been put into memory by "sts" instructions, */  \
 
837
     /* therefore load them as floats. */                               \
 
838
     *(float*)((LIST)->aptr - sizeof(double))                           \
 
839
  )
 
840
#endif
 
841
#if defined(__hppa__)
 
842
/* The first 4 float registers and the first 2 double registers are stored
 
843
 * elsewhere.
 
844
 */
 
845
#if 1 /* gcc-2.5.2 passes these args in general registers! A bug, I think. */
 
846
#define va_arg_float(LIST)  \
 
847
  (*(float*)((LIST)->aptr -= sizeof(float)))
 
848
#define va_arg_double(LIST)  \
 
849
  (__va_align_double(LIST)                                              \
 
850
   *(double*)((LIST)->aptr -= sizeof(double))                           \
 
851
  )
 
852
#else /* this would be correct if the args were passed in float registers. */
 
853
#define va_arg_float(LIST)  \
 
854
  (((LIST)->aptr -= sizeof(float)) >= (LIST)->memargptr                 \
 
855
   ? /* The first 4 float args are stored separately. */                \
 
856
     *(float*)((LIST)->aptr + (LIST)->farg_offset)                      \
 
857
   : *(float*)((LIST)->aptr)                                            \
 
858
  )
 
859
#define va_arg_double(LIST)  \
 
860
  (__va_align_double(LIST)                                              \
 
861
   (((LIST)->aptr -= sizeof(double)) >= (LIST)->memargptr               \
 
862
    ? /* The first 2 double args are stored separately. */              \
 
863
      *(double*)((LIST)->aptr + (LIST)->darg_offset)                    \
 
864
    : *(double*)((LIST)->aptr)                                          \
 
865
  ))
 
866
#endif
 
867
#endif
 
868
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)
 
869
/* The first 0,1,2 registers are stored elsewhere if they are floating-point
 
870
 * parameters.
 
871
 */
 
872
#define va_arg_float(LIST)  \
 
873
  ((LIST)->aptr += sizeof(float),                                       \
 
874
   (LIST)->anum++,                                                      \
 
875
   ((LIST)->anum == 1                                                   \
 
876
    ? ((LIST)->flags |= __VA_FLOAT_1, (LIST)->farg[0])                  \
 
877
    : ((LIST)->anum == 2 && ((LIST)->flags & __VA_FLOAT_1)              \
 
878
       ? (/* (LIST)->flags |= __VA_FLOAT_2, */ (LIST)->farg[1])         \
 
879
       : *(float*)((LIST)->aptr - sizeof(float))                        \
 
880
  ))  )
 
881
#define va_arg_double(LIST)  \
 
882
  (__va_align_double(LIST)                                              \
 
883
   (LIST)->aptr += sizeof(double),                                      \
 
884
   (LIST)->anum++,                                                      \
 
885
   ((LIST)->anum == 1                                                   \
 
886
    ? ((LIST)->flags |= __VA_FLOAT_1, (LIST)->darg[0])                  \
 
887
    : ((LIST)->anum == 2 && ((LIST)->flags & __VA_FLOAT_1)              \
 
888
       ? (/* (LIST)->flags |= __VA_FLOAT_2, */ (LIST)->darg[1])         \
 
889
       : *(double*)((LIST)->aptr - sizeof(double))                      \
 
890
  ))  )
 
891
#endif
 
892
#if defined(__mipsn32__) || defined(__mips64__)
 
893
/* The first 0,..,8 registers are stored elsewhere if they are floating-point
 
894
 * parameters.
 
895
 */
 
896
#define va_arg_float(LIST)  \
 
897
  (__va_align_double(LIST)                                              \
 
898
   (LIST)->aptr += sizeof(double),                                      \
 
899
   (++(LIST)->anum <= 8                                                 \
 
900
    ? (LIST)->farg[(LIST)->anum - 1]                                    \
 
901
    : *(float*)((LIST)->aptr - sizeof(double))                          \
 
902
  ))
 
903
#define va_arg_double(LIST)  \
 
904
  (__va_align_double(LIST)                                              \
 
905
   (LIST)->aptr += sizeof(double),                                      \
 
906
   (++(LIST)->anum <= 8                                                 \
 
907
    ? (LIST)->darg[(LIST)->anum - 1]                                    \
 
908
    : *(double*)((LIST)->aptr - sizeof(double))                         \
 
909
  ))
 
910
#endif
 
911
#if defined(__sparc64__)
 
912
/* The first 0,..,16 registers are stored elsewhere if they are floating-point
 
913
 * parameters.
 
914
 */
 
915
#define va_arg_float(LIST)  \
 
916
  (__va_align_double(LIST)                                              \
 
917
   (LIST)->aptr += sizeof(double),                                      \
 
918
   (++(LIST)->anum <= 16                                                \
 
919
    ? (LIST)->farg[(LIST)->anum - 1]                                    \
 
920
    : *(float*)((LIST)->aptr - sizeof(double))                          \
 
921
  ))
 
922
#define va_arg_double(LIST)  \
 
923
  (__va_align_double(LIST)                                              \
 
924
   (LIST)->aptr += sizeof(double),                                      \
 
925
   (++(LIST)->anum <= 16                                                \
 
926
    ? (LIST)->darg[(LIST)->anum - 1]                                    \
 
927
    : *(double*)((LIST)->aptr - sizeof(double))                         \
 
928
  ))
 
929
#endif
 
930
#if defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
 
931
/* The first 13 floating-point args have been stored elsewhere. */
 
932
#define va_arg_float(LIST)  \
 
933
  ((LIST)->aptr += sizeof(float),                                       \
 
934
   ((LIST)->memfargptr < &(LIST)->farg[13]                              \
 
935
    ? (float) *((LIST)->memfargptr++)                                   \
 
936
    : *(float*)((LIST)->aptr - sizeof(float))                           \
 
937
  ))
 
938
#define va_arg_double(LIST)  \
 
939
  (__va_align_double(LIST)                                              \
 
940
   (LIST)->aptr += sizeof(double),                                      \
 
941
   ((LIST)->memfargptr < &(LIST)->farg[13]                              \
 
942
    ? *((LIST)->memfargptr++)                                           \
 
943
    : *(double*)((LIST)->aptr - sizeof(double))                         \
 
944
  ))
 
945
#endif
 
946
#if defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
 
947
/* The first 8 floating-point args have been stored elsewhere. */
 
948
#define va_arg_float(LIST)  \
 
949
  ((LIST)->memfargptr < &(LIST)->farg[8]                                \
 
950
   ? (float) *((LIST)->memfargptr++)                                    \
 
951
   : ((LIST)->aptr = ((LIST)->onstack == 0                              \
 
952
                       ? ((LIST)->onstack=1, (LIST)->saptr)             \
 
953
                       : (LIST)->aptr                                   \
 
954
                      ),                                                \
 
955
      (LIST)->aptr += sizeof(float),                                    \
 
956
      *(float*)((LIST)->aptr - sizeof(float))                           \
 
957
  ))
 
958
#define va_arg_double(LIST)  \
 
959
  ((LIST)->memfargptr < &(LIST)->farg[8]                                \
 
960
    ? *((LIST)->memfargptr++)                                           \
 
961
    : ((LIST)->aptr = ((LIST)->onstack == 0                             \
 
962
                       ? ((LIST)->onstack=1, (LIST)->saptr)             \
 
963
                       : (LIST)->aptr                                   \
 
964
                      ),                                                \
 
965
       __va_align_double(LIST)                                          \
 
966
       (LIST)->aptr += sizeof(double),                                  \
 
967
       *(double*)((LIST)->aptr - sizeof(double))                        \
 
968
  ))
 
969
#endif
 
970
#if defined(__powerpc64__)
 
971
/* The first 13 floating-point args have been stored elsewhere. */
 
972
#define va_arg_float(LIST)  \
 
973
  ((LIST)->aptr += sizeof(__vaword),                                    \
 
974
   ((LIST)->memfargptr < &(LIST)->farg[13]                              \
 
975
    ? (float) *((LIST)->memfargptr++)                                   \
 
976
    : *(float*)((LIST)->aptr - sizeof(float))                           \
 
977
  ))
 
978
#define va_arg_double(LIST)  \
 
979
  (__va_align_double(LIST)                                              \
 
980
   (LIST)->aptr += sizeof(double),                                      \
 
981
   ((LIST)->memfargptr < &(LIST)->farg[13]                              \
 
982
    ? *((LIST)->memfargptr++)                                           \
 
983
    : *(double*)((LIST)->aptr - sizeof(double))                         \
 
984
  ))
 
985
#endif
 
986
#if defined(__s390__)
 
987
/* The first 2 floating-point args have been stored elsewhere. */
 
988
#define va_arg_float(LIST)  \
 
989
  ((LIST)->memfargptr < &(LIST)->farg[2]                                \
 
990
   ? (LIST)->memdargptr++, (float) *((LIST)->memfargptr++)              \
 
991
   : ((LIST)->aptr = ((LIST)->onstack == 0                              \
 
992
                       ? ((LIST)->onstack=1, (LIST)->saptr)             \
 
993
                       : (LIST)->aptr                                   \
 
994
                      ),                                                \
 
995
      (LIST)->aptr += sizeof(float),                                    \
 
996
      *(float*)((LIST)->aptr - sizeof(float))                           \
 
997
  ))
 
998
#define va_arg_double(LIST)  \
 
999
  ((LIST)->memdargptr < &(LIST)->darg[2]                                \
 
1000
    ? (LIST)->memfargptr++, *((LIST)->memdargptr++)                     \
 
1001
    : ((LIST)->aptr = ((LIST)->onstack == 0                             \
 
1002
                       ? ((LIST)->onstack=1, (LIST)->saptr)             \
 
1003
                       : (LIST)->aptr                                   \
 
1004
                      ),                                                \
 
1005
       __va_align_double(LIST)                                          \
 
1006
       (LIST)->aptr += sizeof(double),                                  \
 
1007
       *(double*)((LIST)->aptr - sizeof(double))                        \
 
1008
  ))
 
1009
#endif
 
1010
#if defined(__ia64__)
 
1011
/* The first 8 floating-point args have been stored elsewhere. */
 
1012
#define va_arg_float(LIST)  \
 
1013
  ((LIST)->aptr += sizeof(__vaword),                                    \
 
1014
   ((LIST)->memfargptr < &(LIST)->farg[8]                               \
 
1015
    ? (float) *((LIST)->memfargptr++)                                   \
 
1016
    : *(float*)((LIST)->aptr - sizeof(__vaword))                        \
 
1017
  ))
 
1018
#define va_arg_double(LIST)  \
 
1019
  (__va_align_double(LIST)                                              \
 
1020
   (LIST)->aptr += sizeof(double),                                      \
 
1021
   ((LIST)->memfargptr < &(LIST)->farg[8]                               \
 
1022
    ? *((LIST)->memfargptr++)                                           \
 
1023
    : *(double*)((LIST)->aptr - sizeof(double))                         \
 
1024
  ))
 
1025
#endif
 
1026
#if defined(__x86_64__)
 
1027
/* The first 8 floating-point args have been stored elsewhere. */
 
1028
#define va_arg_float(LIST)  \
 
1029
  ((LIST)->memfargptr < &(LIST)->farg[8]                                \
 
1030
   ? ((LIST)->memfargptr++,                                             \
 
1031
      *(float*)((LIST)->memfargptr - 1)                                 \
 
1032
     )                                                                  \
 
1033
   : ((LIST)->aptr += sizeof(__vaword),                                 \
 
1034
      *(float*)((LIST)->aptr - sizeof(__vaword))                        \
 
1035
  )  )
 
1036
#define va_arg_double(LIST)  \
 
1037
  ((LIST)->memfargptr < &(LIST)->farg[8]                                \
 
1038
   ? *(LIST)->memfargptr++                                              \
 
1039
   : ((LIST)->aptr += sizeof(__vaword),                                 \
 
1040
      *(double*)((LIST)->aptr - sizeof(__vaword))                       \
 
1041
  )  )
 
1042
#endif
 
1043
#ifndef va_arg_float
 
1044
#define va_arg_float(LIST)      __va_arg(LIST,float)
 
1045
#endif
 
1046
#ifndef va_arg_double
 
1047
#define va_arg_double(LIST)  \
 
1048
  (__va_align_double(LIST) __va_arg(LIST,double))
 
1049
#endif
 
1050
 
 
1051
/* Pointer arguments. */
 
1052
#define va_arg_ptr(LIST,TYPE)   __va_arg(LIST,TYPE)
 
1053
 
 
1054
/* Structure arguments. */
 
1055
#define va_arg_struct(LIST,TYPE)  \
 
1056
  *(TYPE*)__va_arg_struct(LIST,sizeof(TYPE),__VA_alignof(TYPE))
 
1057
/* _va_arg_struct() is like va_arg_struct(), except that you pass the type's
 
1058
 * size and alignment instead of the type and get the value's address instead
 
1059
 * of the value itself.
 
1060
 */
 
1061
#define _va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
1062
  (void*)__va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)
 
1063
/* Structure argument alignment. */
 
1064
#if defined(__i386__) && defined(_MSC_VER)
 
1065
/* In MSVC, doubles inside structures have alignment 8, i.e.
 
1066
 * __VA_alignof(double) = 8, but doubles (and also structures containing
 
1067
 * doubles) are passed on the stack with alignment 4. Looks really weird.
 
1068
 */
 
1069
#define __va_struct_alignment(TYPE_ALIGN)  \
 
1070
  ((TYPE_ALIGN) <= 4 ? (TYPE_ALIGN) : 4)
 
1071
#else
 
1072
#define __va_struct_alignment(TYPE_ALIGN)  \
 
1073
  (TYPE_ALIGN)
 
1074
#endif
 
1075
#define __va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
1076
  (LIST)->aptr = ((LIST)->aptr + __va_struct_alignment(TYPE_ALIGN)-1) & -(long)__va_struct_alignment(TYPE_ALIGN),
 
1077
#if defined(__i386__) || defined(__m68k__) || defined(__alpha__) || defined(__arm__) || defined(__powerpc64__) || defined(__m88k__) || defined(__convex__) || defined(__x86_64__)
 
1078
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
1079
  (__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN)                         \
 
1080
   __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN)                         \
 
1081
  )
 
1082
#endif
 
1083
#if defined(__mips__) && !defined(__mipsn32__) && !defined(__mips64__)
 
1084
/* small structures < 1 word are adjusted depending on compiler */
 
1085
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
1086
  (__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN)                         \
 
1087
   ((LIST)->flags & __VA_SGICC_STRUCT_ARGS                              \
 
1088
    ? /* SGI MIPS cc passes small structures left-adjusted, although big-endian! */\
 
1089
      __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)                  \
 
1090
    : /* SGI MIPS gcc passes small structures within the first four words left-    \
 
1091
       * adjusted, for compatibility with cc. But structures in memory are passed  \
 
1092
       * right-adjusted!! See gcc-2.6.3/config/mips/mips.c:function_arg().         \
 
1093
       */                                                                          \
 
1094
      ((LIST)->aptr < (LIST)->memargptr                                 \
 
1095
       ? __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)               \
 
1096
       : __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)              \
 
1097
  ))  )
 
1098
#endif
 
1099
#if defined(__mipsn32__) || defined(__mips64__)
 
1100
/* small structures < 1 word are adjusted depending on compiler */
 
1101
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
1102
  (__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN)                         \
 
1103
   ((LIST)->flags & __VA_SGICC_STRUCT_ARGS                              \
 
1104
    ? /* SGI MIPS cc passes small structures left-adjusted, although big-endian! */\
 
1105
      __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)                  \
 
1106
    : /* SGI MIPS gcc passes small structures right-adjusted. */        \
 
1107
      __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)                 \
 
1108
  ))
 
1109
#endif
 
1110
#if defined(__powerpc__) && !defined(__powerpc64__) && (defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
 
1111
/* small structures < 1 word are adjusted depending on compiler */
 
1112
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
1113
  (__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN)                         \
 
1114
   ((LIST)->flags & __VA_AIXCC_STRUCT_ARGS                              \
 
1115
    ? /* AIX cc and xlc pass small structures left-adjusted, although big-endian! */\
 
1116
      __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)                  \
 
1117
    : /* gcc passes small structures right-adjusted. */                 \
 
1118
      __va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)                 \
 
1119
  ))
 
1120
#endif
 
1121
#if defined(__powerpc__) && !defined(__powerpc64__) && !(defined(_AIX) || (defined(__MACH__) && defined(__APPLE__)))
 
1122
/* Structures are passed as pointers to caller-made local copies. */
 
1123
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
1124
  va_arg_ptr(LIST,void*)
 
1125
#endif
 
1126
#if defined(__sparc__) && !defined(__sparc64__)
 
1127
/* Structures are passed as pointers to caller-made local copies. */
 
1128
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
1129
  va_arg_ptr(LIST,void*)
 
1130
#endif
 
1131
#if defined(__sparc64__)
 
1132
/* Small structures are passed left-adjusted, although big-endian! */
 
1133
/* Big structures are passed as pointers to caller-made local copies. */
 
1134
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
1135
  ((TYPE_SIZE) <= 16                                                    \
 
1136
   ? (__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN)                      \
 
1137
      __va_arg_leftadjusted(LIST,TYPE_SIZE,TYPE_ALIGN))                 \
 
1138
   : va_arg_ptr(LIST,void*)                                             \
 
1139
  )
 
1140
#endif
 
1141
#if defined(__s390__)
 
1142
/* Structures <= 8 bytes are passed as embedded copies on the arg stack.
 
1143
 * Big structures are passed as pointers to caller-made local copies.
 
1144
 */
 
1145
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
1146
  ((TYPE_SIZE) != 1 && (TYPE_SIZE) != 2 && (TYPE_SIZE) != 4 && (TYPE_SIZE) != 8 \
 
1147
   ? va_arg_ptr(LIST,void*)                                             \
 
1148
   : (void*)__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)           \
 
1149
  )
 
1150
#endif
 
1151
#if defined(__hppa__)
 
1152
/* Structures <= 8 bytes are passed as embedded copies on the arg stack.
 
1153
 * Big structures are passed as pointers to caller-made local copies.
 
1154
 */
 
1155
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
1156
  ((TYPE_SIZE) > 8                                                      \
 
1157
   ? va_arg_ptr(LIST,void*)                                             \
 
1158
   : /* FIXME: gcc-2.6.3 passes structures <= 4 bytes in memory left-adjusted! ?? */\
 
1159
     (void*)__va_arg_rightadjusted(LIST,TYPE_SIZE,TYPE_ALIGN)           \
 
1160
  )
 
1161
#endif
 
1162
#if defined(__ia64__)
 
1163
/* Types larger than a word have 2-word alignment. */
 
1164
#define __va_arg_struct(LIST,TYPE_SIZE,TYPE_ALIGN)  \
 
1165
  (__va_align_struct(LIST,TYPE_SIZE,TYPE_ALIGN)                         \
 
1166
   ((TYPE_SIZE) > sizeof(__vaword) && (((__vaword*)(LIST)->aptr - (LIST)->saptr) & 1) ? (LIST)->aptr += sizeof(__vaword) : 0), \
 
1167
   __va_arg_adjusted(LIST,TYPE_SIZE,TYPE_ALIGN)                         \
 
1168
  )
 
1169
#endif
 
1170
 
 
1171
 
 
1172
/*
 
1173
 * Definition of the va_return_xxx macros.
 
1174
 */
 
1175
#define __va_return(LIST,RETTYPE)  \
 
1176
  (((LIST)->rtype == (RETTYPE)) || __va_error1((LIST)->rtype,RETTYPE))
 
1177
#define va_return_void(LIST)  \
 
1178
  __va_return(LIST,__VAvoid)
 
1179
#define va_return_char(LIST,VAL)  \
 
1180
  (__va_return(LIST,__VAchar), (LIST)->tmp._char = (VAL))
 
1181
#define va_return_schar(LIST,VAL)  \
 
1182
  (__va_return(LIST,__VAschar), (LIST)->tmp._schar = (VAL))
 
1183
#define va_return_uchar(LIST,VAL)  \
 
1184
  (__va_return(LIST,__VAuchar), (LIST)->tmp._uchar = (VAL))
 
1185
#define va_return_short(LIST,VAL)  \
 
1186
  (__va_return(LIST,__VAshort), (LIST)->tmp._short = (VAL))
 
1187
#define va_return_ushort(LIST,VAL)  \
 
1188
  (__va_return(LIST,__VAushort), (LIST)->tmp._ushort = (VAL))
 
1189
#define va_return_int(LIST,VAL)  \
 
1190
  (__va_return(LIST,__VAint), (LIST)->tmp._int = (VAL))
 
1191
#define va_return_uint(LIST,VAL)  \
 
1192
  (__va_return(LIST,__VAuint), (LIST)->tmp._uint = (VAL))
 
1193
#define va_return_long(LIST,VAL)  \
 
1194
  (__va_return(LIST,__VAlong), (LIST)->tmp._long = (VAL))
 
1195
#define va_return_ulong(LIST,VAL)  \
 
1196
  (__va_return(LIST,__VAulong), (LIST)->tmp._ulong = (VAL))
 
1197
#if defined(__mips64__) || defined(__sparc64__) || defined(__alpha__) || defined(__powerpc64__) || defined(__ia64__) || defined(__x86_64__)
 
1198
#define va_return_longlong(LIST,VAL)  \
 
1199
  (__va_return(LIST,__VAlonglong), (LIST)->tmp._long = (VAL))
 
1200
#define va_return_ulonglong(LIST,VAL)  \
 
1201
  (__va_return(LIST,__VAulonglong), (LIST)->tmp._ulong = (VAL))
 
1202
#else
 
1203
#define va_return_longlong(LIST,VAL)  \
 
1204
  (__va_return(LIST,__VAlonglong), (LIST)->tmp._longlong = (VAL))
 
1205
#define va_return_ulonglong(LIST,VAL)  \
 
1206
  (__va_return(LIST,__VAulonglong), (LIST)->tmp._ulonglong = (VAL))
 
1207
#endif
 
1208
#define va_return_float(LIST,VAL)  \
 
1209
  (__va_return(LIST,__VAfloat), (LIST)->tmp._float = (VAL))
 
1210
#define va_return_double(LIST,VAL)  \
 
1211
  (__va_return(LIST,__VAdouble), (LIST)->tmp._double = (VAL))
 
1212
#define va_return_ptr(LIST,TYPE,VAL)  \
 
1213
  (__va_return(LIST,__VAvoidp), (LIST)->tmp._ptr = (void*)(TYPE)(VAL))
 
1214
#define va_return_struct(LIST,TYPE,VAL)  \
 
1215
  (__va_return(LIST,__VAstruct), *(TYPE*)((LIST)->raddr) = (VAL))
 
1216
#define _va_return_struct(LIST,TYPE_SIZE,TYPE_ALIGN,VAL_ADDR)  \
 
1217
  (__va_return(LIST,__VAstruct),                                        \
 
1218
   __structcpy((void*)((LIST)->raddr),VAL_ADDR,TYPE_SIZE,TYPE_ALIGN)    \
 
1219
  )
 
1220
 
 
1221
 
 
1222
/* Determine whether a struct type is word-splittable, i.e. whether each of
 
1223
 * its components fit into a register.
 
1224
 * The entire computation is done at compile time.
 
1225
 */
 
1226
#define va_word_splittable_1(slot1)  \
 
1227
  (__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword))
 
1228
#define va_word_splittable_2(slot1,slot2)  \
 
1229
  ((__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword)) \
 
1230
   && (__va_offset2(slot1,slot2)/sizeof(__vaword) == (__va_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__vaword)) \
 
1231
  )
 
1232
#define va_word_splittable_3(slot1,slot2,slot3)  \
 
1233
  ((__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword)) \
 
1234
   && (__va_offset2(slot1,slot2)/sizeof(__vaword) == (__va_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__vaword)) \
 
1235
   && (__va_offset3(slot1,slot2,slot3)/sizeof(__vaword) == (__va_offset3(slot1,slot2,slot3)+sizeof(slot3)-1)/sizeof(__vaword)) \
 
1236
  )
 
1237
#define va_word_splittable_4(slot1,slot2,slot3,slot4)  \
 
1238
  ((__va_offset1(slot1)/sizeof(__vaword) == (__va_offset1(slot1)+sizeof(slot1)-1)/sizeof(__vaword)) \
 
1239
   && (__va_offset2(slot1,slot2)/sizeof(__vaword) == (__va_offset2(slot1,slot2)+sizeof(slot2)-1)/sizeof(__vaword)) \
 
1240
   && (__va_offset3(slot1,slot2,slot3)/sizeof(__vaword) == (__va_offset3(slot1,slot2,slot3)+sizeof(slot3)-1)/sizeof(__vaword)) \
 
1241
   && (__va_offset4(slot1,slot2,slot3,slot4)/sizeof(__vaword) == (__va_offset4(slot1,slot2,slot3,slot4)+sizeof(slot4)-1)/sizeof(__vaword)) \
 
1242
  )
 
1243
#define __va_offset1(slot1)  \
 
1244
  0
 
1245
#define __va_offset2(slot1,slot2)  \
 
1246
  ((__va_offset1(slot1)+sizeof(slot1)+__VA_alignof(slot2)-1) & -(long)__VA_alignof(slot2))
 
1247
#define __va_offset3(slot1,slot2,slot3)  \
 
1248
  ((__va_offset2(slot1,slot2)+sizeof(slot2)+__VA_alignof(slot3)-1) & -(long)__VA_alignof(slot3))
 
1249
#define __va_offset4(slot1,slot2,slot3,slot4)  \
 
1250
  ((__va_offset3(slot1,slot2,slot3)+sizeof(slot3)+__VA_alignof(slot4)-1) & -(long)__VA_alignof(slot4))
 
1251
 
 
1252
 
 
1253
/*
 
1254
 * Miscellaneous declarations.
 
1255
 */
 
1256
#ifdef __cplusplus
 
1257
extern "C" void (*vacall) (); /* the return type is variable, not void! */
 
1258
#else
 
1259
extern void (*vacall) (); /* the return type is variable, not void! */
 
1260
#endif
 
1261
extern void (* vacall_function) (va_alist);
 
1262
extern int __va_error1 (enum __VAtype, enum __VAtype);
 
1263
extern int __va_error2 (unsigned int);
 
1264
extern void __structcpy (void* dest, const void* src, unsigned long size, unsigned long alignment);
 
1265
typedef union { __vaword room[__VA_ALIST_WORDS]; double align; } __va_struct_buffer_t;
 
1266
extern __va_struct_buffer_t __va_struct_buffer;
 
1267
 
 
1268
 
 
1269
#endif /* _VACALL_H */