#define __vpad(I, T) ((((I) + __vali (T) - 1) / __vali (T)) \
* __vali (T) + __vsiz (T))
+/* Avoid errors if compiling GCC v2 with GCC v1. */
+#if __GNUC__ == 1
+#define __extension__
+#endif
+
#ifdef _STDARG_H
-#define va_start(AP, LASTARG) ((AP)[1] = 0, \
- *(AP) = (unsigned) __builtin_next_arg ())
+/* Call __builtin_next_arg even though we aren't using its value, so that
+ we can verify that firstarg is correct. */
+#define va_start(AP, LASTARG) \
+__extension__ \
+({ __builtin_next_arg (LASTARG); \
+ __asm__ ("st g14,%0" : "=m" (*(AP))); \
+ (AP)[1] = (__builtin_args_info (0) + __builtin_args_info (1)) * 4; })
+
#else
#define va_alist __builtin_va_alist
#define va_dcl char *__builtin_va_alist; __va_ellipsis
-#define va_start(AP) ((AP)[1] = 0, *(AP) = (unsigned) &va_alist)
+#define va_start(AP) \
+__extension__ \
+({ __asm__ ("st g14,%0" : "=m" (*(AP))); \
+ (AP)[1] = (__builtin_args_info (0) + __builtin_args_info (1)) * 4; })
#endif
/* We cast to void * and then to TYPE * because this avoids
*((T *) (void *) ((char *) *(AP) + (AP)[1] - __vsiz (T))) \
)
+#ifndef va_end
void va_end (__gnuc_va_list); /* Defined in libgcc.a */
-#define va_end(AP)
+#endif
+#define va_end(AP) ((void *)0)
#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */