home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 April / PCWorld_2000-04_cd.bin / Software / Servis / Devc / _SETUP.6 / Group15 / va-pyr.h < prev    next >
C/C++ Source or Header  |  1999-11-07  |  4KB  |  131 lines

  1. /**
  2.  *
  3.  *     Varargs for PYR/GNU CC
  4.  *
  5.  * WARNING -- WARNING -- DANGER
  6.  *
  7.  * The code in this file implements varargs for gcc on a pyr in
  8.  * a way that is compatible with code compiled by the Pyramid Technology
  9.  * C compiler.
  10.  * As such, it depends strongly on the Pyramid conventions for
  11.  * parameter passing.ct and independent implementation. 
  12.  * These (somewhat bizarre) parameter-passing conventions are described
  13.  * in the ``OSx Operating System Porting Guide''.
  14.  * 
  15.  * A quick summary is useful:
  16.  * 12 of the 48 register-windowed regs available for
  17.  * parameter passing.  Parameters of a function call that are eligible
  18.  * to be passed in registers are assigned registers from TR0/PR0 onwards;
  19.  * all other arguments are passed on the stack.
  20.  * Structure and union parameters are *never* passed in registers,
  21.  * even if they are small enough to fit.  They are always passed on
  22.  * the stack.
  23.  *
  24.  * Double-sized parameters cannot be passed in TR11, because
  25.  * TR12 is not used for passing parameters.  If, in the absence of this
  26.  * rule, a double-sized param would have been passed in TR11,
  27.  * that parameter is passed on the stack and no parameters are
  28.  * passed in TR11.
  29.  * 
  30.  * It is only known to work for passing 32-bit integer quantities
  31.  * (ie chars, shorts, ints/enums, longs), doubles, or pointers. 
  32.  * Passing structures on a Pyramid via varargs is a loser.
  33.  * Passing an object larger than 8 bytes on a pyramid via varargs may
  34.  * also be a loser.
  35.  * 
  36.  */
  37.  
  38.  
  39. /*
  40.  *  pointer to next stack parameter in __va_buf[0]
  41.  *  pointer to next parameter register in __va_buf[1]
  42.  *  Count of registers seen at __va_buf[2]
  43.  *  saved pr0..pr11 in __va_buf[3..14]
  44.  *  # of calls to va_arg (debugging) at __va_buf[15]
  45.  */
  46.  
  47. /* Define __gnuc_va_list.  */
  48.  
  49. #ifndef __GNUC_VA_LIST
  50. #define __GNUC_VA_LIST
  51.  
  52. typedef void *__voidptr;
  53. #if 1
  54.  
  55. typedef struct __va_regs {
  56.       __voidptr __stackp,__regp,__count;
  57.       __voidptr __pr0,__pr1,__pr2,__pr3,__pr4,__pr5,__pr6,__pr7,__pr8,__pr9,__pr10,__pr11;
  58.   } __va_regs;
  59.  
  60. typedef __va_regs __va_buf;
  61. #else
  62.  
  63. /* __va_buf[0] = address of next arg passed on the stack
  64.    __va_buf[1] = address of next arg passed in a register
  65.    __va_buf[2] = register-# of next arg passed in a register
  66.  */
  67. typedef __voidptr(*__va_buf);
  68.  
  69. #endif
  70.  
  71. typedef __va_buf __gnuc_va_list;
  72.  
  73. #endif /* not __GNUC_VA_LIST */
  74.  
  75. /* If this is for internal libc use, don't define anything but
  76.    __gnuc_va_list.  */
  77. #if defined (_STDARG_H) || defined (_VARARGS_H)
  78.  
  79. /* In GCC version 2, we want an ellipsis at the end of the declaration
  80.    of the argument list.  GCC version 1 can't parse it.  */
  81.  
  82. #if __GNUC__ > 1
  83. #define __va_ellipsis ...
  84. #else
  85. #define __va_ellipsis
  86. #endif
  87.  
  88. #define va_alist \
  89.   __va0,__va1,__va2,__va3,__va4,__va5,__va6,__va7,__va8,__va9,__va10,__va11, \
  90.  __builtin_va_alist
  91.  
  92. /* The ... causes current_function_varargs to be set in cc1.  */
  93. #define va_dcl __voidptr va_alist; __va_ellipsis
  94.  
  95.  
  96. /* __asm ("rcsp %0" : "=r" ( _AP [0]));*/
  97.  
  98. #define va_start(_AP)  \
  99.   _AP =  ((struct __va_regs) {                        \
  100.    &(_AP.__pr0), (void*)&__builtin_va_alist, (void*)0,            \
  101.         __va0,__va1,__va2,__va3,__va4,__va5,                \
  102.     __va6,__va7,__va8,__va9,__va10,__va11})
  103.  
  104.  
  105. /* Avoid errors if compiling GCC v2 with GCC v1.  */
  106. #if __GNUC__ == 1
  107. #define __extension__
  108. #endif
  109.  
  110. /* We cast to void * and then to TYPE * because this avoids
  111.    a warning about increasing the alignment requirement.  */
  112. #define va_arg(_AP, _MODE)    \
  113. __extension__                                \
  114. (*({__voidptr *__ap = (__voidptr*)&_AP;                    \
  115.   register int __size = sizeof (_MODE);                    \
  116.   register int __onstack =                        \
  117.       (__size > 8 || ( (int)(__ap[2]) > 11) ||            \
  118.         (__size==8 && (int)(__ap[2])==11));                \
  119.   register int* __param_addr =  ((int*)((__ap) [__onstack]));        \
  120.                                     \
  121.   ((void *)__ap[__onstack])+=__size;                    \
  122.     if (__onstack==0 || (int)(__ap[2])==11)                \
  123.       __ap[2]+= (__size >> 2);                        \
  124.   (( _MODE *) (void *) __param_addr);                    \
  125. }))
  126.  
  127. void va_end (__gnuc_va_list);        /* Defined in libgcc.a */
  128. #define va_end(_X)    ((void)0)
  129.  
  130. #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
  131.