home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / gccsrc2 / va_pyr.h < prev    next >
Text File  |  1993-07-23  |  3KB  |  101 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. #define va_alist \
  67.   _va0,_va1,_va2,_va3,_va4,_va5,_va6,_va7,_va8,_va9,_va10,_va11, \
  68.  __builtin_va_alist
  69.  
  70. #define va_dcl _voidptr va_alist;
  71.  
  72. #define va_list _va_buf
  73.  
  74.  
  75. /* __asm ("rcsp %0" : "=r" ( _AP [0]));*/
  76.  
  77. #define va_start(_AP)  \
  78. { _AP =  ((struct _va_regs) {                        \
  79.    &(_AP._pr0), (void*)&__builtin_va_alist, (void*)0,            \
  80.         _va0,_va1,_va2,_va3,_va4,_va5,                    \
  81.         _va6,_va7,_va8,_va9,_va10,_va11})
  82.  
  83.   
  84.      
  85.  
  86. #define va_arg(_AP, _MODE)    \
  87. ({_voidptr *_ap = (_voidptr*)&_AP;                    \
  88.   register int _size = sizeof (_MODE);                    \
  89.   register int _onstack =                        \
  90.       (_size > 8 || ( (int)(_ap[2]) > 11) ||            \
  91.         (_size==8 && (int)(_ap[2])==11));                \
  92.   register int* _param_addr =  ((int*)((_ap) [_onstack]));        \
  93.                                     \
  94.   ((void *)_ap[_onstack])+=_size;                    \
  95.     if (_onstack==0 || (int)(_ap[2])==11)                \
  96.       _ap[2]+= (_size >> 2);                        \
  97.   *(( _MODE *)_param_addr);                        \
  98. })
  99.  
  100. #define va_end(_X)    }
  101.