11539Srgrimes/* Note:  We must use the name __builtin_savregs.  GCC attaches special
21539Srgrimes   significance to that name.  In particular, regardless of where in a
31539Srgrimes   function __builtin_saveregs is called, GCC moves the call up to the
41539Srgrimes   very start of the function.  */
51539Srgrimes
61539Srgrimes
71539Srgrimes/* Define __gnuc_va_list.  */
81539Srgrimes
91539Srgrimes#ifndef __GNUC_VA_LIST
101539Srgrimes#define __GNUC_VA_LIST
111539Srgrimes
121539Srgrimestypedef union {
131539Srgrimes  float		__freg[8];
141539Srgrimes  double	__dreg[4];
151539Srgrimes} __f_regs;
161539Srgrimes
171539Srgrimestypedef struct {
181539Srgrimes#if defined (__SVR4__) || defined (__svr4__) || defined (__alliant__) || defined (__PARAGON__)
191539Srgrimes  __f_regs __float_regs; long __ireg[12];
201539Srgrimes#else /* pre-SVR4 */
211539Srgrimes  long __ireg[12]; __f_regs __float_regs;
221539Srgrimes#endif
231539Srgrimes} __va_saved_regs;
241539Srgrimes
251539Srgrimestypedef struct {
261539Srgrimes#if defined(__SVR4__) || defined(__svr4__) || defined(__alliant__) || defined (__PARAGON__)
271539Srgrimes  unsigned	__ireg_used;	/* How many int regs consumed 'til now? */
281539Srgrimes  unsigned	__freg_used;	/* How many flt regs consumed 'til now? */
291539Srgrimes  long		*__reg_base;	/* Address of where we stored the regs. */
301539Srgrimes  long *	__mem_ptr;	/* Address of memory overflow args area. */
311539Srgrimes#else /* pre-SVR4 */
321539Srgrimes  long		*__reg_base;	/* Address of where we stored the regs. */
3323650Speter  long *	__mem_ptr;	/* Address of memory overflow args area. */
3478169Sru  unsigned	__ireg_used;	/* How many int regs consumed 'til now? */
351539Srgrimes  unsigned	__freg_used;	/* How many flt regs consumed 'til now? */
361539Srgrimes#endif
371539Srgrimes} __gnuc_va_list;
381539Srgrimes#endif /* not __GNUC_VA_LIST */
391539Srgrimes
401539Srgrimes/* If this is for internal libc use, don't define anything but
411539Srgrimes   __gnuc_va_list.  */
421539Srgrimes#if defined (_STDARG_H) || defined (_VARARGS_H)
431539Srgrimes
441539Srgrimes#if !defined(_STDARG_H)
451539Srgrimes
461539Srgrimes/* varargs support */
471539Srgrimes#define va_alist __builtin_va_alist
481539Srgrimes#if defined (__PARAGON__)
4978169Sru#define va_dcl int va_alist;
50103726Swollman#else	/* __PARAGON__ */
511539Srgrimes#define va_dcl
521539Srgrimes#endif	/* __PARAGON__ */
531539Srgrimes#define va_start(pvar) ((pvar) = * (__gnuc_va_list *) __builtin_saveregs ())
541539Srgrimes
551539Srgrimes#else /* STDARG.H */
561539Srgrimes
571539Srgrimes/* ANSI alternative.  */
581539Srgrimes/* Note that CUMULATIVE_ARGS elements are measured in bytes on the i860,
5923650Speter   so we divide by 4 to get # of registers.  */
6023650Speter#define va_start(pvar, firstarg) \
611539Srgrimes ((pvar) = *(__gnuc_va_list *) __builtin_saveregs (),			\
6223650Speter  (pvar).__ireg_used = __builtin_args_info (0) / 4,		\
6323650Speter  (pvar).__freg_used = __builtin_args_info (1) / 4,		\
641539Srgrimes  (pvar).__mem_ptr = __builtin_next_arg (firstarg))
65103726Swollman
661539Srgrimes#endif /* _STDARG_H */
671539Srgrimes
681539Srgrimes/* Values returned by __builtin_classify_type.  */
691539Srgrimes
701539Srgrimes#ifndef va_end
711539Srgrimesenum {
721539Srgrimes  __no_type_class = -1,
731539Srgrimes  __void_type_class,
741539Srgrimes  __integer_type_class,
751539Srgrimes  __char_type_class,
761539Srgrimes  __enumeral_type_class,
771539Srgrimes  __boolean_type_class,
781539Srgrimes  __pointer_type_class,
791539Srgrimes  __reference_type_class,
801539Srgrimes  __offset_type_class,
811539Srgrimes  __real_type_class,
821539Srgrimes  __complex_type_class,
831539Srgrimes  __function_type_class,
841539Srgrimes  __method_type_class,
851539Srgrimes  __record_type_class,
861539Srgrimes  __union_type_class,
871539Srgrimes  __array_type_class,
881539Srgrimes  __string_type_class,
891539Srgrimes  __set_type_class,
901539Srgrimes  __file_type_class,
911539Srgrimes  __lang_type_class
921539Srgrimes};
931539Srgrimes
941539Srgrimesvoid va_end (__gnuc_va_list);		/* Defined in libgcc.a */
951539Srgrimes#endif
961539Srgrimes#define va_end(__va)	((void) 0)
971539Srgrimes
981539Srgrimes#define __NUM_PARM_FREGS	8
991539Srgrimes#define __NUM_PARM_IREGS	12
1001539Srgrimes
1011539Srgrimes#define __savereg(__va) ((__va_saved_regs *) ((__va).__reg_base))
10223650Speter
1031539Srgrimes/* This macro works both for SVR4 and pre-SVR4 environments.  */
1041539Srgrimes
1051539Srgrimes/* Note that parameters are always aligned at least to a word boundary
1061539Srgrimes   (when passed) regardless of what GCC's __alignof__ operator says.  */
10723650Speter
1081539Srgrimes/* Make allowances here for adding 128-bit (long double) floats someday.  */
1091539Srgrimes
1101539Srgrimes#if 0 /* What was this for? */
1111539Srgrimes#ifndef __GNU_VA_LIST
1121539Srgrimes#define __ireg_used ireg_used
1131539Srgrimes#define __freg_used freg_used
1141539Srgrimes#define __mem_ptr mem_ptr
1151539Srgrimes#define __reg_base reg_base
1161539Srgrimes#endif
117103726Swollman#endif /* 0 */
118103726Swollman
1191539Srgrimes/* Avoid errors if compiling GCC v2 with GCC v1.  */
1201539Srgrimes#if __GNUC__ == 1
1211539Srgrimes#define __extension__
1221539Srgrimes#endif
1231539Srgrimes
12493032Simp#define va_arg(__va, __type)						\
12593032Simp__extension__								\
126103726Swollman(* (__type *)								\
127103726Swollman({									\
128103726Swollman  register void *__rv;  /* result value */				\
129103726Swollman  register unsigned __align;						\
13093032Simp  switch (__builtin_classify_type (* (__type *) 0))			\
131103726Swollman    {									\
13293032Simp    case __real_type_class:						\
13393032Simp      switch (sizeof (__type))						\
134103726Swollman	{								\
1351539Srgrimes	  case sizeof (float):						\
1361539Srgrimes	  case sizeof (double):						\
1371539Srgrimes	    if ((__va).__freg_used < __NUM_PARM_FREGS - 1)		\
138	      {								\
139	        if (((__va).__freg_used & 1) != 0)			\
140	          (__va).__freg_used++;	/* skip odd */			\
141	        __rv = &__savereg((__va))->__float_regs.__freg[(__va).__freg_used];\
142		(__va).__freg_used += 2;				\
143	      }								\
144	    else							\
145	      {								\
146	        if ((((unsigned) (__va).__mem_ptr) & (sizeof(double)-1)) != 0) \
147	          (__va).__mem_ptr++;	/* skip odd */			\
148	        __rv = (__va).__mem_ptr;				\
149	        (__va).__mem_ptr += 2;					\
150	      }								\
151	    if (sizeof (__type) == sizeof (float))			\
152	      {								\
153	        *((float *) __rv) = *((double *) __rv);			\
154		*(((long *) __rv) + 1) = 0xfff00001;			\
155	      }								\
156	    break;							\
157	  default:							\
158	    abort ();							\
159	}								\
160      break;								\
161    case __void_type_class:						\
162    case __integer_type_class:						\
163    case __char_type_class:						\
164    case __enumeral_type_class:						\
165    case __boolean_type_class:						\
166    case __pointer_type_class:						\
167    case __reference_type_class:					\
168    case __offset_type_class:						\
169      if (sizeof (__type) <= 4)						\
170	{								\
171          __rv = ((__va).__ireg_used < __NUM_PARM_IREGS			\
172	          ? (&__savereg((__va))->__ireg[(__va).__ireg_used++])	\
173	          : (__va).__mem_ptr++);				\
174	  break;							\
175	}								\
176      else if ((__va).__ireg_used + sizeof (__type) / 4 <= __NUM_PARM_IREGS) \
177	{								\
178	  __rv = &__savereg((__va))->__ireg[(__va).__ireg_used];	\
179	  (__va).__ireg_used += sizeof (__type) / 4;			\
180          break;							\
181	}								\
182      /* Fall through to fetch from memory.  */				\
183    case __record_type_class:						\
184    case __union_type_class:						\
185      __align = (__alignof__ (__type) < sizeof (long)			\
186		 ? sizeof (long)					\
187		 : __alignof__ (__type));				\
188      (__va).__mem_ptr							\
189	= (long *)							\
190	  ((((unsigned) (__va).__mem_ptr) + (__align-1)) & ~(__align-1)); \
191      __rv = (__va).__mem_ptr;						\
192      (__va).__mem_ptr							\
193	+= ((sizeof (__type) + sizeof (long) - 1) / sizeof (long));	\
194      break;								\
195    case __complex_type_class:						\
196    case __function_type_class:						\
197    case __method_type_class:						\
198    case __array_type_class:						\
199    case __string_type_class:						\
200    case __set_type_class:						\
201    case __file_type_class:						\
202    case __lang_type_class:						\
203    case __no_type_class:						\
204    default:								\
205	abort ();							\
206    }									\
207  __rv;									\
208}))
209
210/* Copy __gnuc_va_list into another variable of this type.  */
211#define __va_copy(dest, src) (dest) = (src)
212
213#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
214
215