OSDN Git Service

Set TARGET_LIBGCC2_CFLAGS instead of LIBGCC2_CFLAGS.
[pf3gnuchains/gcc-fork.git] / gcc / ginclude / va-ppc.h
1 /* GNU C varargs support for the PowerPC with either the V.4 or Windows NT calling sequences */
2
3 #ifndef _WIN32
4 /* System V.4 support */
5 /* Define __gnuc_va_list.  */
6
7 #ifndef __GNUC_VA_LIST
8 #define __GNUC_VA_LIST
9
10 #ifndef _SYS_VA_LIST_H
11 #define _SYS_VA_LIST_H          /* Solaris sys/va_list.h */
12
13 /* Solaris decided to rename overflow_arg_area to input_arg_area,
14    so handle it via a macro.  */
15 #define __va_overflow(AP) (AP)->overflow_arg_area
16
17 /* Note that the names in this structure are in the user's namespace, but
18    that the V.4 abi explicitly states that these names should be used.  */
19 typedef struct __va_list_tag {
20   char gpr;                     /* index into the array of 8 GPRs stored in the
21                                    register save area gpr=0 corresponds to r3,
22                                    gpr=1 to r4, etc. */
23   char fpr;                     /* index into the array of 8 FPRs stored in the
24                                    register save area fpr=0 corresponds to f1,
25                                    fpr=1 to f2, etc. */
26   char *overflow_arg_area;      /* location on stack that holds the next
27                                    overflow argument */
28   char *reg_save_area;          /* where r3:r10 and f1:f8, if saved are stored */
29 } __va_list[1], __gnuc_va_list[1];
30
31 #else /* _SYS_VA_LIST */
32
33 typedef __va_list __gnuc_va_list;
34 #define __va_overflow(AP) (AP)->input_arg_area
35
36 #endif /* not _SYS_VA_LIST */
37 #endif /* not __GNUC_VA_LIST */
38
39 /* If this is for internal libc use, don't define anything but
40    __gnuc_va_list.  */
41 #if defined (_STDARG_H) || defined (_VARARGS_H)
42
43 /* Register save area located below the frame pointer */
44 #ifndef __VA_PPC_H__
45 #define __VA_PPC_H__
46 typedef struct {
47   long   __gp_save[8];          /* save area for GP registers */
48   double __fp_save[8];          /* save area for FP registers */
49 } __va_regsave_t;
50
51 /* Macros to access the register save area */
52 /* We cast to void * and then to TYPE * because this avoids
53    a warning about increasing the alignment requirement.  */
54 #define __VA_FP_REGSAVE(AP,TYPE)                                        \
55   ((TYPE *) (void *) (&(((__va_regsave_t *)                             \
56                          (AP)->reg_save_area)->__fp_save[(int)(AP)->fpr])))
57
58 #define __VA_GP_REGSAVE(AP,TYPE)                                        \
59   ((TYPE *) (void *) (&(((__va_regsave_t *)                             \
60                          (AP)->reg_save_area)->__gp_save[(int)(AP)->gpr])))
61
62 /* Common code for va_start for both varargs and stdarg.  This depends
63    on the format of rs6000_args in rs6000.h.  The fields used are:
64
65    #0   WORDS                   # words used for GP regs/stack values
66    #1   FREGNO                  next available FP register
67    #2   NARGS_PROTOTYPE         # args left in the current prototype
68    #3   ORIG_NARGS              original value of NARGS_PROTOTYPE
69    #4   VARARGS_OFFSET          offset from frame pointer of varargs area */
70
71 #define __va_words              __builtin_args_info (0)
72 #define __va_fregno             __builtin_args_info (1)
73 #define __va_nargs              __builtin_args_info (2)
74 #define __va_orig_nargs         __builtin_args_info (3)
75 #define __va_varargs_offset     __builtin_args_info (4)
76
77 #define __va_start_common(AP, FAKE)                                     \
78 __extension__ ({                                                        \
79    register int __words = __va_words - FAKE;                            \
80                                                                         \
81    (AP)->gpr = (__words < 8) ? __words : 8;                             \
82    (AP)->fpr = __va_fregno - 33;                                        \
83    (AP)->reg_save_area = (((char *) __builtin_frame_address (0))        \
84                           + __va_varargs_offset);                       \
85    __va_overflow(AP) = ((char *)__builtin_saveregs ()                   \
86                         + (((__words >= 8) ? __words - 8 : 0)           \
87                            * sizeof (long)));                           \
88    (void)0;                                                             \
89 })
90
91 #ifdef _STDARG_H /* stdarg.h support */
92
93 /* Calling __builtin_next_arg gives the proper error message if LASTARG is
94    not indeed the last argument.  */
95 #define va_start(AP,LASTARG) \
96   (__builtin_next_arg (LASTARG), __va_start_common (AP, 0))
97
98 #else /* varargs.h support */
99
100 #define va_start(AP) __va_start_common (AP, 1)
101 #define va_alist __va_1st_arg
102 #define va_dcl register int va_alist; ...
103
104 #endif /* _STDARG_H */
105
106 #ifdef _SOFT_FLOAT
107 #define __va_float_p(TYPE)      0
108 #else
109 #define __va_float_p(TYPE)      (__builtin_classify_type(*(TYPE *)0) == 8)
110 #endif
111
112 #define __va_longlong_p(TYPE) \
113   ((__builtin_classify_type(*(TYPE *)0) == 1) && (sizeof(TYPE) == 8))
114
115 #define __va_aggregate_p(TYPE)  (__builtin_classify_type(*(TYPE *)0) >= 12)
116 #define __va_size(TYPE)         ((sizeof(TYPE) + sizeof (long) - 1) / sizeof (long))
117
118 #define va_arg(AP,TYPE)                                                 \
119 __extension__ (*({                                                      \
120   register TYPE *__ptr;                                                 \
121                                                                         \
122   if (__va_float_p (TYPE) && (AP)->fpr < 8)                             \
123     {                                                                   \
124       __ptr = __VA_FP_REGSAVE (AP, TYPE);                               \
125       (AP)->fpr++;                                                      \
126     }                                                                   \
127                                                                         \
128   else if (__va_aggregate_p (TYPE) && (AP)->gpr < 8)                    \
129     {                                                                   \
130       __ptr = * __VA_GP_REGSAVE (AP, TYPE *);                           \
131       (AP)->gpr++;                                                      \
132     }                                                                   \
133                                                                         \
134   else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE)             \
135            && (AP)->gpr + __va_size(TYPE) <= 8                          \
136            && (!__va_longlong_p(TYPE)                                   \
137                || (AP)->gpr + __va_size(TYPE) <= 7))                    \
138     {                                                                   \
139       if (__va_longlong_p(TYPE) && ((AP)->gpr & 1) != 0)                \
140         (AP)->gpr++;                                                    \
141                                                                         \
142       __ptr = __VA_GP_REGSAVE (AP, TYPE);                               \
143       (AP)->gpr += __va_size (TYPE);                                    \
144     }                                                                   \
145                                                                         \
146   else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE)             \
147            && (AP)->gpr < 8)                                            \
148     {                                                                   \
149       (AP)->gpr = 8;                                                    \
150       __ptr = (TYPE *) (void *) (__va_overflow(AP));                    \
151       __va_overflow(AP) += __va_size (TYPE) * sizeof (long);            \
152     }                                                                   \
153                                                                         \
154   else if (__va_aggregate_p (TYPE))                                     \
155     {                                                                   \
156       __ptr = * (TYPE **) (void *) (__va_overflow(AP));                 \
157       __va_overflow(AP) += sizeof (TYPE *);                             \
158     }                                                                   \
159   else                                                                  \
160     {                                                                   \
161       if (__va_longlong_p(TYPE) && ((long)__va_overflow(AP) & 4) != 0)  \
162         __va_overflow(AP) += 4;                                         \
163                                                                         \
164       __ptr = (TYPE *) (void *) (__va_overflow(AP));                    \
165       __va_overflow(AP) += __va_size (TYPE) * sizeof (long);            \
166     }                                                                   \
167                                                                         \
168   __ptr;                                                                \
169 }))
170
171 #define va_end(AP)      ((void)0)
172
173 /* Copy __gnuc_va_list into another variable of this type.  */
174 #define __va_copy(dest, src) *(dest) = *(src)
175
176 #endif /* __VA_PPC_H__ */
177 #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
178
179 \f
180 #else
181 /* Windows NT */
182 /* Define __gnuc_va_list.  */
183
184 #ifndef __GNUC_VA_LIST
185 #define __GNUC_VA_LIST
186 typedef char *__gnuc_va_list;
187 #endif /* not __GNUC_VA_LIST */
188
189 /* If this is for internal libc use, don't define anything but
190    __gnuc_va_list.  */
191 #if defined (_STDARG_H) || defined (_VARARGS_H)
192
193 #define __va_start_common(AP, LASTARG, FAKE)                            \
194   ((__builtin_saveregs ()), ((AP) = ((char *) &LASTARG) + __va_rounded_size (AP)), 0)
195
196 #ifdef _STDARG_H /* stdarg.h support */
197
198 /* Calling __builtin_next_arg gives the proper error message if LASTARG is
199    not indeed the last argument.  */
200 #define va_start(AP,LASTARG)                                            \
201   (__builtin_saveregs (),                                               \
202    (AP) = __builtin_next_arg (LASTARG),                                 \
203    0)
204
205 #else /* varargs.h support */
206
207 #define va_start(AP)                                                    \
208   (__builtin_saveregs (),                                               \
209    (AP) = __builtin_next_arg (__va_1st_arg) - sizeof (int),             \
210    0)
211
212 #define va_alist __va_1st_arg
213 #define va_dcl register int __va_1st_arg; ...
214
215 #endif /* _STDARG_H */
216
217 #define __va_rounded_size(TYPE) ((sizeof (TYPE) + 3) & ~3)
218 #define __va_align(AP, TYPE)                                            \
219      ((((unsigned long)(AP)) + ((sizeof (TYPE) >= 8) ? 7 : 3))          \
220       & ~((sizeof (TYPE) >= 8) ? 7 : 3))
221
222 #define va_arg(AP,TYPE)                                                 \
223 ( *(TYPE *)((AP = (char *) (__va_align(AP, TYPE)                        \
224                             + __va_rounded_size(TYPE)))                 \
225             - __va_rounded_size(TYPE)))
226
227 #define va_end(AP)      ((void)0)
228
229 /* Copy __gnuc_va_list into another variable of this type.  */
230 #define __va_copy(dest, src) (dest) = (src)
231
232 #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
233 #endif /* Windows NT */