diff --git a/Makefile b/Makefile index 0b377d0..39c9dc3 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ CFLAGS+=-m386 -malign-functions=0 CFLAGS+=-DCONFIG_TCC_PREFIX=\"$(prefix)\" DISAS=objdump -d INSTALL=install -VERSION=0.9.13 +VERSION=0.9.14 # run local version of tcc with local libraries and includes TCC=./tcc -B. -I. @@ -122,7 +122,7 @@ install: tcc libtcc1.o bcheck.o mkdir -p $(prefix)/lib/tcc mkdir -p $(prefix)/lib/tcc/include $(INSTALL) -m644 libtcc1.o bcheck.o $(prefix)/lib/tcc - $(INSTALL) -m644 stdarg.h stddef.h float.h stdbool.h \ + $(INSTALL) -m644 stdarg.h stddef.h stdbool.h float.h varargs.h \ tcclib.h $(prefix)/lib/tcc/include clean: @@ -176,6 +176,10 @@ instr: instr.o instr.o: instr.S gcc -O2 -Wall -g -c -o $@ $< +cache: tcc_g + cachegrind ./tcc_g -o /tmp/linpack -lm bench/linpack.c + vg_annotate tcc.c > /tmp/linpack.cache.log + # documentation tcc-doc.html: tcc-doc.texi texi2html -monolithic -number $< @@ -188,10 +192,10 @@ FILES= Makefile Makefile.uClibc \ bcheck.c libtcc1.c \ il-opcodes.h il-gen.c \ elf.h stab.h stab.def \ - stddef.h stdarg.h stdbool.h float.h \ + stddef.h stdarg.h stdbool.h float.h varargs.h \ tcclib.h libtcc.h libtcc_test.c \ ex1.c ex2.c ex3.c ex4.c ex5.c \ - tcctest.c boundtest.c + tcctest.c boundtest.c gcctestsuite.sh FILE=tcc-$(VERSION) diff --git a/TODO b/TODO index 6e607f9..94b42d9 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,22 @@ TODO list: -- add 'CType' structure to optimize type handling (= compile even faster) -- suppress unneeded hash table for Symbols (= compile even faster) +- finish varargs.h support - add alloca() +- fix static functions declared inside block +- fix bitfield binary operations +- C99: add variable size arrays +- C99: add complex types +- GCC: add statment expressions +- ignore __extension__ keyword (see 20010328-1.c). +- Add __restrict keyword (20010611-1.c). +- postfix compound literals (see 20010124-1.c) +- handle '? x, y : z' in reversed function arguments or unsized + variable initialization (',' is considered incorrectly as separator + in preparser) : use a "record" parse mode ? +- fix multiple unions init +- test includes in libtcc_test. +- look at GCC 3.2 compatibility problems. +- add option for auto run - implement minimal 'asm' extension - setjmp is not supported properly in bound checking. - better local variables handling (needed for other targets) @@ -15,10 +29,14 @@ TODO list: - make libtcc fully reentrant (except for the compilation stage itself). - '-MD' option +Optimizations: + +- suppress specific anonymous symbol handling +- more parse optimizations (=even faster compilation) +- memory alloc optimizations (=even faster compilation) + Not critical: -- C99: add variable size arrays -- C99: add complex types - C99: fix multiple compound literals inits in blocks (ISOC99 normative example - only relevant when using gotos! -> must add boolean variable to tell if compound literal was already @@ -35,6 +53,7 @@ Not critical: al. check GetModuleHandle for dlls. check exception code (exception filter func). - handle void (__attribute__() *ptr)() -- handle '? x, y : z' in reversed function arguments or unsized - variable initialization (',' is considered incorrectly as separator - in preparser). + + + + diff --git a/tcctest.c b/tcctest.c index 64258ad..a893f60 100644 --- a/tcctest.c +++ b/tcctest.c @@ -74,7 +74,8 @@ int isid(int c); #define pf printf #define M1(a, b) (a) + (b) -#define str(s) # s +#define str\ +(s) # s #define glue(a, b) a ## b #define xglue(a, b) glue(a, b) #define HIGHLOW "hello" @@ -195,8 +196,8 @@ void macro_test(void) #line 203 "test" printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__); -#line 198 "tcctest.c" - +#line 200 "tcctest.c" + /* not strictly preprocessor, but we test it there */ #ifdef C99_MACROS printf("__func__ = %s\n", __func__); @@ -219,6 +220,9 @@ void macro_test(void) glue(a <, <= 2); printf("a=%d\n", a); } + + /* comment with stray handling *\ +/ } int op(a,b) @@ -255,10 +259,12 @@ void string_test() printf("\x41\x42\x43\x3a\n"); printf("c=%c\n", 'r'); printf("wc=%C 0x%lx %C\n", L'a', L'\x1234', L'c'); +#if 0 printf("wstring=%S\n", L"abc"); printf("wstring=%S\n", L"abc" L"def" "ghi"); printf("'\\377'=%d '\\xff'=%d\n", '\377', '\xff'); printf("L'\\377'=%d L'\\xff'=%d\n", L'\377', L'\xff'); +#endif ps("test\n"); b = 32; while ((b = b + 1) < 96) { @@ -660,6 +666,26 @@ void expr_cmp_test() printf("%d\n", (unsigned)b > a); } +struct empty { +}; + +struct aligntest1 { + char a[10]; +}; + +struct aligntest2 { + int a; + char b[10]; +}; + +struct aligntest3 { + double a, b; +}; + +struct aligntest4 { + double a[0]; +}; + void struct_test() { struct1 *s; @@ -689,6 +715,20 @@ void struct_test() printf("st2: %d %d %d\n", s->f1, s->f2, s->f3); printf("str_addr=%x\n", (int)st1.str - (int)&st1.f1); + + /* align / size tests */ + printf("aligntest1 sizeof=%d alignof=%d\n", + sizeof(struct aligntest1), __alignof__(struct aligntest1)); + printf("aligntest2 sizeof=%d alignof=%d\n", + sizeof(struct aligntest2), __alignof__(struct aligntest2)); + printf("aligntest3 sizeof=%d alignof=%d\n", + sizeof(struct aligntest3), __alignof__(struct aligntest3)); + printf("aligntest4 sizeof=%d alignof=%d\n", + sizeof(struct aligntest4), __alignof__(struct aligntest4)); + + /* empty structures (GCC extension) */ + printf("sizeof(struct empty) = %d\n", sizeof(struct empty)); + printf("alignof(struct empty) = %d\n", __alignof__(struct empty)); } /* XXX: depend on endianness */ @@ -730,9 +770,17 @@ typedef struct Sym { struct Sym *prev; } Sym; +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) + +static int toupper1(int a) +{ + return TOUPPER(a); +} + void bool_test() { - int *s, a, b, t, f; + int *s, a, b, t, f, i; a = 0; s = (void*)0; @@ -786,6 +834,12 @@ void bool_test() printf("aspect=%d\n", aspect); } } + + /* again complex expression */ + for(i=0;i<256;i++) { + if (toupper1 (i) != TOUPPER (i)) + printf("error %d\n", i); + } } @@ -1004,6 +1058,16 @@ char *sinit13[] = { char sinit14[10] = { "abc" }; int sinit15[3] = { sizeof(sinit15), 1, 2 }; +struct { int a[3], b; } sinit16[] = { { 1 }, 2 }; + +struct bar { + char *s; + int len; +} sinit17[] = { + "a1", 4, + "a2", 1 +}; + void init_test(void) { int linit1 = 2; @@ -1089,6 +1153,10 @@ void init_test(void) /* test that initialisation is done after variable declare */ printf("linit17=%d\n", linit17); printf("sinit15=%d\n", sinit15[0]); + printf("sinit16=%d %d\n", sinit16[0].a[0], sinit16[1].a[0]); + printf("sinit17=%s %d %s %d\n", + sinit17[0].s, sinit17[0].len, + sinit17[1].s, sinit17[1].len); } void switch_test() @@ -1290,13 +1358,17 @@ void lloptest(long long a, long long b) ua = a; ub = b; /* arith */ - printf("arith: %Ld %Ld %Ld %Ld %Ld\n", + printf("arith: %Ld %Ld %Ld\n", a + b, a - b, - a * b, + a * b); + + if (b != 0) { + printf("arith1: %Ld %Ld\n", a / b, a % b); - + } + /* binary */ printf("bin: %Ld %Ld %Ld\n", a & b, @@ -1438,6 +1510,7 @@ void longlong_test(void) a.item = 3; printf("%lld\n", value(&a)); } + lloptest(0x80000000, 0); } void vprintf1(const char *fmt, ...) diff --git a/tcctok.h b/tcctok.h index 6dc6cf4..fd61744 100644 --- a/tcctok.h +++ b/tcctok.h @@ -55,7 +55,9 @@ DEF(TOK_DEFINED, "defined") DEF(TOK_UNDEF, "undef") DEF(TOK_ERROR, "error") + DEF(TOK_WARNING, "warning") DEF(TOK_LINE, "line") + DEF(TOK_PRAGMA, "pragma") DEF(TOK___LINE__, "__LINE__") DEF(TOK___FILE__, "__FILE__") DEF(TOK___DATE__, "__DATE__")