/*
**  stdarg.h            ANSI C++, ANSI C, and K&R Runtime Library
**
**  Copyright (C)       Microway, Inc. 1987 - 1994.
**                      P.O. BOX 79
**                      Kingston, MA. 02364
**                      (508) 746 - 7341 Voice
**                      (508) 746 - 4678 FAX
**                      e-mail uunet!microway!mark
**                             mark@microway.com
**
**  This program is the property of Microway, Inc, its contents are
**  proprietary information and no part of it is to be disclosed to anyone
**  except employees of Microway, Inc., or as agreed in writing by the
**  President of Microway, Inc.
*/

#ifndef _STDARG_H
#define _STDARG_H

/* in winuser.h, #include "stdarg.h" is specified, which brings in the NT
   stdarg.h, not the NDP stdarg.h. The following guard will prevent the
   NT stdarg.h from being used.
*/
#ifdef __WIN32__
#define _INC_STDARG
#endif
#if defined(__STDC__) || defined(__NDPX__)

#if defined(__ALPHA__)

#ifndef _VA_LIST
#define _VA_LIST

typedef struct
 {
  unsigned int sp_offset;  /* byte offset of the parameter in the stack    */
  unsigned int rr_offset;  /* byte offset of the parameter in the core reg */
  unsigned int fr_offset;  /* byte offset of the parameter in the fp reg   */
  unsigned int rr_max_offset;  /* maximum byte offset in the core reg      */
  unsigned int fr_max_offset;  /* maximum byte offset in the fp reg        */
  char *sp_buf;    /* stack parameter space     */
 }
va_list;

#endif

/*
   '___builtin_va_start' sets up offsets the 'va_list' structure
   the second parameter, which must be a scalara number, determines
   which offset will be affected:
      1 - sp_offset
      2 - rr_offset
      3 - fr_offset
      4 - rr_max_offset
      5 - fr_max_offset
      6 - sp_buf
*/
extern long ___builtin_va_start(...);
/*
   '___builtin_isfloat(...)' return 1 if it argument is of floating point type
                                   0 otherwise
*/
extern int ___builtin_isfloat(...);


#define va_start(list,v)  ( (list).sp_offset = ___builtin_va_start( v, 1 ), \
                            (list).rr_offset = ___builtin_va_start( v, 2 ), \
                            (list).fr_offset = ___builtin_va_start( v, 3 ), \
                        (list).rr_max_offset = ___builtin_va_start( v, 4 ), \
                        (list).fr_max_offset = ___builtin_va_start( v, 5 ), \
                    (list).sp_buf = ( char * ) ___builtin_va_start( v, 6 )  \
                          )

#define va_end(list)

#define va_arg(l,mode)                                                 \
    ( *(  ( (l).rr_offset += ( ( int )sizeof(mode) + 7) & -8 ) ,       \
          ( (l).fr_offset += ( ( int )sizeof(mode) + 7) & -8 ) ,       \
 ( (l).sp_offset = ( (l).rr_offset > (l).rr_max_offset ) ?             \
      ( (l).sp_offset + ( ( ( int )sizeof(mode) + 7) & -8 ) )   :      \
      (l).sp_offset                                                    \
 ),                                                                    \
                                                                       \
       ___builtin_isfloat( ( mode ) (l).sp_offset ) ?                    \
          (                                                            \
           (mode *)( (l).sp_buf +                                      \
                            ( ( (l).fr_offset <= (l).fr_max_offset ) ? \
                              (l).fr_offset : (l).sp_offset )          \
                   )                                                   \
          )                                                            \
                                                  :                    \
          (                                                            \
           (mode *)( (l).sp_buf +                                      \
                            ( ( (l).rr_offset <= (l).rr_max_offset ) ? \
                              (l).rr_offset : (l).sp_offset )          \
                   )                                                   \
          )                                                            \
       )                                                               \
    )



#else

#ifndef _VA_LIST
#define _VA_LIST

typedef char *va_list;

#endif

#define va_end(_Ignore)
/* Nothing comes smaller than an int in argument lists */
#define _SIZ(_S) (sizeof(_S) < sizeof(int) ? sizeof(int) : sizeof(_S))
#define va_start(ap,_P)  (void)((ap) = (va_list)(((char *) &_P) + sizeof(_P)))
#define va_arg(ap,_Type) (*(_Type *)((ap += _SIZ(_Type)) - _SIZ(_Type)))

#endif /* __ALPHA__ */

#else /* K&R version, formerly <varargs.h> */

#ifndef _VARARGS_H

typedef char *va_list;
#define va_end(_Ignore)
#define va_dcl                  int va_alist;
#define va_start(ap)    (ap) = (char *)(&va_alist)
#define va_arg(ap,_Mode) *((_Mode *)(ap))++

#endif /* _VARARGS_H */

#endif /* _STDC__ || __NDPX__ */

#endif /* _STDARG_H */
