1 /* va_list.c - tinycc support for va_list on X86_64 */
3 #if defined TCC_TARGET_X86_64
5 /* Avoid include files, they may not be available when cross compiling */
6 extern void *memset(void *s
, int c
, __SIZE_TYPE__ n
);
7 extern void abort(void);
9 /* This should be in sync with our include/stdarg.h */
11 __va_gen_reg
, __va_float_reg
, __va_stack
14 /* GCC compatible definition of va_list. */
16 unsigned int gp_offset
;
17 unsigned int fp_offset
;
19 unsigned int overflow_offset
;
20 char *overflow_arg_area
;
25 void __va_start(__va_list_struct
*ap
, void *fp
)
27 memset(ap
, 0, sizeof(__va_list_struct
));
28 *ap
= *(__va_list_struct
*)((char *)fp
- 16);
29 ap
->overflow_arg_area
= (char *)fp
+ ap
->overflow_offset
;
30 ap
->reg_save_area
= (char *)fp
- 176 - 16;
33 void *__va_arg(__va_list_struct
*ap
,
34 enum __va_arg_type arg_type
,
37 size
= (size
+ 7) & ~7;
38 align
= (align
+ 7) & ~7;
41 if (ap
->gp_offset
+ size
<= 48) {
42 ap
->gp_offset
+= size
;
43 return ap
->reg_save_area
+ ap
->gp_offset
- size
;
45 goto use_overflow_area
;
48 if (ap
->fp_offset
< 128 + 48) {
50 return ap
->reg_save_area
+ ap
->fp_offset
- 16;
53 goto use_overflow_area
;
57 ap
->overflow_arg_area
+= size
;
58 ap
->overflow_arg_area
= (char*)((long long)(ap
->overflow_arg_area
+ align
- 1) & -align
);
59 return ap
->overflow_arg_area
- size
;
61 default: /* should never happen */