OSDN Git Service

Add @plt if -fpic; Fix double->int conversions if stack > 32k; Redo t-* files; Fix...
[pf3gnuchains/gcc-fork.git] / gcc / ginclude / va-sh.h
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 __SH3E__
10
11 typedef long __va_greg;
12 typedef double __va_freg;
13
14 typedef struct {
15   __va_greg * __va_next_o;              /* next available register */
16   __va_greg * __va_next_o_limit;        /* past last available register */
17   __va_freg * __va_next_fp;             /* next available fp register */
18   __va_freg * __va_next_fp_limit;       /* last available fp register */
19   __va_greg * __va_next_stack;          /* next extended word on stack */
20 } __gnuc_va_list;
21
22 #else /* ! SH3E */
23
24 typedef void *__gnuc_va_list;
25
26 #define __va_rounded_size(TYPE)  \
27   (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
28
29 #endif /* ! SH3E */
30
31 #endif /* __GNUC_VA_LIST */
32
33 /* If this is for internal libc use, don't define anything but
34    __gnuc_va_list.  */
35 #if defined (_STDARG_H) || defined (_VARARGS_H)
36
37 #ifdef _STDARG_H
38
39 #ifdef __SH3E__
40
41 #define va_start(AP, LASTARG) \
42 __extension__ \
43   ({ \
44      AP.__va_next_fp = (__va_freg *) __builtin_saveregs (); \
45      AP.__va_next_fp_limit = (AP.__va_next_fp + \
46                               (__builtin_args_info (1) < 8 ? 8 - __builtin_args_info (1) : 0)); \
47      AP.__va_next_o = (__va_greg *) AP.__va_next_fp_limit; \
48      AP.__va_next_o_limit = (AP.__va_next_o + \
49                              (__builtin_args_info (0) < 4 ? 4 - __builtin_args_info (0) : 0)); \
50      AP.__va_next_stack = (__va_greg *) __builtin_next_arg (LASTARG); \
51   })
52
53 #else /* ! SH3E */
54
55 #define va_start(AP, LASTARG)                                           \
56  (AP = ((__gnuc_va_list) __builtin_next_arg (LASTARG)))
57
58 #endif /* ! SH3E */
59
60 #else /* _VARARGS_H */
61
62 #define va_alist  __builtin_va_alist
63 #define va_dcl    int __builtin_va_alist;...
64
65 #ifdef __SH3E__
66
67 #define va_start(AP) \
68 __extension__ \
69   ({ \
70      AP.__va_next_fp = (__va_freg *) __builtin_saveregs (); \
71      AP.__va_next_fp_limit = (AP.__va_next_fp + \
72                               (__builtin_args_info (1) < 8 ? 8 - __builtin_args_info (1) : 0)); \
73      AP.__va_next_o = (__va_greg *) AP.__va_next_fp_limit; \
74      AP.__va_next_o_limit = (AP.__va_next_o + \
75                              (__builtin_args_info (0) < 4 ? 4 - __builtin_args_info (0) : 0)); \
76      AP.__va_next_stack = (__va_greg *) __builtin_next_arg (__builtin_va_alist) \
77        - (__builtin_args_info (0) >= 4 || __builtin_args_info (1) >= 8 ? 1 : 0); \
78   })
79
80 #else /* ! SH3E */
81
82 #define va_start(AP)  AP=(char *) &__builtin_va_alist
83
84 #endif /* ! SH3E */
85
86 #endif /* _STDARG */
87
88 #ifndef va_end
89 void va_end (__gnuc_va_list);           /* Defined in libgcc.a */
90
91 /* Values returned by __builtin_classify_type.  */
92
93 enum __va_type_classes {
94   __no_type_class = -1,
95   __void_type_class,
96   __integer_type_class,
97   __char_type_class,
98   __enumeral_type_class,
99   __boolean_type_class,
100   __pointer_type_class,
101   __reference_type_class,
102   __offset_type_class,
103   __real_type_class,
104   __complex_type_class,
105   __function_type_class,
106   __method_type_class,
107   __record_type_class,
108   __union_type_class,
109   __array_type_class,
110   __string_type_class,
111   __set_type_class,
112   __file_type_class,
113   __lang_type_class
114 };
115
116 #endif
117 #define va_end(pvar)    ((void)0)
118
119 /* RECORD_TYPE args passed using the C calling convention are
120    passed by invisible reference.  ??? RECORD_TYPE args passed
121    in the stack are made to be word-aligned; for an aggregate that is
122    not word-aligned, we advance the pointer to the first non-reg slot.  */
123
124 #ifdef __SH3E__
125
126 #ifdef __LITTLE_ENDIAN__
127
128 #define va_arg(pvar,TYPE)                                       \
129 __extension__                                                   \
130 (*({int __type = __builtin_classify_type (* (TYPE *) 0);        \
131   void * __result;                                              \
132   if (__type == __real_type_class && sizeof(TYPE) == 4)         \
133                                                 /* float? */    \
134     {                                                           \
135       __va_freg *__r;                                           \
136       if (pvar.__va_next_fp < pvar.__va_next_fp_limit)          \
137         __r = (__va_freg *) pvar.__va_next_fp++;                \
138       else                                                      \
139         __r = (__va_freg *) pvar.__va_next_stack++;             \
140       __result = (char *) __r;                                  \
141     }                                                           \
142   else                                                          \
143     {                                                           \
144       __va_greg *_r;                                            \
145       if (pvar.__va_next_o + ((sizeof (TYPE) + 3) / 4)          \
146           <= pvar.__va_next_o_limit)                            \
147         {                                                       \
148           _r = pvar.__va_next_o;                                \
149           pvar.__va_next_o += (sizeof (TYPE) + 3) / 4;          \
150         }                                                       \
151       else                                                      \
152         {                                                       \
153           _r = pvar.__va_next_stack;                            \
154           pvar.__va_next_stack += (sizeof (TYPE) + 3) / 4;      \
155         }                                                       \
156       __result = (char *) _r;                                   \
157     }                                                           \
158   (TYPE *) __result;}))
159
160 #else /* ! __LITTLE_ENDIAN__ */
161
162 #define va_arg(pvar,TYPE)                                       \
163 __extension__                                                   \
164 (*({int __type = __builtin_classify_type (* (TYPE *) 0);        \
165   void * __result;                                              \
166   if (__type == __real_type_class && sizeof(TYPE) == 4)         \
167                                                 /* float? */    \
168     {                                                           \
169       __va_freg *__r;                                           \
170       if (pvar.__va_next_fp < pvar.__va_next_fp_limit)          \
171         __r = (__va_freg *) pvar.__va_next_fp++;                \
172       else                                                      \
173         __r = (__va_freg *) pvar.__va_next_stack++;             \
174       __result = (char *) __r;                                  \
175     }                                                           \
176   else                                                          \
177     {                                                           \
178       __va_greg *_r;                                            \
179       if (pvar.__va_next_o + ((sizeof (TYPE) + 3) / 4)          \
180           <= pvar.__va_next_o_limit)                            \
181         {                                                       \
182           pvar.__va_next_o += (sizeof (TYPE) + 3) / 4;          \
183           _r = pvar.__va_next_o;                                \
184         }                                                       \
185       else                                                      \
186         {                                                       \
187           pvar.__va_next_stack += (sizeof (TYPE) + 3) / 4;      \
188           _r = pvar.__va_next_stack;                            \
189         }                                                       \
190       __result = ((char *) _r                                   \
191                   - (sizeof (TYPE) < 4 ? sizeof (TYPE)          \
192                      : ((sizeof (TYPE) + 3) / 4) * 4));         \
193     }                                                           \
194   (TYPE *) __result;}))
195
196 #endif /* __LITTLE_ENDIAN__ */
197
198 #else /* ! SH3E */
199
200 #ifdef __LITTLE_ENDIAN__
201
202 /* This is for little-endian machines; small args are padded upward.  */
203 #define va_arg(AP, TYPE)                                                \
204  (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)),     \
205   *((TYPE *) (void *) ((char *) (AP) - __va_rounded_size (TYPE))))
206
207 #else /* ! __LITTLE_ENDIAN__ */
208
209 /* This is for big-endian machines; small args are padded downward.  */
210 #define va_arg(AP, TYPE)                                                \
211  (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)),     \
212   *((TYPE *) (void *) ((char *) (AP)                                    \
213                        - ((sizeof (TYPE) < __va_rounded_size (char)     \
214                            ? sizeof (TYPE) : __va_rounded_size (TYPE))))))
215
216 #endif /* __LITTLE_ENDIAN__ */
217
218 #endif /* SH3E */
219
220 #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */