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

Revision 8834, 6.7 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/* This is just like the default gvarargs.h
2   except for differences described below.  */
3
4/* Define __gnuc_va_list.  */
5
6#ifndef __GNUC_VA_LIST
7#define __GNUC_VA_LIST
8
9#ifdef __sparc_v9__
10typedef long long __va_greg;
11typedef double __va_freg;
12typedef struct {
13  __va_greg * __va_next_o;              /* next available %o* register */
14  __va_greg * __va_next_o_limit;        /* past last available %o* register */
15  __va_freg * __va_next_fp;             /* next available %f* register */
16  __va_freg * __va_next_fp_limit;       /* last available %f* register */
17  __va_greg * __va_next_stack;          /* next extended word on stack */
18} __gnuc_va_list;
19#else
20#ifndef __svr4__
21/* This has to be a char * to be compatible with Sun.
22   i.e., we have to pass a `va_list' to vsprintf.  */
23typedef char * __gnuc_va_list;
24#else
25/* This has to be a void * to be compatible with Sun svr4.
26   i.e., we have to pass a `va_list' to vsprintf.  */
27typedef void * __gnuc_va_list;
28#endif
29#endif /* not __sparc_v9__ */
30#endif /* not __GNUC_VA_LIST */
31
32/* If this is for internal libc use, don't define anything but
33   __gnuc_va_list.  */
34#if defined (_STDARG_H) || defined (_VARARGS_H)
35
36#ifdef _STDARG_H
37
38#ifdef __sparc_v9__
39#define va_start(AP, LASTARG) \
40__extension__ \
41  ({ \
42     AP.__va_next_o = (__va_greg *) __builtin_saveregs (); \
43     AP.__va_next_o_limit = (AP.__va_next_o + \
44                             (__builtin_args_info (0) < 6 ? 6 - __builtin_args_info (0) : 0)); \
45     AP.__va_next_fp = (__va_freg *) AP.__va_next_o_limit; \
46     AP.__va_next_fp_limit = (AP.__va_next_fp + \
47                              (__builtin_args_info (1) < 16 ? (16 - __builtin_args_info (1) + 1) / 2 : 0)); \
48     AP.__va_next_stack = (__va_greg *) __builtin_next_arg (LASTARG); \
49  })
50#else
51/* Call __builtin_next_arg even though we aren't using its value, so that
52   we can verify that LASTARG is correct.  */
53#ifdef __GCC_NEW_VARARGS__
54#define va_start(AP, LASTARG) \
55  (__builtin_next_arg (LASTARG), AP = (char *) __builtin_saveregs ())
56#else
57#define va_start(AP, LASTARG)                                   \
58  (__builtin_saveregs (), AP = ((char *) __builtin_next_arg (LASTARG)))
59#endif
60#endif /* not __sparc_v9__ */
61
62#else
63
64#define va_alist  __builtin_va_alist
65#define va_dcl    int __builtin_va_alist;...
66
67#ifdef __sparc_v9__
68#define va_start(AP) \
69__extension__ \
70  ({ \
71     AP.__va_next_o = (__va_greg *) __builtin_saveregs (); \
72     AP.__va_next_o_limit = (AP.__va_next_o + \
73                             (__builtin_args_info (0) < 6 ? 6 - __builtin_args_info (0) : 0)); \
74     AP.__va_next_fp = (__va_freg *) AP.__va_next_o_limit; \
75     AP.__va_next_fp_limit = (AP.__va_next_fp + \
76                              (__builtin_args_info (1) < 16 ? (16 - __builtin_args_info (1) + 1) / 2 : 0)); \
77     AP.__va_next_stack = (__va_greg *) __builtin_next_arg (__builtin_va_alist) \
78       - (__builtin_args_info (0) >= 6 || __builtin_args_info (1) >= 16 ? 1 : 0); \
79  })
80#else
81#ifdef __GCC_NEW_VARARGS__
82#define va_start(AP)            ((AP) = (char *) __builtin_saveregs ())
83#else
84#define va_start(AP)                                            \
85 (__builtin_saveregs (), (AP) = ((char *) &__builtin_va_alist))
86#endif
87#endif /* not __sparc_v9__ */
88
89#endif
90
91#ifndef va_end
92void va_end (__gnuc_va_list);           /* Defined in libgcc.a */
93
94/* Values returned by __builtin_classify_type.  */
95
96enum __va_type_classes {
97  __no_type_class = -1,
98  __void_type_class,
99  __integer_type_class,
100  __char_type_class,
101  __enumeral_type_class,
102  __boolean_type_class,
103  __pointer_type_class,
104  __reference_type_class,
105  __offset_type_class,
106  __real_type_class,
107  __complex_type_class,
108  __function_type_class,
109  __method_type_class,
110  __record_type_class,
111  __union_type_class,
112  __array_type_class,
113  __string_type_class,
114  __set_type_class,
115  __file_type_class,
116  __lang_type_class
117};
118
119#endif
120#define va_end(pvar)    ((void)0)
121
122/* Avoid errors if compiling GCC v2 with GCC v1.  */
123#if __GNUC__ == 1
124#define __extension__
125#endif
126
127/* RECORD_TYPE args passed using the C calling convention are
128   passed by invisible reference.  ??? RECORD_TYPE args passed
129   in the stack are made to be word-aligned; for an aggregate that is
130   not word-aligned, we advance the pointer to the first non-reg slot.  */
131
132#ifdef __sparc_v9__
133
134#define va_arg(pvar,TYPE)                                       \
135__extension__                                                   \
136(*({int __type = __builtin_classify_type (* (TYPE *) 0);        \
137  void * __result;                                              \
138  if (__type == __real_type_class)              /* float? */    \
139    {                                                           \
140      __va_freg *__r;                                           \
141      /* see PASS_IN_REG_P in gcc's sparc.h */                  \
142      if (pvar.__va_next_fp < pvar.__va_next_fp_limit           \
143          && ((__r = (__va_freg *) (((__va_greg) pvar.__va_next_fp + sizeof (TYPE) - 1) & ~(__va_greg) (sizeof (TYPE) - 1))) \
144              < pvar.__va_next_fp_limit))                       \
145        {                                                       \
146          pvar.__va_next_fp = __r + (sizeof (TYPE) + 7) / 8;    \
147        }                                                       \
148      else                                                      \
149        {                                                       \
150          __r = (__va_freg *) pvar.__va_next_stack;             \
151          pvar.__va_next_stack += (sizeof (TYPE) + 7) / 8;      \
152        }                                                       \
153      __result = __r;                                           \
154    }                                                           \
155  else if (__type < __record_type_class)        /* integer? */  \
156    {                                                           \
157      __va_greg *__r;                                           \
158      if (pvar.__va_next_o < pvar.__va_next_o_limit)            \
159        __r = pvar.__va_next_o++;                               \
160      else                                                      \
161        __r = pvar.__va_next_stack++;                           \
162      /* adjust for 4 byte ints */                              \
163      __result = (char *) __r + 8 - sizeof (TYPE);              \
164    }                                                           \
165  else /* aggregate object */                                   \
166    {                                                           \
167      void **__r;                                               \
168      if (pvar.__va_next_o < pvar.__va_next_o_limit)            \
169        __r = (void **) pvar.__va_next_o++;                     \
170      else                                                      \
171        __r = (void **) pvar.__va_next_stack++;                 \
172      __result = *__r;                                          \
173    }                                                           \
174  (TYPE *) __result;}))
175
176#else /* not __sparc_v9__ */
177
178#define __va_rounded_size(TYPE)  \
179  (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
180
181/* We don't declare the union member `d' to have type TYPE
182   because that would lose in C++ if TYPE has a constructor.  */
183/* We cast to void * and then to TYPE * because this avoids
184   a warning about increasing the alignment requirement.
185   The casts to char * avoid warnings about invalid pointer arithmetic.  */
186#define va_arg(pvar,TYPE)                                       \
187__extension__                                                   \
188(*({((__builtin_classify_type (*(TYPE*) 0) >= __record_type_class \
189      || (__builtin_classify_type (*(TYPE*) 0) == __real_type_class \
190          && sizeof (TYPE) == 16))                              \
191    ? ((pvar) = (char *)(pvar) + __va_rounded_size (TYPE *),    \
192       *(TYPE **) (void *) ((char *)(pvar) - __va_rounded_size (TYPE *))) \
193    : __va_rounded_size (TYPE) == 8                             \
194    ? ({ union {char __d[sizeof (TYPE)]; int __i[2];} __u;      \
195         __u.__i[0] = ((int *) (void *) (pvar))[0];             \
196         __u.__i[1] = ((int *) (void *) (pvar))[1];             \
197         (pvar) = (char *)(pvar) + 8;                           \
198         (TYPE *) (void *) __u.__d; })                          \
199    : ((pvar) = (char *)(pvar) + __va_rounded_size (TYPE),      \
200       ((TYPE *) (void *) ((char *)(pvar) - __va_rounded_size (TYPE)))));}))
201#endif /* not __sparc_v9__ */
202
203#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
Note: See TracBrowser for help on using the repository browser.