1178172Simp/*
2178172Simp *	JNPR: stdarg.h,v 1.3 2006/09/15 12:52:34 katta
3178172Simp * $FreeBSD$
4178172Simp */
5178172Simp
6178172Simp#ifndef _MACHINE_STDARG_H_
7178172Simp#define	_MACHINE_STDARG_H_
8178172Simp#include <sys/cdefs.h>
9178172Simp#include <sys/_types.h>
10178172Simp
11178172Simp
12178172Simp#if __GNUC__ >= 3
13178172Simp
14178172Simp#ifndef _VA_LIST_DECLARED
15178172Simp#define	_VA_LIST_DECLARED
16178172Simptypedef __va_list	va_list;
17178172Simp#endif
18178172Simp#define	va_start(v,l)	__builtin_va_start((v),l)
19178172Simp#define	va_end		__builtin_va_end
20178172Simp#define	va_arg		__builtin_va_arg
21178172Simp#define	va_copy		__builtin_va_copy
22178172Simp
23178172Simp#else  /* __GNUC__ */
24178172Simp
25178172Simp
26178172Simp/* ---------------------------------------- */
27178172Simp/*	     VARARGS  for MIPS/GNU CC	    */
28178172Simp/* ---------------------------------------- */
29178172Simp
30178172Simp#include <machine/endian.h>
31178172Simp
32178172Simp/* These macros implement varargs for GNU C--either traditional or ANSI.  */
33178172Simp
34178172Simp/* Define __gnuc_va_list.  */
35178172Simp
36178172Simp#ifndef __GNUC_VA_LIST
37178172Simp#define	__GNUC_VA_LIST
38178172Simp
39178172Simptypedef char * __gnuc_va_list;
40178172Simptypedef __gnuc_va_list va_list;
41178172Simp
42178172Simp#endif /* ! __GNUC_VA_LIST */
43178172Simp
44178172Simp/* If this is for internal libc use, don't define anything but
45178172Simp   __gnuc_va_list.  */
46178172Simp
47178172Simp#ifndef _VA_MIPS_H_ENUM
48178172Simp#define	_VA_MIPS_H_ENUM
49178172Simpenum {
50178172Simp	__no_type_class = -1,
51178172Simp	__void_type_class,
52178172Simp	__integer_type_class,
53178172Simp	__char_type_class,
54178172Simp	__enumeral_type_class,
55178172Simp	__boolean_type_class,
56178172Simp	__pointer_type_class,
57178172Simp	__reference_type_class,
58178172Simp	__offset_type_class,
59178172Simp	__real_type_class,
60178172Simp	__complex_type_class,
61178172Simp	__function_type_class,
62178172Simp	__method_type_class,
63178172Simp	__record_type_class,
64178172Simp	__union_type_class,
65178172Simp	__array_type_class,
66178172Simp	__string_type_class,
67178172Simp	__set_type_class,
68178172Simp	__file_type_class,
69178172Simp	__lang_type_class
70178172Simp};
71178172Simp#endif
72178172Simp
73178172Simp/* In GCC version 2, we want an ellipsis at the end of the declaration
74178172Simp   of the argument list.  GCC version 1 can't parse it.	 */
75178172Simp
76178172Simp#if __GNUC__ > 1
77178172Simp#define	__va_ellipsis ...
78178172Simp#else
79178172Simp#define	__va_ellipsis
80178172Simp#endif
81178172Simp
82178172Simp
83178172Simp#define	va_start(__AP, __LASTARG) \
84178172Simp	(__AP = (__gnuc_va_list) __builtin_next_arg (__LASTARG))
85178172Simp
86178172Simp#define	va_end(__AP)	((void)0)
87178172Simp
88178172Simp
89178172Simp/* We cast to void * and then to TYPE * because this avoids
90178172Simp   a warning about increasing the alignment requirement.  */
91178172Simp/* The __mips64 cases are reversed from the 32 bit cases, because the standard
92178172Simp   32 bit calling convention left-aligns all parameters smaller than a word,
93178172Simp   whereas the __mips64 calling convention does not (and hence they are
94178172Simp   right aligned).  */
95178172Simp
96178172Simp#ifdef __mips64
97178172Simp
98178172Simp#define	__va_rounded_size(__TYPE)	(((sizeof (__TYPE) + 8 - 1) / 8) * 8)
99178172Simp
100178172Simp#define	__va_reg_size			8
101178172Simp
102178172Simp#if defined(__MIPSEB__) || (BYTE_ORDER == BIG_ENDIAN)
103178172Simp#define	va_arg(__AP, __type)						\
104178172Simp	((__type *) (void *) (__AP = (char *)				\
105178172Simp	    ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8)			\
106178172Simp	    + __va_rounded_size (__type))))[-1]
107178172Simp#else	/* ! __MIPSEB__ && !BYTE_ORDER == BIG_ENDIAN */
108178172Simp#define	va_arg(__AP, __type)						\
109178172Simp	((__AP = (char *) ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8)	\
110178172Simp	    + __va_rounded_size (__type))),				\
111178172Simp	    *(__type *) (void *) (__AP - __va_rounded_size (__type)))
112178172Simp#endif	/* ! __MIPSEB__ && !BYTE_ORDER == BIG_ENDIAN */
113178172Simp
114178172Simp#else	/* ! __mips64 */
115178172Simp
116178172Simp#define	__va_rounded_size(__TYPE)					\
117178172Simp	(((sizeof (__TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
118178172Simp
119178172Simp#define	__va_reg_size 4
120178172Simp
121178172Simp#if defined(__MIPSEB__) || (BYTE_ORDER == BIG_ENDIAN)
122178172Simp/* For big-endian machines.  */
123178172Simp#define	va_arg(__AP, __type)					\
124178172Simp	((__AP = (char *) ((__alignof__ (__type) > 4		\
125178172Simp	    ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8		\
126178172Simp	    : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4)		\
127178172Simp	    + __va_rounded_size (__type))),			\
128178172Simp	*(__type *) (void *) (__AP - __va_rounded_size (__type)))
129178172Simp#else	/* ! __MIPSEB__ && !BYTE_ORDER == BIG_ENDIAN */
130178172Simp/* For little-endian machines.	*/
131178172Simp#define	va_arg(__AP, __type)						\
132178172Simp	((__type *) (void *) (__AP = (char *) ((__alignof__(__type) > 4	\
133178172Simp	    ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8			\
134178172Simp	    : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4)			\
135178172Simp	    + __va_rounded_size(__type))))[-1]
136178172Simp#endif	/* ! __MIPSEB__ && !BYTE_ORDER == BIG_ENDIAN */
137178172Simp#endif	/* ! __mips64 */
138178172Simp
139178172Simp/* Copy __gnuc_va_list into another variable of this type.  */
140178172Simp#define	__va_copy(dest, src)	(dest) = (src)
141178172Simp#define	va_copy(dest, src)	(dest) = (src)
142178172Simp
143178172Simp#endif /* __GNUC__ */
144178172Simp#endif /* _MACHINE_STDARG_H_ */
145