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 >
Wrap
Text File
|
1993-07-23
|
3KB
|
101 lines
/**
*
* Varargs for PYR/GNU CC
*
* WARNING -- WARNING -- DANGER
*
* The code in this file implements varargs for gcc on a pyr in
* a way that is compatible with code compiled by the Pyramid Technology
* C compiler.
* As such, it depends strongly on the Pyramid conventions for
* parameter passing.ct and indepenent implementation.
* These (somewhat bizarre) paramter-passing conventions are described
* in the ``OSx Operating System Porting Guide''.
*
* A quick summary is useful:
* 12 of the 48 register-windowed regs available for
* parameter passing. Parameters of a function call that are eligible
* to be passed in registers are assigned registers from TR0/PR0 onwards;
* all other arguments are passed on the stack.
* Structure and union parameters are *never* passed in registers,
* even if they are small enough to fit. They are always passed on
* the stack.
*
* Double-sized parameters cannot be passed in TR11, because
* TR12 is not used for passing parameters. If, in the absence of this
* rule, a double-sized param would have been passed in TR11,
* that parameter is passed on the stack and no parameters are
* passed in TR11.
*
* It is only known to work for passing 32-bit integer quantities
* (ie chars, shorts, ints/enums, longs), doubles, or pointers.
* Passing structures on a Pyramid via varargs is a loser.
* Passing an object larger than 8 bytes on a pyramid via varargs may
* also be a loser.
*
*/
/*
* pointer to next stack parameter in _va_buf[0]
* pointer to next parameter register in _va_buf[1]
* Count of registers seen at _va_buf[2]
* saved pr0..pr11 in _va_buf[3..14]
* # of calls to va_arg (debugging) at _va_buf[15]
*/
typedef void *_voidptr;
#if 1
typedef struct _va_regs {
_voidptr __stackp,__regp,__count;
_voidptr _pr0,_pr1,_pr2,_pr3,_pr4,_pr5,_pr6,_pr7,_pr8,_pr9,_pr10,_pr11;
} _va_regs;
typedef _va_regs _va_buf;
#else
/* _va_buf[0] = address of next arg passed on the stack
_va_buf[1] = address of next arg passed in a register
_va_buf[2] = register-# of next arg passed in a register
*/
typedef _voidptr(*_va_buf);
#endif
#define va_alist \
_va0,_va1,_va2,_va3,_va4,_va5,_va6,_va7,_va8,_va9,_va10,_va11, \
__builtin_va_alist
#define va_dcl _voidptr va_alist;
#define va_list _va_buf
/* __asm ("rcsp %0" : "=r" ( _AP [0]));*/
#define va_start(_AP) \
{ _AP = ((struct _va_regs) { \
&(_AP._pr0), (void*)&__builtin_va_alist, (void*)0, \
_va0,_va1,_va2,_va3,_va4,_va5, \
_va6,_va7,_va8,_va9,_va10,_va11})
#define va_arg(_AP, _MODE) \
({_voidptr *_ap = (_voidptr*)&_AP; \
register int _size = sizeof (_MODE); \
register int _onstack = \
(_size > 8 || ( (int)(_ap[2]) > 11) || \
(_size==8 && (int)(_ap[2])==11)); \
register int* _param_addr = ((int*)((_ap) [_onstack])); \
\
((void *)_ap[_onstack])+=_size; \
if (_onstack==0 || (int)(_ap[2])==11) \
_ap[2]+= (_size >> 2); \
*(( _MODE *)_param_addr); \
})
#define va_end(_X) }