]>
Commit | Line | Data |
---|---|---|
f3db20a3 RS |
1 | /* This is just like the default gvarargs.h |
2 | except for differences decribed below. */ | |
3 | ||
4 | /* Make this a macro rather than a typedef, so we can undef any other defn. */ | |
5 | #define va_list __va___list | |
6 | /* This has to be a char * to be compatible with Sun. | |
7 | i.e., we have to pass a `va_list' to vsprintf. */ | |
8 | typedef char * __va___list; | |
9 | ||
10 | /* In GCC version 2, we want an ellipsis at the end of the declaration | |
11 | of the argument list. GCC version 1 can't parse it. */ | |
12 | ||
13 | #if __GNUC__ > 1 | |
14 | #define __va_ellipsis ... | |
15 | #else | |
16 | #define __va_ellipsis | |
17 | #endif | |
18 | ||
19 | #define va_alist __builtin_va_alist | |
20 | /* The ... causes current_function_varargs to be set in cc1. */ | |
21 | #define va_dcl int __builtin_va_alist; __va_ellipsis | |
22 | ||
23 | /* The difference is to store the stack address in both components | |
24 | instead of in AP itself. */ | |
25 | #define va_start(AP) \ | |
26 | (__builtin_saveregs (), (AP) = ((char *) &__builtin_va_alist)) | |
27 | #define va_end(pvar) | |
28 | ||
29 | #define __va_rounded_size(TYPE) \ | |
30 | (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) | |
31 | ||
32 | /* RECORD_TYPE args passed using the C calling convention are | |
33 | passed by invisible reference. ??? RECORD_TYPE args passed | |
34 | in the stack are made to be word-aligned; for an aggregate that is | |
35 | not word-aligned, we advance the pointer to the first non-reg slot. */ | |
36 | #define va_arg(pvar,TYPE) \ | |
e13d81d0 | 37 | __extension__ \ |
f3db20a3 RS |
38 | ({ TYPE __va_temp; \ |
39 | ((__builtin_classify_type (__va_temp) >= 12) \ | |
40 | ? ((pvar) += __va_rounded_size (TYPE *), \ | |
41 | **(TYPE **) (pvar) - __va_rounded_size (TYPE *)) \ | |
42 | : ((pvar) += __va_rounded_size (TYPE), \ | |
43 | *((TYPE *) ((pvar) - __va_rounded_size (TYPE)))));}) |