xref: /csrg-svn/sys/sparc/include/stdarg.h (revision 63320)
155126Storek /*
2*63320Sbostic  * Copyright (c) 1992, 1993
3*63320Sbostic  *	The Regents of the University of California.  All rights reserved.
455126Storek  *
555126Storek  * This software was developed by the Computer Systems Engineering group
655126Storek  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
755126Storek  * contributed to Berkeley.
855126Storek  *
955501Sbostic  * All advertising materials mentioning features or use of this software
1055501Sbostic  * must display the following acknowledgement:
1155501Sbostic  *	This product includes software developed by the University of
1259210Storek  *	California, Lawrence Berkeley Laboratory.
1355501Sbostic  *
1455126Storek  * %sccs.include.redist.c%
1555126Storek  *
16*63320Sbostic  *	@(#)stdarg.h	8.1 (Berkeley) 06/11/93
1755126Storek  *
1859792Storek  * from: $Header: stdarg.h,v 1.8 93/05/07 18:10:14 torek Exp $
1955126Storek  */
2055126Storek 
2155126Storek /*
2255126Storek  * SPARC stdarg.h
2355126Storek  */
2455126Storek 
2555126Storek #ifndef _MACHINE_STDARG_H
2655126Storek #define _MACHINE_STDARG_H
2755126Storek 
2855126Storek typedef char *va_list;
2955126Storek 
3055126Storek /*
3155126Storek  * va_start sets ap to point to the first variable argument.
3255126Storek  * The `last fixed argument' parameter l is ignored (and should
3355126Storek  * never have been included in the ANSI standard!).
3455126Storek  *
3555126Storek  * va_end cleans up after va_start.  There is nothing to do there.
3655126Storek  */
3755126Storek #define va_start(ap, l)	(__builtin_saveregs(), \
3855126Storek 			 ap = (char *)__builtin_next_arg())
3955126Storek #define va_end(ap)	/* empty */
4055126Storek 
4156566Storek #if __GNUC__ == 1
4256566Storek #define __extension__	/* hack for bootstrapping via gcc 1.x */
4356566Storek #endif
4456566Storek 
4555126Storek /*
4656566Storek  * va_arg picks up the next argument of type `ty'.  Appending an
4756566Storek  * asterisk to ty must produce a pointer to ty (i.e., ty may not be,
4856566Storek  * e.g., `int (*)()').  In addition, ty must not be any type which
4955126Storek  * undergoes promotion to some other type (e.g., char): it must
5055126Storek  * be the promoted type instead.
5156566Storek  *
5256566Storek  * Gcc-2.x tries to use ldd/std for double and quad_t values, but Sun's
5356566Storek  * brain-damaged calling convention does not quad-align these.  Thus,
5456566Storek  * for 8-byte arguments, we have to pick up the actual value four bytes
5556566Storek  * at a time, and use type punning (i.e., a union) to produce the result.
5656566Storek  * (We could also do this with a libc function, actually, by returning
5756566Storek  * 8 byte integers in %o0+%o1 and the same 8 bytes as a double in %f0+%f1.)
5859792Storek  *
5959792Storek  * Note: we cannot use the union trick (which generates better code) for
6059792Storek  * C++, since `ty' might be a type with a constructor (these may not appear
6159792Storek  * in a union).
6259792Storek  *
6359792Storek  * The extraneous casts through `void *' avoid gcc alignment warnings.
6455126Storek  */
6559792Storek #ifdef __cplusplus
6659792Storek #define	__va_8byte(ap, ty) ({ \
6759792Storek 	int __va_i[2]; \
6859792Storek 	__va_i[0] = ((int *)(void *)(ap))[0]; \
6959792Storek 	__va_i[1] = ((int *)(void *)(ap))[1]; \
7059792Storek 	(ap) += 8; *(ty *)(void *)__va_i; })
7159792Storek #else
7259792Storek #define	__va_8byte(ap, ty) ({ \
7359792Storek 	union { ty __d; int __i[2]; } __va_u; \
7459792Storek 	__va_u.__i[0] = ((int *)(void *)(ap))[0]; \
7559792Storek 	__va_u.__i[1] = ((int *)(void *)(ap))[1]; \
7659792Storek 	(ap) += 8; __va_u.__d; })
7759792Storek #endif /* __cplusplus */
7855126Storek 
7959792Storek #define va_arg(ap, ty) __extension__ ({ \
8059792Storek     ty __va_temp; /* to check for invisible-ptr struct-valued args */ \
8159792Storek     __builtin_classify_type(__va_temp) >= 12 ? \
8259792Storek 	((ty **)(void *)((ap) += sizeof(ty *)))[-1][0] : \
8359792Storek     sizeof(ty) == 8 ? __va_8byte(ap, ty) : \
8459792Storek 	((ty *)(void *)(ap += sizeof(ty)))[-1]; })
8559792Storek 
8655126Storek #endif /* _MACHINE_STDARG_H */
87