xref: /haiku/headers/build/gcc-2.95.3/va-arc.h (revision 1deede7388b04dbeec5af85cae7164735ea9e70d)
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