xref: /haiku/headers/build/gcc-2.95.3/va-i860.h (revision 893988af824e65e49e55f517b157db8386e8002b)
1 /* Note:  We must use the name __builtin_savregs.  GCC attaches special
2    significance to that name.  In particular, regardless of where in a
3    function __builtin_saveregs is called, GCC moves the call up to the
4    very start of the function.  */
5 
6 
7 /* Define __gnuc_va_list.  */
8 
9 #ifndef __GNUC_VA_LIST
10 #define __GNUC_VA_LIST
11 
12 typedef union {
13   float		__freg[8];
14   double	__dreg[4];
15 } __f_regs;
16 
17 typedef struct {
18 #if defined (__SVR4__) || defined (__svr4__) || defined (__alliant__) || defined (__PARAGON__)
19   __f_regs __float_regs; long __ireg[12];
20 #else /* pre-SVR4 */
21   long __ireg[12]; __f_regs __float_regs;
22 #endif
23 } __va_saved_regs;
24 
25 typedef struct {
26 #if defined(__SVR4__) || defined(__svr4__) || defined(__alliant__) || defined (__PARAGON__)
27   unsigned	__ireg_used;	/* How many int regs consumed 'til now? */
28   unsigned	__freg_used;	/* How many flt regs consumed 'til now? */
29   long		*__reg_base;	/* Address of where we stored the regs. */
30   long *	__mem_ptr;	/* Address of memory overflow args area. */
31 #else /* pre-SVR4 */
32   long		*__reg_base;	/* Address of where we stored the regs. */
33   long *	__mem_ptr;	/* Address of memory overflow args area. */
34   unsigned	__ireg_used;	/* How many int regs consumed 'til now? */
35   unsigned	__freg_used;	/* How many flt regs consumed 'til now? */
36 #endif
37 } __gnuc_va_list;
38 #endif /* not __GNUC_VA_LIST */
39 
40 /* If this is for internal libc use, don't define anything but
41    __gnuc_va_list.  */
42 #if defined (_STDARG_H) || defined (_VARARGS_H)
43 
44 #if !defined(_STDARG_H)
45 
46 /* varargs support */
47 #define va_alist __builtin_va_alist
48 #if defined (__PARAGON__)
49 #define va_dcl int va_alist;
50 #else	/* __PARAGON__ */
51 #define va_dcl
52 #endif	/* __PARAGON__ */
53 #define va_start(pvar) ((pvar) = * (__gnuc_va_list *) __builtin_saveregs ())
54 
55 #else /* STDARG.H */
56 
57 /* ANSI alternative.  */
58 /* Note that CUMULATIVE_ARGS elements are measured in bytes on the i860,
59    so we divide by 4 to get # of registers.  */
60 #define va_start(pvar, firstarg) \
61  ((pvar) = *(__gnuc_va_list *) __builtin_saveregs (),			\
62   (pvar).__ireg_used = __builtin_args_info (0) / 4,		\
63   (pvar).__freg_used = __builtin_args_info (1) / 4,		\
64   (pvar).__mem_ptr = __builtin_next_arg (firstarg))
65 
66 #endif /* _STDARG_H */
67 
68 /* Values returned by __builtin_classify_type.  */
69 
70 #ifndef va_end
71 enum {
72   __no_type_class = -1,
73   __void_type_class,
74   __integer_type_class,
75   __char_type_class,
76   __enumeral_type_class,
77   __boolean_type_class,
78   __pointer_type_class,
79   __reference_type_class,
80   __offset_type_class,
81   __real_type_class,
82   __complex_type_class,
83   __function_type_class,
84   __method_type_class,
85   __record_type_class,
86   __union_type_class,
87   __array_type_class,
88   __string_type_class,
89   __set_type_class,
90   __file_type_class,
91   __lang_type_class
92 };
93 
94 void va_end (__gnuc_va_list);		/* Defined in libgcc.a */
95 #endif
96 #define va_end(__va)	((void) 0)
97 
98 #define __NUM_PARM_FREGS	8
99 #define __NUM_PARM_IREGS	12
100 
101 #define __savereg(__va) ((__va_saved_regs *) ((__va).__reg_base))
102 
103 /* This macro works both for SVR4 and pre-SVR4 environments.  */
104 
105 /* Note that parameters are always aligned at least to a word boundary
106    (when passed) regardless of what GCC's __alignof__ operator says.  */
107 
108 /* Make allowances here for adding 128-bit (long double) floats someday.  */
109 
110 #if 0 /* What was this for? */
111 #ifndef __GNU_VA_LIST
112 #define __ireg_used ireg_used
113 #define __freg_used freg_used
114 #define __mem_ptr mem_ptr
115 #define __reg_base reg_base
116 #endif
117 #endif /* 0 */
118 
119 /* Avoid errors if compiling GCC v2 with GCC v1.  */
120 #if __GNUC__ == 1
121 #define __extension__
122 #endif
123 
124 #define va_arg(__va, __type)						\
125 __extension__								\
126 (* (__type *)								\
127 ({									\
128   register void *__rv;  /* result value */				\
129   register unsigned __align;						\
130   switch (__builtin_classify_type (* (__type *) 0))			\
131     {									\
132     case __real_type_class:						\
133       switch (sizeof (__type))						\
134 	{								\
135 	  case sizeof (float):						\
136 	  case sizeof (double):						\
137 	    if ((__va).__freg_used < __NUM_PARM_FREGS - 1)		\
138 	      {								\
139 	        if (((__va).__freg_used & 1) != 0)			\
140 	          (__va).__freg_used++;	/* skip odd */			\
141 	        __rv = &__savereg((__va))->__float_regs.__freg[(__va).__freg_used];\
142 		(__va).__freg_used += 2;				\
143 	      }								\
144 	    else							\
145 	      {								\
146 	        if ((((unsigned) (__va).__mem_ptr) & (sizeof(double)-1)) != 0) \
147 	          (__va).__mem_ptr++;	/* skip odd */			\
148 	        __rv = (__va).__mem_ptr;				\
149 	        (__va).__mem_ptr += 2;					\
150 	      }								\
151 	    if (sizeof (__type) == sizeof (float))			\
152 	      {								\
153 	        *((float *) __rv) = *((double *) __rv);			\
154 		*(((long *) __rv) + 1) = 0xfff00001;			\
155 	      }								\
156 	    break;							\
157 	  default:							\
158 	    abort ();							\
159 	}								\
160       break;								\
161     case __void_type_class:						\
162     case __integer_type_class:						\
163     case __char_type_class:						\
164     case __enumeral_type_class:						\
165     case __boolean_type_class:						\
166     case __pointer_type_class:						\
167     case __reference_type_class:					\
168     case __offset_type_class:						\
169       if (sizeof (__type) <= 4)						\
170 	{								\
171           __rv = ((__va).__ireg_used < __NUM_PARM_IREGS			\
172 	          ? (&__savereg((__va))->__ireg[(__va).__ireg_used++])	\
173 	          : (__va).__mem_ptr++);				\
174 	  break;							\
175 	}								\
176       else if ((__va).__ireg_used + sizeof (__type) / 4 <= __NUM_PARM_IREGS) \
177 	{								\
178 	  __rv = &__savereg((__va))->__ireg[(__va).__ireg_used];	\
179 	  (__va).__ireg_used += sizeof (__type) / 4;			\
180           break;							\
181 	}								\
182       /* Fall through to fetch from memory.  */				\
183     case __record_type_class:						\
184     case __union_type_class:						\
185       __align = (__alignof__ (__type) < sizeof (long)			\
186 		 ? sizeof (long)					\
187 		 : __alignof__ (__type));				\
188       (__va).__mem_ptr							\
189 	= (long *)							\
190 	  ((((unsigned) (__va).__mem_ptr) + (__align-1)) & ~(__align-1)); \
191       __rv = (__va).__mem_ptr;						\
192       (__va).__mem_ptr							\
193 	+= ((sizeof (__type) + sizeof (long) - 1) / sizeof (long));	\
194       break;								\
195     case __complex_type_class:						\
196     case __function_type_class:						\
197     case __method_type_class:						\
198     case __array_type_class:						\
199     case __string_type_class:						\
200     case __set_type_class:						\
201     case __file_type_class:						\
202     case __lang_type_class:						\
203     case __no_type_class:						\
204     default:								\
205 	abort ();							\
206     }									\
207   __rv;									\
208 }))
209 
210 /* Copy __gnuc_va_list into another variable of this type.  */
211 #define __va_copy(dest, src) (dest) = (src)
212 
213 #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
214 
215