This makes code with va_arg work with -nostdlib on x86_64.
Showing the changes to lib (2 of 3 files). Show all
Unified · Split
| @@ -59,8 +59,8 @@ $(Cbc)COMMON_O += bcheck.o · 58 unmodified lines | |||
| 59 | EXTRA_O = runmain.o bt-exe.o bt-dll.o bt-log.o bcheck.o | 59 | EXTRA_O = runmain.o bt-exe.o bt-dll.o bt-log.o bcheck.o |
| 60 | 60 | ||
| 61 | OBJ-i386 = $(I386_O) $(LIN_O) | 61 | OBJ-i386 = $(I386_O) $(LIN_O) |
| 62 | OBJ-x86_64 = $(X86_64_O) va_list.o $(LIN_O) | 62 | OBJ-x86_64 = $(X86_64_O) $(LIN_O) |
| 63 | OBJ-x86_64-osx = $(X86_64_O) va_list.o $(OSX_O) | 63 | OBJ-x86_64-osx = $(X86_64_O) $(OSX_O) |
| 64 | OBJ-i386-win32 = $(I386_O) chkstk.o $(WIN_O) | 64 | OBJ-i386-win32 = $(I386_O) chkstk.o $(WIN_O) |
| 65 | OBJ-x86_64-win32 = $(X86_64_O) chkstk.o $(WIN_O) | 65 | OBJ-x86_64-win32 = $(X86_64_O) chkstk.o $(WIN_O) |
| 66 | OBJ-arm64 = $(ARM64_O) $(LIN_O) | 66 | OBJ-arm64 = $(ARM64_O) $(LIN_O) |
| @@ -1,67 +0,0 @@ | |||
| 1 | /* va_list.c - tinycc support for va_list on X86_64 */ | ||
| 2 | |||
| 3 | #if defined __x86_64__ | ||
| 4 | |||
| 5 | /* Avoid include files, they may not be available when cross compiling */ | ||
| 6 | extern void abort(void); | ||
| 7 | |||
| 8 | /* This should be in sync with our include/stdarg.h */ | ||
| 9 | enum __va_arg_type { | ||
| 10 | __va_gen_reg, __va_float_reg, __va_stack | ||
| 11 | }; | ||
| 12 | |||
| 13 | /* GCC compatible definition of va_list. */ | ||
| 14 | /*predefined by TCC (tcc_predefs.h): | ||
| 15 | typedef struct { | ||
| 16 | unsigned int gp_offset; | ||
| 17 | unsigned int fp_offset; | ||
| 18 | union { | ||
| 19 | unsigned int overflow_offset; | ||
| 20 | char *overflow_arg_area; | ||
| 21 | }; | ||
| 22 | char *reg_save_area; | ||
| 23 | } __builtin_va_list[1]; | ||
| 24 | */ | ||
| 25 | |||
| 26 | extern void *memcpy(void *dest, const void *src, unsigned long n); | ||
| 27 | |||
| 28 | void *__va_arg(__builtin_va_list ap, | ||
| 29 | int arg_type, | ||
| 30 | int size, int align) | ||
| 31 | { | ||
| 32 | size = (size + 7) & ~7; | ||
| 33 | align = (align + 7) & ~7; | ||
| 34 | switch ((enum __va_arg_type)arg_type) { | ||
| 35 | case __va_gen_reg: | ||
| 36 | if (ap->gp_offset + size <= 48) { | ||
| 37 | ap->gp_offset += size; | ||
| 38 | return ap->reg_save_area + ap->gp_offset - size; | ||
| 39 | } | ||
| 40 | goto use_overflow_area; | ||
| 41 | |||
| 42 | case __va_float_reg: | ||
| 43 | if (ap->fp_offset < 128 + 48) { | ||
| 44 | ap->fp_offset += 16; | ||
| 45 | if (size == 8) | ||
| 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); | ||
| 50 | ap->fp_offset += 16; | ||
| 51 | return ap->reg_save_area + ap->fp_offset - 32; | ||
| 52 | } | ||
| 53 | } | ||
| 54 | goto use_overflow_area; | ||
| 55 | |||
| 56 | case __va_stack: | ||
| 57 | 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; | ||
| 61 | |||
| 62 | default: /* should never happen */ | ||
| 63 | abort(); | ||
| 64 | return 0; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | #endif | ||