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