diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Makefile | 57 | ||||
| -rw-r--r-- | lib/armflush.c | 58 | ||||
| -rw-r--r-- | lib/libtcc1.c | 128 | ||||
| -rw-r--r-- | lib/va_list.c | 65 |
4 files changed, 164 insertions, 144 deletions
diff --git a/lib/Makefile b/lib/Makefile index 00ab7dc..fe517e9 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -17,61 +17,54 @@ XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include XFLAGS = $(XFLAGS$(XCFG)) XCFG = $(or $(findstring -win,$T),-unx) -ifeq ($(X),) - BCHECK_O = bcheck.o - ifeq "$T" "arm" - XCC = $(CC) - XAR = $(AR) - XFLAGS = $(CFLAGS) -fPIC - endif -endif +# using gcc ("make armlib-usegcc=no" to use tcc) +armlib-usegcc ?= no -ifdef CONFIG_OSX - XFLAGS += -D_ANSI_SOURCE +ifeq "$($(X)$(T)lib-usegcc)" "yes" + XCC = $(CC) + XAR = $(AR) + XFLAGS = $(CFLAGS) -fPIC endif +# only for native compiler +$(X)BCHECK_O = bcheck.o + ifeq ($(CONFIG_musl),yes) BCHECK_O = endif +ifdef CONFIG_OSX + XFLAGS += -D_ANSI_SOURCE +endif + I386_O = libtcc1.o alloca86.o alloca86-bt.o X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o -ARM_O = libtcc1.o armeabi.o alloca-arm.o +ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o ARM64_O = lib-arm64.o WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o OBJ-i386 = $(I386_O) $(BCHECK_O) -TGT-i386 = -DTCC_TARGET_I386 - -OBJ-x86_64 = $(X86_64_O) $(BCHECK_O) -TGT-x86_64 = -DTCC_TARGET_X86_64 - -OBJ-x86_64-osx = $(X86_64_O) -TGT-x86_64-osx = -DTCC_TARGET_X86_64 -DTCC_TARGET_MACHO - -OBJ-arm = $(ARM_O) -TGT-arm = -DTCC_TARGET_ARM - -OBJ-arm64 = $(ARM64_O) -TGT-arm64 = -DTCC_TARGET_ARM64 - +OBJ-x86_64 = $(X86_64_O) va_list.o $(BCHECK_O) +OBJ-x86_64-osx = $(X86_64_O) va_list.o OBJ-i386-win32 = $(I386_O) chkstk.o bcheck.o $(WIN_O) -TGT-i386-win32 = -DTCC_TARGET_I386 -DTCC_TARGET_PE - OBJ-x86_64-win32 = $(X86_64_O) chkstk.o bcheck.o $(WIN_O) -TGT-x86_64-win32 = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE - +OBJ-arm64 = $(ARM64_O) +OBJ-arm = $(ARM_O) +OBJ-arm-fpa = $(ARM_O) +OBJ-arm-fpa-ld = $(ARM_O) +OBJ-arm-vfp = $(ARM_O) +OBJ-arm-eabi = $(ARM_O) +OBJ-arm-eabihf = $(ARM_O) OBJ-arm-wince = $(ARM_O) $(WIN_O) -TGT-arm-wince = -DTCC_TARGET_ARM -DTCC_TARGET_PE $(BIN) : $(patsubst %.o,$(X)%.o,$(OBJ-$T)) $(XAR) rcs $@ $^ $(X)%.o : %.c - $(XCC) -c $< -o $@ $(TGT-$T) $(XFLAGS) + $(XCC) -c $< -o $@ $(DEFINES) $(XFLAGS) $(X)%.o : %.S - $(XCC) -c $< -o $@ $(TGT-$T) $(XFLAGS) + $(XCC) -c $< -o $@ $(DEFINES) $(XFLAGS) $(X)crt1w.o : crt1.c $(X)wincrt1w.o : wincrt1.c diff --git a/lib/armflush.c b/lib/armflush.c new file mode 100644 index 0000000..eae3260 --- /dev/null +++ b/lib/armflush.c @@ -0,0 +1,58 @@ +/* armflush.c - flush the instruction cache + + __clear_cache is used in tccrun.c, It is a built-in + intrinsic with gcc. However tcc in order to compile + itself needs this function */ + +#ifdef __TINYC__ + +/* syscall wrapper */ +unsigned syscall(unsigned syscall_nr, ...); + +/* arm-tcc supports only fake asm currently */ +__asm__( + ".global syscall\n" + "syscall:\n" + ".int 0xe92d4080\n" // push {r7, lr} + ".int 0xe1a07000\n" // mov r7, r0 + ".int 0xe1a00001\n" // mov r0, r1 + ".int 0xe1a01002\n" // mov r1, r2 + ".int 0xe1a02003\n" // mov r2, r3 + ".int 0xef000000\n" // svc 0x00000000 + ".int 0xe8bd8080\n" // pop {r7, pc} + ); + +/* from unistd.h: */ +#if defined(__thumb__) || defined(__ARM_EABI__) +# define __NR_SYSCALL_BASE 0x0 +#else +# define __NR_SYSCALL_BASE 0x900000 +#endif +#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000) +#define __ARM_NR_cacheflush (__ARM_NR_BASE+2) + +#else + +#define _GNU_SOURCE +#include <unistd.h> +#include <sys/syscall.h> +#include <stdio.h> + +#endif + +/* Flushing for tccrun */ +void __clear_cache(void *beginning, void *end) +{ +/* __ARM_NR_cacheflush is kernel private and should not be used in user space. + * However, there is no ARM asm parser in tcc so we use it for now */ +#if 1 + syscall(__ARM_NR_cacheflush, beginning, end, 0); +#else + __asm__ ("push {r7}\n\t" + "mov r7, #0xf0002\n\t" + "mov r2, #0\n\t" + "swi 0\n\t" + "pop {r7}\n\t" + "ret"); +#endif +} diff --git a/lib/libtcc1.c b/lib/libtcc1.c index 9195489..0702a59 100644 --- a/lib/libtcc1.c +++ b/lib/libtcc1.c @@ -550,6 +550,13 @@ unsigned long long __fixunssfdi (float a1) return 0; } +long long __fixsfdi (float a1) +{ + long long ret; int s; + ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1); + return s ? ret : -ret; +} + unsigned long long __fixunsdfdi (double a1) { register union double_long dl1; @@ -575,6 +582,14 @@ unsigned long long __fixunsdfdi (double a1) return 0; } +long long __fixdfdi (double a1) +{ + long long ret; int s; + ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1); + return s ? ret : -ret; +} + +#ifndef TCC_TARGET_ARM unsigned long long __fixunsxfdi (long double a1) { register union ldouble_long dl1; @@ -598,121 +613,10 @@ unsigned long long __fixunsxfdi (long double a1) return 0; } -long long __fixsfdi (float a1) -{ - long long ret; int s; - ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1); - return s ? ret : -ret; -} - -long long __fixdfdi (double a1) -{ - long long ret; int s; - ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1); - return s ? ret : -ret; -} - long long __fixxfdi (long double a1) { long long ret; int s; ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1); return s ? ret : -ret; } - -#if defined(TCC_TARGET_X86_64) && !defined(_WIN64) - -#ifndef __TINYC__ -# include <stdlib.h> -# include <stdio.h> -# include <string.h> -# undef __va_start -# undef __va_arg -# undef __va_copy -# undef __va_end -#else -/* Avoid include files, they may not be available when cross compiling */ -extern void *memset(void *s, int c, __SIZE_TYPE__ n); -extern void abort(void); -#endif - -/* This should be in sync with our include/stdarg.h */ -enum __va_arg_type { - __va_gen_reg, __va_float_reg, __va_stack -}; - -/* GCC compatible definition of va_list. */ -typedef struct { - unsigned int gp_offset; - unsigned int fp_offset; - union { - unsigned int overflow_offset; - char *overflow_arg_area; - }; - char *reg_save_area; -} __va_list_struct; - -void __va_start(__va_list_struct *ap, void *fp) -{ - memset(ap, 0, sizeof(__va_list_struct)); - *ap = *(__va_list_struct *)((char *)fp - 16); - ap->overflow_arg_area = (char *)fp + ap->overflow_offset; - ap->reg_save_area = (char *)fp - 176 - 16; -} - -void *__va_arg(__va_list_struct *ap, - enum __va_arg_type arg_type, - int size, int align) -{ - size = (size + 7) & ~7; - align = (align + 7) & ~7; - switch (arg_type) { - case __va_gen_reg: - if (ap->gp_offset + size <= 48) { - ap->gp_offset += size; - return ap->reg_save_area + ap->gp_offset - size; - } - goto use_overflow_area; - - case __va_float_reg: - if (ap->fp_offset < 128 + 48) { - ap->fp_offset += 16; - return ap->reg_save_area + ap->fp_offset - 16; - } - size = 8; - goto use_overflow_area; - - case __va_stack: - use_overflow_area: - ap->overflow_arg_area += size; - ap->overflow_arg_area = (char*)((long long)(ap->overflow_arg_area + align - 1) & -align); - return ap->overflow_arg_area - size; - - default: /* should never happen */ - abort(); - } -} -#endif /* __x86_64__ */ - -#if defined TCC_TARGET_ARM && !defined __TINYC__ -#define _GNU_SOURCE -#include <unistd.h> -#include <sys/syscall.h> -#include <stdio.h> - -/* Flushing for tccrun */ -void __clear_cache(void *beginning, void *end) -{ -/* __ARM_NR_cacheflush is kernel private and should not be used in user space. - * However, there is no ARM asm parser in tcc so we use it for now */ -#if 1 - syscall(__ARM_NR_cacheflush, beginning, end, 0); -#else - __asm__ ("push {r7}\n\t" - "mov r7, #0xf0002\n\t" - "mov r2, #0\n\t" - "swi 0\n\t" - "pop {r7}\n\t" - "ret"); -#endif -} -#endif /* arm */ +#endif /* !ARM */ diff --git a/lib/va_list.c b/lib/va_list.c new file mode 100644 index 0000000..57dce0d --- /dev/null +++ b/lib/va_list.c @@ -0,0 +1,65 @@ +/* va_list.c - tinycc support for va_list on X86_64 */ + +#if defined TCC_TARGET_X86_64 + +/* Avoid include files, they may not be available when cross compiling */ +extern void *memset(void *s, int c, __SIZE_TYPE__ n); +extern void abort(void); + +/* This should be in sync with our include/stdarg.h */ +enum __va_arg_type { + __va_gen_reg, __va_float_reg, __va_stack +}; + +/* GCC compatible definition of va_list. */ +typedef struct { + unsigned int gp_offset; + unsigned int fp_offset; + union { + unsigned int overflow_offset; + char *overflow_arg_area; + }; + char *reg_save_area; +} __va_list_struct; + +void __va_start(__va_list_struct *ap, void *fp) +{ + memset(ap, 0, sizeof(__va_list_struct)); + *ap = *(__va_list_struct *)((char *)fp - 16); + ap->overflow_arg_area = (char *)fp + ap->overflow_offset; + ap->reg_save_area = (char *)fp - 176 - 16; +} + +void *__va_arg(__va_list_struct *ap, + enum __va_arg_type arg_type, + int size, int align) +{ + size = (size + 7) & ~7; + align = (align + 7) & ~7; + switch (arg_type) { + case __va_gen_reg: + if (ap->gp_offset + size <= 48) { + ap->gp_offset += size; + return ap->reg_save_area + ap->gp_offset - size; + } + goto use_overflow_area; + + case __va_float_reg: + if (ap->fp_offset < 128 + 48) { + ap->fp_offset += 16; + return ap->reg_save_area + ap->fp_offset - 16; + } + size = 8; + goto use_overflow_area; + + case __va_stack: + use_overflow_area: + ap->overflow_arg_area += size; + ap->overflow_arg_area = (char*)((long long)(ap->overflow_arg_area + align - 1) & -align); + return ap->overflow_arg_area - size; + + default: /* should never happen */ + abort(); + } +} +#endif |
