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
16typedef __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
39typedef char * __gnuc_va_list;
40typedef __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
49enum {
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