Commit | Line | Data |
---|---|---|
9b58980d C |
1 | /* GNU C varargs support for the Intel 80960. */ |
2 | ||
3 | /* Define __gnuc_va_list. */ | |
4 | ||
5 | #ifndef __GNUC_VA_LIST | |
6 | #define __GNUC_VA_LIST | |
7 | /* The first element is the address of the first argument. | |
8 | The second element is the number of bytes skipped past so far. */ | |
9 | typedef unsigned __gnuc_va_list[2]; | |
10 | #endif /* not __GNUC_VA_LIST */ | |
11 | ||
12 | /* If this is for internal libc use, don't define anything but | |
13 | __gnuc_va_list. */ | |
14 | #if defined (_STDARG_H) || defined (_VARARGS_H) | |
15 | ||
16 | /* In GCC version 2, we want an ellipsis at the end of the declaration | |
17 | of the argument list. GCC version 1 can't parse it. */ | |
18 | ||
19 | #if __GNUC__ > 1 | |
20 | #define __va_ellipsis ... | |
21 | #else | |
22 | #define __va_ellipsis | |
23 | #endif | |
24 | ||
25 | /* The stack size of the type t. */ | |
26 | #define __vsiz(T) (((sizeof (T) + 3) / 4) * 4) | |
27 | /* The stack alignment of the type t. */ | |
28 | #define __vali(T) (__alignof__ (T) >= 4 ? __alignof__ (T) : 4) | |
29 | /* The offset of the next stack argument after one of type t at offset i. */ | |
30 | #define __vpad(I, T) ((((I) + __vali (T) - 1) / __vali (T)) \ | |
31 | * __vali (T) + __vsiz (T)) | |
32 | ||
33 | #ifdef _STDARG_H | |
34 | #define va_start(AP, LASTARG) \ | |
35 | __extension__ \ | |
36 | ({ __asm__ ("st g14,%0" : "=m" (*(AP))); \ | |
37 | (AP)[1] = (unsigned) __builtin_next_arg () - *AP; }) | |
38 | #else | |
39 | ||
40 | #define va_alist __builtin_va_alist | |
41 | #define va_dcl char *__builtin_va_alist; __va_ellipsis | |
42 | #define va_start(AP) ((AP)[1] = 0, *(AP) = (unsigned) &va_alist) | |
43 | #endif | |
44 | ||
45 | /* We cast to void * and then to TYPE * because this avoids | |
46 | a warning about increasing the alignment requirement. */ | |
47 | #define va_arg(AP, T) \ | |
48 | ( \ | |
49 | ( \ | |
50 | ((AP)[1] <= 48 && (__vpad ((AP)[1], T) > 48 || __vsiz (T) > 16)) \ | |
51 | ? ((AP)[1] = 48 + __vsiz (T)) \ | |
52 | : ((AP)[1] = __vpad ((AP)[1], T)) \ | |
53 | ), \ | |
54 | \ | |
55 | *((T *) (void *) ((char *) *(AP) + (AP)[1] - __vsiz (T))) \ | |
56 | ) | |
57 | ||
58 | #ifndef va_end | |
59 | void va_end (__gnuc_va_list); /* Defined in libgcc.a */ | |
60 | #endif | |
61 | #define va_end(AP) | |
62 | ||
63 | #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */ | |
64 |