1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
|
/* This is just like the default gvarargs.h
except for differences described below. */
/* Define __gnuc_va_list. */
#ifndef __GNUC_VA_LIST
#define __GNUC_VA_LIST
#ifdef __sparc_v9__
typedef long long __va_greg;
typedef double __va_freg;
typedef struct {
__va_greg * __va_next_o; /* next available %o* register */
__va_greg * __va_next_o_limit; /* past last available %o* register */
__va_freg * __va_next_fp; /* next available %f* register */
__va_freg * __va_next_fp_limit; /* last available %f* register */
__va_greg * __va_next_stack; /* next extended word on stack */
} __gnuc_va_list;
#else
#ifdef __linux__
/* This has to be a void * to be compatible with Linux.
i.e., we have to pass a `va_list' to vsprintf. */
typedef void * __gnuc_va_list;
#else
#ifndef __svr4__
/* This has to be a char * to be compatible with Sun.
i.e., we have to pass a `va_list' to vsprintf. */
typedef char * __gnuc_va_list;
#else
/* This has to be a void * to be compatible with Sun svr4.
i.e., we have to pass a `va_list' to vsprintf. */
typedef void * __gnuc_va_list;
#endif
#endif /* not __linux__ */
#endif /* not __sparc_v9__ */
#endif /* not __GNUC_VA_LIST */
/* If this is for internal libc use, don't define anything but
__gnuc_va_list. */
#if defined (_STDARG_H) || defined (_VARARGS_H)
#ifdef _STDARG_H
#ifdef __sparc_v9__
#define va_start(AP, LASTARG) \
__extension__ \
({ \
AP.__va_next_o = (__va_greg *) __builtin_saveregs (); \
AP.__va_next_o_limit = (AP.__va_next_o + \
(__builtin_args_info (0) < 6 ? 6 - __builtin_args_info (0) : 0)); \
AP.__va_next_fp = (__va_freg *) AP.__va_next_o_limit; \
AP.__va_next_fp_limit = (AP.__va_next_fp + \
(__builtin_args_info (1) < 16 ? (16 - __builtin_args_info (1) + 1) / 2 : 0)); \
AP.__va_next_stack = (__va_greg *) __builtin_next_arg (LASTARG); \
})
#else
/* Call __builtin_next_arg even though we aren't using its value, so that
we can verify that LASTARG is correct. */
#ifdef __GCC_NEW_VARARGS__
#define va_start(AP, LASTARG) \
(__builtin_next_arg (LASTARG), AP = (char *) __builtin_saveregs ())
#else
#define va_start(AP, LASTARG) \
(__builtin_saveregs (), AP = ((char *) __builtin_next_arg (LASTARG)))
#endif
#endif /* not __sparc_v9__ */
#else
#define va_alist __builtin_va_alist
#define va_dcl int __builtin_va_alist;...
#ifdef __sparc_v9__
#define va_start(AP) \
__extension__ \
({ \
AP.__va_next_o = (__va_greg *) __builtin_saveregs (); \
AP.__va_next_o_limit = (AP.__va_next_o + \
(__builtin_args_info (0) < 6 ? 6 - __builtin_args_info (0) : 0)); \
AP.__va_next_fp = (__va_freg *) AP.__va_next_o_limit; \
AP.__va_next_fp_limit = (AP.__va_next_fp + \
(__builtin_args_info (1) < 16 ? (16 - __builtin_args_info (1) + 1) / 2 : 0)); \
AP.__va_next_stack = (__va_greg *) __builtin_next_arg (__builtin_va_alist) \
- (__builtin_args_info (0) >= 6 || __builtin_args_info (1) >= 16 ? 1 : 0); \
})
#else
#ifdef __GCC_NEW_VARARGS__
#define va_start(AP) ((AP) = (char *) __builtin_saveregs ())
#else
#define va_start(AP) \
(__builtin_saveregs (), (AP) = ((char *) &__builtin_va_alist))
#endif
#endif /* not __sparc_v9__ */
#endif
#ifndef va_end
void va_end (__gnuc_va_list); /* Defined in libgcc.a */
/* Values returned by __builtin_classify_type. */
enum __va_type_classes {
__no_type_class = -1,
__void_type_class,
__integer_type_class,
__char_type_class,
__enumeral_type_class,
__boolean_type_class,
__pointer_type_class,
__reference_type_class,
__offset_type_class,
__real_type_class,
__complex_type_class,
__function_type_class,
__method_type_class,
__record_type_class,
__union_type_class,
__array_type_class,
__string_type_class,
__set_type_class,
__file_type_class,
__lang_type_class
};
#endif
#define va_end(pvar) ((void)0)
/* Avoid errors if compiling GCC v2 with GCC v1. */
#if __GNUC__ == 1
#define __extension__
#endif
/* RECORD_TYPE args passed using the C calling convention are
passed by invisible reference. ??? RECORD_TYPE args passed
in the stack are made to be word-aligned; for an aggregate that is
not word-aligned, we advance the pointer to the first non-reg slot. */
#ifdef __sparc_v9__
#define va_arg(pvar,TYPE) \
__extension__ \
(*({int __type = __builtin_classify_type (* (TYPE *) 0); \
void * __result; \
if (__type == __real_type_class) /* float? */ \
{ \
__va_freg *__r; \
/* see PASS_IN_REG_P in gcc's sparc.h */ \
if (pvar.__va_next_fp < pvar.__va_next_fp_limit \
&& ((__r = (__va_freg *) (((__va_greg) pvar.__va_next_fp + sizeof (TYPE) - 1) & ~(__va_greg) (sizeof (TYPE) - 1))) \
< pvar.__va_next_fp_limit)) \
{ \
pvar.__va_next_fp = __r + (sizeof (TYPE) + 7) / 8; \
} \
else \
{ \
__r = (__va_freg *) pvar.__va_next_stack; \
pvar.__va_next_stack += (sizeof (TYPE) + 7) / 8; \
} \
__result = __r; \
} \
else if (__type < __record_type_class) /* integer? */ \
{ \
__va_greg *__r; \
if (pvar.__va_next_o < pvar.__va_next_o_limit) \
__r = pvar.__va_next_o++; \
else \
__r = pvar.__va_next_stack++; \
/* adjust for 4 byte ints */ \
__result = (char *) __r + 8 - sizeof (TYPE); \
} \
else /* aggregate object */ \
{ \
void **__r; \
if (pvar.__va_next_o < pvar.__va_next_o_limit) \
__r = (void **) pvar.__va_next_o++; \
else \
__r = (void **) pvar.__va_next_stack++; \
__result = *__r; \
} \
(TYPE *) __result;}))
#else /* not __sparc_v9__ */
#define __va_rounded_size(TYPE) \
(((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
/* We don't declare the union member `d' to have type TYPE
because that would lose in C++ if TYPE has a constructor. */
/* We cast to void * and then to TYPE * because this avoids
a warning about increasing the alignment requirement.
The casts to char * avoid warnings about invalid pointer arithmetic. */
#define va_arg(pvar,TYPE) \
__extension__ \
(*({((__builtin_classify_type (*(TYPE*) 0) >= __record_type_class \
|| (__builtin_classify_type (*(TYPE*) 0) == __real_type_class \
&& sizeof (TYPE) == 16)) \
? ((pvar) = (char *)(pvar) + __va_rounded_size (TYPE *), \
*(TYPE **) (void *) ((char *)(pvar) - __va_rounded_size (TYPE *))) \
: __va_rounded_size (TYPE) == 8 \
? ({ union {char __d[sizeof (TYPE)]; int __i[2];} __u; \
__u.__i[0] = ((int *) (void *) (pvar))[0]; \
__u.__i[1] = ((int *) (void *) (pvar))[1]; \
(pvar) = (char *)(pvar) + 8; \
(TYPE *) (void *) __u.__d; }) \
: ((pvar) = (char *)(pvar) + __va_rounded_size (TYPE), \
((TYPE *) (void *) ((char *)(pvar) - __va_rounded_size (TYPE)))));}))
#endif /* not __sparc_v9__ */
#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
|