xref: /haiku/headers/build/gcc-2.95.3/va-mips.h (revision 404a0fea4653b894fabf4d5fee8e73df7bf84e75)
1*404a0feaSIngo Weinhold /* ---------------------------------------- */
2*404a0feaSIngo Weinhold /*           VARARGS  for MIPS/GNU CC       */
3*404a0feaSIngo Weinhold /*                                          */
4*404a0feaSIngo Weinhold /*                                          */
5*404a0feaSIngo Weinhold /*                                          */
6*404a0feaSIngo Weinhold /*                                          */
7*404a0feaSIngo Weinhold /* ---------------------------------------- */
8*404a0feaSIngo Weinhold 
9*404a0feaSIngo Weinhold 
10*404a0feaSIngo Weinhold /* These macros implement varargs for GNU C--either traditional or ANSI.  */
11*404a0feaSIngo Weinhold 
12*404a0feaSIngo Weinhold /* Define __gnuc_va_list.  */
13*404a0feaSIngo Weinhold 
14*404a0feaSIngo Weinhold #ifndef __GNUC_VA_LIST
15*404a0feaSIngo Weinhold #define __GNUC_VA_LIST
16*404a0feaSIngo Weinhold #if defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)
17*404a0feaSIngo Weinhold 
18*404a0feaSIngo Weinhold typedef struct {
19*404a0feaSIngo Weinhold   /* Pointer to FP regs.  */
20*404a0feaSIngo Weinhold   char *__fp_regs;
21*404a0feaSIngo Weinhold   /* Number of FP regs remaining.  */
22*404a0feaSIngo Weinhold   int __fp_left;
23*404a0feaSIngo Weinhold   /* Pointer to GP regs followed by stack parameters.  */
24*404a0feaSIngo Weinhold   char *__gp_regs;
25*404a0feaSIngo Weinhold } __gnuc_va_list;
26*404a0feaSIngo Weinhold 
27*404a0feaSIngo Weinhold #else /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
28*404a0feaSIngo Weinhold 
29*404a0feaSIngo Weinhold typedef char * __gnuc_va_list;
30*404a0feaSIngo Weinhold 
31*404a0feaSIngo Weinhold #endif /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
32*404a0feaSIngo Weinhold #endif /* not __GNUC_VA_LIST */
33*404a0feaSIngo Weinhold 
34*404a0feaSIngo Weinhold /* If this is for internal libc use, don't define anything but
35*404a0feaSIngo Weinhold    __gnuc_va_list.  */
36*404a0feaSIngo Weinhold #if defined (_STDARG_H) || defined (_VARARGS_H)
37*404a0feaSIngo Weinhold 
38*404a0feaSIngo Weinhold #ifndef _VA_MIPS_H_ENUM
39*404a0feaSIngo Weinhold #define _VA_MIPS_H_ENUM
40*404a0feaSIngo Weinhold enum {
41*404a0feaSIngo Weinhold   __no_type_class = -1,
42*404a0feaSIngo Weinhold   __void_type_class,
43*404a0feaSIngo Weinhold   __integer_type_class,
44*404a0feaSIngo Weinhold   __char_type_class,
45*404a0feaSIngo Weinhold   __enumeral_type_class,
46*404a0feaSIngo Weinhold   __boolean_type_class,
47*404a0feaSIngo Weinhold   __pointer_type_class,
48*404a0feaSIngo Weinhold   __reference_type_class,
49*404a0feaSIngo Weinhold   __offset_type_class,
50*404a0feaSIngo Weinhold   __real_type_class,
51*404a0feaSIngo Weinhold   __complex_type_class,
52*404a0feaSIngo Weinhold   __function_type_class,
53*404a0feaSIngo Weinhold   __method_type_class,
54*404a0feaSIngo Weinhold   __record_type_class,
55*404a0feaSIngo Weinhold   __union_type_class,
56*404a0feaSIngo Weinhold   __array_type_class,
57*404a0feaSIngo Weinhold   __string_type_class,
58*404a0feaSIngo Weinhold   __set_type_class,
59*404a0feaSIngo Weinhold   __file_type_class,
60*404a0feaSIngo Weinhold   __lang_type_class
61*404a0feaSIngo Weinhold };
62*404a0feaSIngo Weinhold #endif
63*404a0feaSIngo Weinhold 
64*404a0feaSIngo Weinhold /* In GCC version 2, we want an ellipsis at the end of the declaration
65*404a0feaSIngo Weinhold    of the argument list.  GCC version 1 can't parse it.  */
66*404a0feaSIngo Weinhold 
67*404a0feaSIngo Weinhold #if __GNUC__ > 1
68*404a0feaSIngo Weinhold #define __va_ellipsis ...
69*404a0feaSIngo Weinhold #else
70*404a0feaSIngo Weinhold #define __va_ellipsis
71*404a0feaSIngo Weinhold #endif
72*404a0feaSIngo Weinhold 
73*404a0feaSIngo Weinhold #ifdef __mips64
74*404a0feaSIngo Weinhold #define __va_rounded_size(__TYPE)  \
75*404a0feaSIngo Weinhold   (((sizeof (__TYPE) + 8 - 1) / 8) * 8)
76*404a0feaSIngo Weinhold #else
77*404a0feaSIngo Weinhold #define __va_rounded_size(__TYPE)  \
78*404a0feaSIngo Weinhold   (((sizeof (__TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
79*404a0feaSIngo Weinhold #endif
80*404a0feaSIngo Weinhold 
81*404a0feaSIngo Weinhold #ifdef __mips64
82*404a0feaSIngo Weinhold #define __va_reg_size 8
83*404a0feaSIngo Weinhold #else
84*404a0feaSIngo Weinhold #define __va_reg_size 4
85*404a0feaSIngo Weinhold #endif
86*404a0feaSIngo Weinhold 
87*404a0feaSIngo Weinhold /* Get definitions for _MIPS_SIM_ABI64 etc.  */
88*404a0feaSIngo Weinhold #ifdef _MIPS_SIM
89*404a0feaSIngo Weinhold #include <sgidefs.h>
90*404a0feaSIngo Weinhold #endif
91*404a0feaSIngo Weinhold 
92*404a0feaSIngo Weinhold #ifdef _STDARG_H
93*404a0feaSIngo Weinhold #if defined (__mips_eabi)
94*404a0feaSIngo Weinhold #if ! defined (__mips_soft_float) && ! defined (__mips_single_float)
95*404a0feaSIngo Weinhold #ifdef __mips64
96*404a0feaSIngo Weinhold #define va_start(__AP, __LASTARG)					\
97*404a0feaSIngo Weinhold   (__AP.__gp_regs = ((char *) __builtin_next_arg (__LASTARG)		\
98*404a0feaSIngo Weinhold 		     - (__builtin_args_info (2) < 8			\
99*404a0feaSIngo Weinhold 			? (8 - __builtin_args_info (2)) * __va_reg_size	\
100*404a0feaSIngo Weinhold 			: 0)),						\
101*404a0feaSIngo Weinhold    __AP.__fp_left = 8 - __builtin_args_info (3),			\
102*404a0feaSIngo Weinhold    __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * __va_reg_size)
103*404a0feaSIngo Weinhold #else /* ! defined (__mips64) */
104*404a0feaSIngo Weinhold #define va_start(__AP, __LASTARG)					\
105*404a0feaSIngo Weinhold   (__AP.__gp_regs = ((char *) __builtin_next_arg (__LASTARG)		\
106*404a0feaSIngo Weinhold 		     - (__builtin_args_info (2) < 8			\
107*404a0feaSIngo Weinhold 			? (8 - __builtin_args_info (2)) * __va_reg_size	\
108*404a0feaSIngo Weinhold 			: 0)),						\
109*404a0feaSIngo Weinhold    __AP.__fp_left = (8 - __builtin_args_info (3)) / 2,			\
110*404a0feaSIngo Weinhold    __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * 8,		\
111*404a0feaSIngo Weinhold    __AP.__fp_regs = (char *) ((int) __AP.__fp_regs & -8))
112*404a0feaSIngo Weinhold #endif /* ! defined (__mips64) */
113*404a0feaSIngo Weinhold #else /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float) ) */
114*404a0feaSIngo Weinhold #define va_start(__AP, __LASTARG)					\
115*404a0feaSIngo Weinhold   (__AP = ((__gnuc_va_list) __builtin_next_arg (__LASTARG)		\
116*404a0feaSIngo Weinhold 	   - (__builtin_args_info (2) >= 8 ? 0				\
117*404a0feaSIngo Weinhold 	      : (8 - __builtin_args_info (2)) * __va_reg_size)))
118*404a0feaSIngo Weinhold #endif /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float) ) */
119*404a0feaSIngo Weinhold #else /* ! defined (__mips_eabi) */
120*404a0feaSIngo Weinhold #define va_start(__AP, __LASTARG) \
121*404a0feaSIngo Weinhold   (__AP = (__gnuc_va_list) __builtin_next_arg (__LASTARG))
122*404a0feaSIngo Weinhold #endif /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
123*404a0feaSIngo Weinhold #else /* ! _STDARG_H */
124*404a0feaSIngo Weinhold #define va_alist  __builtin_va_alist
125*404a0feaSIngo Weinhold #ifdef __mips64
126*404a0feaSIngo Weinhold /* This assumes that `long long int' is always a 64 bit type.  */
127*404a0feaSIngo Weinhold #define va_dcl    long long int __builtin_va_alist; __va_ellipsis
128*404a0feaSIngo Weinhold #else
129*404a0feaSIngo Weinhold #define va_dcl    int __builtin_va_alist; __va_ellipsis
130*404a0feaSIngo Weinhold #endif
131*404a0feaSIngo Weinhold #if defined (__mips_eabi)
132*404a0feaSIngo Weinhold #if ! defined (__mips_soft_float) && ! defined (__mips_single_float)
133*404a0feaSIngo Weinhold #ifdef __mips64
134*404a0feaSIngo Weinhold #define va_start(__AP)							\
135*404a0feaSIngo Weinhold   (__AP.__gp_regs = ((char *) __builtin_next_arg ()			\
136*404a0feaSIngo Weinhold 		     - (__builtin_args_info (2) < 8			\
137*404a0feaSIngo Weinhold 			? (8 - __builtin_args_info (2)) * __va_reg_size	\
138*404a0feaSIngo Weinhold 			: __va_reg_size)),				\
139*404a0feaSIngo Weinhold    __AP.__fp_left = 8 - __builtin_args_info (3),			\
140*404a0feaSIngo Weinhold    __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * __va_reg_size)
141*404a0feaSIngo Weinhold #else /* ! defined (__mips64) */
142*404a0feaSIngo Weinhold #define va_start(__AP)							\
143*404a0feaSIngo Weinhold   (__AP.__gp_regs = ((char *) __builtin_next_arg ()			\
144*404a0feaSIngo Weinhold 		     - (__builtin_args_info (2) < 8			\
145*404a0feaSIngo Weinhold 			? (8 - __builtin_args_info (2)) * __va_reg_size	\
146*404a0feaSIngo Weinhold 			: __va_reg_size)),				\
147*404a0feaSIngo Weinhold    __AP.__fp_left = (8 - __builtin_args_info (3)) / 2,			\
148*404a0feaSIngo Weinhold    __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * 8,		\
149*404a0feaSIngo Weinhold    __AP.__fp_regs = (char *) ((int) __AP.__fp_regs & -8))
150*404a0feaSIngo Weinhold #endif /* ! defined (__mips64) */
151*404a0feaSIngo Weinhold #else /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
152*404a0feaSIngo Weinhold #define va_start(__AP)							\
153*404a0feaSIngo Weinhold   (__AP = ((__gnuc_va_list) __builtin_next_arg ()			\
154*404a0feaSIngo Weinhold 	   - (__builtin_args_info (2) >= 8 ? __va_reg_size		\
155*404a0feaSIngo Weinhold 	      : (8 - __builtin_args_info (2)) * __va_reg_size)))
156*404a0feaSIngo Weinhold #endif /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
157*404a0feaSIngo Weinhold /* Need alternate code for _MIPS_SIM_ABI64.  */
158*404a0feaSIngo Weinhold #elif defined(_MIPS_SIM) && (_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32)
159*404a0feaSIngo Weinhold #define va_start(__AP)							\
160*404a0feaSIngo Weinhold   (__AP = (__gnuc_va_list) __builtin_next_arg ()			\
161*404a0feaSIngo Weinhold    + (__builtin_args_info (2) >= 8 ? -8 : 0))
162*404a0feaSIngo Weinhold #else
163*404a0feaSIngo Weinhold #define va_start(__AP)  __AP = (char *) &__builtin_va_alist
164*404a0feaSIngo Weinhold #endif
165*404a0feaSIngo Weinhold #endif /* ! _STDARG_H */
166*404a0feaSIngo Weinhold 
167*404a0feaSIngo Weinhold #ifndef va_end
168*404a0feaSIngo Weinhold void va_end (__gnuc_va_list);		/* Defined in libgcc.a */
169*404a0feaSIngo Weinhold #endif
170*404a0feaSIngo Weinhold #define va_end(__AP)	((void)0)
171*404a0feaSIngo Weinhold 
172*404a0feaSIngo Weinhold #if defined (__mips_eabi)
173*404a0feaSIngo Weinhold 
174*404a0feaSIngo Weinhold #if ! defined (__mips_soft_float) && ! defined (__mips_single_float)
175*404a0feaSIngo Weinhold #ifdef __mips64
176*404a0feaSIngo Weinhold #define __va_next_addr(__AP, __type)					\
177*404a0feaSIngo Weinhold   ((__builtin_classify_type (*(__type *) 0) == __real_type_class	\
178*404a0feaSIngo Weinhold     && __AP.__fp_left > 0)						\
179*404a0feaSIngo Weinhold    ? (--__AP.__fp_left, (__AP.__fp_regs += 8) - 8)			\
180*404a0feaSIngo Weinhold    : (__AP.__gp_regs += __va_reg_size) - __va_reg_size)
181*404a0feaSIngo Weinhold #else
182*404a0feaSIngo Weinhold #define __va_next_addr(__AP, __type)					\
183*404a0feaSIngo Weinhold   ((__builtin_classify_type (*(__type *) 0) == __real_type_class	\
184*404a0feaSIngo Weinhold     && __AP.__fp_left > 0)						\
185*404a0feaSIngo Weinhold    ? (--__AP.__fp_left, (__AP.__fp_regs += 8) - 8)			\
186*404a0feaSIngo Weinhold    : (((__builtin_classify_type (* (__type *) 0) < __record_type_class	\
187*404a0feaSIngo Weinhold 	&& __alignof__ (__type) > 4)					\
188*404a0feaSIngo Weinhold        ? __AP.__gp_regs = (char *) (((int) __AP.__gp_regs + 8 - 1) & -8) \
189*404a0feaSIngo Weinhold        : (char *) 0),							\
190*404a0feaSIngo Weinhold       (__builtin_classify_type (* (__type *) 0) >= __record_type_class	\
191*404a0feaSIngo Weinhold        ? (__AP.__gp_regs += __va_reg_size) - __va_reg_size		\
192*404a0feaSIngo Weinhold        : ((__AP.__gp_regs += __va_rounded_size (__type))		\
193*404a0feaSIngo Weinhold 	  - __va_rounded_size (__type)))))
194*404a0feaSIngo Weinhold #endif
195*404a0feaSIngo Weinhold #else /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
196*404a0feaSIngo Weinhold #ifdef __mips64
197*404a0feaSIngo Weinhold #define __va_next_addr(__AP, __type)					\
198*404a0feaSIngo Weinhold   ((__AP += __va_reg_size) - __va_reg_size)
199*404a0feaSIngo Weinhold #else
200*404a0feaSIngo Weinhold #define __va_next_addr(__AP, __type)					\
201*404a0feaSIngo Weinhold   (((__builtin_classify_type (* (__type *) 0) < __record_type_class	\
202*404a0feaSIngo Weinhold      && __alignof__ (__type) > 4)					\
203*404a0feaSIngo Weinhold     ? __AP = (char *) (((__PTRDIFF_TYPE__) __AP + 8 - 1) & -8)		\
204*404a0feaSIngo Weinhold     : (char *) 0),							\
205*404a0feaSIngo Weinhold    (__builtin_classify_type (* (__type *) 0) >= __record_type_class	\
206*404a0feaSIngo Weinhold     ? (__AP += __va_reg_size) - __va_reg_size				\
207*404a0feaSIngo Weinhold     : ((__AP += __va_rounded_size (__type))				\
208*404a0feaSIngo Weinhold        - __va_rounded_size (__type))))
209*404a0feaSIngo Weinhold #endif
210*404a0feaSIngo Weinhold #endif /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */
211*404a0feaSIngo Weinhold 
212*404a0feaSIngo Weinhold #ifdef __MIPSEB__
213*404a0feaSIngo Weinhold #define va_arg(__AP, __type)						\
214*404a0feaSIngo Weinhold   ((__va_rounded_size (__type) <= __va_reg_size)			\
215*404a0feaSIngo Weinhold    ? *(__type *) (void *) (__va_next_addr (__AP, __type)		\
216*404a0feaSIngo Weinhold 			   + __va_reg_size				\
217*404a0feaSIngo Weinhold 			   - sizeof (__type))				\
218*404a0feaSIngo Weinhold    : (__builtin_classify_type (*(__type *) 0) >= __record_type_class	\
219*404a0feaSIngo Weinhold       ? **(__type **) (void *) (__va_next_addr (__AP, __type)		\
220*404a0feaSIngo Weinhold 				+ __va_reg_size				\
221*404a0feaSIngo Weinhold 				- sizeof (char *))			\
222*404a0feaSIngo Weinhold       : *(__type *) (void *) __va_next_addr (__AP, __type)))
223*404a0feaSIngo Weinhold #else
224*404a0feaSIngo Weinhold #define va_arg(__AP, __type)						\
225*404a0feaSIngo Weinhold   ((__va_rounded_size (__type) <= __va_reg_size)			\
226*404a0feaSIngo Weinhold    ? *(__type *) (void *) __va_next_addr (__AP, __type)		\
227*404a0feaSIngo Weinhold    : (__builtin_classify_type (* (__type *) 0) >= __record_type_class	\
228*404a0feaSIngo Weinhold       ? **(__type **) (void *) __va_next_addr (__AP, __type)		\
229*404a0feaSIngo Weinhold       : *(__type *) (void *) __va_next_addr (__AP, __type)))
230*404a0feaSIngo Weinhold #endif
231*404a0feaSIngo Weinhold 
232*404a0feaSIngo Weinhold #else /* ! defined (__mips_eabi) */
233*404a0feaSIngo Weinhold 
234*404a0feaSIngo Weinhold /* We cast to void * and then to TYPE * because this avoids
235*404a0feaSIngo Weinhold    a warning about increasing the alignment requirement.  */
236*404a0feaSIngo Weinhold /* The __mips64 cases are reversed from the 32 bit cases, because the standard
237*404a0feaSIngo Weinhold    32 bit calling convention left-aligns all parameters smaller than a word,
238*404a0feaSIngo Weinhold    whereas the __mips64 calling convention does not (and hence they are
239*404a0feaSIngo Weinhold    right aligned).  */
240*404a0feaSIngo Weinhold #ifdef __mips64
241*404a0feaSIngo Weinhold #ifdef __MIPSEB__
242*404a0feaSIngo Weinhold #define va_arg(__AP, __type)                                    \
243*404a0feaSIngo Weinhold   ((__type *) (void *) (__AP = (char *)                         \
244*404a0feaSIngo Weinhold                        ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8) \
245*404a0feaSIngo Weinhold 			   + __va_rounded_size (__type))))[-1]
246*404a0feaSIngo Weinhold #else
247*404a0feaSIngo Weinhold #define va_arg(__AP, __type)                                    \
248*404a0feaSIngo Weinhold   ((__AP = (char *) ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8)	\
249*404a0feaSIngo Weinhold 		     + __va_rounded_size (__type))),		\
250*404a0feaSIngo Weinhold    *(__type *) (void *) (__AP - __va_rounded_size (__type)))
251*404a0feaSIngo Weinhold #endif
252*404a0feaSIngo Weinhold 
253*404a0feaSIngo Weinhold #else /* not __mips64 */
254*404a0feaSIngo Weinhold 
255*404a0feaSIngo Weinhold #ifdef __MIPSEB__
256*404a0feaSIngo Weinhold /* For big-endian machines.  */
257*404a0feaSIngo Weinhold #define va_arg(__AP, __type)					\
258*404a0feaSIngo Weinhold   ((__AP = (char *) ((__alignof__ (__type) > 4			\
259*404a0feaSIngo Weinhold 		      ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8	\
260*404a0feaSIngo Weinhold 		      : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4)	\
261*404a0feaSIngo Weinhold 		     + __va_rounded_size (__type))),		\
262*404a0feaSIngo Weinhold    *(__type *) (void *) (__AP - __va_rounded_size (__type)))
263*404a0feaSIngo Weinhold #else
264*404a0feaSIngo Weinhold /* For little-endian machines.  */
265*404a0feaSIngo Weinhold #define va_arg(__AP, __type)						    \
266*404a0feaSIngo Weinhold   ((__type *) (void *) (__AP = (char *) ((__alignof__(__type) > 4	    \
267*404a0feaSIngo Weinhold 				? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8	    \
268*404a0feaSIngo Weinhold 				: ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4)    \
269*404a0feaSIngo Weinhold 					 + __va_rounded_size(__type))))[-1]
270*404a0feaSIngo Weinhold #endif
271*404a0feaSIngo Weinhold #endif
272*404a0feaSIngo Weinhold #endif /* ! defined (__mips_eabi)  */
273*404a0feaSIngo Weinhold 
274*404a0feaSIngo Weinhold /* Copy __gnuc_va_list into another variable of this type.  */
275*404a0feaSIngo Weinhold #define __va_copy(dest, src) (dest) = (src)
276*404a0feaSIngo Weinhold 
277*404a0feaSIngo Weinhold #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
278