1 /* ---------------------------------------- */ 2 /* VARARGS for MIPS/GNU CC */ 3 /* */ 4 /* */ 5 /* */ 6 /* */ 7 /* ---------------------------------------- */ 8 9 10 /* These macros implement varargs for GNU C--either traditional or ANSI. */ 11 12 /* Define __gnuc_va_list. */ 13 14 #ifndef __GNUC_VA_LIST 15 #define __GNUC_VA_LIST 16 #if defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float) 17 18 typedef struct { 19 /* Pointer to FP regs. */ 20 char *__fp_regs; 21 /* Number of FP regs remaining. */ 22 int __fp_left; 23 /* Pointer to GP regs followed by stack parameters. */ 24 char *__gp_regs; 25 } __gnuc_va_list; 26 27 #else /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */ 28 29 typedef char * __gnuc_va_list; 30 31 #endif /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */ 32 #endif /* not __GNUC_VA_LIST */ 33 34 /* If this is for internal libc use, don't define anything but 35 __gnuc_va_list. */ 36 #if defined (_STDARG_H) || defined (_VARARGS_H) 37 38 #ifndef _VA_MIPS_H_ENUM 39 #define _VA_MIPS_H_ENUM 40 enum { 41 __no_type_class = -1, 42 __void_type_class, 43 __integer_type_class, 44 __char_type_class, 45 __enumeral_type_class, 46 __boolean_type_class, 47 __pointer_type_class, 48 __reference_type_class, 49 __offset_type_class, 50 __real_type_class, 51 __complex_type_class, 52 __function_type_class, 53 __method_type_class, 54 __record_type_class, 55 __union_type_class, 56 __array_type_class, 57 __string_type_class, 58 __set_type_class, 59 __file_type_class, 60 __lang_type_class 61 }; 62 #endif 63 64 /* In GCC version 2, we want an ellipsis at the end of the declaration 65 of the argument list. GCC version 1 can't parse it. */ 66 67 #if __GNUC__ > 1 68 #define __va_ellipsis ... 69 #else 70 #define __va_ellipsis 71 #endif 72 73 #ifdef __mips64 74 #define __va_rounded_size(__TYPE) \ 75 (((sizeof (__TYPE) + 8 - 1) / 8) * 8) 76 #else 77 #define __va_rounded_size(__TYPE) \ 78 (((sizeof (__TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) 79 #endif 80 81 #ifdef __mips64 82 #define __va_reg_size 8 83 #else 84 #define __va_reg_size 4 85 #endif 86 87 /* Get definitions for _MIPS_SIM_ABI64 etc. */ 88 #ifdef _MIPS_SIM 89 #include <sgidefs.h> 90 #endif 91 92 #ifdef _STDARG_H 93 #if defined (__mips_eabi) 94 #if ! defined (__mips_soft_float) && ! defined (__mips_single_float) 95 #ifdef __mips64 96 #define va_start(__AP, __LASTARG) \ 97 (__AP.__gp_regs = ((char *) __builtin_next_arg (__LASTARG) \ 98 - (__builtin_args_info (2) < 8 \ 99 ? (8 - __builtin_args_info (2)) * __va_reg_size \ 100 : 0)), \ 101 __AP.__fp_left = 8 - __builtin_args_info (3), \ 102 __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * __va_reg_size) 103 #else /* ! defined (__mips64) */ 104 #define va_start(__AP, __LASTARG) \ 105 (__AP.__gp_regs = ((char *) __builtin_next_arg (__LASTARG) \ 106 - (__builtin_args_info (2) < 8 \ 107 ? (8 - __builtin_args_info (2)) * __va_reg_size \ 108 : 0)), \ 109 __AP.__fp_left = (8 - __builtin_args_info (3)) / 2, \ 110 __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * 8, \ 111 __AP.__fp_regs = (char *) ((int) __AP.__fp_regs & -8)) 112 #endif /* ! defined (__mips64) */ 113 #else /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float) ) */ 114 #define va_start(__AP, __LASTARG) \ 115 (__AP = ((__gnuc_va_list) __builtin_next_arg (__LASTARG) \ 116 - (__builtin_args_info (2) >= 8 ? 0 \ 117 : (8 - __builtin_args_info (2)) * __va_reg_size))) 118 #endif /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float) ) */ 119 #else /* ! defined (__mips_eabi) */ 120 #define va_start(__AP, __LASTARG) \ 121 (__AP = (__gnuc_va_list) __builtin_next_arg (__LASTARG)) 122 #endif /* ! (defined (__mips_eabi) && ! defined (__mips_soft_float) && ! defined (__mips_single_float)) */ 123 #else /* ! _STDARG_H */ 124 #define va_alist __builtin_va_alist 125 #ifdef __mips64 126 /* This assumes that `long long int' is always a 64 bit type. */ 127 #define va_dcl long long int __builtin_va_alist; __va_ellipsis 128 #else 129 #define va_dcl int __builtin_va_alist; __va_ellipsis 130 #endif 131 #if defined (__mips_eabi) 132 #if ! defined (__mips_soft_float) && ! defined (__mips_single_float) 133 #ifdef __mips64 134 #define va_start(__AP) \ 135 (__AP.__gp_regs = ((char *) __builtin_next_arg () \ 136 - (__builtin_args_info (2) < 8 \ 137 ? (8 - __builtin_args_info (2)) * __va_reg_size \ 138 : __va_reg_size)), \ 139 __AP.__fp_left = 8 - __builtin_args_info (3), \ 140 __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * __va_reg_size) 141 #else /* ! defined (__mips64) */ 142 #define va_start(__AP) \ 143 (__AP.__gp_regs = ((char *) __builtin_next_arg () \ 144 - (__builtin_args_info (2) < 8 \ 145 ? (8 - __builtin_args_info (2)) * __va_reg_size \ 146 : __va_reg_size)), \ 147 __AP.__fp_left = (8 - __builtin_args_info (3)) / 2, \ 148 __AP.__fp_regs = __AP.__gp_regs - __AP.__fp_left * 8, \ 149 __AP.__fp_regs = (char *) ((int) __AP.__fp_regs & -8)) 150 #endif /* ! defined (__mips64) */ 151 #else /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */ 152 #define va_start(__AP) \ 153 (__AP = ((__gnuc_va_list) __builtin_next_arg () \ 154 - (__builtin_args_info (2) >= 8 ? __va_reg_size \ 155 : (8 - __builtin_args_info (2)) * __va_reg_size))) 156 #endif /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */ 157 /* Need alternate code for _MIPS_SIM_ABI64. */ 158 #elif defined(_MIPS_SIM) && (_MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32) 159 #define va_start(__AP) \ 160 (__AP = (__gnuc_va_list) __builtin_next_arg () \ 161 + (__builtin_args_info (2) >= 8 ? -8 : 0)) 162 #else 163 #define va_start(__AP) __AP = (char *) &__builtin_va_alist 164 #endif 165 #endif /* ! _STDARG_H */ 166 167 #ifndef va_end 168 void va_end (__gnuc_va_list); /* Defined in libgcc.a */ 169 #endif 170 #define va_end(__AP) ((void)0) 171 172 #if defined (__mips_eabi) 173 174 #if ! defined (__mips_soft_float) && ! defined (__mips_single_float) 175 #ifdef __mips64 176 #define __va_next_addr(__AP, __type) \ 177 ((__builtin_classify_type (*(__type *) 0) == __real_type_class \ 178 && __AP.__fp_left > 0) \ 179 ? (--__AP.__fp_left, (__AP.__fp_regs += 8) - 8) \ 180 : (__AP.__gp_regs += __va_reg_size) - __va_reg_size) 181 #else 182 #define __va_next_addr(__AP, __type) \ 183 ((__builtin_classify_type (*(__type *) 0) == __real_type_class \ 184 && __AP.__fp_left > 0) \ 185 ? (--__AP.__fp_left, (__AP.__fp_regs += 8) - 8) \ 186 : (((__builtin_classify_type (* (__type *) 0) < __record_type_class \ 187 && __alignof__ (__type) > 4) \ 188 ? __AP.__gp_regs = (char *) (((int) __AP.__gp_regs + 8 - 1) & -8) \ 189 : (char *) 0), \ 190 (__builtin_classify_type (* (__type *) 0) >= __record_type_class \ 191 ? (__AP.__gp_regs += __va_reg_size) - __va_reg_size \ 192 : ((__AP.__gp_regs += __va_rounded_size (__type)) \ 193 - __va_rounded_size (__type))))) 194 #endif 195 #else /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */ 196 #ifdef __mips64 197 #define __va_next_addr(__AP, __type) \ 198 ((__AP += __va_reg_size) - __va_reg_size) 199 #else 200 #define __va_next_addr(__AP, __type) \ 201 (((__builtin_classify_type (* (__type *) 0) < __record_type_class \ 202 && __alignof__ (__type) > 4) \ 203 ? __AP = (char *) (((__PTRDIFF_TYPE__) __AP + 8 - 1) & -8) \ 204 : (char *) 0), \ 205 (__builtin_classify_type (* (__type *) 0) >= __record_type_class \ 206 ? (__AP += __va_reg_size) - __va_reg_size \ 207 : ((__AP += __va_rounded_size (__type)) \ 208 - __va_rounded_size (__type)))) 209 #endif 210 #endif /* ! (! defined (__mips_soft_float) && ! defined (__mips_single_float)) */ 211 212 #ifdef __MIPSEB__ 213 #define va_arg(__AP, __type) \ 214 ((__va_rounded_size (__type) <= __va_reg_size) \ 215 ? *(__type *) (void *) (__va_next_addr (__AP, __type) \ 216 + __va_reg_size \ 217 - sizeof (__type)) \ 218 : (__builtin_classify_type (*(__type *) 0) >= __record_type_class \ 219 ? **(__type **) (void *) (__va_next_addr (__AP, __type) \ 220 + __va_reg_size \ 221 - sizeof (char *)) \ 222 : *(__type *) (void *) __va_next_addr (__AP, __type))) 223 #else 224 #define va_arg(__AP, __type) \ 225 ((__va_rounded_size (__type) <= __va_reg_size) \ 226 ? *(__type *) (void *) __va_next_addr (__AP, __type) \ 227 : (__builtin_classify_type (* (__type *) 0) >= __record_type_class \ 228 ? **(__type **) (void *) __va_next_addr (__AP, __type) \ 229 : *(__type *) (void *) __va_next_addr (__AP, __type))) 230 #endif 231 232 #else /* ! defined (__mips_eabi) */ 233 234 /* We cast to void * and then to TYPE * because this avoids 235 a warning about increasing the alignment requirement. */ 236 /* The __mips64 cases are reversed from the 32 bit cases, because the standard 237 32 bit calling convention left-aligns all parameters smaller than a word, 238 whereas the __mips64 calling convention does not (and hence they are 239 right aligned). */ 240 #ifdef __mips64 241 #ifdef __MIPSEB__ 242 #define va_arg(__AP, __type) \ 243 ((__type *) (void *) (__AP = (char *) \ 244 ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8) \ 245 + __va_rounded_size (__type))))[-1] 246 #else 247 #define va_arg(__AP, __type) \ 248 ((__AP = (char *) ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8) \ 249 + __va_rounded_size (__type))), \ 250 *(__type *) (void *) (__AP - __va_rounded_size (__type))) 251 #endif 252 253 #else /* not __mips64 */ 254 255 #ifdef __MIPSEB__ 256 /* For big-endian machines. */ 257 #define va_arg(__AP, __type) \ 258 ((__AP = (char *) ((__alignof__ (__type) > 4 \ 259 ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8 \ 260 : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4) \ 261 + __va_rounded_size (__type))), \ 262 *(__type *) (void *) (__AP - __va_rounded_size (__type))) 263 #else 264 /* For little-endian machines. */ 265 #define va_arg(__AP, __type) \ 266 ((__type *) (void *) (__AP = (char *) ((__alignof__(__type) > 4 \ 267 ? ((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8 \ 268 : ((__PTRDIFF_TYPE__)__AP + 4 - 1) & -4) \ 269 + __va_rounded_size(__type))))[-1] 270 #endif 271 #endif 272 #endif /* ! defined (__mips_eabi) */ 273 274 /* Copy __gnuc_va_list into another variable of this type. */ 275 #define __va_copy(dest, src) (dest) = (src) 276 277 #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */ 278