xref: /f-stack/freebsd/mips/include/stdarg.h (revision ebf5cedb)
1 /*
2  *	JNPR: stdarg.h,v 1.3 2006/09/15 12:52:34 katta
3  * $FreeBSD$
4  */
5 
6 #ifndef _MACHINE_STDARG_H_
7 #define	_MACHINE_STDARG_H_
8 #include <sys/cdefs.h>
9 #include <sys/_types.h>
10 
11 
12 #if __GNUC__ >= 3
13 
14 #ifndef _VA_LIST_DECLARED
15 #define	_VA_LIST_DECLARED
16 typedef __va_list	va_list;
17 #endif
18 #define	va_start(v,l)	__builtin_va_start((v),l)
19 #define	va_end		__builtin_va_end
20 #define	va_arg		__builtin_va_arg
21 #define	va_copy		__builtin_va_copy
22 
23 #else  /* __GNUC__ */
24 
25 
26 /* ---------------------------------------- */
27 /*	     VARARGS  for MIPS/GNU CC	    */
28 /* ---------------------------------------- */
29 
30 #include <machine/endian.h>
31 
32 /* These macros implement varargs for GNU C--either traditional or ANSI.  */
33 
34 /* Define __gnuc_va_list.  */
35 
36 #ifndef __GNUC_VA_LIST
37 #define	__GNUC_VA_LIST
38 
39 typedef char * __gnuc_va_list;
40 typedef __gnuc_va_list va_list;
41 
42 #endif /* ! __GNUC_VA_LIST */
43 
44 /* If this is for internal libc use, don't define anything but
45    __gnuc_va_list.  */
46 
47 #ifndef _VA_MIPS_H_ENUM
48 #define	_VA_MIPS_H_ENUM
49 enum {
50 	__no_type_class = -1,
51 	__void_type_class,
52 	__integer_type_class,
53 	__char_type_class,
54 	__enumeral_type_class,
55 	__boolean_type_class,
56 	__pointer_type_class,
57 	__reference_type_class,
58 	__offset_type_class,
59 	__real_type_class,
60 	__complex_type_class,
61 	__function_type_class,
62 	__method_type_class,
63 	__record_type_class,
64 	__union_type_class,
65 	__array_type_class,
66 	__string_type_class,
67 	__set_type_class,
68 	__file_type_class,
69 	__lang_type_class
70 };
71 #endif
72 
73 /* In GCC version 2, we want an ellipsis at the end of the declaration
74    of the argument list.  GCC version 1 can't parse it.	 */
75 
76 #if __GNUC__ > 1
77 #define	__va_ellipsis ...
78 #else
79 #define	__va_ellipsis
80 #endif
81 
82 
83 #define	va_start(__AP, __LASTARG) \
84 	(__AP = (__gnuc_va_list) __builtin_next_arg (__LASTARG))
85 
86 #define	va_end(__AP)	((void)0)
87 
88 
89 /* We cast to void * and then to TYPE * because this avoids
90    a warning about increasing the alignment requirement.  */
91 /* The __mips64 cases are reversed from the 32 bit cases, because the standard
92    32 bit calling convention left-aligns all parameters smaller than a word,
93    whereas the __mips64 calling convention does not (and hence they are
94    right aligned).  */
95 
96 #ifdef __mips64
97 
98 #define	__va_rounded_size(__TYPE)	(((sizeof (__TYPE) + 8 - 1) / 8) * 8)
99 
100 #define	__va_reg_size			8
101 
102 #if defined(__MIPSEB__) || (BYTE_ORDER == BIG_ENDIAN)
103 #define	va_arg(__AP, __type)						\
104 	((__type *) (void *) (__AP = (char *)				\
105 	    ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8)			\
106 	    + __va_rounded_size (__type))))[-1]
107 #else	/* ! __MIPSEB__ && !BYTE_ORDER == BIG_ENDIAN */
108 #define	va_arg(__AP, __type)						\
109 	((__AP = (char *) ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8)	\
110 	    + __va_rounded_size (__type))),				\
111 	    *(__type *) (void *) (__AP - __va_rounded_size (__type)))
112 #endif	/* ! __MIPSEB__ && !BYTE_ORDER == BIG_ENDIAN */
113 
114 #else	/* ! __mips64 */
115 
116 #define	__va_rounded_size(__TYPE)					\
117 	(((sizeof (__TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
118 
119 #define	__va_reg_size 4
120 
121 #if defined(__MIPSEB__) || (BYTE_ORDER == BIG_ENDIAN)
122 /* For big-endian machines.  */
123 #define	va_arg(__AP, __type)					\
124 	((__AP = (char *) ((__alignof__ (__type) > 4		\
125 	    ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8		\
126 	    : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4)		\
127 	    + __va_rounded_size (__type))),			\
128 	*(__type *) (void *) (__AP - __va_rounded_size (__type)))
129 #else	/* ! __MIPSEB__ && !BYTE_ORDER == BIG_ENDIAN */
130 /* For little-endian machines.	*/
131 #define	va_arg(__AP, __type)						\
132 	((__type *) (void *) (__AP = (char *) ((__alignof__(__type) > 4	\
133 	    ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8			\
134 	    : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4)			\
135 	    + __va_rounded_size(__type))))[-1]
136 #endif	/* ! __MIPSEB__ && !BYTE_ORDER == BIG_ENDIAN */
137 #endif	/* ! __mips64 */
138 
139 /* Copy __gnuc_va_list into another variable of this type.  */
140 #define	__va_copy(dest, src)	(dest) = (src)
141 #define	va_copy(dest, src)	(dest) = (src)
142 
143 #endif /* __GNUC__ */
144 #endif /* _MACHINE_STDARG_H_ */
145