Import (slightly modified) ru.koi8-r.win.kbd:1.1 from FreeBSD (fjoe):
[dragonfly.git] / contrib / gcc / ginclude / va-pyr.h
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 \f
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
52 typedef void *__voidptr;
53 #if 1
54
55 typedef 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
60 typedef __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  */
67 typedef __voidptr(*__va_buf);
68
69 #endif
70
71 typedef __va_buf __gnuc_va_list;
72
73 #endif /* not __GNUC_VA_LIST */
74 \f
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
127 void 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) */