summaryrefslogtreecommitdiffstats
path: root/sys/mips/include/stdarg.h
blob: 802ea73c95e2206f1b9f466875f3ce53ed065e00 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 *	JNPR: stdarg.h,v 1.3 2006/09/15 12:52:34 katta
 * $FreeBSD$
 */

#ifndef _MACHINE_STDARG_H_
#define	_MACHINE_STDARG_H_
#include <sys/cdefs.h>
#include <sys/_types.h>


#if __GNUC__ >= 3

#ifndef _VA_LIST_DECLARED
#define	_VA_LIST_DECLARED
typedef __va_list	va_list;
#endif
#define	va_start(v,l)	__builtin_va_start((v),l)
#define	va_end		__builtin_va_end
#define	va_arg		__builtin_va_arg
#define	va_copy		__builtin_va_copy

#else  /* __GNUC__ */


/* ---------------------------------------- */
/*	     VARARGS  for MIPS/GNU CC	    */
/* ---------------------------------------- */

#include <machine/endian.h>

/* These macros implement varargs for GNU C--either traditional or ANSI.  */

/* Define __gnuc_va_list.  */

#ifndef __GNUC_VA_LIST
#define	__GNUC_VA_LIST

typedef char * __gnuc_va_list;
typedef __gnuc_va_list va_list;

#endif /* ! __GNUC_VA_LIST */

/* If this is for internal libc use, don't define anything but
   __gnuc_va_list.  */

#ifndef _VA_MIPS_H_ENUM
#define	_VA_MIPS_H_ENUM
enum {
	__no_type_class = -1,
	__void_type_class,
	__integer_type_class,
	__char_type_class,
	__enumeral_type_class,
	__boolean_type_class,
	__pointer_type_class,
	__reference_type_class,
	__offset_type_class,
	__real_type_class,
	__complex_type_class,
	__function_type_class,
	__method_type_class,
	__record_type_class,
	__union_type_class,
	__array_type_class,
	__string_type_class,
	__set_type_class,
	__file_type_class,
	__lang_type_class
};
#endif

/* In GCC version 2, we want an ellipsis at the end of the declaration
   of the argument list.  GCC version 1 can't parse it.	 */

#if __GNUC__ > 1
#define	__va_ellipsis ...
#else
#define	__va_ellipsis
#endif


#define	va_start(__AP, __LASTARG) \
	(__AP = (__gnuc_va_list) __builtin_next_arg (__LASTARG))

#define	va_end(__AP)	((void)0)


/* We cast to void * and then to TYPE * because this avoids
   a warning about increasing the alignment requirement.  */
/* The __mips64 cases are reversed from the 32 bit cases, because the standard
   32 bit calling convention left-aligns all parameters smaller than a word,
   whereas the __mips64 calling convention does not (and hence they are
   right aligned).  */

#ifdef __mips64

#define	__va_rounded_size(__TYPE)	(((sizeof (__TYPE) + 8 - 1) / 8) * 8)

#define	__va_reg_size			8

#if defined(__MIPSEB__) || (BYTE_ORDER == BIG_ENDIAN)
#define	va_arg(__AP, __type)						\
	((__type *) (void *) (__AP = (char *)				\
	    ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8)			\
	    + __va_rounded_size (__type))))[-1]
#else	/* ! __MIPSEB__ && !BYTE_ORDER == BIG_ENDIAN */
#define	va_arg(__AP, __type)						\
	((__AP = (char *) ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8)	\
	    + __va_rounded_size (__type))),				\
	    *(__type *) (void *) (__AP - __va_rounded_size (__type)))
#endif	/* ! __MIPSEB__ && !BYTE_ORDER == BIG_ENDIAN */

#else	/* ! __mips64 */

#define	__va_rounded_size(__TYPE)					\
	(((sizeof (__TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))

#define	__va_reg_size 4

#if defined(__MIPSEB__) || (BYTE_ORDER == BIG_ENDIAN)
/* For big-endian machines.  */
#define	va_arg(__AP, __type)					\
	((__AP = (char *) ((__alignof__ (__type) > 4		\
	    ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8		\
	    : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4)		\
	    + __va_rounded_size (__type))),			\
	*(__type *) (void *) (__AP - __va_rounded_size (__type)))
#else	/* ! __MIPSEB__ && !BYTE_ORDER == BIG_ENDIAN */
/* For little-endian machines.	*/
#define	va_arg(__AP, __type)						\
	((__type *) (void *) (__AP = (char *) ((__alignof__(__type) > 4	\
	    ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8			\
	    : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4)			\
	    + __va_rounded_size(__type))))[-1]
#endif	/* ! __MIPSEB__ && !BYTE_ORDER == BIG_ENDIAN */
#endif	/* ! __mips64 */

/* Copy __gnuc_va_list into another variable of this type.  */
#define	__va_copy(dest, src)	(dest) = (src)
#define	va_copy(dest, src)	(dest) = (src)

#endif /* __GNUC__ */
#endif /* _MACHINE_STDARG_H_ */
OpenPOWER on IntegriCloud