home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cc-61.0.1 / cc / va-pyr.h < prev    next >
Text File  |  1991-04-24  |  3KB  |  111 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 indepenent implementation. 
  12.  * These (somewhat bizarre) paramter-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. typedef void *__voidptr;
  48. #if 1
  49.  
  50. typedef struct __va_regs {
  51.       __voidptr __stackp,__regp,__count;
  52.       __voidptr __pr0,__pr1,__pr2,__pr3,__pr4,__pr5,__pr6,__pr7,__pr8,__pr9,__pr10,__pr11;
  53.   } __va_regs;
  54.  
  55. typedef __va_regs __va_buf;
  56. #else
  57.  
  58. /* __va_buf[0] = address of next arg passed on the stack
  59.    __va_buf[1] = address of next arg passed in a register
  60.    __va_buf[2] = register-# of next arg passed in a register
  61.  */
  62. typedef __voidptr(*__va_buf);
  63.  
  64. #endif
  65.  
  66. /* In GCC version 2, we want an ellipsis at the end of the declaration
  67.    of the argument list.  GCC version 1 can't parse it.  */
  68.  
  69. #if __GNUC__ > 1
  70. #define __va_ellipsis ...
  71. #else
  72. #define __va_ellipsis
  73. #endif
  74.  
  75. #define va_alist \
  76.   __va0,__va1,__va2,__va3,__va4,__va5,__va6,__va7,__va8,__va9,__va10,__va11, \
  77.  __builtin_va_alist
  78.  
  79. /* The ... causes current_function_varargs to be set in cc1.  */
  80. #define va_dcl __voidptr va_alist; __va_ellipsis
  81.  
  82. #define va_list __va_buf
  83.  
  84.  
  85. /* __asm ("rcsp %0" : "=r" ( _AP [0]));*/
  86.  
  87. #define va_start(_AP)  \
  88.   _AP =  ((struct __va_regs) {                        \
  89.    &(_AP.__pr0), (void*)&__builtin_va_alist, (void*)0,            \
  90.         __va0,__va1,__va2,__va3,__va4,__va5,                \
  91.     __va6,__va7,__va8,__va9,__va10,__va11})
  92.  
  93.   
  94.      
  95.  
  96. #define va_arg(_AP, _MODE)    \
  97. ({__voidptr *__ap = (__voidptr*)&_AP;                    \
  98.   register int __size = sizeof (_MODE);                    \
  99.   register int __onstack =                        \
  100.       (__size > 8 || ( (int)(__ap[2]) > 11) ||            \
  101.         (__size==8 && (int)(__ap[2])==11));                \
  102.   register int* __param_addr =  ((int*)((__ap) [__onstack]));        \
  103.                                     \
  104.   ((void *)__ap[__onstack])+=__size;                    \
  105.     if (__onstack==0 || (int)(__ap[2])==11)                \
  106.       __ap[2]+= (__size >> 2);                        \
  107.   *(( _MODE *)__param_addr);                        \
  108. })
  109.  
  110. #define va_end(_X)
  111.