1 /* va_list.c - tinycc support for va_list on X86_64 */
5 /* Avoid include files, they may not be available when cross compiling */
6 extern void abort(void);
8 /* This should be in sync with our include/stdarg.h */
10 __va_gen_reg
, __va_float_reg
, __va_stack
13 /* GCC compatible definition of va_list. */
14 /*predefined by TCC (tcc_predefs.h):
16 unsigned int gp_offset;
17 unsigned int fp_offset;
19 unsigned int overflow_offset;
20 char *overflow_arg_area;
23 } __builtin_va_list[1];
26 extern void *memcpy(void *dest
, const void *src
, unsigned long n
);
28 void *__va_arg(__builtin_va_list ap
,
32 size
= (size
+ 7) & ~7;
33 align
= (align
+ 7) & ~7;
34 switch ((enum __va_arg_type
)arg_type
) {
36 if (ap
->gp_offset
+ size
<= 48) {
37 ap
->gp_offset
+= size
;
38 return ap
->reg_save_area
+ ap
->gp_offset
- size
;
40 goto use_overflow_area
;
43 if (ap
->fp_offset
< 128 + 48) {
46 return ap
->reg_save_area
+ ap
->fp_offset
- 16;
47 if (ap
->fp_offset
< 128 + 48) {
48 memcpy(ap
->reg_save_area
+ ap
->fp_offset
- 8,
49 ap
->reg_save_area
+ ap
->fp_offset
, 8);
51 return ap
->reg_save_area
+ ap
->fp_offset
- 32;
54 goto use_overflow_area
;
58 ap
->overflow_arg_area
+= size
;
59 ap
->overflow_arg_area
= (char*)((long long)(ap
->overflow_arg_area
+ align
- 1) & -align
);
60 return ap
->overflow_arg_area
- size
;
62 default: /* should never happen */