From 60163eae1b932f9d15ad3345e44593e27d8bfb0a Mon Sep 17 00:00:00 2001 From: Richard Stallman Date: Wed, 4 Sep 1991 02:25:28 +0000 Subject: [PATCH] Initial revision From-SVN: r38 --- gcc/ginclude/va-pyr.h | 110 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 gcc/ginclude/va-pyr.h diff --git a/gcc/ginclude/va-pyr.h b/gcc/ginclude/va-pyr.h new file mode 100644 index 00000000000..d24a1f533b2 --- /dev/null +++ b/gcc/ginclude/va-pyr.h @@ -0,0 +1,110 @@ +/** + * + * 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 + +/* In GCC version 2, we want an ellipsis at the end of the declaration + of the argument list. GCC version 1 can't parse it. */ + +#if __GNUC__ > 1 +#define __va_ellipsis ... +#else +#define __va_ellipsis +#endif + +#define va_alist \ + __va0,__va1,__va2,__va3,__va4,__va5,__va6,__va7,__va8,__va9,__va10,__va11, \ + __builtin_va_alist + +/* The ... causes current_function_varargs to be set in cc1. */ +#define va_dcl __voidptr va_alist; __va_ellipsis + +typedef __va_buf va_list; + + +/* __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) -- 2.30.2