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 18typedef 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 29typedef 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 40enum { 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 168void 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