1 /* ---------------------------------------- */
2 /* VARARGS for MIPS/GNU CC */
7 /* ---------------------------------------- */
10 /* These macros implement varargs for GNU C--either traditional or ANSI. */
12 /* Define __gnuc_va_list. */
14 #ifndef __GNUC_VA_LIST
15 #define __GNUC_VA_LIST
16 #if defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)
19 /* Pointer to FP regs. */
21 /* Number of FP regs remaining. */
23 /* Pointer to GP regs followed by stack parameters. */
27 #else /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
29 typedef char * __gnuc_va_list;
31 #endif /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
32 #endif /* not __GNUC_VA_LIST */
34 /* If this is for internal libc use, don't define anything but
36 #if defined (_STDARG_H) || defined (_VARARGS_H)
43 __enumeral_type_class,
46 __reference_type_class,
50 __function_type_class,
61 /* In GCC version 2, we want an ellipsis at the end of the declaration
62 of the argument list. GCC version 1 can't parse it. */
65 #define __va_ellipsis ...
71 #define __va_rounded_size(__TYPE) \
72 (((sizeof (__TYPE) + 8 - 1) / 8) * 8)
74 #define __va_rounded_size(__TYPE) \
75 (((sizeof (__TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
79 #define __va_reg_size 8
81 #define __va_reg_size 4
84 /* Get definitions for _MIPS_SIM_ABI64 etc. */
90 #if defined (__mips_eabi)
91 #if ! defined (__mips_soft_float) && ! defined (__mips_single_float)
93 #define va_start(__AP, __LASTARG) \
94 (__AP.__gp_regs = ((char *) __builtin_next_arg (__LASTARG) \
95 - (__builtin_args_info (2) < 8 \
96 ? (8 - __builtin_args_info (2)) * __va_reg_size \
98 __AP.__fp_left = 8 - __builtin_args_info (3), \
99 __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * __va_reg_size)
100 #else /* ! defined (__mips64) */
101 #define va_start(__AP, __LASTARG) \
102 (__AP.__gp_regs = ((char *) __builtin_next_arg (__LASTARG) \
103 - (__builtin_args_info (2) < 8 \
104 ? (8 - __builtin_args_info (2)) * __va_reg_size \
106 __AP.__fp_left = (8 - __builtin_args_info (3)) / 2, \
107 __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * 8, \
108 __AP.__fp_regs = (char *) ((int) __AP.__fp_regs & -8))
109 #endif /* ! defined (__mips64) */
110 #else /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float) ) */
111 #define va_start(__AP, __LASTARG) \
112 (__AP = ((__gnuc_va_list) __builtin_next_arg (__LASTARG) \
113 - (__builtin_args_info (2) >= 8 ? 0 \
114 : (8 - __builtin_args_info (2)) * __va_reg_size)))
115 #endif /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float) ) */
116 #else /* ! defined (__mips_eabi) */
117 #define va_start(__AP, __LASTARG) \
118 (__AP = (__gnuc_va_list) __builtin_next_arg (__LASTARG))
119 #endif /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
120 #else /* ! _STDARG_H */
121 #define va_alist __builtin_va_alist
123 /* This assumes that `long long int' is always a 64 bit type. */
124 #define va_dcl long long int __builtin_va_alist; __va_ellipsis
126 #define va_dcl int __builtin_va_alist; __va_ellipsis
128 #if defined (__mips_eabi)
129 #if ! defined (__mips_soft_float) && ! defined (__mips_single_float)
131 #define va_start(__AP) \
132 (__AP.__gp_regs = ((char *) __builtin_next_arg () \
133 - (__builtin_args_info (2) < 8 \
134 ? (8 - __builtin_args_info (2)) * __va_reg_size \
136 __AP.__fp_left = 8 - __builtin_args_info (3), \
137 __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * __va_reg_size)
138 #else /* ! defined (__mips64) */
139 #define va_start(__AP) \
140 (__AP.__gp_regs = ((char *) __builtin_next_arg () \
141 - (__builtin_args_info (2) < 8 \
142 ? (8 - __builtin_args_info (2)) * __va_reg_size \
144 __AP.__fp_left = (8 - __builtin_args_info (3)) / 2, \
145 __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * 8, \
146 __AP.__fp_regs = (char *) ((int) __AP.__fp_regs & -8))
147 #endif /* ! defined (__mips64) */
148 #else /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
149 #define va_start(__AP) \
150 (__AP = ((__gnuc_va_list) __builtin_next_arg () \
151 - (__builtin_args_info (2) >= 8 ? __va_reg_size \
152 : (8 - __builtin_args_info (2)) * __va_reg_size)))
153 #endif /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
154 /* Need alternate code for _MIPS_SIM_ABI64. */
155 #elif defined(_MIPS_SIM) && (_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32)
156 #define va_start(__AP) \
157 (__AP = (__gnuc_va_list) __builtin_next_arg () \
158 + (__builtin_args_info (2) >= 8 ? -8 : 0))
160 #define va_start(__AP) __AP = (char *) &__builtin_va_alist
162 #endif /* ! _STDARG_H */
165 void va_end (__gnuc_va_list); /* Defined in libgcc.a */
167 #define va_end(__AP) ((void)0)
169 #if defined (__mips_eabi)
171 #if ! defined (__mips_soft_float) && ! defined (__mips_single_float)
173 #define __va_next_addr(__AP, __type) \
174 ((__builtin_classify_type (*(__type *) 0) == __real_type_class \
175 && __AP.__fp_left > 0) \
176 ? (--__AP.__fp_left, (__AP.__fp_regs += 8) - 8) \
177 : (__AP.__gp_regs += __va_reg_size) - __va_reg_size)
179 #define __va_next_addr(__AP, __type) \
180 ((__builtin_classify_type (*(__type *) 0) == __real_type_class \
181 && __AP.__fp_left > 0) \
182 ? (--__AP.__fp_left, (__AP.__fp_regs += 8) - 8) \
183 : (((__builtin_classify_type (* (__type *) 0) < __record_type_class \
184 && __alignof__ (__type) > 4) \
185 ? __AP.__gp_regs = (char *) (((int) __AP.__gp_regs + 8 - 1) & -8) \
187 (__builtin_classify_type (* (__type *) 0) >= __record_type_class \
188 ? (__AP.__gp_regs += __va_reg_size) - __va_reg_size \
189 : ((__AP.__gp_regs += __va_rounded_size (__type)) \
190 - __va_rounded_size (__type)))))
192 #else /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
194 #define __va_next_addr(__AP, __type) \
195 ((__AP += __va_reg_size) - __va_reg_size)
197 #define __va_next_addr(__AP, __type) \
198 (((__builtin_classify_type (* (__type *) 0) < __record_type_class \
199 && __alignof__ (__type) > 4) \
200 ? __AP = (char *) (((int) __AP + 8 - 1) & -8) \
202 (__builtin_classify_type (* (__type *) 0) >= __record_type_class \
203 ? (__AP += __va_reg_size) - __va_reg_size \
204 : ((__AP += __va_rounded_size (__type)) \
205 - __va_rounded_size (__type))))
207 #endif /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
210 #define va_arg(__AP, __type) \
211 ((__va_rounded_size (__type) <= __va_reg_size) \
212 ? *(__type *) (void *) (__va_next_addr (__AP, __type) \
215 : (__builtin_classify_type (*(__type *) 0) >= __record_type_class \
216 ? **(__type **) (void *) (__va_next_addr (__AP, __type) \
219 : *(__type *) (void *) __va_next_addr (__AP, __type)))
221 #define va_arg(__AP, __type) \
222 ((__va_rounded_size (__type) <= __va_reg_size) \
223 ? *(__type *) (void *) __va_next_addr (__AP, __type) \
224 : (__builtin_classify_type (* (__type *) 0) >= __record_type_class \
225 ? **(__type **) (void *) __va_next_addr (__AP, __type) \
226 : *(__type *) (void *) __va_next_addr (__AP, __type)))
229 #else /* ! defined (__mips_eabi) */
231 /* We cast to void * and then to TYPE * because this avoids
232 a warning about increasing the alignment requirement. */
233 /* The __mips64 cases are reversed from the 32 bit cases, because the standard
234 32 bit calling convention left-aligns all parameters smaller than a word,
235 whereas the __mips64 calling convention does not (and hence they are
239 #define va_arg(__AP, __type) \
240 ((__type *) (void *) (__AP = (char *) ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8) \
241 + __va_rounded_size (__type))))[-1]
243 #define va_arg(__AP, __type) \
244 ((__AP = (char *) ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8) \
245 + __va_rounded_size (__type))), \
246 *(__type *) (void *) (__AP - __va_rounded_size (__type)))
249 #else /* not __mips64 */
252 /* For big-endian machines. */
253 #define va_arg(__AP, __type) \
254 ((__AP = (char *) ((__alignof__ (__type) > 4 \
255 ? ((int)__AP + 8 - 1) & -8 \
256 : ((int)__AP + 4 - 1) & -4) \
257 + __va_rounded_size (__type))), \
258 *(__type *) (void *) (__AP - __va_rounded_size (__type)))
260 /* For little-endian machines. */
261 #define va_arg(__AP, __type) \
262 ((__type *) (void *) (__AP = (char *) ((__alignof__(__type) > 4 \
263 ? ((int)__AP + 8 - 1) & -8 \
264 : ((int)__AP + 4 - 1) & -4) \
265 + __va_rounded_size(__type))))[-1]
268 #endif /* ! defined (__mips_eabi) */
270 /* Copy __gnuc_va_list into another variable of this type. */
271 #define __va_copy(dest, src) (dest) = (src)
273 #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */