source: trunk/third/gcc/ginclude/va-pyr.h @ 8834

Revision 8834, 4.0 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8833, which included commits to RCS files with non-trunk default branches.
Line 
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
52typedef void *__voidptr;
53#if 1
54
55typedef 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
60typedef __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 */
67typedef __voidptr(*__va_buf);
68
69#endif
70
71typedef __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
127void 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) */
Note: See TracBrowser for help on using the repository browser.