stdarg.h revision 85113
11638Srgrimes/*-
21638Srgrimes * Copyright (c) 2000 Tsubai Masanari.  All rights reserved.
31638Srgrimes *
41638Srgrimes * Redistribution and use in source and binary forms, with or without
51638Srgrimes * modification, are permitted provided that the following conditions
61638Srgrimes * are met:
71638Srgrimes * 1. Redistributions of source code must retain the above copyright
81638Srgrimes *    notice, this list of conditions and the following disclaimer.
91638Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
101638Srgrimes *    notice, this list of conditions and the following disclaimer in the
111638Srgrimes *    documentation and/or other materials provided with the distribution.
121638Srgrimes * 3. The name of the author may not be used to endorse or promote products
131638Srgrimes *    derived from this software without specific prior written permission.
141638Srgrimes *
151638Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
161638Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
171638Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
181638Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
191638Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
201638Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
211638Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
221638Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
231638Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
241638Srgrimes * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
251638Srgrimes *
261638Srgrimes *	$NetBSD: stdarg.h,v 1.5 2000/02/27 17:50:21 tsubai Exp $
271638Srgrimes * $FreeBSD: head/sys/powerpc/include/stdarg.h 85113 2001-10-18 19:11:12Z mp $
281638Srgrimes */
291638Srgrimes
301638Srgrimes#ifndef _POWERPC_STDARG_H_
311638Srgrimes#define	_POWERPC_STDARG_H_
321638Srgrimes
331638Srgrimes#include <machine/ansi.h>
34108533Sschweikh
35108533Sschweikh#if 0
361638Srgrimestypedef struct {
371638Srgrimes	char __gpr;	/* GPR offset */
381638Srgrimes	char __fpr;	/* FPR offset */
391638Srgrimes/*	char __pad[2]; */
401638Srgrimes	char *__stack;	/* args passed on stack */
411638Srgrimes	char *__base;	/* args passed by registers (r3-r10, f1-f8) */
421638Srgrimes} va_list;
431638Srgrimes#endif
441638Srgrimes
451638Srgrimestypedef _BSD_VA_LIST_	va_list;
461638Srgrimes
471638Srgrimes#ifdef __lint__
481638Srgrimes
491638Srgrimes#define	va_start(ap, last)	((ap) = *(va_list *)0)
501638Srgrimes#define	va_arg(ap, type)	(*(type *)(void *)&(ap))
511638Srgrimes
521638Srgrimes#else
531638Srgrimes
541638Srgrimes#if defined __GNUC__ && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ == 95)
551638Srgrimes#define	va_start(ap, last)						\
561638Srgrimes	(__builtin_next_arg(last),					\
571638Srgrimes	 __builtin_memcpy ((ap), __builtin_saveregs (), sizeof(__gnuc_va_list)))
581638Srgrimes#else
591638Srgrimes#define	va_start(ap, last)						\
601638Srgrimes	(__builtin_next_arg(last),					\
611638Srgrimes	 (ap).__stack = __va_stack_args,				\
621638Srgrimes	 (ap).__base = __va_reg_args,					\
631638Srgrimes	 (ap).__gpr = __va_first_gpr,					\
641638Srgrimes	 (ap).__fpr = __va_first_fpr)
651638Srgrimes#endif
661638Srgrimes
671638Srgrimes#define	__va_first_gpr	(__builtin_args_info(0))
681638Srgrimes#define	__va_first_fpr	(__builtin_args_info(1) - 32 - 1)
691638Srgrimes#define	__va_stack_args							\
701638Srgrimes	((char *)__builtin_saveregs() +					\
711638Srgrimes	 (__va_first_gpr >= 8 ? __va_first_gpr - 8 : 0) * sizeof(int))
721638Srgrimes#define	__va_reg_args							\
731638Srgrimes	((char *)__builtin_frame_address(0) + __builtin_args_info(4))
741638Srgrimes
751638Srgrimes#define	__INTEGER_TYPE_CLASS	1
761638Srgrimes#define	__REAL_TYPE_CLASS	8
771638Srgrimes#define	__RECORD_TYPE_CLASS	12
781638Srgrimes
791638Srgrimes#define	__va_longlong(type)						\
801638Srgrimes	(__builtin_classify_type(*(type *)0) == __INTEGER_TYPE_CLASS &&	\
811638Srgrimes	 sizeof(type) == 8)
821638Srgrimes
831638Srgrimes#define	__va_double(type)						\
841638Srgrimes	(__builtin_classify_type(*(type *)0) == __REAL_TYPE_CLASS)
851638Srgrimes
861638Srgrimes#define	__va_struct(type)						\
871638Srgrimes	(__builtin_classify_type(*(type *)0) >= __RECORD_TYPE_CLASS)
881638Srgrimes
891638Srgrimes#define	__va_size(type)							\
901638Srgrimes	((sizeof(type) + sizeof(int) - 1) / sizeof(int) * sizeof(int))
911638Srgrimes
921638Srgrimes#if defined __GNUC__ && (__GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ == 95)
931638Srgrimes#define	__va_savedgpr(ap, type)						\
941638Srgrimes	((ap)->__base + (ap)->__gpr * sizeof(int) - sizeof(type))
951638Srgrimes
961638Srgrimes#define	__va_savedfpr(ap, type)						\
971638Srgrimes	((ap)->__base + 8 * sizeof(int) + (ap)->__fpr * sizeof(double) -	\
981638Srgrimes	 sizeof(type))
991638Srgrimes
1001638Srgrimes#define	__va_stack(ap, type)						\
1011638Srgrimes	((ap)->__stack += __va_size(type) +				\
1021638Srgrimes			(__va_longlong(type) ? (int)(ap)->__stack & 4 : 0), \
1031638Srgrimes	 (ap)->__stack - sizeof(type))
1041638Srgrimes
1051638Srgrimes#define	__va_gpr(ap, type)						\
1061638Srgrimes	((ap)->__gpr += __va_size(type) / sizeof(int) +			\
1071638Srgrimes		      (__va_longlong(type) ? (ap)->__gpr & 1 : 0),	\
1081638Srgrimes	 (ap)->__gpr <= 8 ? __va_savedgpr(ap, type) : __va_stack(ap, type))
1091638Srgrimes
1101638Srgrimes#define	__va_fpr(ap, type)						\
1111638Srgrimes	((ap)->__fpr++,							\
1121638Srgrimes	 (ap)->__fpr <= 8 ? __va_savedfpr(ap, type) : __va_stack(ap, type))
1131638Srgrimes#else
1141638Srgrimes#define	__va_savedgpr(ap, type)						\
1151638Srgrimes	((ap).__base + (ap).__gpr * sizeof(int) - sizeof(type))
1161638Srgrimes
1171638Srgrimes#define	__va_savedfpr(ap, type)						\
1181638Srgrimes	((ap).__base + 8 * sizeof(int) + (ap).__fpr * sizeof(double) -	\
1191638Srgrimes	 sizeof(type))
1201638Srgrimes
1211638Srgrimes#define	__va_stack(ap, type)						\
1221638Srgrimes	((ap).__stack += __va_size(type) +				\
1231638Srgrimes			(__va_longlong(type) ? (int)(ap).__stack & 4 : 0), \
1241638Srgrimes	 (ap).__stack - sizeof(type))
1251638Srgrimes
1261638Srgrimes#define	__va_gpr(ap, type)						\
1271638Srgrimes	((ap).__gpr += __va_size(type) / sizeof(int) +			\
1281638Srgrimes		      (__va_longlong(type) ? (ap).__gpr & 1 : 0),	\
1291638Srgrimes	 (ap).__gpr <= 8 ? __va_savedgpr(ap, type) : __va_stack(ap, type))
1301638Srgrimes
1311638Srgrimes#define	__va_fpr(ap, type)						\
1321638Srgrimes	((ap).__fpr++,							\
1331638Srgrimes	 (ap).__fpr <= 8 ? __va_savedfpr(ap, type) : __va_stack(ap, type))
1341638Srgrimes#endif
1351638Srgrimes
1361638Srgrimes#define	va_arg(ap, type)						\
1371638Srgrimes	(*(type *)(__va_struct(type) ? (*(void **)__va_gpr(ap, void *)) : \
1381638Srgrimes		   __va_double(type) ? __va_fpr(ap, type) :		\
1391638Srgrimes		   __va_gpr(ap, type)))
1401638Srgrimes
1411638Srgrimes#endif /* __lint__ */
1421638Srgrimes
1431638Srgrimes#define	va_end(ap)
1441638Srgrimes
1451638Srgrimes#if !defined(_ANSI_SOURCE) &&						\
1461638Srgrimes    (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE) ||		\
1471638Srgrimes     defined(_ISOC99_SOURCE) || (__STDC_VERSION__ - 0) >= 199901L)
1481638Srgrimes#define	va_copy(dest, src)						\
1491638Srgrimes	((dest) = (src))
1501638Srgrimes#endif
1511638Srgrimes
1521638Srgrimes#endif /* _POWERPC_STDARG_H_ */
1531638Srgrimes