1 /* stdarg/varargs support for the ARC */ 2 3 /* Define __gnuc_va_list. */ 4 5 #ifndef __GNUC_VA_LIST 6 #define __GNUC_VA_LIST 7 typedef void * __gnuc_va_list; 8 #endif /* not __GNUC_VA_LIST */ 9 10 /* If this is for internal libc use, don't define anything but 11 __gnuc_va_list. */ 12 #if defined (_STDARG_H) || defined (_VARARGS_H) 13 14 /* In GCC version 2, we want an ellipsis at the end of the declaration 15 of the argument list. GCC version 1 can't parse it. */ 16 17 #if __GNUC__ > 1 18 #define __va_ellipsis ... 19 #else 20 #define __va_ellipsis 21 #endif 22 23 /* See arc_setup_incoming_varargs for reasons for the oddity in va_start. */ 24 #ifdef _STDARG_H 25 #define va_start(AP, LASTARG) \ 26 (AP = (__gnuc_va_list) ((int *) __builtin_next_arg (LASTARG) \ 27 + (__builtin_args_info (0) < 8 \ 28 ? (__builtin_args_info (0) & 1) \ 29 : 0))) 30 #else 31 #define va_alist __builtin_va_alist 32 #define va_dcl int __builtin_va_alist; __va_ellipsis 33 #define va_start(AP) \ 34 (AP = (__gnuc_va_list) ((int *) &__builtin_va_alist \ 35 + (__builtin_args_info (0) < 8 \ 36 ? (__builtin_args_info (0) & 1) \ 37 : 0))) 38 #endif 39 40 #ifndef va_end 41 void va_end (__gnuc_va_list); /* Defined in libgcc.a */ 42 43 /* Values returned by __builtin_classify_type. */ 44 45 enum __va_type_classes { 46 __no_type_class = -1, 47 __void_type_class, 48 __integer_type_class, 49 __char_type_class, 50 __enumeral_type_class, 51 __boolean_type_class, 52 __pointer_type_class, 53 __reference_type_class, 54 __offset_type_class, 55 __real_type_class, 56 __complex_type_class, 57 __function_type_class, 58 __method_type_class, 59 __record_type_class, 60 __union_type_class, 61 __array_type_class, 62 __string_type_class, 63 __set_type_class, 64 __file_type_class, 65 __lang_type_class 66 }; 67 68 #endif 69 #define va_end(AP) ((void)0) 70 71 /* Avoid errors if compiling GCC v2 with GCC v1. */ 72 #if __GNUC__ == 1 73 #define __extension__ 74 #endif 75 76 /* All aggregates are passed by reference. All scalar types larger than 8 77 bytes are passed by reference. */ 78 /* We cast to void * and then to TYPE * because this avoids 79 a warning about increasing the alignment requirement. 80 The casts to char * avoid warnings about invalid pointer arithmetic. */ 81 82 #define __va_rounded_size(TYPE) \ 83 (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) 84 85 #ifdef __big_endian__ 86 #define va_arg(AP,TYPE) \ 87 __extension__ \ 88 (*({((__builtin_classify_type (*(TYPE*) 0) >= __record_type_class \ 89 || __va_rounded_size (TYPE) > 8) \ 90 ? ((AP) = (char *)(AP) + __va_rounded_size (TYPE *), \ 91 *(TYPE **) (void *) ((char *)(AP) - __va_rounded_size (TYPE *))) \ 92 : ((TYPE *) (void *) \ 93 (AP = (void *) ((__alignof__ (TYPE) > 4 \ 94 ? ((int) AP + 8 - 1) & -8 \ 95 : (int) AP) \ 96 + __va_rounded_size (TYPE))) - 1));})) 97 #else 98 #define va_arg(AP,TYPE) \ 99 __extension__ \ 100 (*({((__builtin_classify_type (*(TYPE*) 0) >= __record_type_class \ 101 || __va_rounded_size (TYPE) > 8) \ 102 ? ((AP) = (char *)(AP) + __va_rounded_size (TYPE *), \ 103 *(TYPE **) (void *) ((char *)(AP) - __va_rounded_size (TYPE *))) \ 104 : ((AP = (void *) ((__alignof__ (TYPE) > 4 \ 105 ? ((int) AP + 8 - 1) & -8 \ 106 : (int) AP) \ 107 + __va_rounded_size (TYPE))), \ 108 (TYPE *) (void *) (AP - __va_rounded_size (TYPE))));})) 109 #endif 110 111 #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */ 112