History

more minor fixes

* tccgen: re-allow long double constants for x87 cross sizeof (long double) may be 12 or 16 depending on host platform (i386/x86_64 on unix/windows). Except that it's 8 if the host is on windows and not gcc was used to compile tcc. * win64: fix builtin_va_start after VT_REF removal See also a8b83ce43a95fa519dacfe7690a3a0098af7909c * tcctest.c: remove outdated limitation for ll-bitfield test It always worked, there is no reason why it should not work in future. * libtcc1.c: exclude long double conversion on ARM * Makefile: remove CFLAGS from link recipes * lib/Makefile: use target DEFINES as passed from main Makefile * lib/armflush.c lib/va_list.c: factor out from libtcc1.c * arm-gen.c: disable "depreciated" warnings for now

grischka committed 9 years ago

Commit 44abffe1 parent 94ac9f29 files · +194 −166Browse files

Unified · Split

9 files
  1. Makefile +8 −6
  2. arm-gen.c +2 −0
  3. lib/Makefile +25 −32
  4. lib/armflush.c +58 −0
  5. lib/libtcc1.c +16 −112
  6. lib/va_list.c +65 −0
  7. tccgen.c +11 −4
  8. tests/abitest.c +7 −4
  9. tests/tcctest.c +2 −8
Makefile+8−6
@@ -195,14 +195,14 @@ $(X)arm-gen.o : arm-asm.c · 194 unmodified lines
195195
196196 # Host Tiny C Compiler
197197 tcc$(EXESUF): tcc.o $(LIBTCC)
198− $(CC) -o $@ $^ $(DEFINES) $(CFLAGS) $(LIBS) $(LDFLAGS) $(LINK_LIBTCC)
198+ $(CC) -o $@ $^ $(LIBS) $(LDFLAGS) $(LINK_LIBTCC)
199199
200200 # Cross Tiny C Compilers
201201 %-tcc$(EXESUF): FORCE
202202 @$(MAKE) --no-print-directory $@ CROSS_TARGET=$* ONE_SOURCE=$(or $(ONE_SOURCE),yes)
203203
204204 $(CROSS_TARGET)-tcc$(EXESUF): $(TCC_FILES)
205− $(CC) -o $@ $^ $(DEFINES) $(CFLAGS) $(LIBS) $(LDFLAGS)
205+ $(CC) -o $@ $^ $(LIBS) $(LDFLAGS)
206206
207207 # profiling version
208208 tcc_p$(EXESUF): $($T_FILES)
@@ -214,13 +214,14 @@ libtcc.a: $(LIBTCC_OBJ) · 5 unmodified lines
214214
215215 # dynamic libtcc library
216216 libtcc.so: $(LIBTCC_OBJ)
217− $(CC) -shared -Wl,-soname,$@ -o $@ $^ $(CFLAGS) $(LDFLAGS)
217+ $(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
218218
219219 libtcc.so: CFLAGS+=-fPIC
220+libtcc.so: LDFLAGS+=-fPIC
220221
221222 # windows dynamic libtcc library
222223 libtcc.dll : $(LIBTCC_OBJ)
223− $(CC) -shared -o $@ $^ $(CFLAGS) $(LDFLAGS)
224+ $(CC) -shared -o $@ $^ $(LDFLAGS)
224225
225226 libtcc.def : libtcc.dll tcc$(EXESUF)
226227 ./tcc$(EXESUF) -impdef $< -o $@
@@ -229,12 +230,13 @@ libtcc.dll : DEFINES += -DLIBTCC_AS_DLL · 2 unmodified lines
229230
230231 # TinyCC runtime libraries
231232 libtcc1.a : tcc$(EXESUF) FORCE
232− @$(MAKE) -C lib
233+ @$(MAKE) -C lib DEFINES="$(DEF-$T)"
233234
234235 # Cross libtcc1.a
235236 libtcc1-%.a : %-tcc$(EXESUF) FORCE
236− @$(MAKE) -C lib CROSS_TARGET=$*
237+ @$(MAKE) -C lib DEFINES="$(DEF-$*)" CROSS_TARGET=$*
237238
239+.PRECIOUS: libtcc1-%.a
238240 FORCE:
239241
240242 # --------------------------------------------------------------------------
arm-gen.c+2−0
@@ -179,6 +179,7 @@ ST_FUNC void arm_init(struct TCCState *s) · 178 unmodified lines
179179 #define func_ldouble_type func_old_type
180180 ST_FUNC void arm_init(struct TCCState *s)
181181 {
182+#if 0
182183 #if !defined (TCC_ARM_VFP)
183184 tcc_warning("Support for FPA is deprecated and will be removed in next"
184185 " release");
@@ -187,6 +188,7 @@ ST_FUNC void arm_init(struct TCCState *s) · 2 unmodified lines
187188 tcc_warning("Support for OABI is deprecated and will be removed in next"
188189 " release");
189190 #endif
191+#endif
190192 }
191193 #endif
192194
lib/Makefile+25−32
@@ -17,61 +17,54 @@ XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include · 16 unmodified lines
1717 XFLAGS = $(XFLAGS$(XCFG))
1818 XCFG = $(or $(findstring -win,$T),-unx)
1919
20−ifeq ($(X),)
21− BCHECK_O = bcheck.o
22− ifeq "$T" "arm"
23− XCC = $(CC)
24− XAR = $(AR)
25− XFLAGS = $(CFLAGS) -fPIC
26− endif
27−endif
20+# using gcc ("make armlib-usegcc=no" to use tcc)
21+armlib-usegcc ?= no
2822
29−ifdef CONFIG_OSX
30− XFLAGS += -D_ANSI_SOURCE
23+ifeq "$($(X)$(T)lib-usegcc)" "yes"
24+ XCC = $(CC)
25+ XAR = $(AR)
26+ XFLAGS = $(CFLAGS) -fPIC
3127 endif
3228
29+# only for native compiler
30+$(X)BCHECK_O = bcheck.o
31+
3332 ifeq ($(CONFIG_musl),yes)
3433 BCHECK_O =
3534 endif
3635
36+ifdef CONFIG_OSX
37+ XFLAGS += -D_ANSI_SOURCE
38+endif
39+
3740 I386_O = libtcc1.o alloca86.o alloca86-bt.o
3841 X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o
39−ARM_O = libtcc1.o armeabi.o alloca-arm.o
42+ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o
4043 ARM64_O = lib-arm64.o
4144 WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
4245
4346 OBJ-i386 = $(I386_O) $(BCHECK_O)
44−TGT-i386 = -DTCC_TARGET_I386
45−
46−OBJ-x86_64 = $(X86_64_O) $(BCHECK_O)
47−TGT-x86_64 = -DTCC_TARGET_X86_64
48−
49−OBJ-x86_64-osx = $(X86_64_O)
50−TGT-x86_64-osx = -DTCC_TARGET_X86_64 -DTCC_TARGET_MACHO
51−
52−OBJ-arm = $(ARM_O)
53−TGT-arm = -DTCC_TARGET_ARM
54−
55−OBJ-arm64 = $(ARM64_O)
56−TGT-arm64 = -DTCC_TARGET_ARM64
57−
47+OBJ-x86_64 = $(X86_64_O) va_list.o $(BCHECK_O)
48+OBJ-x86_64-osx = $(X86_64_O) va_list.o
5849 OBJ-i386-win32 = $(I386_O) chkstk.o bcheck.o $(WIN_O)
59−TGT-i386-win32 = -DTCC_TARGET_I386 -DTCC_TARGET_PE
60−
6150 OBJ-x86_64-win32 = $(X86_64_O) chkstk.o bcheck.o $(WIN_O)
62−TGT-x86_64-win32 = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE
63−
51+OBJ-arm64 = $(ARM64_O)
52+OBJ-arm = $(ARM_O)
53+OBJ-arm-fpa = $(ARM_O)
54+OBJ-arm-fpa-ld = $(ARM_O)
55+OBJ-arm-vfp = $(ARM_O)
56+OBJ-arm-eabi = $(ARM_O)
57+OBJ-arm-eabihf = $(ARM_O)
6458 OBJ-arm-wince = $(ARM_O) $(WIN_O)
65−TGT-arm-wince = -DTCC_TARGET_ARM -DTCC_TARGET_PE
6659
6760 $(BIN) : $(patsubst %.o,$(X)%.o,$(OBJ-$T))
6861 $(XAR) rcs $@ $^
6962
7063 $(X)%.o : %.c
71− $(XCC) -c $< -o $@ $(TGT-$T) $(XFLAGS)
64+ $(XCC) -c $< -o $@ $(DEFINES) $(XFLAGS)
7265
7366 $(X)%.o : %.S
74− $(XCC) -c $< -o $@ $(TGT-$T) $(XFLAGS)
67+ $(XCC) -c $< -o $@ $(DEFINES) $(XFLAGS)
7568
7669 $(X)crt1w.o : crt1.c
7770 $(X)wincrt1w.o : wincrt1.c
lib/armflush.c+58−0
@@ -0,0 +1,58 @@
1+/* armflush.c - flush the instruction cache
2+
3+ __clear_cache is used in tccrun.c, It is a built-in
4+ intrinsic with gcc. However tcc in order to compile
5+ itself needs this function */
6+
7+#ifdef __TINYC__
8+
9+/* syscall wrapper */
10+unsigned syscall(unsigned syscall_nr, ...);
11+
12+/* arm-tcc supports only fake asm currently */
13+__asm__(
14+ ".global syscall\n"
15+ "syscall:\n"
16+ ".int 0xe92d4080\n" // push {r7, lr}
17+ ".int 0xe1a07000\n" // mov r7, r0
18+ ".int 0xe1a00001\n" // mov r0, r1
19+ ".int 0xe1a01002\n" // mov r1, r2
20+ ".int 0xe1a02003\n" // mov r2, r3
21+ ".int 0xef000000\n" // svc 0x00000000
22+ ".int 0xe8bd8080\n" // pop {r7, pc}
23+ );
24+
25+/* from unistd.h: */
26+#if defined(__thumb__) || defined(__ARM_EABI__)
27+# define __NR_SYSCALL_BASE 0x0
28+#else
29+# define __NR_SYSCALL_BASE 0x900000
30+#endif
31+#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000)
32+#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
33+
34+#else
35+
36+#define _GNU_SOURCE
37+#include <unistd.h>
38+#include <sys/syscall.h>
39+#include <stdio.h>
40+
41+#endif
42+
43+/* Flushing for tccrun */
44+void __clear_cache(void *beginning, void *end)
45+{
46+/* __ARM_NR_cacheflush is kernel private and should not be used in user space.
47+ * However, there is no ARM asm parser in tcc so we use it for now */
48+#if 1
49+ syscall(__ARM_NR_cacheflush, beginning, end, 0);
50+#else
51+ __asm__ ("push {r7}\n\t"
52+ "mov r7, #0xf0002\n\t"
53+ "mov r2, #0\n\t"
54+ "swi 0\n\t"
55+ "pop {r7}\n\t"
56+ "ret");
57+#endif
58+}
lib/libtcc1.c+16−112
@@ -550,6 +550,13 @@ unsigned long long __fixunssfdi (float a1) · 549 unmodified lines
550550 return 0;
551551 }
552552
553+long long __fixsfdi (float a1)
554+{
555+ long long ret; int s;
556+ ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1);
557+ return s ? ret : -ret;
558+}
559+
553560 unsigned long long __fixunsdfdi (double a1)
554561 {
555562 register union double_long dl1;
@@ -575,6 +582,14 @@ unsigned long long __fixunsdfdi (double a1) · 19 unmodified lines
575582 return 0;
576583 }
577584
585+long long __fixdfdi (double a1)
586+{
587+ long long ret; int s;
588+ ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1);
589+ return s ? ret : -ret;
590+}
591+
592+#ifndef TCC_TARGET_ARM
578593 unsigned long long __fixunsxfdi (long double a1)
579594 {
580595 register union ldouble_long dl1;
@@ -598,121 +613,10 @@ unsigned long long __fixunsxfdi (long double a1) · 17 unmodified lines
598613 return 0;
599614 }
600615
601−long long __fixsfdi (float a1)
602−{
603− long long ret; int s;
604− ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1);
605− return s ? ret : -ret;
606−}
607−
608−long long __fixdfdi (double a1)
609−{
610− long long ret; int s;
611− ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1);
612− return s ? ret : -ret;
613−}
614−
615616 long long __fixxfdi (long double a1)
616617 {
617618 long long ret; int s;
618619 ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1);
619620 return s ? ret : -ret;
620621 }
621−
622−#if defined(TCC_TARGET_X86_64) && !defined(_WIN64)
623−
624−#ifndef __TINYC__
625−# include <stdlib.h>
626−# include <stdio.h>
627−# include <string.h>
628−# undef __va_start
629−# undef __va_arg
630−# undef __va_copy
631−# undef __va_end
632−#else
633−/* Avoid include files, they may not be available when cross compiling */
634−extern void *memset(void *s, int c, __SIZE_TYPE__ n);
635−extern void abort(void);
636−#endif
637−
638−/* This should be in sync with our include/stdarg.h */
639−enum __va_arg_type {
640− __va_gen_reg, __va_float_reg, __va_stack
641−};
642−
643−/* GCC compatible definition of va_list. */
644−typedef struct {
645− unsigned int gp_offset;
646− unsigned int fp_offset;
647− union {
648− unsigned int overflow_offset;
649− char *overflow_arg_area;
650− };
651− char *reg_save_area;
652−} __va_list_struct;
653−
654−void __va_start(__va_list_struct *ap, void *fp)
655−{
656− memset(ap, 0, sizeof(__va_list_struct));
657− *ap = *(__va_list_struct *)((char *)fp - 16);
658− ap->overflow_arg_area = (char *)fp + ap->overflow_offset;
659− ap->reg_save_area = (char *)fp - 176 - 16;
660−}
661−
662−void *__va_arg(__va_list_struct *ap,
663− enum __va_arg_type arg_type,
664− int size, int align)
665−{
666− size = (size + 7) & ~7;
667− align = (align + 7) & ~7;
668− switch (arg_type) {
669− case __va_gen_reg:
670− if (ap->gp_offset + size <= 48) {
671− ap->gp_offset += size;
672− return ap->reg_save_area + ap->gp_offset - size;
673− }
674− goto use_overflow_area;
675−
676− case __va_float_reg:
677− if (ap->fp_offset < 128 + 48) {
678− ap->fp_offset += 16;
679− return ap->reg_save_area + ap->fp_offset - 16;
680− }
681− size = 8;
682− goto use_overflow_area;
683−
684− case __va_stack:
685− use_overflow_area:
686− ap->overflow_arg_area += size;
687− ap->overflow_arg_area = (char*)((long long)(ap->overflow_arg_area + align - 1) & -align);
688− return ap->overflow_arg_area - size;
689−
690− default: /* should never happen */
691− abort();
692− }
693−}
694−#endif /* __x86_64__ */
695−
696−#if defined TCC_TARGET_ARM && !defined __TINYC__
697−#define _GNU_SOURCE
698−#include <unistd.h>
699−#include <sys/syscall.h>
700−#include <stdio.h>
701−
702−/* Flushing for tccrun */
703−void __clear_cache(void *beginning, void *end)
704−{
705−/* __ARM_NR_cacheflush is kernel private and should not be used in user space.
706− * However, there is no ARM asm parser in tcc so we use it for now */
707−#if 1
708− syscall(__ARM_NR_cacheflush, beginning, end, 0);
709−#else
710− __asm__ ("push {r7}\n\t"
711− "mov r7, #0xf0002\n\t"
712− "mov r2, #0\n\t"
713− "swi 0\n\t"
714− "pop {r7}\n\t"
715− "ret");
716−#endif
717−}
718−#endif /* arm */
622+#endif /* !ARM */
lib/va_list.c+65−0
@@ -0,0 +1,65 @@
1+/* va_list.c - tinycc support for va_list on X86_64 */
2+
3+#if defined TCC_TARGET_X86_64
4+
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);
8+
9+/* This should be in sync with our include/stdarg.h */
10+enum __va_arg_type {
11+ __va_gen_reg, __va_float_reg, __va_stack
12+};
13+
14+/* GCC compatible definition of va_list. */
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+} __va_list_struct;
24+
25+void __va_start(__va_list_struct *ap, void *fp)
26+{
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;
31+}
32+
33+void *__va_arg(__va_list_struct *ap,
34+ enum __va_arg_type arg_type,
35+ int size, int align)
36+{
37+ size = (size + 7) & ~7;
38+ align = (align + 7) & ~7;
39+ switch (arg_type) {
40+ case __va_gen_reg:
41+ if (ap->gp_offset + size <= 48) {
42+ ap->gp_offset += size;
43+ return ap->reg_save_area + ap->gp_offset - size;
44+ }
45+ goto use_overflow_area;
46+
47+ case __va_float_reg:
48+ if (ap->fp_offset < 128 + 48) {
49+ ap->fp_offset += 16;
50+ return ap->reg_save_area + ap->fp_offset - 16;
51+ }
52+ size = 8;
53+ goto use_overflow_area;
54+
55+ case __va_stack:
56+ 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;
60+
61+ default: /* should never happen */
62+ abort();
63+ }
64+}
65+#endif
tccgen.c+11−4
@@ -4578,9 +4578,12 @@ ST_FUNC void unary(void) · 4577 unmodified lines
45784578 #ifdef TCC_TARGET_PE
45794579 case TOK_builtin_va_start:
45804580 parse_builtin_params(0, "ee");
4581− if ((vtop->r & VT_VALMASK) != VT_LOCAL)
4582− tcc_error("__builtin_va_start expects a local variable");
4583− vtop->r &= ~VT_LVAL;
4581+ r = vtop->r & VT_VALMASK;
4582+ if (r == VT_LLOCAL)
4583+ r = VT_LOCAL;
4584+ if (r != VT_LOCAL)
4585+ tcc_error("__builtin_va_start expects a local variable");
4586+ vtop->r = r;
45844587 vtop->type = char_pointer_type;
45854588 vtop->c.i += 8;
45864589 vstore();
@@ -6169,7 +6172,11 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 1582 unmodified lines
61696172 if (sizeof(long double) == LDOUBLE_SIZE)
61706173 *(long double *)ptr = vtop->c.ld;
61716174 else if (sizeof(double) == LDOUBLE_SIZE)
6172− *(double *)ptr = vtop->c.ld;
6175+ *(double *)ptr = (double)vtop->c.ld;
6176+#if (defined __i386__ || defined __x86_64__) && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
6177+ else if (sizeof (long double) >= 10)
6178+ memcpy(memset(ptr, 0, LDOUBLE_SIZE), &vtop->c.ld, 10);
6179+#endif
61736180 else
61746181 tcc_error("can't cross compile long double constants");
61756182 break;
tests/abitest.c+7−4
@@ -637,10 +637,13 @@ int main(int argc, char **argv) { · 636 unmodified lines
637637 RUN_TEST(ret_longdouble_test);
638638 RUN_TEST(ret_2float_test);
639639 RUN_TEST(ret_2double_test);
640− /* RUN_TEST(ret_8plus2double_test); currently broken on x86_64 */
641− /* RUN_TEST(ret_6plus2longlong_test); currently broken on x86_64 */
642− /* RUN_TEST(ret_mixed_test); currently broken on x86_64 */
643− /* RUN_TEST(ret_mixed2_test); currently broken on x86_64 */
640+#if !defined __x86_64__ || defined _WIN32
641+ /* currently broken on x86_64 linux */
642+ RUN_TEST(ret_8plus2double_test);
643+ RUN_TEST(ret_6plus2longlong_test);
644+ RUN_TEST(ret_mixed_test);
645+ RUN_TEST(ret_mixed2_test);
646+#endif
644647 RUN_TEST(ret_mixed3_test);
645648 RUN_TEST(reg_pack_test);
646649 RUN_TEST(reg_pack_longlong_test);
tests/tcctest.c+2−8
@@ -2044,13 +2044,6 @@ void bitfield_test(void) · 2043 unmodified lines
20442044 else
20452045 printf("st1.f2 != -1\n");
20462046
2047−#ifndef __i386__
2048− /* on i386 we don't correctly support long long bit-fields.
2049− The bitfields can straddle long long boundaries (at least with
2050− GCC bitfield layout) and code generation isn't prepared for this
2051− (would have to work with two words in that case). */
2052− /* bit sizes below must be bigger than 32 since GCC doesn't allow
2053− long-long bitfields whose size is not bigger than int */
20542047 struct sbf2 {
20552048 long long f1 : 45;
20562049 long long : 2;
@@ -2063,7 +2056,7 @@ void bitfield_test(void) · 6 unmodified lines
20632056 st2.f3 = a;
20642057 st2.f2++;
20652058 printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
2066−#endif
2059+
20672060 #if 0
20682061 Disabled for now until further clarification re GCC compatibility
20692062 struct sbf3 {
@@ -2076,6 +2069,7 @@ void bitfield_test(void) · 6 unmodified lines
20762069 } st3;
20772070 printf("sizeof(st3) = %d\n", sizeof(st3));
20782071 #endif
2072+
20792073 struct sbf4 {
20802074 int x : 31;
20812075 char y : 2;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t