diff options
Diffstat (limited to '05/tcc-0.9.27/tests')
237 files changed, 14021 insertions, 0 deletions
diff --git a/05/tcc-0.9.27/tests/42test.h b/05/tcc-0.9.27/tests/42test.h new file mode 100644 index 0000000..5db7d1c --- /dev/null +++ b/05/tcc-0.9.27/tests/42test.h @@ -0,0 +1,13 @@ +/* This file is to test compute #include directives. It's named so + that it starts with a pre-processing number which isn't a valid + number (42test.h). Including this must work. */ +#ifndef INC42_FIRST +int have_included_42test_h; +#define INC42_FIRST +#elif !defined INC42_SECOND +#define INC42_SECOND +int have_included_42test_h_second; +#else +#define INC42_THIRD +int have_included_42test_h_third; +#endif diff --git a/05/tcc-0.9.27/tests/Makefile b/05/tcc-0.9.27/tests/Makefile new file mode 100644 index 0000000..5f6777d --- /dev/null +++ b/05/tcc-0.9.27/tests/Makefile @@ -0,0 +1,289 @@ +# +# Tiny C Compiler Makefile - tests +# + +TOP = .. +include $(TOP)/Makefile +VPATH = $(TOPSRC)/tests $(TOPSRC) $(TOP) +CFLAGS := $(filter-out -W% -g% -O%,$(CFLAGS)) -I$(TOPSRC) $(LDFLAGS) + +# what tests to run +TESTS = \ + hello-exe \ + hello-run \ + libtest \ + test3 \ + memtest \ + dlltest \ + abitest \ + asm-c-connect-test \ + vla_test-run \ + cross-test \ + tests2-dir \ + pp-dir + +BTESTS = test1b test3b btest + +# test4 -- problem with -static +# asmtest / asmtest2 -- minor differences with gcc +# btest -- works on i386 (including win32) + +# bounds-checking is supported only on i386 +ifneq ($(ARCH),i386) + TESTS := $(filter-out $(BTESTS),$(TESTS)) +endif +ifdef CONFIG_WIN32 + TESTS := $(filter-out $(BTESTS),$(TESTS)) +endif +ifdef CONFIG_OSX # -run only + TESTS := hello-run libtest tests2-dir pp-dir +endif +ifeq (,$(filter arm64 i386 x86_64,$(ARCH))) + TESTS := $(filter-out vla_test-run,$(TESTS)) +endif +ifeq ($(CONFIG_arm_eabi),yes) + TESTS := $(filter-out test3,$(TESTS)) +endif +ifeq (,$(filter i386 x86_64,$(ARCH))) + TESTS := $(filter-out dlltest asm-c-connect-test,$(TESTS)) +endif +ifndef CONFIG_cross + TESTS := $(filter-out cross-%,$(TESTS)) +endif + +ifeq ($(OS),Windows_NT) # for libtcc_test to find libtcc.dll + PATH := $(CURDIR)/$(TOP)$(if $(findstring :\,$(PATH)),;,:)$(PATH) +endif + +RUN_TCC = $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS) +DISAS = objdump -d +DUMPTCC = (set -x; $(TOP)/tcc -vv; ldd $(TOP)/tcc; exit 1) + +all test : clean-s $(TESTS) + +hello-exe: ../examples/ex1.c + @echo ------------ $@ ------------ + $(TCC) $< -o hello$(EXESUF) && ./hello$(EXESUF) || $(DUMPTCC) + +hello-run: ../examples/ex1.c + @echo ------------ $@ ------------ + $(TCC) -run $< || $(DUMPTCC) + +libtest: libtcc_test$(EXESUF) + @echo ------------ $@ ------------ + ./libtcc_test$(EXESUF) $(TCCFLAGS) + +libtcc_test$(EXESUF): libtcc_test.c $(LIBTCC) + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +%-dir: + @echo ------------ $@ ------------ + $(MAKE) -k -C $* + +# test.ref - generate using cc +test.ref: tcctest.c + $(CC) -o tcctest.gcc $< $(NATIVE_DEFINES) $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer + ./tcctest.gcc > $@ + +# auto test +test1 test1b: tcctest.c test.ref + @echo ------------ $@ ------------ + $(TCC) -run $< > test.out1 + @diff -u test.ref test.out1 && echo "Auto Test OK" + +# iterated test2 (compile tcc then compile tcctest.c !) +test2 test2b: tcctest.c test.ref + @echo ------------ $@ ------------ + $(TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out2 + @diff -u test.ref test.out2 && echo "Auto Test2 OK" + +# iterated test3 (compile tcc then compile tcc then compile tcctest.c !) +test3 test3b: tcctest.c test.ref + @echo ------------ $@ ------------ + $(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out3 + @diff -u test.ref test.out3 && echo "Auto Test3 OK" + +test%b : TCCFLAGS += -b + +# binary output test +test4: tcctest.c test.ref + @echo ------------ $@ ------------ +# object + link output + $(TCC) -c -o tcctest3.o $< + $(TCC) -o tcctest3 tcctest3.o + ./tcctest3 > test3.out + @if diff -u test.ref test3.out ; then echo "Object Auto Test OK"; fi +# dynamic output + $(TCC) -o tcctest1 $< + ./tcctest1 > test1.out + @if diff -u test.ref test1.out ; then echo "Dynamic Auto Test OK"; fi +# dynamic output + bound check + $(TCC) -b -o tcctest4 $< + ./tcctest4 > test4.out + @if diff -u test.ref test4.out ; then echo "BCheck Auto Test OK"; fi +# static output + $(TCC) -static -o tcctest2 $< + ./tcctest2 > test2.out + @if diff -u test.ref test2.out ; then echo "Static Auto Test OK"; fi + +# use tcc to create libtcc.so/.dll and the tcc(.exe) frontend and run them +dlltest: + @echo ------------ $@ ------------ + $(TCC) $(NATIVE_DEFINES) -DLIBTCC_AS_DLL $(TOPSRC)/libtcc.c $(LIBS) -shared -o libtcc2$(DLLSUF) + $(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF) + ./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c +ifndef CONFIG_WIN32 + @echo ------------ $@ with PIC ------------ + $(CC) $(CFLAGS) -fPIC $(NATIVE_DEFINES) -DLIBTCC_AS_DLL -c $(TOPSRC)/libtcc.c + $(TCC) libtcc.o $(LIBS) -shared -o libtcc2$(DLLSUF) + $(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF) + ./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c +endif + @rm tcc2$(EXESUF) libtcc2$(DLLSUF) + +memtest: + @echo ------------ $@ ------------ + $(CC) $(CFLAGS) $(NATIVE_DEFINES) -DMEM_DEBUG=2 $(TOPSRC)/tcc.c $(LIBS) -o memtest-tcc$(EXESUF) + ./memtest-tcc$(EXESUF) $(TCCFLAGS) $(NATIVE_DEFINES) $(TOPSRC)/tcc.c $(LIBS) + ./memtest-tcc$(EXESUF) $(TCCFLAGS) $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS) $(TOPSRC)/tests/tcctest.c + + +# memory and bound check auto test +BOUNDS_OK = 1 4 8 10 14 +BOUNDS_FAIL= 2 5 7 9 11 12 13 15 + +btest: boundtest.c + @echo ------------ $@ ------------ + @for i in $(BOUNDS_OK); do \ + echo ; echo --- boundtest $$i ---; \ + if $(TCC) -b -run $< $$i ; then \ + echo succeeded as expected; \ + else\ + echo Failed positive test $$i ; exit 1 ; \ + fi ;\ + done ;\ + for i in $(BOUNDS_FAIL); do \ + echo ; echo --- boundtest $$i ---; \ + if $(TCC) -b -run $< $$i ; then \ + echo Failed negative test $$i ; exit 1 ;\ + else\ + echo failed as expected; \ + fi ;\ + done ;\ + echo; echo Bound test OK + +# speed test +speedtest: ex2 ex3 + @echo ------------ $@ ------------ + time ./ex2 1238 2 3 4 10 13 4 + time $(TCC) -run $(TOPSRC)/examples/ex2.c 1238 2 3 4 10 13 4 + time ./ex3 35 + time $(TCC) -run $(TOPSRC)/examples/ex3.c 35 + +weaktest: tcctest.c test.ref + $(TCC) -c $< -o weaktest.tcc.o + $(CC) -c $< -o weaktest.gcc.o $(NATIVE_DEFINES) $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer + objdump -t weaktest.tcc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.tcc.o.txt + objdump -t weaktest.gcc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.gcc.o.txt + diff weaktest.gcc.o.txt weaktest.tcc.o.txt && echo "Weak Auto Test OK" + +ex%: $(TOPSRC)/examples/ex%.c + $(CC) -o $@ $< $(CFLAGS) + +# tiny assembler testing +asmtest.ref: asmtest.S + $(CC) -Wa,-W -o asmtest.ref.o -c asmtest.S + objdump -D asmtest.ref.o > asmtest.ref + +asmtest asmtest2: asmtest.ref + @echo ------------ $@ ------------ + $(TCC) $(MAYBE_RUN_TCC) -c asmtest.S + objdump -D asmtest.o > asmtest.out + @if diff -u --ignore-matching-lines="file format" asmtest.ref asmtest.out ; then echo "ASM Auto Test OK"; fi + +# test assembler with tcc compiled by itself +asmtest2: MAYBE_RUN_TCC = $(RUN_TCC) + +# Check that code generated by libtcc is binary compatible with +# that generated by CC +abitest-cc$(EXESUF): abitest.c $(LIBTCC) + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -w + +abitest-tcc$(EXESUF): abitest.c libtcc.c + $(TCC) -o $@ $^ $(NATIVE_DEFINES) $(LIBS) + +ABITESTS := abitest-cc$(EXESUF) +ifneq ($(CONFIG_arm_eabi),yes) # not ARM soft-float + ABITESTS += abitest-tcc$(EXESUF) +endif + +abitest: $(ABITESTS) + @echo ------------ $@ ------------ + ./abitest-cc$(EXESUF) $(TCCFLAGS) +ifneq ($(CONFIG_arm_eabi),yes) # not ARM soft-float + ./abitest-tcc$(EXESUF) $(TCCFLAGS) +endif + +vla_test$(EXESUF): vla_test.c + $(TCC) -o $@ $^ + +vla_test-run: vla_test$(EXESUF) + @echo ------------ $@ ------------ + ./vla_test$(EXESUF) + +asm-c-connect$(EXESUF): asm-c-connect-1.c asm-c-connect-2.c + $(TCC) -o $@ $^ + +asm-c-connect-%.o: asm-c-connect-%.c + $(TCC) -c -o $@ $< + +asm-c-connect-sep$(EXESUF): asm-c-connect-1.o asm-c-connect-2.o + $(TCC) -o $@ $^ + +asm-c-connect-test: asm-c-connect$(EXESUF) asm-c-connect-sep$(EXESUF) + @echo ------------ $@ ------------ + ./asm-c-connect$(EXESUF) > asm-c-connect.out1 && cat asm-c-connect.out1 + ./asm-c-connect-sep$(EXESUF) > asm-c-connect.out2 && cat asm-c-connect.out2 + @diff -u asm-c-connect.out1 asm-c-connect.out2 && echo "ok" + +cross-test : + @echo ------------ $@ ------------ + $(TOP)/i386-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/x86_64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/arm-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/arm64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/c67-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok" + $(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok" + $(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/win32/examples/hello_win.c && echo "ok" + +# targets for development +%.bin: %.c tcc + $(TCC) -g -o $@ $< + $(DISAS) $@ + +instr: instr.o + objdump -d instr.o + +instr.o: instr.S + $(CC) -o $@ -c $< -O2 -Wall -g + +cache: tcc_g + cachegrind ./tcc_g -o /tmp/linpack -lm bench/linpack.c + vg_annotate tcc.c > /tmp/linpack.cache.log + +# clean +clean: + rm -f *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.cc *.gcc + rm -f *-cc *-gcc *-tcc *.exe hello libtcc_test vla_test tcctest[1234] + rm -f asm-c-connect$(EXESUF) + rm -f ex? tcc_g weaktest.*.txt *.def + @$(MAKE) -C tests2 $@ + @$(MAKE) -C pp $@ + +# silent clean, used before running tests +clean-s: + @$(MAKE) -s --no-print-directory clean diff --git a/05/tcc-0.9.27/tests/abitest.c b/05/tcc-0.9.27/tests/abitest.c new file mode 100644 index 0000000..4a192bd --- /dev/null +++ b/05/tcc-0.9.27/tests/abitest.c @@ -0,0 +1,691 @@ +#include <libtcc.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +// MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC +#if defined(_WIN32) && defined(__GNUC__) +#define LONG_DOUBLE double +#define LONG_DOUBLE_LITERAL(x) x +#else +#define LONG_DOUBLE long double +#define LONG_DOUBLE_LITERAL(x) x ## L +#endif + +static int g_argc; +static char **g_argv; + +static void set_options(TCCState *s, int argc, char **argv) +{ + int i; + for (i = 1; i < argc; ++i) { + char *a = argv[i]; + if (a[0] == '-') { + if (a[1] == 'B') + tcc_set_lib_path(s, a+2); + else if (a[1] == 'I') + tcc_add_include_path(s, a+2); + else if (a[1] == 'L') + tcc_add_library_path(s, a+2); + } + } +} + +typedef int (*callback_type) (void*); + +/* + * Compile source code and call a callback with a pointer to the symbol "f". + */ +static int run_callback(const char *src, callback_type callback) { + TCCState *s; + int result; + void *ptr; + + s = tcc_new(); + if (!s) + return -1; + + set_options(s, g_argc, g_argv); + + if (tcc_set_output_type(s, TCC_OUTPUT_MEMORY) == -1) + return -1; + if (tcc_compile_string(s, src) == -1) + return -1; + if (tcc_relocate(s, TCC_RELOCATE_AUTO) == -1) + return -1; + + ptr = tcc_get_symbol(s, "f"); + if (!ptr) + return -1; + result = callback(ptr); + + tcc_delete(s); + + return result; +} + +#define STR2(x) #x +#define STR(x) STR2(x) + +#define RET_PRIMITIVE_TEST(name, type, val) \ + static int ret_ ## name ## _test_callback(void *ptr) { \ + type (*callback) (type) = (type(*)(type))ptr; \ + type x = val; \ + type y = callback(x); \ + return (y == x+x) ? 0 : -1; \ + } \ + \ + static int ret_ ## name ## _test(void) { \ + const char *src = STR(type) " f(" STR(type) " x) {return x+x;}"; \ + return run_callback(src, ret_ ## name ## _test_callback); \ + } + +RET_PRIMITIVE_TEST(int, int, 70000) +RET_PRIMITIVE_TEST(longlong, long long, 4333369356528LL) +RET_PRIMITIVE_TEST(float, float, 63.0) +RET_PRIMITIVE_TEST(double, double, 14789798.0) +RET_PRIMITIVE_TEST(longdouble, LONG_DOUBLE, LONG_DOUBLE_LITERAL(378943892.0)) + +/* + * ret_2float_test: + * + * On x86-64, a struct with 2 floats should be packed into a single + * SSE register (VT_DOUBLE is used for this purpose). + */ +typedef struct ret_2float_test_type_s {float x, y;} ret_2float_test_type; +typedef ret_2float_test_type (*ret_2float_test_function_type) (ret_2float_test_type); + +static int ret_2float_test_callback(void *ptr) { + ret_2float_test_function_type f = (ret_2float_test_function_type)ptr; + ret_2float_test_type a = {10, 35}; + ret_2float_test_type r; + r = f(a); + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; +} + +static int ret_2float_test(void) { + const char *src = + "typedef struct ret_2float_test_type_s {float x, y;} ret_2float_test_type;" + "ret_2float_test_type f(ret_2float_test_type a) {\n" + " ret_2float_test_type r = {a.x*5, a.y*3};\n" + " return r;\n" + "}\n"; + + return run_callback(src, ret_2float_test_callback); +} + +/* + * ret_2double_test: + * + * On x86-64, a struct with 2 doubles should be passed in two SSE + * registers. + */ +typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type; +typedef ret_2double_test_type (*ret_2double_test_function_type) (ret_2double_test_type); + +static int ret_2double_test_callback(void *ptr) { + ret_2double_test_function_type f = (ret_2double_test_function_type)ptr; + ret_2double_test_type a = {10, 35}; + ret_2double_test_type r; + r = f(a); + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; +} + +static int ret_2double_test(void) { + const char *src = + "typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;" + "ret_2double_test_type f(ret_2double_test_type a) {\n" + " ret_2double_test_type r = {a.x*5, a.y*3};\n" + " return r;\n" + "}\n"; + + return run_callback(src, ret_2double_test_callback); +} + +/* + * ret_8plus2double_test: + * + * This catches a corner case in the x86_64 ABI code: the first 7 + * arguments fit into registers, the 8th doesn't, but the 9th argument + * fits into the 8th XMM register. + * + * Note that the purpose of the 10th argument is to avoid a situation + * in which gcc would accidentally put the double at the right + * address, thus causing a success message even though TCC actually + * generated incorrect code. + */ +typedef ret_2double_test_type (*ret_8plus2double_test_function_type) (double, double, double, double, double, double, double, ret_2double_test_type, double, double); + +static int ret_8plus2double_test_callback(void *ptr) { + ret_8plus2double_test_function_type f = (ret_8plus2double_test_function_type)ptr; + ret_2double_test_type a = {10, 35}; + ret_2double_test_type r; + r = f(0, 0, 0, 0, 0, 0, 0, a, 37, 38); + return ((r.x == 37) && (r.y == 37)) ? 0 : -1; +} + +static int ret_8plus2double_test(void) { + const char *src = + "typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;" + "ret_2double_test_type f(double x1, double x2, double x3, double x4, double x5, double x6, double x7, ret_2double_test_type a, double x8, double x9) {\n" + " ret_2double_test_type r = { x8, x8 };\n" + " return r;\n" + "}\n"; + + return run_callback(src, ret_8plus2double_test_callback); +} + +/* + * ret_mixed_test: + * + * On x86-64, a struct with a double and a 64-bit integer should be + * passed in one SSE register and one integer register. + */ +typedef struct ret_mixed_test_type_s {double x; long long y;} ret_mixed_test_type; +typedef ret_mixed_test_type (*ret_mixed_test_function_type) (ret_mixed_test_type); + +static int ret_mixed_test_callback(void *ptr) { + ret_mixed_test_function_type f = (ret_mixed_test_function_type)ptr; + ret_mixed_test_type a = {10, 35}; + ret_mixed_test_type r; + r = f(a); + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; +} + +static int ret_mixed_test(void) { + const char *src = + "typedef struct ret_mixed_test_type_s {double x; long long y;} ret_mixed_test_type;" + "ret_mixed_test_type f(ret_mixed_test_type a) {\n" + " ret_mixed_test_type r = {a.x*5, a.y*3};\n" + " return r;\n" + "}\n"; + + return run_callback(src, ret_mixed_test_callback); +} + +/* + * ret_mixed2_test: + * + * On x86-64, a struct with two floats and two 32-bit integers should + * be passed in one SSE register and one integer register. + */ +typedef struct ret_mixed2_test_type_s {float x,x2; int y,y2;} ret_mixed2_test_type; +typedef ret_mixed2_test_type (*ret_mixed2_test_function_type) (ret_mixed2_test_type); + +static int ret_mixed2_test_callback(void *ptr) { + ret_mixed2_test_function_type f = (ret_mixed2_test_function_type)ptr; + ret_mixed2_test_type a = {10, 5, 35, 7 }; + ret_mixed2_test_type r; + r = f(a); + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; +} + +static int ret_mixed2_test(void) { + const char *src = + "typedef struct ret_mixed2_test_type_s {float x, x2; int y,y2;} ret_mixed2_test_type;" + "ret_mixed2_test_type f(ret_mixed2_test_type a) {\n" + " ret_mixed2_test_type r = {a.x*5, 0, a.y*3, 0};\n" + " return r;\n" + "}\n"; + + return run_callback(src, ret_mixed2_test_callback); +} + +/* + * ret_mixed3_test: + * + * On x86-64, this struct should be passed in two integer registers. + */ +typedef struct ret_mixed3_test_type_s {float x; int y; float x2; int y2;} ret_mixed3_test_type; +typedef ret_mixed3_test_type (*ret_mixed3_test_function_type) (ret_mixed3_test_type); + +static int ret_mixed3_test_callback(void *ptr) { + ret_mixed3_test_function_type f = (ret_mixed3_test_function_type)ptr; + ret_mixed3_test_type a = {10, 5, 35, 7 }; + ret_mixed3_test_type r; + r = f(a); + return ((r.x == a.x*5) && (r.y2 == a.y*3)) ? 0 : -1; +} + +static int ret_mixed3_test(void) { + const char *src = + "typedef struct ret_mixed3_test_type_s {float x; int y; float x2; int y2;} ret_mixed3_test_type;" + "ret_mixed3_test_type f(ret_mixed3_test_type a) {\n" + " ret_mixed3_test_type r = {a.x*5, 0, 0, a.y*3};\n" + " return r;\n" + "}\n"; + + return run_callback(src, ret_mixed3_test_callback); +} + +/* + * reg_pack_test: return a small struct which should be packed into + * registers (Win32) during return. + */ +typedef struct reg_pack_test_type_s {int x, y;} reg_pack_test_type; +typedef reg_pack_test_type (*reg_pack_test_function_type) (reg_pack_test_type); + +static int reg_pack_test_callback(void *ptr) { + reg_pack_test_function_type f = (reg_pack_test_function_type)ptr; + reg_pack_test_type a = {10, 35}; + reg_pack_test_type r; + r = f(a); + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; +} + +static int reg_pack_test(void) { + const char *src = + "typedef struct reg_pack_test_type_s {int x, y;} reg_pack_test_type;" + "reg_pack_test_type f(reg_pack_test_type a) {\n" + " reg_pack_test_type r = {a.x*5, a.y*3};\n" + " return r;\n" + "}\n"; + + return run_callback(src, reg_pack_test_callback); +} + +/* + * reg_pack_longlong_test: return a small struct which should be packed into + * registers (x86-64) during return. + */ +typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type; +typedef reg_pack_longlong_test_type (*reg_pack_longlong_test_function_type) (reg_pack_longlong_test_type); + +static int reg_pack_longlong_test_callback(void *ptr) { + reg_pack_longlong_test_function_type f = (reg_pack_longlong_test_function_type)ptr; + reg_pack_longlong_test_type a = {10, 35}; + reg_pack_longlong_test_type r; + r = f(a); + return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1; +} + +static int reg_pack_longlong_test(void) { + const char *src = + "typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;" + "reg_pack_longlong_test_type f(reg_pack_longlong_test_type a) {\n" + " reg_pack_longlong_test_type r = {a.x*5, a.y*3};\n" + " return r;\n" + "}\n"; + + return run_callback(src, reg_pack_longlong_test_callback); +} + +/* + * ret_6plus2longlong_test: + * + * This catches a corner case in the x86_64 ABI code: the first 5 + * arguments fit into registers, the 6th doesn't, but the 7th argument + * fits into the 6th argument integer register, %r9. + * + * Note that the purpose of the 10th argument is to avoid a situation + * in which gcc would accidentally put the longlong at the right + * address, thus causing a success message even though TCC actually + * generated incorrect code. + */ +typedef reg_pack_longlong_test_type (*ret_6plus2longlong_test_function_type) (long long, long long, long long, long long, long long, reg_pack_longlong_test_type, long long, long long); + +static int ret_6plus2longlong_test_callback(void *ptr) { + ret_6plus2longlong_test_function_type f = (ret_6plus2longlong_test_function_type)ptr; + reg_pack_longlong_test_type a = {10, 35}; + reg_pack_longlong_test_type r; + r = f(0, 0, 0, 0, 0, a, 37, 38); + return ((r.x == 37) && (r.y == 37)) ? 0 : -1; +} + +static int ret_6plus2longlong_test(void) { + const char *src = + "typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;" + "reg_pack_longlong_test_type f(long long x1, long long x2, long long x3, long long x4, long long x5, reg_pack_longlong_test_type a, long long x8, long long x9) {\n" + " reg_pack_longlong_test_type r = { x8, x8 };\n" + " return r;\n" + "}\n"; + + return run_callback(src, ret_6plus2longlong_test_callback); +} + +/* + * sret_test: Create a struct large enough to be returned via sret + * (hidden pointer as first function argument) + */ +typedef struct sret_test_type_s {long long a, b, c;} sret_test_type; +typedef sret_test_type (*sret_test_function_type) (sret_test_type); + +static int sret_test_callback(void *ptr) { + sret_test_function_type f = (sret_test_function_type)(ptr); + sret_test_type x = {5436LL, 658277698LL, 43878957LL}; + sret_test_type r = f(x); + return ((r.a==x.a*35)&&(r.b==x.b*19)&&(r.c==x.c*21)) ? 0 : -1; +} + +static int sret_test(void) { + const char *src = + "typedef struct sret_test_type_s {long long a, b, c;} sret_test_type;\n" + "sret_test_type f(sret_test_type x) {\n" + " sret_test_type r = {x.a*35, x.b*19, x.c*21};\n" + " return r;\n" + "}\n"; + + return run_callback(src, sret_test_callback); +} + +/* + * one_member_union_test: + * + * In the x86-64 ABI a union should always be passed on the stack. However + * it appears that a single member union is treated by GCC as its member. + */ +typedef union one_member_union_test_type_u {int x;} one_member_union_test_type; +typedef one_member_union_test_type (*one_member_union_test_function_type) (one_member_union_test_type); + +static int one_member_union_test_callback(void *ptr) { + one_member_union_test_function_type f = (one_member_union_test_function_type)ptr; + one_member_union_test_type a, b; + a.x = 34; + b = f(a); + return (b.x == a.x*2) ? 0 : -1; +} + +static int one_member_union_test(void) { + const char *src = + "typedef union one_member_union_test_type_u {int x;} one_member_union_test_type;\n" + "one_member_union_test_type f(one_member_union_test_type a) {\n" + " one_member_union_test_type b;\n" + " b.x = a.x * 2;\n" + " return b;\n" + "}\n"; + return run_callback(src, one_member_union_test_callback); +} + +/* + * two_member_union_test: + * + * In the x86-64 ABI a union should always be passed on the stack. + */ +typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type; +typedef two_member_union_test_type (*two_member_union_test_function_type) (two_member_union_test_type); + +static int two_member_union_test_callback(void *ptr) { + two_member_union_test_function_type f = (two_member_union_test_function_type)ptr; + two_member_union_test_type a, b; + a.x = 34; + b = f(a); + return (b.x == a.x*2) ? 0 : -1; +} + +static int two_member_union_test(void) { + const char *src = + "typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type;\n" + "two_member_union_test_type f(two_member_union_test_type a) {\n" + " two_member_union_test_type b;\n" + " b.x = a.x * 2;\n" + " return b;\n" + "}\n"; + return run_callback(src, two_member_union_test_callback); +} + +/* + * Win64 calling convention test. + */ + +typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type; +typedef many_struct_test_type (*many_struct_test_function_type) (many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type); + +static int many_struct_test_callback(void *ptr) { + many_struct_test_function_type f = (many_struct_test_function_type)ptr; + many_struct_test_type v = {1, 2, 3}; + many_struct_test_type r = f(v,v,v,v,v,v); + return ((r.a == 6) && (r.b == 12) && (r.c == 18))?0:-1; +} + +static int many_struct_test(void) { + const char *src = + "typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;\n" + "many_struct_test_type f(many_struct_test_type x1, many_struct_test_type x2, many_struct_test_type x3, many_struct_test_type x4, many_struct_test_type x5, many_struct_test_type x6) {\n" + " many_struct_test_type y;\n" + " y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n" + " y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n" + " y.c = x1.c + x2.c + x3.c + x4.c + x5.c + x6.c;\n" + " return y;\n" + "}\n"; + return run_callback(src, many_struct_test_callback); +} + +/* + * Win64 calling convention test. + */ + +typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type; +typedef many_struct_test_2_type (*many_struct_test_2_function_type) (many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type); + +static int many_struct_test_2_callback(void *ptr) { + many_struct_test_2_function_type f = (many_struct_test_2_function_type)ptr; + many_struct_test_2_type v = {1,2}; + many_struct_test_2_type r = f(v,v,v,v,v,v); + return ((r.a == 6) && (r.b == 12))?0:-1; +} + +static int many_struct_test_2(void) { + const char *src = + "typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;\n" + "many_struct_test_2_type f(many_struct_test_2_type x1, many_struct_test_2_type x2, many_struct_test_2_type x3, many_struct_test_2_type x4, many_struct_test_2_type x5, many_struct_test_2_type x6) {\n" + " many_struct_test_2_type y;\n" + " y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n" + " y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n" + " return y;\n" + "}\n"; + return run_callback(src, many_struct_test_2_callback); +} + +/* + * Win64 calling convention test. + */ + +typedef struct many_struct_test_3_type_s {int a, b;} many_struct_test_3_type; +typedef many_struct_test_3_type (*many_struct_test_3_function_type) (many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type, ...); +typedef struct many_struct_test_3_struct_type { many_struct_test_3_function_type f; many_struct_test_3_function_type *f2; } many_struct_test_3_struct_type; + +static void many_struct_test_3_dummy(double d, ...) +{ + volatile double x = d; +} + +static int many_struct_test_3_callback(void *ptr) { + many_struct_test_3_struct_type s = { ptr, }; + many_struct_test_3_struct_type *s2 = &s; + s2->f2 = &s2->f; + many_struct_test_3_dummy(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, &s2); + many_struct_test_3_function_type f = *(s2->f2); + many_struct_test_3_type v = {1,2}; + many_struct_test_3_type r = (*((s2->f2=&f)+0))(v,v,v,v,v,v,1.0); + return ((r.a == 6) && (r.b == 12))?0:-1; +} + +static int many_struct_test_3(void) { + const char *src = + "typedef struct many_struct_test_3_type_s {int a, b;} many_struct_test_3_type;\n" + "many_struct_test_3_type f(many_struct_test_3_type x1, many_struct_test_3_type x2, many_struct_test_3_type x3, many_struct_test_3_type x4, many_struct_test_3_type x5, many_struct_test_3_type x6, ...) {\n" + " many_struct_test_3_type y;\n" + " y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n" + " y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n" + " return y;\n" + "}\n"; + return run_callback(src, many_struct_test_3_callback); +} + +/* + * stdarg_test: Test variable argument list ABI + */ + +typedef struct {long long a, b, c;} stdarg_test_struct_type; +typedef void (*stdarg_test_function_type) (int,int,int,...); + +static int stdarg_test_callback(void *ptr) { + stdarg_test_function_type f = (stdarg_test_function_type)ptr; + int x; + double y; + stdarg_test_struct_type z = {1, 2, 3}, w; + f(10, 10, 5, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, &x, + 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, &y, + z, z, z, z, z, &w); + return ((x == 55) && (y == 55) && (w.a == 5) && (w.b == 10) && (w.c == 15)) ? 0 : -1; +} + +static int stdarg_test(void) { + const char *src = + "#include <stdarg.h>\n" + "typedef struct {long long a, b, c;} stdarg_test_struct_type;\n" + "void f(int n_int, int n_float, int n_struct, ...) {\n" + " int i, ti = 0;\n" + " double td = 0.0;\n" + " stdarg_test_struct_type ts = {0,0,0}, tmp;\n" + " va_list ap;\n" + " va_start(ap, n_struct);\n" + " for (i = 0, ti = 0; i < n_int; ++i)\n" + " ti += va_arg(ap, int);\n" + " *va_arg(ap, int*) = ti;\n" + " for (i = 0, td = 0; i < n_float; ++i)\n" + " td += va_arg(ap, double);\n" + " *va_arg(ap, double*) = td;\n" + " for (i = 0; i < n_struct; ++i) {\n" + " tmp = va_arg(ap, stdarg_test_struct_type);\n" + " ts.a += tmp.a; ts.b += tmp.b; ts.c += tmp.c;" + " }\n" + " *va_arg(ap, stdarg_test_struct_type*) = ts;\n" + " va_end(ap);" + "}\n"; + return run_callback(src, stdarg_test_callback); +} + +typedef struct {long long a, b;} stdarg_many_test_struct_type; +typedef void (*stdarg_many_test_function_type) (int, int, int, int, int, + stdarg_many_test_struct_type, + int, int, ...); + +static int stdarg_many_test_callback(void *ptr) +{ + stdarg_many_test_function_type f = (stdarg_many_test_function_type)ptr; + int x; + stdarg_many_test_struct_type l = {10, 11}; + f(1, 2, 3, 4, 5, l, 6, 7, &x, 44); + return x == 44 ? 0 : -1; +} + +static int stdarg_many_test(void) +{ + const char *src = + "#include <stdarg.h>\n" + "typedef struct {long long a, b;} stdarg_many_test_struct_type;\n" + "void f (int a, int b, int c, int d, int e, stdarg_many_test_struct_type l, int f, int g, ...){\n" + " va_list ap;\n" + " int *p;\n" + " va_start (ap, g);\n" + " p = va_arg(ap, int*);\n" + " *p = va_arg(ap, int);\n" + " va_end (ap);\n" + "}\n"; + return run_callback(src, stdarg_many_test_callback); +} + +/* + * Test Win32 stdarg handling, since the calling convention will pass a pointer + * to the struct and the stdarg pointer must point to that pointer initially. + */ + +typedef struct {long long a, b, c;} stdarg_struct_test_struct_type; +typedef int (*stdarg_struct_test_function_type) (stdarg_struct_test_struct_type a, ...); + +static int stdarg_struct_test_callback(void *ptr) { + stdarg_struct_test_function_type f = (stdarg_struct_test_function_type)ptr; + stdarg_struct_test_struct_type v = {10, 35, 99}; + int x = f(v, 234); + return (x == 378) ? 0 : -1; +} + +static int stdarg_struct_test(void) { + const char *src = + "#include <stdarg.h>\n" + "typedef struct {long long a, b, c;} stdarg_struct_test_struct_type;\n" + "int f(stdarg_struct_test_struct_type a, ...) {\n" + " va_list ap;\n" + " va_start(ap, a);\n" + " int z = va_arg(ap, int);\n" + " va_end(ap);\n" + " return z + a.a + a.b + a.c;\n" + "}\n"; + return run_callback(src, stdarg_struct_test_callback); +} + +/* Test that x86-64 arranges the stack correctly for arguments with alignment >8 bytes */ + +typedef LONG_DOUBLE (*arg_align_test_callback_type) (LONG_DOUBLE,int,LONG_DOUBLE,int,LONG_DOUBLE); + +static int arg_align_test_callback(void *ptr) { + arg_align_test_callback_type f = (arg_align_test_callback_type)ptr; + long double x = f(12, 0, 25, 0, 37); + return (x == 74) ? 0 : -1; +} + +static int arg_align_test(void) { + const char *src = + "long double f(long double a, int b, long double c, int d, long double e) {\n" + " return a + c + e;\n" + "}\n"; + return run_callback(src, arg_align_test_callback); +} + +#define RUN_TEST(t) \ + if (!testname || (strcmp(#t, testname) == 0)) { \ + fputs(#t "... ", stdout); \ + fflush(stdout); \ + if (t() == 0) { \ + fputs("success\n", stdout); \ + } else { \ + fputs("failure\n", stdout); \ + retval = EXIT_FAILURE; \ + } \ + } + +int main(int argc, char **argv) { + int i; + const char *testname = NULL; + int retval = EXIT_SUCCESS; + + /* if tcclib.h and libtcc1.a are not installed, where can we find them */ + for (i = 1; i < argc; ++i) { + if (!memcmp(argv[i], "run_test=", 9)) + testname = argv[i] + 9; + } + + g_argv = argv, g_argc = argc; + + RUN_TEST(ret_int_test); + RUN_TEST(ret_longlong_test); + RUN_TEST(ret_float_test); + RUN_TEST(ret_double_test); + RUN_TEST(ret_longdouble_test); + RUN_TEST(ret_2float_test); + RUN_TEST(ret_2double_test); + RUN_TEST(ret_8plus2double_test); + RUN_TEST(ret_6plus2longlong_test); +#if !defined __x86_64__ || defined _WIN32 + /* currently broken on x86_64 linux */ + RUN_TEST(ret_mixed_test); + RUN_TEST(ret_mixed2_test); +#endif + RUN_TEST(ret_mixed3_test); + RUN_TEST(reg_pack_test); + RUN_TEST(reg_pack_longlong_test); + RUN_TEST(sret_test); + RUN_TEST(one_member_union_test); + RUN_TEST(two_member_union_test); + RUN_TEST(many_struct_test); + RUN_TEST(many_struct_test_2); + RUN_TEST(many_struct_test_3); + RUN_TEST(stdarg_test); + RUN_TEST(stdarg_many_test); + RUN_TEST(stdarg_struct_test); + RUN_TEST(arg_align_test); + return retval; +} diff --git a/05/tcc-0.9.27/tests/asm-c-connect-1.c b/05/tcc-0.9.27/tests/asm-c-connect-1.c new file mode 100644 index 0000000..8a28d78 --- /dev/null +++ b/05/tcc-0.9.27/tests/asm-c-connect-1.c @@ -0,0 +1,57 @@ +#include <stdio.h> + +#if defined _WIN32 && !defined __TINYC__ +# define _ "_" +#else +# define _ +#endif + +static int x1_c(void) +{ + printf(" x1"); + return 1; +} + +asm(".text;"_"x1: call "_"x1_c; ret"); + +void callx4(void); +void callx5_again(void); + +void x6() +{ + printf(" x6-1"); +} + +int main(int argc, char *argv[]) +{ + printf("*"); + asm("call "_"x1"); + asm("call "_"x2"); + asm("call "_"x3"); + callx4(); + asm("call "_"x5"); + callx5_again(); + x6(); + printf(" *\n"); + return 0; +} + +static +int x2(void) +{ + printf(" x2"); + return 2; +} + +extern int x3(void); + +void x4(void) +{ + printf(" x4"); +} + +void x5(void); +void x5(void) +{ + printf(" x5"); +} diff --git a/05/tcc-0.9.27/tests/asm-c-connect-2.c b/05/tcc-0.9.27/tests/asm-c-connect-2.c new file mode 100644 index 0000000..3440b40 --- /dev/null +++ b/05/tcc-0.9.27/tests/asm-c-connect-2.c @@ -0,0 +1,36 @@ +#include <stdio.h> + +#if defined _WIN32 && !defined __TINYC__ +# define _ "_" +#else +# define _ +#endif + +int x3(void) +{ + printf(" x3"); + return 3; +} + +/* That callx4 is defined globally (as if ".globl callx4") + is a TCC extension. GCC doesn't behave like this. */ +void callx4(void); +__asm__(_"callx4: call "_"x4; ret;" +#ifndef __TINYC__ + " .global "_"callx4" +#endif +); + +extern void x5(void); + +void callx5_again(void); +void callx5_again(void) +{ + x5(); + asm("call "_"x6"); +} + +static void x6() +{ + printf(" x6-2"); +} diff --git a/05/tcc-0.9.27/tests/asmtest.S b/05/tcc-0.9.27/tests/asmtest.S new file mode 100644 index 0000000..e9c0e32 --- /dev/null +++ b/05/tcc-0.9.27/tests/asmtest.S @@ -0,0 +1,978 @@ +# gas comment with ``gnu'' style quotes + +/* some directive tests */ + + .byte 0xff + .byte 1, 2, 3 + .short 1, 2, 3 + .word 1, 2, 3 + .long 1, 2, 3 + .int 1, 2, 3 + .align 8 + .byte 1 +/* .align 16, 0x90 gas is too clever for us with 0x90 fill */ + .balign 4, 0x92 + .align 16, 0x91 /* 0x91 tests the non-clever behaviour */ + .skip 3 + .skip 15, 0x90 + .string "hello\0world" +/* Macro expansion should work like with C, the #n shouldn't be parsed + as asm line comment */ +#define __stringify(n) #n +#define stringify(n) __stringify(n) + .skip 8,0x90 + .asciz stringify(BLA) + .skip 8,0x90 + +# 28 "asmtest.S" # a line directive (and a line comment) + movl %eax, %ebx # some more asm comment +/* some label tests */ +L1: + movl %eax, %ebx + mov 0x10000, %eax +L2: + movl $L2 - L1, %ecx +var1: + nop ; nop ; nop ; nop + + mov var1, %eax + +/* instruction tests */ +movl %eax, %ebx +mov 0x10000, %eax +mov 0x10000, %ax +mov 0x10000, %al +mov %al, 0x10000 + +mov $1, %edx +mov $1, %dx +mov $1, %cl +movb $2, 0x100(%ebx,%edx,2) +movw $2, 0x100(%ebx,%edx,2) +movl $2, 0x100(%ebx,%edx,2) +movl %eax, 0x100(%ebx,%edx,2) +movl 0x100(%ebx,%edx,2), %edx +movw %ax, 0x100(%ebx,%edx,2) + +movw $0x1122,%si +movl $0x112233,%edx +movl $0x80000000, %esi +movl $-0x7fffffff, %edi +#ifdef __x86_64__ +mov $0x11223344,%rbx +movq $0x11223344,%rbx +mov $0x1122334455,%rbx +movq $0x1122334455,%rbx +movl $0x11334455,(%rbx) +#endif + +mov %eax, 0x12(,%edx,2) + +#ifdef __i386__ +mov %cr3, %edx +mov %ecx, %cr3 +movl %cr3, %eax +movl %tr3, %eax +movl %db3, %ebx +movl %dr6, %eax +#else +mov %cr3, %rdx +mov %rcx, %cr3 +movq %cr3, %rax +movq %db3, %rbx +movq %dr6, %rax +mov %cr8, %rsi +mov %rdi, %cr8 +#endif +movl %fs, %ecx +movl %ebx, %fs + +#ifdef __x86_64__ +movq %r8, %r9 +movq %r10, %r11 +movq %r12, %r13 +movq %r14, %r15 +movq %rax, %r9 +movq %r15, %rsi +inc %r9b +dec %r10w +not %r11d +negq %r12 +decb %r13b +incw %r14w +notl %r15d +#endif + + movsbl 0x1000, %eax + movsbw 0x1000, %ax + movswl 0x1000, %eax + + movzbl 0x1000, %eax + movzbw 0x1000, %ax + movzwl 0x1000, %eax + + movzb 0x1000, %eax + movzb 0x1000, %ax + + mov $0x12345678,%eax + +#ifdef __x86_64__ + movzb 0x1000, %rax + movzbq 0x1000, %rbx + movsbq 0x1000, %rdx + movzwq 0x1000, %rdi + movswq 0x1000, %rdx + movslq %eax, %rcx + mov $0x12345678,%rax + mov $0x12345678,%rdx + mov $0x12345678,%r10 + mov $0x123456789abcdef0,%rax + mov $0x123456789abcdef0,%rcx + mov $0x123456789abcdef0,%r11 +#endif + +#ifdef __i386__ + pushl %eax + push %eax + push %cs +#else + pushq %rax + push %rax +#endif + pushw %ax + push %gs + push $1 + push $100 + push 0x42(%eax) + pop 0x43(%esi) + +#ifdef __i386__ + popl %eax + pop %eax + pop %ds +#else + popq %rax + pop %rax +#endif + popw %ax + pop %fs + + xchg %eax, %ecx + xchg %edx, %eax + xchg %bx, 0x10000 + xchg 0x10000, %ebx + xchg 0x10000, %dl + + in $100, %al + in $100, %ax + in $100, %eax + in %dx, %al + in %dx, %ax + in %dx, %eax + inb %dx + inw %dx + inl %dx + + out %al, $100 + out %ax, $100 + out %eax, $100 + + /* NOTE: gas is bugged here, so size must be added */ + outb %al, %dx + outw %ax, %dx + outl %eax, %dx + + leal 0x1000(%ebx), %ecx + lea 0x1000(%ebx), %ecx + +#ifdef __i386__ + les 0x2000, %eax + lds 0x2000, %ebx + lss 0x2000, %edx +#endif + lfs 0x2000, %ecx + lgs 0x2000, %edx + +addl $0x123, %eax +add $0x123, %ebx +add $-16, %ecx +add $-0x123, %esi +add $1, %bx +add $1, %ebx +add $-1, %bx +add $-1, %ebx +add $127, %bx +addl $127, %ebx +addl $-128, %ebx +addl $-128, %ebx +addl $-129, %ebx +addl $128, %ebx +addl $255, %ebx +addl $256, %ebx +andb $0xf, %ah +andb $-15, %cl +xorb $127, %dh +cmpb $42, (%eax) +addl $0x123, 0x100 +addl $0x123, 0x100(%ebx) +addl $0x123, 0x100(%ebx,%edx,2) +addl $0x123, 0x100(%esp) +addl $0x123, (3*8)(%esp) +addl $0x123, (%ebp) +addl $0x123, (%esp) +cmpl $0x123, (%esp) + +#ifdef __x86_64__ +xor %bl,%ah +xor %bl,%r8b +xor %r9b,%bl +xor %sil,%cl +add %eax,(%r8d) +add %ebx,(%r9) +add %edx,(%r10d,%r11d) +add %ecx,(%r12,%r13) +add %esi,(%r14,%r15,4) +add %edi,0x1000(%rbx,%r12,8) +add %r11,0x1000(%ebp,%r9d,8) +movb $12, %ah +movb $13, %bpl +movb $14, %dil +movb $15, %r12b +#endif + +add %eax, (%ebx) +add (%ebx), %eax + +or %dx, (%ebx) +or (%ebx), %si + +add %cl, (%ebx) +add (%ebx), %dl + + inc %edx + incl 0x10000 + incb 0x10000 + dec %dx + + test $1, %al + test $1, %cl + + testl $1, 0x1000 + testb $1, 0x1000 + testw $1, 0x1000 + test %eax, %ebx + test %eax, 0x1000 + test 0x1000, %edx + + not %edx + notw 0x10000 + notl 0x10000 + notb 0x10000 + + neg %edx + negw 0x10000 + negl 0x10000 + negb 0x10000 + + imul %ecx + mul %edx + mulb %cl + + imul %eax, %ecx + imul 0x1000, %cx + imul $10, %eax, %ecx + imul $10, %ax, %cx + imul $10, %eax + imul $0x1100000, %eax + imul $1, %eax + + idivw 0x1000 + div %ecx + div %bl + div %ecx, %eax + +and $15,%bx +and $-20,%edx + +shl %edx +shl $10, %edx +shl %cl, %edx + +shld $1, %eax, %edx +shld %cl, %eax, %edx +shld %eax, %edx + +shrd $1, %eax, %edx +shrd %cl, %eax, %edx +shrd %eax, %edx + +L4: +call 0x1000 +call L4 +#ifdef __i386__ +call *%eax +#else +call *%rax +#endif +call *0x1000 +call func1 + +.global L5,L6 + +L5: +L6: + +#ifdef __i386__ +lcall $0x100, $0x1000 +#else +lcall *0x100 +lcall *(%rax) +#endif + +jmp 0x1000 +jmp *(%edi) +#ifdef __i386__ +jmp *%eax +#else +jmp *%rax +#endif +jmp *0x1000 + +#ifdef __i386__ +ljmp $0x100, $0x1000 +#else +ljmp *0x100 +ljmp *(%rdi) +ljmpl *(%esi) +ljmpw *(%esi) +#endif + +ret +ret $10 +#ifdef __i386__ +retl +retl $10 +#else +retq +retq $10 +#endif + +lret + +lret $10 + +enter $1234, $10 + +L3: + jo 0x1000 + jnp 0x1001 + jne 0x1002 + jg 0x1003 + + jo L3 + jnp L3 + jne L3 + jg L3 + + loopne L3 + loopnz L3 + loope L3 + loopz L3 + loop L3 + jecxz L3 + + + seto %al + setc %al + setcb %al + setnp 0x1000 + setl 0xaaaa + setg %dl + + fadd + fadd %st(1), %st + fadd %st(0), %st(1) + fadd %st(3) + + fmul %st(0),%st(0) + fmul %st(0),%st(1) + + faddp %st(5) + faddp + faddp %st(1), %st + + fadds 0x1000 + fiadds 0x1002 + faddl 0x1004 + fiaddl 0x1006 + + fmul + fmul %st(1), %st + fmul %st(3) + + fmulp %st(5) + fmulp + fmulp %st(1), %st + + fmuls 0x1000 + fimuls 0x1002 + fmull 0x1004 + fimull 0x1006 + + fsub + fsub %st(1), %st + fsub %st(3) + + fsubp %st(5) + fsubp + fsubp %st(1), %st + + fsubs 0x1000 + fisubs 0x1002 + fsubl 0x1004 + fisubl 0x1006 + + fsubr + fsubr %st(1), %st + fsubr %st(3) + + fsubrp %st(5) + fsubrp + fsubrp %st(1), %st + + fsubrs 0x1000 + fisubrs 0x1002 + fsubrl 0x1004 + fisubrl 0x1006 + + fdiv + fdiv %st(1), %st + fdiv %st(3) + + fdivp %st(5) + fdivp + fdivp %st(1), %st + + fdivs 0x1000 + fidivs 0x1002 + fdivl 0x1004 + fidivl 0x1006 + + fcom %st(3) + + fcoms 0x1000 + ficoms 0x1002 + fcoml 0x1004 + ficoml 0x1006 + + fcomp %st(5) + fcomp + fcompp + + fcomps 0x1000 + ficomps 0x1002 + fcompl 0x1004 + ficompl 0x1006 + + fld %st(5) + fldl 0x1000 + flds 0x1002 + fildl 0x1004 + fst %st(4) + fstp %st(6) + fstpt 0x1006 + fbstp 0x1008 + + fxch + fxch %st(4) + + fucom %st(6) + fucomp %st(3) + fucompp + + finit + fninit + fldcw 0x1000 + fnstcw 0x1002 + fstcw 0x1002 + fnstsw 0x1004 + fnstsw (%eax) + fstsw 0x1004 + fstsw (%eax) + fnclex + fclex + fnstenv 0x1000 + fstenv 0x1000 + fldenv 0x1000 + fnsave 0x1002 + fsave 0x1000 + frstor 0x1000 + ffree %st(7) + ffreep %st(6) + + ftst + fxam + fld1 + fldl2t + fldl2e + fldpi + fldlg2 + fldln2 + fldz + + f2xm1 + fyl2x + fptan + fpatan + fxtract + fprem1 + fdecstp + fincstp + fprem + fyl2xp1 + fsqrt + fsincos + frndint + fscale + fsin + fcos + fchs + fabs + fnop + fwait + +bswap %edx +bswapl %ecx +xadd %ecx, %edx +xaddb %dl, 0x1000 +xaddw %ax, 0x1000 +xaddl %eax, 0x1000 +cmpxchg %ecx, %edx +cmpxchgb %dl, 0x1000 +cmpxchgw %ax, 0x1000 +cmpxchgl %eax, 0x1000 +invlpg 0x1000 +cmpxchg8b 0x1002 +#ifdef __x86_64__ +cmpxchg16b (%rax) +cmpxchg16b (%r10,%r11) +#endif + +fcmovb %st(5), %st +fcmove %st(5), %st +fcmovbe %st(5), %st +fcmovu %st(5), %st +fcmovnb %st(5), %st +fcmovne %st(5), %st +fcmovnbe %st(5), %st +fcmovnu %st(5), %st +fcomi %st(5), %st +fucomi %st(5), %st +fcomip %st(5), %st +fucomip %st(5), %st + + + + cmovo 0x1000, %eax + cmovs 0x1000, %eax + cmovns %edx, %edi + cmovne %ax, %si + cmovbw %ax, %di + cmovnbel %edx, %ecx +#ifdef __x86_64__ + bswapq %rsi + bswapq %r10 + cmovz %rdi,%rbx + cmovpeq %rsi, %rdx +#endif + +int $3 +int $0x10 + +#ifdef __i386__ + pusha + popa +#endif + clc # another comment + cld # a comment with embedded ' tick + cli + clts + cmc + lahf + sahf +#ifdef __i386__ + pushfl + popfl +#else + pushfq + popfq +#endif + pushf + popf + stc + std + sti +#ifdef __i386__ + aaa + aas + daa + das + aad + aam + into +#endif + cbw + cwd + cwde + cdq + cbtw + cwtd + cwtl + cltd + leave + int3 + iret + rsm + hlt + wait + nop + + /* XXX: handle prefixes */ +#if 0 + aword + addr16 +#endif + lock + rep + repe + repz + repne + repnz + nop + + lock ;negl (%eax) + wait ;pushf + rep ;stosb + repe ;lodsb + repz ;cmpsb + repne;movsb + repnz;outsb + + /* handle one-line prefix + ops */ + lock negl (%eax) + wait pushf + rep stosb + repe lodsb + repz cmpsb + repne movsb + repnz outsb + + invd + wbinvd + cpuid + wrmsr + rdtsc + rdmsr + rdpmc + ud2 +#ifdef __x86_64__ + syscall + sysret + sysretq + lfence + mfence + sfence + prefetchnta 0x18(%rdx) + prefetcht0 (%rcx) + prefetcht1 (%rsi) + prefetcht2 (%rdi) + prefetchw (%rdi) + clflush 0x1000(%rax,%rcx) + fxsaveq (%rdx) + fxsaveq (%r11) + fxrstorq (%rcx) + fxrstorq (%r10) + +#endif + + lar %ax,%dx + lar %eax,%dx + lar %ax,%edx + lar %eax,%edx +#ifdef __x86_64__ + lar %ax,%rdx + lar %eax,%rdx +#endif + emms + movd %edx, %mm3 + movd 0x1000, %mm2 + movd %mm4, %ecx + movd %mm5, 0x1000 + + movq 0x1000, %mm2 + movq %mm4, 0x1000 + + pand 0x1000, %mm3 + pand %mm4, %mm5 + + psllw $1, %mm6 + psllw 0x1000, %mm7 + psllw %mm2, %mm7 + + xlat + cmpsb + scmpw + insl + outsw + lodsb + slodl + movsb + movsl + smovb + scasb + sscaw + stosw + sstol + + bsf 0x1000, %ebx + bsr 0x1000, %ebx + bt %edx, 0x1000 + btl $2, 0x1000 + btc %edx, 0x1000 + btcl $2, 0x1000 + btr %edx, 0x1000 + btrl $2, 0x1000 + bts %edx, 0x1000 + btsl $2, 0x1000 + + + +#ifdef __i386__ + boundl %edx, 0x10000 + boundw %bx, 0x1000 + + arpl %bx, 0x1000 +#endif + lar 0x1000, %eax + lgdt 0x1000 + lidt 0x1000 + lldt 0x1000 + sgdt 0x1000 + sidt 0x1000 + sldt 0x1000 +#ifdef __x86_64__ + lgdtq 0x1000 + lidtq 0x1000 + sgdtq 0x1000 + sidtq 0x1000 + + swapgs + + str %rdx + str %r9 +#endif + + lmsw 0x1000 + lsl 0x1000, %ecx + ltr 0x1000 + ltr %si + smsw 0x1000 + str 0x1000 + str %ecx + str %dx + + verr 0x1000 + verw 0x1000 + +#ifdef __i386__ + push %ds + pushw %ds + pushl %ds + pop %ds + popw %ds + popl %ds +#endif + fxsave 1(%ebx) + fxrstor 1(%ecx) +#ifdef __i386__ + pushl $1 +#else + pushq $1 +#endif + pushw $1 + push $1 + +#ifdef __ASSEMBLER__ // should be defined, for S files + inc %eax +#endif + +#ifndef _WIN32 +ft1: ft2: ft3: ft4: ft5: ft6: ft7: ft8: ft9: + xor %eax, %eax + ret + +.type ft1,STT_FUNC +.type ft2,@STT_FUNC +.type ft3,%STT_FUNC +.type ft4,"STT_FUNC" +.type ft5,function +.type ft6,@function +.type ft7,%function +.type ft8,"function" +#endif + + pause +.rept 6 + nop +.endr +.fill 4,1,0x90 + +.section .text.one,"ax" +nop +.previous +.pushsection .text.one,"ax" +nop +.pushsection .text.two,"ax" +nop +.popsection +.popsection + +1: ud2 +.pushsection __bug_table,"a" +.align 8 +2: .long 1b - 2b + .long 0x600000 - 2b + .long 1b + 42 + .long 43 + 1b + .long 2b + 144 + .long 145 + 2b + .word 164, 0 + .org 2b+32 +#ifdef __x86_64__ + .quad 1b +#else + .long 1b +#endif +.popsection +3: mov %eax,%ecx +4: +.pushsection .text.three, "ax" +nop +.skip (-((4b-3b) > 0) * 2) , 0x90 +.popsection + +.globl overrideme +.weak overrideme + nop +.globl notimplemented +notimplemented: + ret +.set overrideme, notimplemented +overrideme = notimplemented +overrideme: + ret + + movd %esi, %mm1 + movd %edi, %xmm2 + movd (%ebx), %mm3 + movd (%ebx), %xmm3 + movd %mm1, %esi + movd %xmm2, %edi + movd %mm3, (%edx) + movd %xmm3, (%edx) +#ifdef __x86_64__ + movd %rsi, %mm1 + movd %rdi, %xmm2 + movd (%rbx), %mm3 + movd (%rbx), %xmm3 + movd %mm1, %r12 + movd %xmm2, %rdi + movd %mm3, (%r8) + movd %xmm3, (%r13) +#endif + + movq (%ebp), %mm1 + movq %mm2, (%edi) + movq (%edi), %xmm3 + movq %mm4, %mm5 +#ifdef __x86_64__ + movq %rcx, %mm1 + movq %rdx, %xmm2 + movq %r13, %xmm3 + /* movq mem64->xmm is encoded as f30f7e by GAS, but as + 660f6e by tcc (which really is a movd and would need + a REX.W prefix to be movq). */ + movq (%rsi), %xmm3 + movq %mm1, %rdx + movq %xmm3, %rcx + movq %xmm4, (%rsi) +#endif + +#define TEST_MMX_SSE(insn) \ + insn %mm1, %mm2; \ + insn %xmm2, %xmm3; \ + insn (%ebx), %xmm3; +#define TEST_MMX_SSE_I8(insn) \ + TEST_MMX_SSE(insn) \ + insn $0x42, %mm4; \ + insn $0x42, %xmm4; + + TEST_MMX_SSE(packssdw) + TEST_MMX_SSE(packsswb) + TEST_MMX_SSE(packuswb) + TEST_MMX_SSE(paddb) + TEST_MMX_SSE(paddw) + TEST_MMX_SSE(paddd) + TEST_MMX_SSE(paddsb) + TEST_MMX_SSE(paddsw) + TEST_MMX_SSE(paddusb) + TEST_MMX_SSE(paddusw) + TEST_MMX_SSE(pand) + TEST_MMX_SSE(pandn) + TEST_MMX_SSE(pcmpeqb) + TEST_MMX_SSE(pcmpeqw) + TEST_MMX_SSE(pcmpeqd) + TEST_MMX_SSE(pcmpgtb) + TEST_MMX_SSE(pcmpgtw) + TEST_MMX_SSE(pcmpgtd) + TEST_MMX_SSE(pmaddwd) + TEST_MMX_SSE(pmulhw) + TEST_MMX_SSE(pmullw) + TEST_MMX_SSE(por) + TEST_MMX_SSE(psllw) +TEST_MMX_SSE_I8(psllw) + TEST_MMX_SSE(pslld) +TEST_MMX_SSE_I8(pslld) + TEST_MMX_SSE(psllq) +TEST_MMX_SSE_I8(psllq) + TEST_MMX_SSE(psraw) +TEST_MMX_SSE_I8(psraw) + TEST_MMX_SSE(psrad) +TEST_MMX_SSE_I8(psrad) + TEST_MMX_SSE(psrlw) +TEST_MMX_SSE_I8(psrlw) + TEST_MMX_SSE(psrld) +TEST_MMX_SSE_I8(psrld) + TEST_MMX_SSE(psrlq) +TEST_MMX_SSE_I8(psrlq) + TEST_MMX_SSE(psubb) + TEST_MMX_SSE(psubw) + TEST_MMX_SSE(psubd) + TEST_MMX_SSE(psubsb) + TEST_MMX_SSE(psubsw) + TEST_MMX_SSE(psubusb) + TEST_MMX_SSE(psubusw) + TEST_MMX_SSE(punpckhbw) + TEST_MMX_SSE(punpckhwd) + TEST_MMX_SSE(punpckhdq) + TEST_MMX_SSE(punpcklbw) + TEST_MMX_SSE(punpcklwd) + TEST_MMX_SSE(punpckldq) + TEST_MMX_SSE(pxor) + + cvtpi2ps %mm1, %xmm2 + cvtpi2ps (%ebx), %xmm2 + TEST_MMX_SSE(pmaxsw) + TEST_MMX_SSE(pmaxub) + TEST_MMX_SSE(pminsw) + TEST_MMX_SSE(pminub) diff --git a/05/tcc-0.9.27/tests/boundtest.c b/05/tcc-0.9.27/tests/boundtest.c new file mode 100644 index 0000000..15bffb4 --- /dev/null +++ b/05/tcc-0.9.27/tests/boundtest.c @@ -0,0 +1,285 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#define NB_ITS 1000000 +//#define NB_ITS 1 +#define TAB_SIZE 100 + +int tab[TAB_SIZE]; +int ret_sum; +char tab3[256]; + +int test1(void) +{ + int i, sum = 0; + for(i=0;i<TAB_SIZE;i++) { + sum += tab[i]; + } + return sum; +} + +/* error */ +int test2(void) +{ + int i, sum = 0; + for(i=0;i<TAB_SIZE + 1;i++) { + sum += tab[i]; + } + return sum; +} + +/* actually, profiling test */ +int test3(void) +{ + int sum; + int i, it; + + sum = 0; + for(it=0;it<NB_ITS;it++) { + for(i=0;i<TAB_SIZE;i++) { + sum += tab[i]; + } + } + return sum; +} + +/* ok */ +int test4(void) +{ + int i, sum = 0; + int *tab4; + + fprintf(stderr, "%s start\n", __FUNCTION__); + + tab4 = malloc(20 * sizeof(int)); + for(i=0;i<20;i++) { + sum += tab4[i]; + } + free(tab4); + + fprintf(stderr, "%s end\n", __FUNCTION__); + return sum; +} + +/* error */ +int test5(void) +{ + int i, sum = 0; + int *tab4; + + fprintf(stderr, "%s start\n", __FUNCTION__); + + tab4 = malloc(20 * sizeof(int)); + for(i=0;i<21;i++) { + sum += tab4[i]; + } + free(tab4); + + fprintf(stderr, "%s end\n", __FUNCTION__); + return sum; +} + +/* error */ +/* XXX: currently: bug */ +int test6(void) +{ + int i, sum = 0; + int *tab4; + + tab4 = malloc(20 * sizeof(int)); + free(tab4); + for(i=0;i<21;i++) { + sum += tab4[i]; + } + + return sum; +} + +/* error */ +int test7(void) +{ + int i, sum = 0; + int *p; + + for(i=0;i<TAB_SIZE + 1;i++) { + p = &tab[i]; + if (i == TAB_SIZE) + printf("i=%d %x\n", i, p); + sum += *p; + } + return sum; +} + +/* ok */ +int test8(void) +{ + int i, sum = 0; + int tab[10]; + + for(i=0;i<10;i++) { + sum += tab[i]; + } + return sum; +} + +/* error */ +int test9(void) +{ + int i, sum = 0; + char tab[10]; + + for(i=0;i<11;i++) { + sum += tab[i]; + } + return sum; +} + +/* ok */ +int test10(void) +{ + char tab[10]; + char tab1[10]; + + memset(tab, 0, 10); + memcpy(tab, tab1, 10); + memmove(tab, tab1, 10); + return 0; +} + +/* error */ +int test11(void) +{ + char tab[10]; + + memset(tab, 0, 11); + return 0; +} + +/* error */ +int test12(void) +{ + void *ptr; + ptr = malloc(10); + free(ptr); + free(ptr); + return 0; +} + +/* error */ +int test13(void) +{ + char pad1 = 0; + char tab[10]; + char pad2 = 0; + memset(tab, 'a', sizeof(tab)); + return strlen(tab); +} + +int test14(void) +{ + char *p = alloca(TAB_SIZE); + memset(p, 'a', TAB_SIZE); + p[TAB_SIZE-1] = 0; + return strlen(p); +} + +/* error */ +int test15(void) +{ + char *p = alloca(TAB_SIZE-1); + memset(p, 'a', TAB_SIZE); + p[TAB_SIZE-1] = 0; + return strlen(p); +} + +/* ok */ +int test16() +{ + char *demo = "This is only a test."; + char *p; + + fprintf(stderr, "%s start\n", __FUNCTION__); + + p = alloca(16); + strcpy(p,"12345678901234"); + printf("alloca: p is %s\n", p); + + /* Test alloca embedded in a larger expression */ + printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) ); + + fprintf(stderr, "%s end\n", __FUNCTION__); +} + +/* error */ +int test17() +{ + char *demo = "This is only a test."; + char *p; + + fprintf(stderr, "%s start\n", __FUNCTION__); + + p = alloca(16); + strcpy(p,"12345678901234"); + printf("alloca: p is %s\n", p); + + /* Test alloca embedded in a larger expression */ + printf("alloca: %s\n", strcpy(alloca(strlen(demo)),demo) ); + + fprintf(stderr, "%s end\n", __FUNCTION__); +} + +int (*table_test[])(void) = { + test1, + test2, + test3, + test4, + test5, + test6, + test7, + test8, + test9, + test10, + test11, + test12, + test13, + test14, + test15, + test16, + test17, +}; + +int main(int argc, char **argv) +{ + int index; + int (*ftest)(void); + int index_max = sizeof(table_test)/sizeof(table_test[0]); + + if (argc < 2) { + printf( + "test TCC bound checking system\n" + "usage: boundtest N\n" + " 1 <= N <= %d\n", index_max); + exit(1); + } + + index = 0; + if (argc >= 2) + index = atoi(argv[1]) - 1; + + if ((index < 0) || (index >= index_max)) { + printf("N is outside of the valid range (%d)\n", index); + exit(2); + } + + /* well, we also use bounds on this ! */ + ftest = table_test[index]; + ftest(); + + return 0; +} + +/* + * without bound 0.77 s + * with bounds 4.73 + */ diff --git a/05/tcc-0.9.27/tests/gcctestsuite.sh b/05/tcc-0.9.27/tests/gcctestsuite.sh new file mode 100755 index 0000000..f3cc538 --- /dev/null +++ b/05/tcc-0.9.27/tests/gcctestsuite.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +TESTSUITE_PATH=$HOME/gcc/gcc-3.2/gcc/testsuite/gcc.c-torture +TCC="./tcc -B. -I. -DNO_TRAMPOLINES" +rm -f tcc.sum tcc.log +nb_failed="0" + +for src in $TESTSUITE_PATH/compile/*.c ; do + echo $TCC -o /tmp/test.o -c $src + $TCC -o /tmp/test.o -c $src >> tcc.log 2>&1 + if [ "$?" = "0" ] ; then + result="PASS" + else + result="FAIL" + nb_failed=$(( $nb_failed + 1 )) + fi + echo "$result: $src" >> tcc.sum +done + +for src in $TESTSUITE_PATH/execute/*.c ; do + echo $TCC $src + $TCC $src >> tcc.log 2>&1 + if [ "$?" = "0" ] ; then + result="PASS" + else + result="FAIL" + nb_failed=$(( $nb_failed + 1 )) + fi + echo "$result: $src" >> tcc.sum +done + +echo "$nb_failed test(s) failed." >> tcc.sum +echo "$nb_failed test(s) failed." diff --git a/05/tcc-0.9.27/tests/libtcc_test.c b/05/tcc-0.9.27/tests/libtcc_test.c new file mode 100644 index 0000000..480d314 --- /dev/null +++ b/05/tcc-0.9.27/tests/libtcc_test.c @@ -0,0 +1,96 @@ +/* + * Simple Test program for libtcc + * + * libtcc can be useful to use tcc as a "backend" for a code generator. + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "libtcc.h" + +/* this function is called by the generated code */ +int add(int a, int b) +{ + return a + b; +} + +/* this strinc is referenced by the generated code */ +const char hello[] = "Hello World!"; + +char my_program[] = +"#include <tcclib.h>\n" /* include the "Simple libc header for TCC" */ +"extern int add(int a, int b);\n" +"#ifdef _WIN32\n" /* dynamically linked data needs 'dllimport' */ +" __attribute__((dllimport))\n" +"#endif\n" +"extern const char hello[];\n" +"int fib(int n)\n" +"{\n" +" if (n <= 2)\n" +" return 1;\n" +" else\n" +" return fib(n-1) + fib(n-2);\n" +"}\n" +"\n" +"int foo(int n)\n" +"{\n" +" printf(\"%s\\n\", hello);\n" +" printf(\"fib(%d) = %d\\n\", n, fib(n));\n" +" printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n" +" return 0;\n" +"}\n"; + +int main(int argc, char **argv) +{ + TCCState *s; + int i; + int (*func)(int); + + s = tcc_new(); + if (!s) { + fprintf(stderr, "Could not create tcc state\n"); + exit(1); + } + + /* if tcclib.h and libtcc1.a are not installed, where can we find them */ + for (i = 1; i < argc; ++i) { + char *a = argv[i]; + if (a[0] == '-') { + if (a[1] == 'B') + tcc_set_lib_path(s, a+2); + else if (a[1] == 'I') + tcc_add_include_path(s, a+2); + else if (a[1] == 'L') + tcc_add_library_path(s, a+2); + } + } + + /* MUST BE CALLED before any compilation */ + tcc_set_output_type(s, TCC_OUTPUT_MEMORY); + + if (tcc_compile_string(s, my_program) == -1) + return 1; + + /* as a test, we add symbols that the compiled program can use. + You may also open a dll with tcc_add_dll() and use symbols from that */ + tcc_add_symbol(s, "add", add); + tcc_add_symbol(s, "hello", hello); + + /* relocate the code */ + if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0) + return 1; + + /* get entry symbol */ + func = tcc_get_symbol(s, "foo"); + if (!func) + return 1; + + /* run the code */ + func(32); + + /* delete the state */ + tcc_delete(s); + + return 0; +} diff --git a/05/tcc-0.9.27/tests/pp/01.c b/05/tcc-0.9.27/tests/pp/01.c new file mode 100644 index 0000000..2fc3d79 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/01.c @@ -0,0 +1,6 @@ +#define hash_hash # ## # +#define mkstr(a) # a +#define in_between(a) mkstr(a) +#define join(c, d) in_between(c hash_hash d) +char p[] = join(x, y); +// char p[] = "x ## y"; diff --git a/05/tcc-0.9.27/tests/pp/01.expect b/05/tcc-0.9.27/tests/pp/01.expect new file mode 100644 index 0000000..cf5b153 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/01.expect @@ -0,0 +1 @@ +char p[] = "x ## y"; diff --git a/05/tcc-0.9.27/tests/pp/02.c b/05/tcc-0.9.27/tests/pp/02.c new file mode 100644 index 0000000..feb1254 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/02.c @@ -0,0 +1,28 @@ +#define x 3 +#define f(a) f(x * (a)) +#undef x +#define x 2 +#define g f +#define z z[0] +#define h g(~ +#define m(a) a(w) +#define w 0,1 +#define t(a) a +#define p() int +#define q(x) x +#define r(x,y) x ## y +#define str(x) # x +f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); +g(x+(3,4)-w) | h 5) & m +(f)^m(m); +char c[2][6] = { str(hello), str() }; +/* + * f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1); + * f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1); + * char c[2][6] = { "hello", "" }; + */ +#define L21 f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); +#define L22 g(x+(3,4)-w) | h 5) & m\ +(f)^m(m); +L21 +L22 diff --git a/05/tcc-0.9.27/tests/pp/02.expect b/05/tcc-0.9.27/tests/pp/02.expect new file mode 100644 index 0000000..8ae2eb9 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/02.expect @@ -0,0 +1,5 @@ +f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1); +f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1); +char c[2][6] = { "hello", "" }; +f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1); +f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1); diff --git a/05/tcc-0.9.27/tests/pp/03.c b/05/tcc-0.9.27/tests/pp/03.c new file mode 100644 index 0000000..a659245 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/03.c @@ -0,0 +1,15 @@ +#define str(s) # s +#define xstr(s) str(s) +#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \ + x ## s, x ## t) +#define INCFILE(n) vers ## n +#define glue(a, b) a ## b +#define xglue(a, b) glue(a, b) +#define HIGHLOW "hello" +#define LOW LOW ", world" +debug(1, 2); +fputs(str(strncmp("abc\0d", "abc", '\4') // this goes away + == 0) str(: @\n), s); +\#include xstr(INCFILE(2).h) +glue(HIGH, LOW); +xglue(HIGH, LOW) diff --git a/05/tcc-0.9.27/tests/pp/03.expect b/05/tcc-0.9.27/tests/pp/03.expect new file mode 100644 index 0000000..44aad0a --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/03.expect @@ -0,0 +1,5 @@ +printf("x" "1" "= %d, x" "2" "= %s", x1, x2); +fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n", s); +\#include "vers2.h" +"hello"; +"hello" ", world" diff --git a/05/tcc-0.9.27/tests/pp/04.c b/05/tcc-0.9.27/tests/pp/04.c new file mode 100644 index 0000000..0068f37 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/04.c @@ -0,0 +1,4 @@ +#define foobar 1 +#define C(x,y) x##y +#define D(x) (C(x,bar)) +D(foo) diff --git a/05/tcc-0.9.27/tests/pp/04.expect b/05/tcc-0.9.27/tests/pp/04.expect new file mode 100644 index 0000000..7c67b01 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/04.expect @@ -0,0 +1 @@ +(1) diff --git a/05/tcc-0.9.27/tests/pp/05.c b/05/tcc-0.9.27/tests/pp/05.c new file mode 100644 index 0000000..7274941 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/05.c @@ -0,0 +1,7 @@ +#define t(x,y,z) x ## y ## z +#define xxx(s) int s[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), \ + t(10,,), t(,11,), t(,,12), t(,,) }; + +int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), + t(10,,), t(,11,), t(,,12), t(,,) }; +xxx(j) diff --git a/05/tcc-0.9.27/tests/pp/05.expect b/05/tcc-0.9.27/tests/pp/05.expect new file mode 100644 index 0000000..9f9be37 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/05.expect @@ -0,0 +1,3 @@ +int j[] = { 123, 45, 67, 89, + 10, 11, 12, }; +int j[] = { 123, 45, 67, 89, 10, 11, 12, }; diff --git a/05/tcc-0.9.27/tests/pp/06.c b/05/tcc-0.9.27/tests/pp/06.c new file mode 100644 index 0000000..28cfdde --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/06.c @@ -0,0 +1,5 @@ +#define X(a,b, \ + c,d) \ + foo + +X(1,2,3,4) diff --git a/05/tcc-0.9.27/tests/pp/06.expect b/05/tcc-0.9.27/tests/pp/06.expect new file mode 100644 index 0000000..257cc56 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/06.expect @@ -0,0 +1 @@ +foo diff --git a/05/tcc-0.9.27/tests/pp/07.c b/05/tcc-0.9.27/tests/pp/07.c new file mode 100644 index 0000000..b22b22b --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/07.c @@ -0,0 +1,4 @@ +#define a() YES +#define b() a +b() +b()() diff --git a/05/tcc-0.9.27/tests/pp/07.expect b/05/tcc-0.9.27/tests/pp/07.expect new file mode 100644 index 0000000..ad0e20a --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/07.expect @@ -0,0 +1,2 @@ +a +YES diff --git a/05/tcc-0.9.27/tests/pp/08.c b/05/tcc-0.9.27/tests/pp/08.c new file mode 100644 index 0000000..93018e1 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/08.c @@ -0,0 +1,4 @@ +// test macro expansion in arguments +#define s_pos s_s.s_pos +#define foo(x) (x) +foo(hej.s_pos) diff --git a/05/tcc-0.9.27/tests/pp/08.expect b/05/tcc-0.9.27/tests/pp/08.expect new file mode 100644 index 0000000..2b2e3ee --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/08.expect @@ -0,0 +1 @@ +(hej.s_s.s_pos) diff --git a/05/tcc-0.9.27/tests/pp/09.c b/05/tcc-0.9.27/tests/pp/09.c new file mode 100644 index 0000000..315b297 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/09.c @@ -0,0 +1,4 @@ +#define C(a,b,c) a##b##c +#define N(x,y) C(x,_,y) +#define A_O aaaaoooo +N(A,O) diff --git a/05/tcc-0.9.27/tests/pp/09.expect b/05/tcc-0.9.27/tests/pp/09.expect new file mode 100644 index 0000000..adce0f9 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/09.expect @@ -0,0 +1 @@ +aaaaoooo diff --git a/05/tcc-0.9.27/tests/pp/10.c b/05/tcc-0.9.27/tests/pp/10.c new file mode 100644 index 0000000..f180eff --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/10.c @@ -0,0 +1,10 @@ +#define f(x) x +#define g(x) f(x) f(x +#define i(x) g(x)) g(x +#define h(x) i(x))) i(x +#define k(x) i(x))) i(x)))) +f(x) +g(x)) +i(x))) +h(x)))) +k(x)))) diff --git a/05/tcc-0.9.27/tests/pp/10.expect b/05/tcc-0.9.27/tests/pp/10.expect new file mode 100644 index 0000000..bd18e18 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/10.expect @@ -0,0 +1,5 @@ +x +x x +x x x x +x x x x x x x x +x x x x x x x x)))) diff --git a/05/tcc-0.9.27/tests/pp/11.c b/05/tcc-0.9.27/tests/pp/11.c new file mode 100644 index 0000000..c0edf62 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/11.c @@ -0,0 +1,31 @@ +#define D1(s, ...) s +#define D2(s, ...) s D1(__VA_ARGS__) +#define D3(s, ...) s D2(__VA_ARGS__) +#define D4(s, ...) s D3(__VA_ARGS__) + +D1(a) +D2(a, b) +D3(a, b, c) +D4(a, b, c, d) + +x D4(a, b, c, d) y +x D4(a, b, c) y +x D4(a, b) y +x D4(a) y +x D4() y + +#define GNU_COMMA(X,Y...) X,## Y + +x GNU_COMMA(A,B,C) y +x GNU_COMMA(A,B) y +x GNU_COMMA(A) y +x GNU_COMMA() y + +#define __sun_attr___noreturn__ __attribute__((__noreturn__)) +#define ___sun_attr_inner(__a) __sun_attr_##__a +#define __sun_attr__(__a) ___sun_attr_inner __a +#define __NORETURN __sun_attr__((__noreturn__)) +__NORETURN +#define X(...) +#define Y(...) 1 __VA_ARGS__ 2 +Y(X X() ()) diff --git a/05/tcc-0.9.27/tests/pp/11.expect b/05/tcc-0.9.27/tests/pp/11.expect new file mode 100644 index 0000000..6b9806c --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/11.expect @@ -0,0 +1,15 @@ +a +a b +a b c +a b c d +x a b c d y +x a b c y +x a b y +x a y +x y +x A,B,C y +x A,B y +x A y +x y +__attribute__((__noreturn__)) +1 2 diff --git a/05/tcc-0.9.27/tests/pp/12.S b/05/tcc-0.9.27/tests/pp/12.S new file mode 100644 index 0000000..597ccb4 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/12.S @@ -0,0 +1,8 @@ +#define SRC(y...) \ + 9999: y; \ + .section __ex_table, "a"; \ + .long 9999b, 6001f ; \ + // .previous + + SRC(1: movw (%esi), %bx) +6001: diff --git a/05/tcc-0.9.27/tests/pp/12.expect b/05/tcc-0.9.27/tests/pp/12.expect new file mode 100644 index 0000000..17a861c --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/12.expect @@ -0,0 +1,2 @@ + 9999: 1: movw (%esi), %bx; .section __ex_table, "a"; .long 9999b, 6001f ; +6001: diff --git a/05/tcc-0.9.27/tests/pp/13.S b/05/tcc-0.9.27/tests/pp/13.S new file mode 100644 index 0000000..bf0b525 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/13.S @@ -0,0 +1,6 @@ +# `modelist' label. Each video mode record looks like: +#ifdef AAA +# modelist' label. Each video mode record looks like: +#endif +.text +endtext: diff --git a/05/tcc-0.9.27/tests/pp/13.expect b/05/tcc-0.9.27/tests/pp/13.expect new file mode 100644 index 0000000..c7a3230 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/13.expect @@ -0,0 +1,2 @@ +.text +endtext: diff --git a/05/tcc-0.9.27/tests/pp/14.c b/05/tcc-0.9.27/tests/pp/14.c new file mode 100644 index 0000000..e15468c --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/14.c @@ -0,0 +1,13 @@ +#define W Z +#define Z(X) W(X,2) +#define Y(X) Z(X) +#define X Y +return X(X(1)); + +#define P Q +#define Q(n) P(n,2) +return P(1); + +#define A (B * B) +#define B (A + A) +return A + B; diff --git a/05/tcc-0.9.27/tests/pp/14.expect b/05/tcc-0.9.27/tests/pp/14.expect new file mode 100644 index 0000000..3786044 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/14.expect @@ -0,0 +1,3 @@ +return Z(Z(1,2),2); +return Q(1,2); +return ((A + A) * (A + A)) + ((B * B) + (B * B)); diff --git a/05/tcc-0.9.27/tests/pp/15.c b/05/tcc-0.9.27/tests/pp/15.c new file mode 100644 index 0000000..cf13f9a --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/15.c @@ -0,0 +1,18 @@ +// insert a space between two tokens if otherwise they +// would form a single token when read back + +#define n(x) x + +return (n(long)n(double))d; +return n(A)n(++)n(+)n(B); +return n(A)n(+)n(++)n(B); +return n(A)n(++)n(+)n(+)n(B); + +// not a hex float +return n(0x1E)n(-1); + +// unlike gcc but correct +// XXX: return n(x)+n(x)-n(1)+n(1)-2; + +// unlike gcc, but cannot appear in valid C +// XXX: return n(x)n(x)n(1)n(2)n(x); diff --git a/05/tcc-0.9.27/tests/pp/15.expect b/05/tcc-0.9.27/tests/pp/15.expect new file mode 100644 index 0000000..b4f885e --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/15.expect @@ -0,0 +1,5 @@ +return (long double)d; +return A+++B; +return A+ ++B; +return A+++ +B; +return 0x1E -1; diff --git a/05/tcc-0.9.27/tests/pp/16.c b/05/tcc-0.9.27/tests/pp/16.c new file mode 100644 index 0000000..8b5b642 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/16.c @@ -0,0 +1,3 @@ +/* The following should warn */ +#define A ... +#define A <<= diff --git a/05/tcc-0.9.27/tests/pp/16.expect b/05/tcc-0.9.27/tests/pp/16.expect new file mode 100644 index 0000000..695d6d4 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/16.expect @@ -0,0 +1,2 @@ + +16.c:3: warning: A redefined diff --git a/05/tcc-0.9.27/tests/pp/17.c b/05/tcc-0.9.27/tests/pp/17.c new file mode 100644 index 0000000..f12196f --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/17.c @@ -0,0 +1,14 @@ +#define STR1(u) # u +#define pass(a) a +#define __ASM_REG(reg) STR1(one##reg) +#define _ASM_DX __ASM_REG(tok) +X162 pass(__ASM_REG(tok)) +X161 pass(_ASM_DX) +X163 pass(STR1(one##tok)) + +X170 pass(x ## y) +X171 pass(x pass(##) y) + +#define Y(x) Z(x) +#define X Y +X180 return X(X(1)); diff --git a/05/tcc-0.9.27/tests/pp/17.expect b/05/tcc-0.9.27/tests/pp/17.expect new file mode 100644 index 0000000..e95aafe --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/17.expect @@ -0,0 +1,6 @@ +X162 "onetok" +X161 "onetok" +X163 "one##tok" +X170 x ## y +X171 x ## y +X180 return Z(Z(1)); diff --git a/05/tcc-0.9.27/tests/pp/18.c b/05/tcc-0.9.27/tests/pp/18.c new file mode 100644 index 0000000..0961426 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/18.c @@ -0,0 +1,15 @@ +#define M_RETI_ARG27(x,y,z,aa, ...) aa +#define M_RET_ARG27(...) M_RETI_ARG27(__VA_ARGS__) +#define M_COMMA_P(...) M_RET_ARG27(__VA_ARGS__, 1, 1, 0, useless) +#define M_EMPTYI_DETECT(...) 0, 1, +#define M_EMPTYI_P_C1(...) M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__ () ) +#define EX +#define empty(x) +#define fnlike(x) yeah x +/* If the following macro is called with empty arg (X183), the use + of 'x' between fnlike and '(' doesn't hinder the recognition of this + being a further fnlike macro invocation. */ +#define usefnlike(x) fnlike x (x) +X181 M_EMPTYI_P_C1() +X182 M_EMPTYI_P_C1(x) +X183 usefnlike() diff --git a/05/tcc-0.9.27/tests/pp/18.expect b/05/tcc-0.9.27/tests/pp/18.expect new file mode 100644 index 0000000..447a9b2 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/18.expect @@ -0,0 +1,3 @@ +X181 1 +X182 0 +X183 yeah diff --git a/05/tcc-0.9.27/tests/pp/19.c b/05/tcc-0.9.27/tests/pp/19.c new file mode 100644 index 0000000..aa91abe --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/19.c @@ -0,0 +1,101 @@ +#define M_C2I(a, ...) a ## __VA_ARGS__ +#define M_C(a, ...) M_C2I(a, __VA_ARGS__) +#define M_C3I(a, b, ...) a ## b ## __VA_ARGS__ +#define M_C3(a, b, ...) M_C3I(a ,b, __VA_ARGS__) + +#define M_RETI_ARG2(a, b, ...) b +#define M_RET_ARG2(...) M_RETI_ARG2(__VA_ARGS__) +#define M_RETI_ARG27(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa, ...) aa +#define M_RET_ARG27(...) M_RETI_ARG27(__VA_ARGS__) + +#define M_TOBOOLI_0 1, 0, +#define M_BOOL(x) M_RET_ARG2(M_C(M_TOBOOLI_, x), 1, useless) + +#define M_IFI_0(true_macro, ...) __VA_ARGS__ +#define M_IFI_1(true_macro, ...) true_macro +#define M_IF(c) M_C(M_IFI_, M_BOOL(c)) + +#define M_FLAT(...) __VA_ARGS__ +#define M_INVI_0 1 +#define M_INVI_1 0 +#define M_INV(x) M_C(M_INVI_, x) + +#define M_ANDI_00 0 +#define M_ANDI_01 0 +#define M_ANDI_10 0 +#define M_ANDI_11 1 +#define M_AND(x,y) M_C3(M_ANDI_, x, y) + +#define M_ORI_00 0 +#define M_ORI_01 1 +#define M_ORI_10 1 +#define M_ORI_11 1 +#define M_OR(x,y) M_C3(M_ORI_, x, y) + +#define M_COMMA_P(...) M_RET_ARG27(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, useless) + +#define M_EMPTYI_DETECT(...) 0, 1, +#define M_EMPTYI_P_C1(...) M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__ ()) +#define M_EMPTYI_P_C2(...) M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__) +#define M_EMPTYI_P_C3(...) M_COMMA_P(__VA_ARGS__ () ) +#define M_EMPTY_P(...) M_AND(M_EMPTYI_P_C1(__VA_ARGS__), M_INV(M_OR(M_OR(M_EMPTYI_P_C2(__VA_ARGS__), M_COMMA_P(__VA_ARGS__)),M_EMPTYI_P_C3(__VA_ARGS__)))) +#define M_APPLY_FUNC2B(func, arg1, arg2) \ + M_IF(M_EMPTY_P(arg2))(,func(arg1, arg2)) +#define M_MAP2B_0(func, data, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,...) \ + M_APPLY_FUNC2B(func, data, a) M_APPLY_FUNC2B(func, data, b) M_APPLY_FUNC2B(func, data, c) \ + M_APPLY_FUNC2B(func, data, d) M_APPLY_FUNC2B(func, data, e) M_APPLY_FUNC2B(func, data, f) \ + M_APPLY_FUNC2B(func, data, g) M_APPLY_FUNC2B(func, data, h) M_APPLY_FUNC2B(func, data, i) \ + M_APPLY_FUNC2B(func, data, j) M_APPLY_FUNC2B(func, data, k) M_APPLY_FUNC2B(func, data, l) \ + M_APPLY_FUNC2B(func, data, m) M_APPLY_FUNC2B(func, data, n) M_APPLY_FUNC2B(func, data, o) \ + M_APPLY_FUNC2B(func, data, p) M_APPLY_FUNC2B(func, data, q) M_APPLY_FUNC2B(func, data, r) \ + M_APPLY_FUNC2B(func, data, s) M_APPLY_FUNC2B(func, data, t) M_APPLY_FUNC2B(func, data, u) \ + M_APPLY_FUNC2B(func, data, v) M_APPLY_FUNC2B(func, data, w) M_APPLY_FUNC2B(func, data, x) \ + M_APPLY_FUNC2B(func, data, y) M_APPLY_FUNC2B(func, data, z) +#define M_MAP2B(f, ...) M_MAP2B_0(f, __VA_ARGS__, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ) +#define M_INIT_INIT(a) ,a, + +#define M_GET_METHOD(method, method_default, ...) \ + M_RET_ARG2 (M_MAP2B(M_C, M_C3(M_, method, _), __VA_ARGS__), method_default,) + +#define M_TEST_METHOD_P(method, oplist) \ + M_BOOL(M_GET_METHOD (method, 0, M_FLAT oplist)) + +#define TRUE 1 +#define TEST1(n) \ + M_IF(n)(ok,nok) +#define TEST2(op) \ + M_TEST_METHOD_P(INIT, op) +#define TEST3(op) \ + M_IF(M_TEST_METHOD_P(INIT, op))(ok, nok) +#define TEST4(op) \ + TEST1(TEST2(op)) +#define KO(a) ((void)1) + +/* This checks that the various expansions that ultimately lead to + something like 'KO(arg,arg)', where 'KO' comes from a macro + expansion reducing from a large macro chain do not are regarded + as funclike macro invocation of KO. E.g. X93 and X94 expand to 'KO', + but X95 must not consume the (a,b) arguments outside the M_IF() + invocation to reduce the 'KO' macro to an invocation. Instead + X95 should reduce via M_IF(KO)(a,b) to 'a'. + + The other lines here are variations on this scheme, with X1 to + X6 coming from the bug report at + http://lists.nongnu.org/archive/html/tinycc-devel/2017-07/msg00017.html */ +X92 M_IF(KO) +X93 M_GET_METHOD(INIT, 0, INIT(KO)) +X94 M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO))) +X95 M_IF(M_GET_METHOD(INIT, 0, INIT(KO)))(a,b) +X96 M_IF(M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO)))) +X97 M_IF(M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO))))(ok,nok) +X98 (M_TEST_METHOD_P(INIT, (INIT(KO))))(ok, nok) +X99 M_IF(M_TEST_METHOD_P(INIT, (INIT(KO))))(ok, nok) +// test begins +X1 TEST1(TRUE) // ==> expect ok, get ok +// First test with a token which is not a macro +X2 TEST2((INIT(ok))) // ==> expect 1, get 1 +X3 TEST3((INIT(ok))) // ==> expect ok, get ok +// Then test with a token which is a macro, but should not be expanded. +X4 TEST2((INIT(KO))) // ==> expect 1, get 1 +X5 TEST4(INIT(KO)) +X6 TEST3((INIT(KO))) // ==> expect ok, get "error: macro 'KO' used with too many args" diff --git a/05/tcc-0.9.27/tests/pp/19.expect b/05/tcc-0.9.27/tests/pp/19.expect new file mode 100644 index 0000000..08c0858 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/19.expect @@ -0,0 +1,14 @@ +X92 M_IFI_1 +X93 KO +X94 KO +X95 a +X96 M_IFI_1 +X97 ok +X98 (1)(ok, nok) +X99 ok +X1 ok +X2 1 +X3 ok +X4 1 +X5 nok +X6 ok diff --git a/05/tcc-0.9.27/tests/pp/20.c b/05/tcc-0.9.27/tests/pp/20.c new file mode 100644 index 0000000..7944d62 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/20.c @@ -0,0 +1,13 @@ +/* Various things I encountered while hacking the pre processor */ +#define wrap(x) x +#define pr_warning(fmt, ...) printk(KERN_WARNING fmt, ##__VA_ARGS__) +#define pr_warn(x,y) pr_warning(x,y) +#define net_ratelimited_function(function, ...) function(__VA_ARGS__) +X1 net_ratelimited_function(pr_warn, "pipapo", bla); +X2 net_ratelimited_function(wrap(pr_warn), "bla", foo); +#define two m n +#define chain4(a,b,c,d) a ## b ## c ## d +X2 chain4(two,o,p,q) +X3 chain4(o,two,p,q) +X4 chain4(o,p,two,q) +X5 chain4(o,p,q,two) diff --git a/05/tcc-0.9.27/tests/pp/20.expect b/05/tcc-0.9.27/tests/pp/20.expect new file mode 100644 index 0000000..d19405d --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/20.expect @@ -0,0 +1,6 @@ +X1 printk(KERN_WARNING "pipapo",bla); +X2 printk(KERN_WARNING "bla",foo); +X2 twoopq +X3 otwopq +X4 optwoq +X5 opqtwo diff --git a/05/tcc-0.9.27/tests/pp/21.c b/05/tcc-0.9.27/tests/pp/21.c new file mode 100644 index 0000000..1316226 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/21.c @@ -0,0 +1,36 @@ +/* accept 'defined' as result of substitution */ + +----- 1 ------ +#define AAA 2 +#define BBB +#define CCC (defined ( AAA ) && AAA > 1 && !defined BBB) +#if !CCC +OK +#else +NOT OK +#endif + +----- 2 ------ +#undef BBB +#if CCC +OK +#else +NOT OK +#endif + +----- 3 ------ +#define DEFINED defined +#define DDD (DEFINED ( AAA ) && AAA > 1 && !DEFINED BBB) +#if (DDD) +OK +#else +NOT OK +#endif + +----- 4 ------ +#undef AAA +#if !(DDD) +OK +#else +NOT OK +#endif diff --git a/05/tcc-0.9.27/tests/pp/21.expect b/05/tcc-0.9.27/tests/pp/21.expect new file mode 100644 index 0000000..5a1376b --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/21.expect @@ -0,0 +1,8 @@ +----- 1 ------ +OK +----- 2 ------ +OK +----- 3 ------ +OK +----- 4 ------ +OK diff --git a/05/tcc-0.9.27/tests/pp/Makefile b/05/tcc-0.9.27/tests/pp/Makefile new file mode 100644 index 0000000..687aa52 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/Makefile @@ -0,0 +1,49 @@ +# +# credits: 01..13.c from the pcc cpp-tests suite +# + +TOP = ../.. +include $(TOP)/Makefile +SRC = $(TOPSRC)/tests/pp +VPATH = $(SRC) + +files = $(patsubst %.$1,%.test,$(notdir $(wildcard $(SRC)/*.$1))) +TESTS = $(call files,c) $(call files,S) + +all test : $(sort $(TESTS)) + +DIFF_OPTS = -Nu -b -B + +# Filter source directory in warnings/errors (out-of-tree builds) +FILTER = 2>&1 | sed 's,$(SRC)/,,g' + +%.test: %.c %.expect + @echo PPTest $* ... + -@$(TCC) -E -P $< $(FILTER) >$*.output 2>&1 ; \ + diff $(DIFF_OPTS) $(SRC)/$*.expect $*.output \ + && rm -f $*.output + +%.test: %.S %.expect + @echo PPTest $* ... + -@$(TCC) -E -P $< $(FILTER) >$*.output 2>&1 ; \ + diff $(DIFF_OPTS) $(SRC)/$*.expect $*.output \ + && rm -f $*.output + +# automatically generate .expect files with gcc: +%.expect: # %.c + gcc -E -P $*.[cS] >$*.expect 2>&1 + +# tell make not to delete +.PRECIOUS: %.expect + +clean: + rm -f *.output + +02.test : DIFF_OPTS += -w +# 15.test : DIFF_OPTS += -I"^XXX:" + +# diff options: +# -b ighore space changes +# -w ighore all whitespace +# -B ignore blank lines +# -I <RE> ignore lines matching RE diff --git a/05/tcc-0.9.27/tests/pp/pp-counter.c b/05/tcc-0.9.27/tests/pp/pp-counter.c new file mode 100644 index 0000000..3978e1a --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/pp-counter.c @@ -0,0 +1,27 @@ +X1 __COUNTER__ +X2 __COUNTER__ +#if __COUNTER__ +X3 __COUNTER__ +#endif +#define pass(x) x +#define a x __COUNTER__ y +#define a2 pass(__COUNTER__) +#define f(c) c __COUNTER__ +#define apply(d) d d __COUNTER__ x2 f(d) y2 __COUNTER__ +#define _paste(a,b) a ## b +#define paste(a,b) _paste(a,b) +#define _paste3(a,b,c) a ## b ## c +#define doublepaste(a,b) _paste3(a,b,b) +#define str(x) #x +X4 a +X5 f(a) +X6 f(b) +X7 f(__COUNTER__) +X8 apply(a) +X9 apply(f(a)) +X10 apply(__COUNTER__) +X11 apply(a2) +X12 str(__COUNTER__) +X13 paste(x,__COUNTER__) +X14 _paste(x,__COUNTER__) +X15 doublepaste(x,__COUNTER__) diff --git a/05/tcc-0.9.27/tests/pp/pp-counter.expect b/05/tcc-0.9.27/tests/pp/pp-counter.expect new file mode 100644 index 0000000..02fc535 --- /dev/null +++ b/05/tcc-0.9.27/tests/pp/pp-counter.expect @@ -0,0 +1,15 @@ +X1 0 +X2 1 +X3 3 +X4 x 4 y +X5 x 5 y 6 +X6 b 7 +X7 8 9 +X8 x 10 y x 10 y 11 x2 x 10 y 12 y2 13 +X9 x 14 y 15 x 14 y 15 16 x2 x 14 y 15 17 y2 18 +X10 19 19 20 x2 19 21 y2 22 +X11 23 23 24 x2 23 25 y2 26 +X12 "__COUNTER__" +X13 x27 +X14 x__COUNTER__ +X15 x2828 diff --git a/05/tcc-0.9.27/tests/tcctest.c b/05/tcc-0.9.27/tests/tcctest.c new file mode 100644 index 0000000..57670be --- /dev/null +++ b/05/tcc-0.9.27/tests/tcctest.c @@ -0,0 +1,3871 @@ +/* + * TCC auto test program + */ +#include "config.h" + +#if GCC_MAJOR >= 3 + +/* Unfortunately, gcc version < 3 does not handle that! */ +#define ALL_ISOC99 + +/* only gcc 3 handles _Bool correctly */ +#define BOOL_ISOC99 + +/* gcc 2.95.3 does not handle correctly CR in strings or after strays */ +#define CORRECT_CR_HANDLING + +#endif + +#if defined(_WIN32) +#define LONG_LONG_FORMAT "%lld" +#define ULONG_LONG_FORMAT "%llu" +#else +#define LONG_LONG_FORMAT "%Ld" +#define ULONG_LONG_FORMAT "%Lu" +#endif + +// MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC +#if defined(_WIN32) && defined(__GNUC__) +#define LONG_DOUBLE double +#define LONG_DOUBLE_LITERAL(x) x +#else +#define LONG_DOUBLE long double +#define LONG_DOUBLE_LITERAL(x) x ## L +#endif + +/* deprecated and no longer supported in gcc 3.3 */ +//#define ACCEPT_CR_IN_STRINGS + +/* __VA_ARGS__ and __func__ support */ +#define C99_MACROS + +/* test various include syntaxes */ + +#define TCCLIB_INC <tcclib.h> +#define TCCLIB_INC1 <tcclib +#define TCCLIB_INC2 h> +#define TCCLIB_INC3 "tcclib.h" + +#include TCCLIB_INC + +#include TCCLIB_INC1.TCCLIB_INC2 + +#include TCCLIB_INC1.h> + +#include TCCLIB_INC3 + +#include <tcclib.h> + +#include "tcclib.h" + +#include "tcctest.h" + +/* Test two more ways to include a file named like a pp-number */ +#define INC(name) <tests/name.h> +#define funnyname 42test.h +#define incdir tests/ +#define incname < incdir funnyname > +#define __stringify(x) #x +#define stringify(x) __stringify(x) +#include INC(42test) +#include incname +#include stringify(funnyname) + +void intdiv_test(); +void string_test(); +void expr_test(); +void macro_test(); +void recursive_macro_test(); +void scope_test(); +void forward_test(); +void funcptr_test(); +void loop_test(); +void switch_test(); +void goto_test(); +void enum_test(); +void typedef_test(); +void struct_test(); +void array_test(); +void expr_ptr_test(); +void bool_test(); +void optimize_out(); +void expr2_test(); +void constant_expr_test(); +void expr_cmp_test(); +void char_short_test(); +void init_test(void); +void compound_literal_test(void); +int kr_test(); +void struct_assign_test(void); +void cast_test(void); +void bitfield_test(void); +void c99_bool_test(void); +void float_test(void); +void longlong_test(void); +void manyarg_test(void); +void stdarg_test(void); +void whitespace_test(void); +void relocation_test(void); +void old_style_function(void); +void alloca_test(void); +void c99_vla_test(int size1, int size2); +void sizeof_test(void); +void typeof_test(void); +void local_label_test(void); +void statement_expr_test(void); +void asm_test(void); +void builtin_test(void); +void weak_test(void); +void global_data_test(void); +void cmp_comparison_test(void); +void math_cmp_test(void); +void callsave_test(void); +void builtin_frame_address_test(void); +void attrib_test(void); + +int fib(int n); +void num(int n); +void forward_ref(void); +int isid(int c); + +/* Line joining happens before tokenization, so the following + must be parsed as ellipsis. */ +void funny_line_continuation (int, ..\ +. ); + +char via_volatile (char); + +#define A 2 +#define N 1234 + A +#define pf printf +#define M1(a, b) (a) + (b) + +#define str\ +(s) # s +#define glue(a, b) a ## b +#define xglue(a, b) glue(a, b) +#define HIGHLOW "hello" +#define LOW LOW ", world" + +static int onetwothree = 123; +#define onetwothree4 onetwothree +#define onetwothree xglue(onetwothree,4) + +#define min(a, b) ((a) < (b) ? (a) : (b)) + +#ifdef C99_MACROS +#define dprintf(level,...) printf(__VA_ARGS__) +#endif + +/* gcc vararg macros */ +#define dprintf1(level, fmt, args...) printf(fmt, ## args) + +#define MACRO_NOARGS() + +#define AAA 3 +#undef AAA +#define AAA 4 + +#if 1 +#define B3 1 +#elif 1 +#define B3 2 +#elif 0 +#define B3 3 +#else +#define B3 4 +#endif + +#ifdef __TINYC__ +/* We try to handle this syntax. Make at least sure it doesn't segfault. */ +char invalid_function_def()[] {} +#endif + +#define __INT64_C(c) c ## LL +#define INT64_MIN (-__INT64_C(9223372036854775807)-1) + +int qq(int x) +{ + return x + 40; +} +#define qq(x) x + +#define spin_lock(lock) do { } while (0) +#define wq_spin_lock spin_lock +#define TEST2() wq_spin_lock(a) + +#define UINT_MAX ((unsigned) -1) + +void intdiv_test(void) +{ + printf("18/21=%u\n", 18/21); + printf("18%%21=%u\n", 18%21); + printf("41/21=%u\n", 41/21); + printf("41%%21=%u\n", 41%21); + printf("42/21=%u\n", 42/21); + printf("42%%21=%u\n", 42%21); + printf("43/21=%u\n", 43/21); + printf("43%%21=%u\n", 43%21); + printf("126/21=%u\n", 126/21); + printf("126%%21=%u\n", 126%21); + printf("131/21=%u\n", 131/21); + printf("131%%21=%u\n", 131%21); + printf("(UINT_MAX/2+3)/2=%u\n", (UINT_MAX/2+3)/2); + printf("(UINT_MAX/2+3)%%2=%u\n", (UINT_MAX/2+3)%2); + + printf("18/-21=%u\n", 18/-21); + printf("18%%-21=%u\n", 18%-21); + printf("41/-21=%u\n", 41/-21); + printf("41%%-21=%u\n", 41%-21); + printf("42/-21=%u\n", 42/-21); + printf("42%%-21=%u\n", 42%-21); + printf("43/-21=%u\n", 43/-21); + printf("43%%-21=%u\n", 43%-21); + printf("126/-21=%u\n", 126/-21); + printf("126%%-21=%u\n", 126%-21); + printf("131/-21=%u\n", 131/-21); + printf("131%%-21=%u\n", 131%-21); + printf("(UINT_MAX/2+3)/-2=%u\n", (UINT_MAX/2+3)/-2); + printf("(UINT_MAX/2+3)%%-2=%u\n", (UINT_MAX/2+3)%-2); + + printf("-18/21=%u\n", -18/21); + printf("-18%%21=%u\n", -18%21); + printf("-41/21=%u\n", -41/21); + printf("-41%%21=%u\n", -41%21); + printf("-42/21=%u\n", -42/21); + printf("-42%%21=%u\n", -42%21); + printf("-43/21=%u\n", -43/21); + printf("-43%%21=%u\n", -43%21); + printf("-126/21=%u\n", -126/21); + printf("-126%%21=%u\n", -126%21); + printf("-131/21=%u\n", -131/21); + printf("-131%%21=%u\n", -131%21); + printf("-(UINT_MAX/2+3)/2=%u\n", (0-(UINT_MAX/2+3))/2); + printf("-(UINT_MAX/2+3)%%2=%u\n", (0-(UINT_MAX/2+3))%2); + + printf("-18/-21=%u\n", -18/-21); + printf("-18%%-21=%u\n", -18%-21); + printf("-41/-21=%u\n", -41/-21); + printf("-41%%-21=%u\n", -41%-21); + printf("-42/-21=%u\n", -42/-21); + printf("-42%%-21=%u\n", -42%-21); + printf("-43/-21=%u\n", -43/-21); + printf("-43%%-21=%u\n", -43%-21); + printf("-126/-21=%u\n", -126/-21); + printf("-126%%-21=%u\n", -126%-21); + printf("-131/-21=%u\n", -131/-21); + printf("-131%%-21=%u\n", -131%-21); + printf("-(UINT_MAX/2+3)/-2=%u\n", (0-(UINT_MAX/2+3))/-2); + printf("-(UINT_MAX/2+3)%%-2=%u\n", (0-(UINT_MAX/2+3))%-2); +} + +void macro_test(void) +{ + printf("macro:\n");
+ pf("N=%d\n", N); + printf("aaa=%d\n", AAA); + + printf("min=%d\n", min(1, min(2, -1))); + + printf("s1=%s\n", glue(HIGH, LOW)); + printf("s2=%s\n", xglue(HIGH, LOW)); + printf("s3=%s\n", str("c")); + printf("s4=%s\n", str(a1)); + printf("B3=%d\n", B3); + + printf("onetwothree=%d\n", onetwothree); + +#ifdef A + printf("A defined\n"); +#endif +#ifdef B + printf("B defined\n"); +#endif +#ifdef A + printf("A defined\n"); +#else + printf("A not defined\n"); +#endif +#ifdef B + printf("B defined\n"); +#else + printf("B not defined\n"); +#endif + +#ifdef A + printf("A defined\n"); +#ifdef B + printf("B1 defined\n"); +#else + printf("B1 not defined\n"); +#endif +#else + printf("A not defined\n"); +#ifdef B + printf("B2 defined\n"); +#else + printf("B2 not defined\n"); +#endif +#endif + +#if 1+1 + printf("test true1\n"); +#endif +#if 0 + printf("test true2\n"); +#endif +#if 1-1 + printf("test true3\n"); +#endif +#if defined(A) + printf("test trueA\n"); +#endif +#if defined(B) + printf("test trueB\n"); +#endif + +#if 0 + printf("test 0\n"); +#elif 0 + printf("test 1\n"); +#elif 2 + printf("test 2\n"); +#else + printf("test 3\n"); +#endif + + MACRO_NOARGS(); + +#ifdef __LINE__ + printf("__LINE__ defined\n"); +#endif + + printf("__LINE__=%d __FILE__=%s\n", + __LINE__, __FILE__); +#if 0 +#line 200 + printf("__LINE__=%d __FILE__=%s\n", + __LINE__, __FILE__); +#line 203 "test" + printf("__LINE__=%d __FILE__=%s\n", + __LINE__, __FILE__); +#line 227 "tcctest.c" +#endif + + /* not strictly preprocessor, but we test it there */ +#ifdef C99_MACROS + printf("__func__ = %s\n", __func__); + dprintf(1, "vaarg=%d\n", 1); +#endif + dprintf1(1, "vaarg1\n"); + dprintf1(1, "vaarg1=%d\n", 2); + dprintf1(1, "vaarg1=%d %d\n", 1, 2); + + /* gcc extension */ + printf("func='%s'\n", __FUNCTION__); + + /* complicated macros in glibc */ + printf("INT64_MIN=" LONG_LONG_FORMAT "\n", INT64_MIN); + { + int a; + a = 1; + glue(a+, +); + printf("a=%d\n", a); + glue(a <, <= 2); + printf("a=%d\n", a); + } + + /* macro function with argument outside the macro string */ +#define MF_s MF_hello +#define MF_hello(msg) printf("%s\n",msg) + +#define MF_t printf("tralala\n"); MF_hello + + MF_s("hi"); + MF_t("hi"); + + /* test macro substitution inside args (should not eat stream) */ + printf("qq=%d\n", qq(qq)(2)); + + /* test zero argument case. NOTE: gcc 2.95.x does not accept a + null argument without a space. gcc 3.2 fixes that. */ + +#define qq1(x) 1 + printf("qq1=%d\n", qq1( )); + + /* comment with stray handling *\ +/ + /* this is a valid *\/ comment */ + /* this is a valid comment *\*/ + // this is a valid\ +comment + + /* test function macro substitution when the function name is + substituted */ + TEST2(); + + /* And again when the name and parentheses are separated by a + comment. */ + TEST2 /* the comment */ (); + + printf("%s\n", get_basefile_from_header()); + printf("%s\n", __BASE_FILE__); + printf("%s\n", get_file_from_header()); + printf("%s\n", __FILE__); + + /* Check that funnily named include was in fact included */ + have_included_42test_h = 1; + have_included_42test_h_second = 1; + have_included_42test_h_third = 1; +} + + +static void print_num(char *fn, int line, int num) { + printf("fn %s, line %d, num %d\n", fn, line, num); +} + +void recursive_macro_test(void) +{ + +#define ELF32_ST_TYPE(val) ((val) & 0xf) +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) +#define STB_WEAK 2 /* Weak symbol */ +#define ELFW(type) ELF##32##_##type + printf("%d\n", ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(123))); + +#define WRAP(x) x + +#define print_num(x) print_num(__FILE__,__LINE__,x) + print_num(123); + WRAP(print_num(123)); + WRAP(WRAP(print_num(123))); + +static struct recursive_macro { int rm_field; } G; +#define rm_field (G.rm_field) + printf("rm_field = %d\n", rm_field); + printf("rm_field = %d\n", WRAP(rm_field)); + WRAP((printf("rm_field = %d %d\n", rm_field, WRAP(rm_field)))); +} + +int op(a,b) +{ + return a / b; +} + +int ret(a) +{ + if (a == 2) + return 1; + if (a == 3) + return 2; + return 0; +} + +void ps(const char *s) +{ + int c; + while (1) { + c = *s; + if (c == 0) + break; + printf("%c", c); + s++; + } +} + +const char foo1_string[] = "\ +bar\n\ +test\14\ +1"; + +void string_test() +{ + unsigned int b; + printf("string:\n"); + printf("\141\1423\143\n");/* dezdez 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'); + printf("foo1_string='%s'\n", foo1_string); +#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) { + printf("%c", b); + } + printf("\n"); + printf("fib=%d\n", fib(33)); + b = 262144; + while (b != 0x80000000) { + num(b); + b = b * 2; + } +} + +void loop_test() +{ + int i; + i = 0; + while (i < 10) + printf("%d", i++); + printf("\n"); + for(i = 0; i < 10;i++) + printf("%d", i); + printf("\n"); + i = 0; + do { + printf("%d", i++); + } while (i < 10); + printf("\n"); + + char count = 123; + /* c99 for loop init test */ + for (size_t count = 1; count < 3; count++) + printf("count=%d\n", count); + printf("count = %d\n", count); + + /* break/continue tests */ + i = 0; + while (1) { + if (i == 6) + break; + i++; + if (i == 3) + continue; + printf("%d", i); + } + printf("\n"); + + /* break/continue tests */ + i = 0; + do { + if (i == 6) + break; + i++; + if (i == 3) + continue; + printf("%d", i); + } while(1); + printf("\n"); + + for(i = 0;i < 10;i++) { + if (i == 3) + continue; + printf("%d", i); + } + printf("\n"); +} + +typedef int typedef_and_label; + +void goto_test() +{ + int i; + static void *label_table[3] = { &&label1, &&label2, &&label3 }; + + printf("goto:\n"); + i = 0; + /* This needs to parse as label, not as start of decl. */ + typedef_and_label: + s_loop: + if (i >= 10) + goto s_end; + printf("%d", i); + i++; + goto s_loop; + s_end: + printf("\n"); + + /* we also test computed gotos (GCC extension) */ + for(i=0;i<3;i++) { + goto *label_table[i]; + label1: + printf("label1\n"); + goto next; + label2: + printf("label2\n"); + goto next; + label3: + printf("label3\n"); + next: ; + } +} + +enum { + E0, + E1 = 2, + E2 = 4, + E3, + E4, +}; + +enum test { + E5 = 1000, +}; + +struct S_enum { + enum {E6 = 42, E7, E8} e:8; +}; + +enum ELong { + /* This is either 0 on L32 machines, or a large number + on L64 machines. We should be able to store this. */ + EL_large = ((unsigned long)0xf000 << 31) << 1, +}; + +enum { BIASU = -1U<<31 }; +enum { BIASS = -1 << 31 }; + +static int getint(int i) +{ + if (i) + return 0; + else + return (int)(-1U << 31); +} + +void enum_test() +{ + enum test b1; + /* The following should give no warning */ + unsigned *p = &b1; + struct S_enum s = {E7}; + printf("enum: %d\n", s.e); + printf("enum:\n%d %d %d %d %d %d\n", + E0, E1, E2, E3, E4, E5); + b1 = 1; + printf("b1=%d\n", b1); + printf("enum large: %ld\n", EL_large); + + if (getint(0) == BIASU) + printf("enum unsigned: ok\n"); + else + printf("enum unsigned: wrong\n"); + if (getint(0) == BIASS) + printf("enum unsigned: ok\n"); + else + printf("enum unsigned: wrong\n"); +} + +typedef int *my_ptr; + +typedef int mytype1; +typedef int mytype2; + +void typedef_test() +{ + my_ptr a; + mytype1 mytype2; + int b; + + a = &b; + *a = 1234; + printf("typedef:\n"); + printf("a=%d\n", *a); + mytype2 = 2; + printf("mytype2=%d\n", mytype2); +} + +void forward_test() +{ + printf("forward:\n"); + forward_ref(); + forward_ref(); +} + + +void forward_ref(void) +{ + printf("forward ok\n"); +} + +typedef struct struct1 { + int f1; + int f2, f3; + union union1 { + int v1; + int v2; + } u; + char str[3]; +} struct1; + +struct struct2 { + int a; + char b; +}; + +union union2 { + int w1; + int w2; +}; + +struct struct1 st1, st2; + +struct empty_mem { + /* nothing */ ; + int x; +}; + +int main(int argc, char **argv) +{ + string_test(); + expr_test(); + macro_test(); + recursive_macro_test(); + scope_test(); + forward_test(); + funcptr_test(); + loop_test(); + switch_test(); + goto_test(); + enum_test(); + typedef_test(); + struct_test(); + array_test(); + expr_ptr_test(); + bool_test(); + optimize_out(); + expr2_test(); + constant_expr_test(); + expr_cmp_test(); + char_short_test(); + init_test(); + compound_literal_test(); + kr_test(); + struct_assign_test(); + cast_test(); + bitfield_test(); + c99_bool_test(); + float_test(); + longlong_test(); + manyarg_test(); + stdarg_test(); + whitespace_test(); + relocation_test(); + old_style_function(); + alloca_test(); + c99_vla_test(5, 2); + sizeof_test(); + typeof_test(); + statement_expr_test(); + local_label_test(); + asm_test(); + builtin_test(); +#ifndef _WIN32 + weak_test(); +#endif + global_data_test(); + cmp_comparison_test(); + math_cmp_test(); + callsave_test(); + builtin_frame_address_test(); + intdiv_test(); + if (via_volatile (42) != 42) + printf ("via_volatile broken\n"); + attrib_test(); + return 0; +} + +int tab[3]; +int tab2[3][2]; + +int g; + +void f1(g) +{ + printf("g1=%d\n", g); +} + +void scope_test() +{ + printf("scope:\n"); + g = 2; + f1(1); + printf("g2=%d\n", g); + { + int g; + g = 3; + printf("g3=%d\n", g); + { + int g; + g = 4; + printf("g4=%d\n", g); + } + } + printf("g5=%d\n", g); +} + +void array_test() +{ + int i, j, a[4]; + + printf("array:\n"); + printf("sizeof(a) = %d\n", sizeof(a)); + printf("sizeof(\"a\") = %d\n", sizeof("a")); +#ifdef C99_MACROS + printf("sizeof(__func__) = %d\n", sizeof(__func__)); +#endif + printf("sizeof tab %d\n", sizeof(tab)); + printf("sizeof tab2 %d\n", sizeof tab2); + tab[0] = 1; + tab[1] = 2; + tab[2] = 3; + printf("%d %d %d\n", tab[0], tab[1], tab[2]); + for(i=0;i<3;i++) + for(j=0;j<2;j++) + tab2[i][j] = 10 * i + j; + for(i=0;i<3*2;i++) { + printf(" %3d", ((int *)tab2)[i]); + } + printf("\n"); + printf("sizeof(size_t)=%d\n", sizeof(size_t)); + printf("sizeof(ptrdiff_t)=%d\n", sizeof(ptrdiff_t)); +} + +void expr_test() +{ + int a, b; + a = 0; + printf("%d\n", a += 1); + printf("%d\n", a -= 2); + printf("%d\n", a *= 31232132); + printf("%d\n", a /= 4); + printf("%d\n", a %= 20); + printf("%d\n", a &= 6); + printf("%d\n", a ^= 7); + printf("%d\n", a |= 8); + printf("%d\n", a >>= 3); + printf("%d\n", a <<= 4); + + a = 22321; + b = -22321; + printf("%d\n", a + 1); + printf("%d\n", a - 2); + printf("%d\n", a * 312); + printf("%d\n", a / 4); + printf("%d\n", b / 4); + printf("%d\n", (unsigned)b / 4); + printf("%d\n", a % 20); + printf("%d\n", b % 20); + printf("%d\n", (unsigned)b % 20); + printf("%d\n", a & 6); + printf("%d\n", a ^ 7); + printf("%d\n", a | 8); + printf("%d\n", a >> 3); + printf("%d\n", b >> 3); + printf("%d\n", (unsigned)b >> 3); + printf("%d\n", a << 4); + printf("%d\n", ~a); + printf("%d\n", -a); + printf("%d\n", +a); + + printf("%d\n", 12 + 1); + printf("%d\n", 12 - 2); + printf("%d\n", 12 * 312); + printf("%d\n", 12 / 4); + printf("%d\n", 12 % 20); + printf("%d\n", 12 & 6); + printf("%d\n", 12 ^ 7); + printf("%d\n", 12 | 8); + printf("%d\n", 12 >> 2); + printf("%d\n", 12 << 4); + printf("%d\n", ~12); + printf("%d\n", -12); + printf("%d\n", +12); + printf("%d %d %d %d\n", + isid('a'), + isid('g'), + isid('T'), + isid('(')); +} + +int isid(int c) +{ + return (c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z') | c == '_'; +} + +/**********************/ + +int vstack[10], *vstack_ptr; + +void vpush(int vt, int vc) +{ + *vstack_ptr++ = vt; + *vstack_ptr++ = vc; +} + +void vpop(int *ft, int *fc) +{ + *fc = *--vstack_ptr; + *ft = *--vstack_ptr; +} + +void expr2_test() +{ + int a, b; + + printf("expr2:\n"); + vstack_ptr = vstack; + vpush(1432432, 2); + vstack_ptr[-2] &= ~0xffffff80; + vpop(&a, &b); + printf("res= %d %d\n", a, b); +} + +void constant_expr_test() +{ + int a; + printf("constant_expr:\n"); + a = 3; + printf("%d\n", a * 16); + printf("%d\n", a * 1); + printf("%d\n", a + 0); +} + +int tab4[10]; + +void expr_ptr_test() +{ + int *p, *q; + int i = -1; + + printf("expr_ptr:\n"); + p = tab4; + q = tab4 + 10; + printf("diff=%d\n", q - p); + p++; + printf("inc=%d\n", p - tab4); + p--; + printf("dec=%d\n", p - tab4); + ++p; + printf("inc=%d\n", p - tab4); + --p; + printf("dec=%d\n", p - tab4); + printf("add=%d\n", p + 3 - tab4); + printf("add=%d\n", 3 + p - tab4); + + /* check if 64bit support is ok */ + q = p = 0; + q += i; + printf("%p %p %ld\n", q, p, p-q); + printf("%d %d %d %d %d %d\n", + p == q, p != q, p < q, p <= q, p >= q, p > q); + i = 0xf0000000; + p += i; + printf("%p %p %ld\n", q, p, p-q); + printf("%d %d %d %d %d %d\n", + p == q, p != q, p < q, p <= q, p >= q, p > q); + p = (int *)((char *)p + 0xf0000000); + printf("%p %p %ld\n", q, p, p-q); + printf("%d %d %d %d %d %d\n", + p == q, p != q, p < q, p <= q, p >= q, p > q); + p += 0xf0000000; + printf("%p %p %ld\n", q, p, p-q); + printf("%d %d %d %d %d %d\n", + p == q, p != q, p < q, p <= q, p >= q, p > q); + { + struct size12 { + int i, j, k; + }; + struct size12 s[2], *sp = s; + int i, j; + sp->i = 42; + sp++; + j = -1; + printf("%d\n", sp[j].i); + } +#ifdef __LP64__ + i = 1; + p = (int*)0x100000000UL + i; + i = ((long)p) >> 32; + printf("largeptr: %p %d\n", p, i); +#endif +} + +void expr_cmp_test() +{ + int a, b; + printf("constant_expr:\n"); + a = -1; + b = 1; + printf("%d\n", a == a); + printf("%d\n", a != a); + + printf("%d\n", a < b); + printf("%d\n", a <= b); + printf("%d\n", a <= a); + printf("%d\n", b >= a); + printf("%d\n", a >= a); + printf("%d\n", b > a); + + printf("%d\n", (unsigned)a < b); + printf("%d\n", (unsigned)a <= b); + printf("%d\n", (unsigned)a <= a); + printf("%d\n", (unsigned)b >= a); + printf("%d\n", (unsigned)a >= a); + 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]; +}; + +struct __attribute__((aligned(16))) aligntest5 +{ + int i; +}; +struct aligntest6 +{ + int i; +} __attribute__((aligned(16))); +struct aligntest7 +{ + int i; +}; +struct aligntest5 altest5[2]; +struct aligntest6 altest6[2]; +int pad1; +/* altest7 is correctly aligned to 16 bytes also with TCC, + but __alignof__ returns the wrong result (4) because we + can't store the alignment yet when specified on symbols + directly (it's stored in the type so we'd need to make + a copy of it). -- FIXED */ +struct aligntest7 altest7[2] __attribute__((aligned(16))); + +struct aligntest8 +{ + int i; +} __attribute__((aligned(4096))); + +struct Large { + unsigned long flags; + union { + void *u1; + int *u2; + }; + + struct { + union { + unsigned long index; + void *freelist; + }; + union { + unsigned long counters; + struct { + int bla; + }; + }; + }; + + union { + struct { + long u3; + long u4; + }; + void *u5; + struct { + unsigned long compound_head; + unsigned int compound_dtor; + unsigned int compound_order; + }; + }; +} __attribute__((aligned(2 * sizeof(long)))); + +typedef unsigned long long __attribute__((aligned(4))) unaligned_u64; + +struct aligntest9 { + unsigned int buf_nr; + unaligned_u64 start_lba; +}; + +struct aligntest10 { + unsigned int buf_nr; + unsigned long long start_lba; +}; + +void struct_test() +{ + struct1 *s; + union union2 u; + struct Large ls; + + printf("struct:\n"); + printf("sizes: %d %d %d %d\n", + sizeof(struct struct1), + sizeof(struct struct2), + sizeof(union union1), + sizeof(union union2)); + printf("offsets: %d\n", (int)((char*)&st1.u.v1 - (char*)&st1)); + st1.f1 = 1; + st1.f2 = 2; + st1.f3 = 3; + printf("st1: %d %d %d\n", + st1.f1, st1.f2, st1.f3); + st1.u.v1 = 1; + st1.u.v2 = 2; + printf("union1: %d\n", st1.u.v1); + u.w1 = 1; + u.w2 = 2; + printf("union2: %d\n", u.w1); + s = &st2; + s->f1 = 3; + s->f2 = 2; + s->f3 = 1; + 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)); + printf("aligntest5 sizeof=%d alignof=%d\n", + sizeof(struct aligntest5), __alignof__(struct aligntest5)); + printf("aligntest6 sizeof=%d alignof=%d\n", + sizeof(struct aligntest6), __alignof__(struct aligntest6)); + printf("aligntest7 sizeof=%d alignof=%d\n", + sizeof(struct aligntest7), __alignof__(struct aligntest7)); + printf("aligntest8 sizeof=%d alignof=%d\n", + sizeof(struct aligntest8), __alignof__(struct aligntest8)); + printf("aligntest9 sizeof=%d alignof=%d\n", + sizeof(struct aligntest9), __alignof__(struct aligntest9)); + printf("aligntest10 sizeof=%d alignof=%d\n", + sizeof(struct aligntest10), __alignof__(struct aligntest10)); + printf("altest5 sizeof=%d alignof=%d\n", + sizeof(altest5), __alignof__(altest5)); + printf("altest6 sizeof=%d alignof=%d\n", + sizeof(altest6), __alignof__(altest6)); + printf("altest7 sizeof=%d alignof=%d\n", + sizeof(altest7), __alignof__(altest7)); + + /* empty structures (GCC extension) */ + printf("sizeof(struct empty) = %d\n", sizeof(struct empty)); + printf("alignof(struct empty) = %d\n", __alignof__(struct empty)); + + printf("Large: sizeof=%d\n", sizeof(ls)); + memset(&ls, 0, sizeof(ls)); + ls.compound_head = 42; + printf("Large: offsetof(compound_head)=%d\n", (int)((char*)&ls.compound_head - (char*)&ls)); +} + +/* XXX: depend on endianness */ +void char_short_test() +{ + int var1, var2; + + printf("char_short:\n"); + + var1 = 0x01020304; + var2 = 0xfffefdfc; + printf("s8=%d %d\n", + *(char *)&var1, *(char *)&var2); + printf("u8=%d %d\n", + *(unsigned char *)&var1, *(unsigned char *)&var2); + printf("s16=%d %d\n", + *(short *)&var1, *(short *)&var2); + printf("u16=%d %d\n", + *(unsigned short *)&var1, *(unsigned short *)&var2); + printf("s32=%d %d\n", + *(int *)&var1, *(int *)&var2); + printf("u32=%d %d\n", + *(unsigned int *)&var1, *(unsigned int *)&var2); + *(char *)&var1 = 0x08; + printf("var1=%x\n", var1); + *(short *)&var1 = 0x0809; + printf("var1=%x\n", var1); + *(int *)&var1 = 0x08090a0b; + printf("var1=%x\n", var1); +} + +/******************/ + +typedef struct Sym { + int v; + int t; + int c; + struct Sym *next; + 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); +} + +static unsigned int calc_vm_flags(unsigned int prot) +{ + unsigned int prot_bits; + /* This used to segfault in some revisions: */ + prot_bits = ((0x1==0x00000001)?(prot&0x1):(prot&0x1)?0x00000001:0); + return prot_bits; +} + +void bool_test() +{ + int *s, a, b, t, f, i; + + a = 0; + s = (void*)0; + printf("!s=%d\n", !s); + + if (!s || !s[0]) + a = 1; + printf("a=%d\n", a); + + printf("a=%d %d %d\n", 0 || 0, 0 || 1, 1 || 1); + printf("a=%d %d %d\n", 0 && 0, 0 && 1, 1 && 1); + printf("a=%d %d\n", 1 ? 1 : 0, 0 ? 1 : 0); +#if 1 && 1 + printf("a1\n"); +#endif +#if 1 || 0 + printf("a2\n"); +#endif +#if 1 ? 0 : 1 + printf("a3\n"); +#endif +#if 0 ? 0 : 1 + printf("a4\n"); +#endif + + a = 4; + printf("b=%d\n", a + (0 ? 1 : a / 2)); + + /* test register spilling */ + a = 10; + b = 10; + a = (a + b) * ((a < b) ? + ((b - a) * (a - b)): a + b); + printf("a=%d\n", a); + + /* test complex || or && expressions */ + t = 1; + f = 0; + a = 32; + printf("exp=%d\n", f == (32 <= a && a <= 3)); + printf("r=%d\n", (t || f) + (t && f)); + + /* test ? : cast */ + { + int aspect_on; + int aspect_native = 65536; + double bfu_aspect = 1.0; + int aspect; + for(aspect_on = 0; aspect_on < 2; aspect_on++) { + aspect=aspect_on?(aspect_native*bfu_aspect+0.5):65535UL; + printf("aspect=%d\n", aspect); + } + } + + /* test ? : GCC extension */ + { + static int v1 = 34 ? : -1; /* constant case */ + static int v2 = 0 ? : -1; /* constant case */ + int a = 30; + + printf("%d %d\n", v1, v2); + printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2); + } + + /* again complex expression */ + for(i=0;i<256;i++) { + if (toupper1 (i) != TOUPPER (i)) + printf("error %d\n", i); + } + printf ("bits = 0x%x\n", calc_vm_flags (0x1)); +} + +extern int undefined_function(void); +extern int defined_function(void); + +static inline void refer_to_undefined(void) +{ + undefined_function(); +} + +void optimize_out(void) +{ + int i = 0 ? undefined_function() : defined_function(); + printf ("oo:%d\n", i); + int j = 1 ? defined_function() : undefined_function(); + printf ("oo:%d\n", j); + if (0) + printf("oo:%d\n", undefined_function()); + else + printf("oo:%d\n", defined_function()); + if (1) + printf("oo:%d\n", defined_function()); + else + printf("oo:%d\n", undefined_function()); + while (1) { + printf("oow:%d\n", defined_function()); + break; + printf("oow:%d\n", undefined_function()); + } + j = 1; + /* Following is a switch without {} block intentionally. */ + switch (j) + case 1: break; + printf ("oos:%d\n", defined_function()); + /* The following break shouldn't lead to disabled code after + the while. */ + while (1) + break; + printf ("ool1:%d\n", defined_function()); + /* Same for the other types of loops. */ + do + break; + while (1); + printf ("ool2:%d\n", defined_function()); + for (;;) + break; + printf ("ool3:%d\n", defined_function()); + /* Normal {} blocks without controlling statements + shouldn't reactivate code emission */ + while (1) { + { + break; + } + printf ("ool4:%d\n", undefined_function()); + } + j = 1; + while (j) { + if (j == 0) + break; /* this break shouldn't disable code outside the if. */ + printf("ool5:%d\n", defined_function()); + j--; + } + + j = 1; + while (j) { + if (1) + j--; + else + breakhere: break; + printf("ool6:%d\n", defined_function()); + goto breakhere; + } + + /* Test that constants in logical && are optimized: */ + i = 0 && undefined_function(); + i = defined_function() && 0 && undefined_function(); + if (0 && undefined_function()) + undefined_function(); + if (defined_function() && 0) + undefined_function(); + if (0 && 0) + undefined_function(); + if (defined_function() && 0 && undefined_function()) + undefined_function(); + /* The same for || : */ + i = 1 || undefined_function(); + i = defined_function() || 1 || undefined_function(); + if (1 || undefined_function()) + ; + else + undefined_function(); + if (defined_function() || 1) + ; + else + undefined_function(); + if (1 || 1) + ; + else + undefined_function(); + if (defined_function() || 1 || undefined_function()) + ; + else + undefined_function(); + + if (defined_function() && 0) + refer_to_undefined(); + + if (0) { + (void)sizeof( ({ + do { } while (0); + 0; + }) ); + undefined_function(); + } + + /* Leave the "if(1)return; printf()" in this order and last in the function */ + if (1) + return; + printf ("oor:%d\n", undefined_function()); +} + +int defined_function(void) +{ + static int i = 40; + return i++; +} + +/* GCC accepts that */ +static int tab_reinit[]; +static int tab_reinit[10]; + +//int cinit1; /* a global variable can be defined several times without error ! */ +int cinit1; +int cinit1; +int cinit1 = 0; +int *cinit2 = (int []){3, 2, 1}; + +void compound_literal_test(void) +{ + int *p, i; + char *q, *q3; + + printf("compound_test:\n"); + + p = (int []){1, 2, 3}; + for(i=0;i<3;i++) + printf(" %d", p[i]); + printf("\n"); + + for(i=0;i<3;i++) + printf("%d", cinit2[i]); + printf("\n"); + + q = "tralala1"; + printf("q1=%s\n", q); + + q = (char *){ "tralala2" }; + printf("q2=%s\n", q); + + q3 = (char *){ q }; + printf("q3=%s\n", q3); + + q = (char []){ "tralala3" }; + printf("q4=%s\n", q); + +#ifdef ALL_ISOC99 + p = (int []){1, 2, cinit1 + 3}; + for(i=0;i<3;i++) + printf(" %d", p[i]); + printf("\n"); + + for(i=0;i<3;i++) { + p = (int []){1, 2, 4 + i}; + printf("%d %d %d\n", + p[0], + p[1], + p[2]); + } +#endif +} + +/* K & R protos */ + +kr_func1(a, b) +{ + return a + b; +} + +int kr_func2(a, b) +{ + return a + b; +} + +kr_test() +{ + printf("kr_test:\n"); + printf("func1=%d\n", kr_func1(3, 4)); + printf("func2=%d\n", kr_func2(3, 4)); + return 0; +} + +void num(int n) +{ + char *tab, *p; + tab = (char*)malloc(20); + p = tab; + while (1) { + *p = 48 + (n % 10); + p++; + n = n / 10; + if (n == 0) + break; + } + while (p != tab) { + p--; + printf("%c", *p); + } + printf("\n"); + free(tab); +} + +/* structure assignment tests */ +struct structa1 { + int f1; + char f2; +}; + +struct structa1 ssta1; + +void struct_assign_test1(struct structa1 s1, int t, float f) +{ + printf("%d %d %d %f\n", s1.f1, s1.f2, t, f); +} + +struct structa1 struct_assign_test2(struct structa1 s1, int t) +{ + s1.f1 += t; + s1.f2 -= t; + return s1; +} + +void struct_assign_test(void) +{ + struct S { + struct structa1 lsta1, lsta2; + int i; + } s, *ps; + + ps = &s; + ps->i = 4; +#if 0 + printf("struct_assign_test:\n"); + + s.lsta1.f1 = 1; + s.lsta1.f2 = 2; + printf("%d %d\n", s.lsta1.f1, s.lsta1.f2); + s.lsta2 = s.lsta1; + printf("%d %d\n", s.lsta2.f1, s.lsta2.f2); +#else + s.lsta2.f1 = 1; + s.lsta2.f2 = 2; +#endif + struct_assign_test1(ps->lsta2, 3, 4.5); + + printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2); + ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i); + printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2); + + static struct { + void (*elem)(); + } t[] = { + /* XXX: we should allow this even without braces */ + { struct_assign_test } + }; + printf("%d\n", struct_assign_test == t[0].elem); +} + +/* casts to short/char */ + +void cast1(char a, short b, unsigned char c, unsigned short d) +{ + printf("%d %d %d %d\n", a, b, c, d); +} + +char bcast; +short scast; + +void cast_test() +{ + int a; + char c; + char tab[10]; + unsigned b,d; + short s; + char *p = NULL; + p -= 0x700000000042; + + printf("cast_test:\n"); + a = 0xfffff; + cast1(a, a, a, a); + a = 0xffffe; + printf("%d %d %d %d\n", + (char)(a + 1), + (short)(a + 1), + (unsigned char)(a + 1), + (unsigned short)(a + 1)); + printf("%d %d %d %d\n", + (char)0xfffff, + (short)0xfffff, + (unsigned char)0xfffff, + (unsigned short)0xfffff); + + a = (bcast = 128) + 1; + printf("%d\n", a); + a = (scast = 65536) + 1; + printf("%d\n", a); + + printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c)); + + /* test cast from unsigned to signed short to int */ + b = 0xf000; + d = (short)b; + printf("((unsigned)(short)0x%08x) = 0x%08x\n", b, d); + b = 0xf0f0; + d = (char)b; + printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d); + + /* test implicit int casting for array accesses */ + c = 0; + tab[1] = 2; + tab[c] = 1; + printf("%d %d\n", tab[0], tab[1]); + + /* test implicit casting on some operators */ + printf("sizeof(+(char)'a') = %d\n", sizeof(+(char)'a')); + printf("sizeof(-(char)'a') = %d\n", sizeof(-(char)'a')); + printf("sizeof(~(char)'a') = %d\n", sizeof(-(char)'a')); + + /* from pointer to integer types */ + printf("%d %d %ld %ld %lld %lld\n", + (int)p, (unsigned int)p, + (long)p, (unsigned long)p, + (long long)p, (unsigned long long)p); + + /* from integers to pointers */ + printf("%p %p %p %p\n", + (void *)a, (void *)b, (void *)c, (void *)d); +} + +/* initializers tests */ +struct structinit1 { + int f1; + char f2; + short f3; + int farray[3]; +}; + +int sinit1 = 2; +int sinit2 = { 3 }; +int sinit3[3] = { 1, 2, {{3}}, }; +int sinit4[3][2] = { {1, 2}, {3, 4}, {5, 6} }; +int sinit5[3][2] = { 1, 2, 3, 4, 5, 6 }; +int sinit6[] = { 1, 2, 3 }; +int sinit7[] = { [2] = 3, [0] = 1, 2 }; +char sinit8[] = "hello" "trala"; + +struct structinit1 sinit9 = { 1, 2, 3 }; +struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 }; +struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1, +#ifdef ALL_ISOC99 + .farray[0] = 10, + .farray[1] = 11, + .farray[2] = 12, +#endif +}; + +char *sinit12 = "hello world"; +char *sinit13[] = { + "test1", + "test2", + "test3", +}; +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 +}; + +int sinit18[10] = { + [2 ... 5] = 20, + 2, + [8] = 10, +}; + +struct complexinit0 { + int a; + int b; +}; + +struct complexinit { + int a; + const struct complexinit0 *b; +}; + +const static struct complexinit cix[] = { + [0] = { + .a = 2000, + .b = (const struct complexinit0[]) { + { 2001, 2002 }, + { 2003, 2003 }, + {} + } + } +}; + +struct complexinit2 { + int a; + int b[]; +}; + +struct complexinit2 cix20; + +struct complexinit2 cix21 = { + .a = 3000, + .b = { 3001, 3002, 3003 } +}; + +struct complexinit2 cix22 = { + .a = 4000, + .b = { 4001, 4002, 4003, 4004, 4005, 4006 } +}; + +typedef int arrtype1[]; +arrtype1 sinit19 = {1}; +arrtype1 sinit20 = {2,3}; +typedef int arrtype2[3]; +arrtype2 sinit21 = {4}; +arrtype2 sinit22 = {5,6,7}; + +/* Address comparisons of non-weak symbols with zero can be const-folded */ +int sinit23[2] = { "astring" ? sizeof("astring") : -1, + &sinit23 ? 42 : -1 }; + +extern int external_inited = 42; + +void init_test(void) +{ + int linit1 = 2; + int linit2 = { 3 }; + int linit4[3][2] = { {1, 2}, {3, 4}, {5, 6} }; + int linit6[] = { 1, 2, 3 }; + int i, j; + char linit8[] = "hello" "trala"; + int linit12[10] = { 1, 2 }; + int linit13[10] = { 1, 2, [7] = 3, [3] = 4, }; + char linit14[10] = "abc"; + int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, }; + struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 }; + int linit17 = sizeof(linit17); + int zero = 0; + /* Addresses on non-weak symbols are non-zero, but not the access itself */ + int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 }; + + printf("init_test:\n"); + + printf("sinit1=%d\n", sinit1); + printf("sinit2=%d\n", sinit2); + printf("sinit3=%d %d %d %d\n", + sizeof(sinit3), + sinit3[0], + sinit3[1], + sinit3[2] + ); + printf("sinit6=%d\n", sizeof(sinit6)); + printf("sinit7=%d %d %d %d\n", + sizeof(sinit7), + sinit7[0], + sinit7[1], + sinit7[2] + ); + printf("sinit8=%s\n", sinit8); + printf("sinit9=%d %d %d\n", + sinit9.f1, + sinit9.f2, + sinit9.f3 + ); + printf("sinit10=%d %d %d\n", + sinit10.f1, + sinit10.f2, + sinit10.f3 + ); + printf("sinit11=%d %d %d %d %d %d\n", + sinit11.f1, + sinit11.f2, + sinit11.f3, + sinit11.farray[0], + sinit11.farray[1], + sinit11.farray[2] + ); + + for(i=0;i<3;i++) + for(j=0;j<2;j++) + printf("[%d][%d] = %d %d %d\n", + i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]); + printf("linit1=%d\n", linit1); + printf("linit2=%d\n", linit2); + printf("linit6=%d\n", sizeof(linit6)); + printf("linit8=%d %s\n", sizeof(linit8), linit8); + + printf("sinit12=%s\n", sinit12); + printf("sinit13=%d %s %s %s\n", + sizeof(sinit13), + sinit13[0], + sinit13[1], + sinit13[2]); + printf("sinit14=%s\n", sinit14); + + for(i=0;i<10;i++) printf(" %d", linit12[i]); + printf("\n"); + for(i=0;i<10;i++) printf(" %d", linit13[i]); + printf("\n"); + for(i=0;i<10;i++) printf(" %d", linit14[i]); + printf("\n"); + for(i=0;i<10;i++) printf(" %d", linit15[i]); + printf("\n"); + printf("%d %d %d %d\n", + linit16.a1, + linit16.a2, + linit16.a3, + linit16.a4); + /* 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); + for(i=0;i<10;i++) + printf("%x ", sinit18[i]); + printf("\n"); + /* complex init check */ + printf("cix: %d %d %d %d %d %d %d\n", + cix[0].a, + cix[0].b[0].a, cix[0].b[0].b, + cix[0].b[1].a, cix[0].b[1].b, + cix[0].b[2].a, cix[0].b[2].b); + printf("cix2: %d %d\n", cix21.b[2], cix22.b[5]); + printf("sizeof cix20 %d, cix21 %d, sizeof cix22 %d\n", sizeof cix20, sizeof cix21, sizeof cix22); + + printf("arrtype1: %d %d %d\n", sinit19[0], sinit20[0], sinit20[1]); + printf("arrtype2: %d %d\n", sizeof(sinit19), sizeof(sinit20)); + printf("arrtype3: %d %d %d\n", sinit21[0], sinit21[1], sinit21[2]); + printf("arrtype4: %d %d %d\n", sinit22[0], sinit22[1], sinit22[2]); + printf("arrtype5: %d %d\n", sizeof(sinit21), sizeof(sinit22)); + printf("arrtype6: %d\n", sizeof(arrtype2)); + + printf("sinit23= %d %d\n", sinit23[0], sinit23[1]); + printf("linit18= %d %d\n", linit18[0], linit18[1]); +} + +void switch_uc(unsigned char uc) +{ + switch (uc) { + case 0xfb ... 0xfe: + printf("ucsw:1\n"); + break; + case 0xff: + printf("ucsw:2\n"); + break; + case 0 ... 5: + printf("ucsw:3\n"); + break; + default: + printf("ucsw: broken!\n"); + } +} + +void switch_sc(signed char sc) +{ + switch (sc) { + case -5 ... -2: + printf("scsw:1\n"); + break; + case -1: + printf("scsw:2\n"); + break; + case 0 ... 5: + printf("scsw:3\n"); + break; + default: + printf("scsw: broken!\n"); + } +} + +void switch_test() +{ + int i; + unsigned long long ull; + long long ll; + + for(i=0;i<15;i++) { + switch(i) { + case 0: + case 1: + printf("a"); + break; + default: + printf("%d", i); + break; + case 8 ... 12: + printf("c"); + break; + case 3: + printf("b"); + break; + case 0xc33c6b9fU: + case 0x7c9eeeb9U: + break; + } + } + printf("\n"); + + for (i = 1; i <= 5; i++) { + ull = (unsigned long long)i << 61; + switch (ull) { + case 1ULL << 61: + printf("ullsw:1\n"); + break; + case 2ULL << 61: + printf("ullsw:2\n"); + break; + case 3ULL << 61: + printf("ullsw:3\n"); + break; + case 4ULL << 61: + printf("ullsw:4\n"); + break; + case 5ULL << 61: + printf("ullsw:5\n"); + break; + default: + printf("ullsw: broken!\n"); + } + } + + for (i = 1; i <= 5; i++) { + ll = (long long)i << 61; + switch (ll) { + case 1LL << 61: + printf("llsw:1\n"); + break; + case 2LL << 61: + printf("llsw:2\n"); + break; + case 3LL << 61: + printf("llsw:3\n"); + break; + case 4LL << 61: + printf("llsw:4\n"); + break; + case 5LL << 61: + printf("llsw:5\n"); + break; + default: + printf("llsw: broken!\n"); + } + } + + for (i = -5; i <= 5; i++) { + switch_uc((unsigned char)i); + } + + for (i = -5; i <= 5; i++) { + switch_sc ((signed char)i); + } +} + +/* ISOC99 _Bool type */ +void c99_bool_test(void) +{ +#ifdef BOOL_ISOC99 + int a; + _Bool b; + + printf("bool_test:\n"); + printf("sizeof(_Bool) = %d\n", sizeof(_Bool)); + a = 3; + printf("cast: %d %d %d\n", (_Bool)10, (_Bool)0, (_Bool)a); + b = 3; + printf("b = %d\n", b); + b++; + printf("b = %d\n", b); +#endif +} + +void bitfield_test(void) +{ + int a; + short sa; + unsigned char ca; + struct sbf1 { + int f1 : 3; + int : 2; + int f2 : 1; + int : 0; + int f3 : 5; + int f4 : 7; + unsigned int f5 : 7; + } st1; + printf("bitfield_test:"); + printf("sizeof(st1) = %d\n", sizeof(st1)); + + st1.f1 = 3; + st1.f2 = 1; + st1.f3 = 15; + a = 120; + st1.f4 = a; + st1.f5 = a; + st1.f5++; + printf("%d %d %d %d %d\n", + st1.f1, st1.f2, st1.f3, st1.f4, st1.f5); + sa = st1.f5; + ca = st1.f5; + printf("%d %d\n", sa, ca); + + st1.f1 = 7; + if (st1.f1 == -1) + printf("st1.f1 == -1\n"); + else + printf("st1.f1 != -1\n"); + if (st1.f2 == -1) + printf("st1.f2 == -1\n"); + else + printf("st1.f2 != -1\n"); + + struct sbf2 { + long long f1 : 45; + long long : 2; + long long f2 : 35; + unsigned long long f3 : 38; + } st2; + st2.f1 = 0x123456789ULL; + a = 120; + st2.f2 = (long long)a << 25; + st2.f3 = a; + st2.f2++; + printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3); + +#if 0 + Disabled for now until further clarification re GCC compatibility + struct sbf3 { + int f1 : 7; + int f2 : 1; + char f3; + int f4 : 8; + int f5 : 1; + int f6 : 16; + } st3; + printf("sizeof(st3) = %d\n", sizeof(st3)); +#endif + + struct sbf4 { + int x : 31; + char y : 2; + } st4; + st4.y = 1; + printf("st4.y == %d\n", st4.y); + struct sbf5 { + int a; + char b; + int x : 12, y : 4, : 0, : 4, z : 3; + char c; + } st5 = { 1, 2, 3, 4, -3, 6 }; + printf("st5 = %d %d %d %d %d %d\n", st5.a, st5.b, st5.x, st5.y, st5.z, st5.c); + struct sbf6 { + short x : 12; + unsigned char y : 2; + } st6; + st6.y = 1; + printf("st6.y == %d\n", st6.y); +} + +#ifdef __x86_64__ +#define FLOAT_FMT "%f\n" +#else +/* x86's float isn't compatible with GCC */ +#define FLOAT_FMT "%.5f\n" +#endif + +/* declare strto* functions as they are C99 */ +double strtod(const char *nptr, char **endptr); + +#if defined(_WIN32) +float strtof(const char *nptr, char **endptr) {return (float)strtod(nptr, endptr);} +LONG_DOUBLE strtold(const char *nptr, char **endptr) {return (LONG_DOUBLE)strtod(nptr, endptr);} +#else +float strtof(const char *nptr, char **endptr); +LONG_DOUBLE strtold(const char *nptr, char **endptr); +#endif + +#define FTEST(prefix, typename, type, fmt)\ +void prefix ## cmp(type a, type b)\ +{\ + printf("%d %d %d %d %d %d\n",\ + a == b,\ + a != b,\ + a < b,\ + a > b,\ + a >= b,\ + a <= b);\ + printf(fmt " " fmt " " fmt " " fmt " " fmt " " fmt " " fmt "\n",\ + a,\ + b,\ + a + b,\ + a - b,\ + a * b,\ + a / b,\ + -a);\ + printf(fmt "\n", ++a);\ + printf(fmt "\n", a++);\ + printf(fmt "\n", a);\ + b = 0;\ + printf("%d %d\n", !a, !b);\ +}\ +void prefix ## fcast(type a)\ +{\ + float fa;\ + double da;\ + LONG_DOUBLE la;\ + int ia;\ + long long llia;\ + unsigned int ua;\ + unsigned long long llua;\ + type b;\ + fa = a;\ + da = a;\ + la = a;\ + printf("ftof: %f %f %Lf\n", fa, da, la);\ + ia = (int)a;\ + llia = (long long)a;\ + a = (a >= 0) ? a : -a;\ + ua = (unsigned int)a;\ + llua = (unsigned long long)a;\ + printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\ + ia = -1234;\ + ua = 0x81234500;\ + llia = -0x123456789012345LL;\ + llua = 0xf123456789012345LLU;\ + b = ia;\ + printf("itof: " fmt "\n", b);\ + b = ua;\ + printf("utof: " fmt "\n", b);\ + b = llia;\ + printf("lltof: " fmt "\n", b);\ + b = llua;\ + printf("ulltof: " fmt "\n", b);\ +}\ +\ +float prefix ## retf(type a) { return a; }\ +double prefix ## retd(type a) { return a; }\ +LONG_DOUBLE prefix ## retld(type a) { return a; }\ +\ +void prefix ## call(void)\ +{\ + printf("float: " FLOAT_FMT, prefix ## retf(42.123456789));\ + printf("double: %f\n", prefix ## retd(42.123456789));\ + printf("long double: %Lf\n", prefix ## retld(42.123456789));\ + printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\ +}\ +\ +void prefix ## signed_zeros(void) \ +{\ + type x = 0.0, y = -0.0, n, p;\ + if (x == y)\ + printf ("Test 1.0 / x != 1.0 / y returns %d (should be 1).\n",\ + 1.0 / x != 1.0 / y);\ + else\ + printf ("x != y; this is wrong!\n");\ +\ + n = -x;\ + if (x == n)\ + printf ("Test 1.0 / x != 1.0 / -x returns %d (should be 1).\n",\ + 1.0 / x != 1.0 / n);\ + else\ + printf ("x != -x; this is wrong!\n");\ +\ + p = +y;\ + if (x == p)\ + printf ("Test 1.0 / x != 1.0 / +y returns %d (should be 1).\n",\ + 1.0 / x != 1.0 / p);\ + else\ + printf ("x != +y; this is wrong!\n");\ + p = -y;\ + if (x == p)\ + printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\ + 1.0 / x != 1.0 / p);\ + else\ + printf ("x != -y; this is wrong!\n");\ +}\ +void prefix ## test(void)\ +{\ + printf("testing '%s'\n", #typename);\ + prefix ## cmp(1, 2.5);\ + prefix ## cmp(2, 1.5);\ + prefix ## cmp(1, 1);\ + prefix ## fcast(234.6);\ + prefix ## fcast(-2334.6);\ + prefix ## call();\ + prefix ## signed_zeros();\ +} + +FTEST(f, float, float, "%f") +FTEST(d, double, double, "%f") +FTEST(ld, long double, LONG_DOUBLE, "%Lf") + +double ftab1[3] = { 1.2, 3.4, -5.6 }; + + +void float_test(void) +{ +#if !defined(__arm__) || defined(__ARM_PCS_VFP) + float fa, fb; + double da, db; + int a; + unsigned int b; + + printf("float_test:\n"); + printf("sizeof(float) = %d\n", sizeof(float)); + printf("sizeof(double) = %d\n", sizeof(double)); + printf("sizeof(long double) = %d\n", sizeof(LONG_DOUBLE)); + ftest(); + dtest(); + ldtest(); + printf("%f %f %f\n", ftab1[0], ftab1[1], ftab1[2]); + printf("%f %f %f\n", 2.12, .5, 2.3e10); + // printf("%f %f %f\n", 0x1234p12, 0x1e23.23p10, 0x12dp-10); + da = 123; + printf("da=%f\n", da); + fa = 123; + printf("fa=%f\n", fa); + a = 4000000000; + da = a; + printf("da = %f\n", da); + b = 4000000000; + db = b; + printf("db = %f\n", db); +#endif +} + +int fib(int n) +{ + if (n <= 2) + return 1; + else + return fib(n-1) + fib(n-2); +} + +void funcptr_test() +{ + void (*func)(int); + int a; + struct { + int dummy; + void (*func)(int); + } st1; + long diff; + + printf("funcptr:\n"); + func = # + (*func)(12345); + func = num; + a = 1; + a = 1; + func(12345); + /* more complicated pointer computation */ + st1.func = num; + st1.func(12346); + printf("sizeof1 = %d\n", sizeof(funcptr_test)); + printf("sizeof2 = %d\n", sizeof funcptr_test); + printf("sizeof3 = %d\n", sizeof(&funcptr_test)); + printf("sizeof4 = %d\n", sizeof &funcptr_test); + a = 0; + func = num + a; + diff = func - num; + func(42); + (func + diff)(42); + (num + a)(43); +} + +void lloptest(long long a, long long b) +{ + unsigned long long ua, ub; + + ua = a; + ub = b; + /* arith */ + printf("arith: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", + a + b, + a - b, + a * b); + + if (b != 0) { + printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", + a / b, + a % b); + } + + /* binary */ + printf("bin: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", + a & b, + a | b, + a ^ b); + + /* tests */ + printf("test: %d %d %d %d %d %d\n", + a == b, + a != b, + a < b, + a > b, + a >= b, + a <= b); + + printf("utest: %d %d %d %d %d %d\n", + ua == ub, + ua != ub, + ua < ub, + ua > ub, + ua >= ub, + ua <= ub); + + /* arith2 */ + a++; + b++; + printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b); + printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a++, b++); + printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", --a, --b); + printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b); + b = ub = 0; + printf("not: %d %d %d %d\n", !a, !ua, !b, !ub); +} + +void llshift(long long a, int b) +{ + printf("shift: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", + (unsigned long long)a >> b, + a >> b, + a << b); + printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", + (unsigned long long)a >> 3, + a >> 3, + a << 3); + printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", + (unsigned long long)a >> 35, + a >> 35, + a << 35); +} + +void llfloat(void) +{ + float fa; + double da; + LONG_DOUBLE lda; + long long la, lb, lc; + unsigned long long ula, ulb, ulc; + la = 0x12345678; + ula = 0x72345678; + la = (la << 20) | 0x12345; + ula = ula << 33; + printf("la=" LONG_LONG_FORMAT " ula=" ULONG_LONG_FORMAT "\n", la, ula); + + fa = la; + da = la; + lda = la; + printf("lltof: %f %f %Lf\n", fa, da, lda); + + la = fa; + lb = da; + lc = lda; + printf("ftoll: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", la, lb, lc); + + fa = ula; + da = ula; + lda = ula; + printf("ulltof: %f %f %Lf\n", fa, da, lda); + + ula = fa; + ulb = da; + ulc = lda; + printf("ftoull: " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT "\n", ula, ulb, ulc); +} + +long long llfunc1(int a) +{ + return a * 2; +} + +struct S { + int id; + char item; +}; + +long long int value(struct S *v) +{ + return ((long long int)v->item); +} + +long long llfunc2(long long x, long long y, int z) +{ + return x * y * z; +} + +void longlong_test(void) +{ + long long a, b, c; + int ia; + unsigned int ua; + printf("longlong_test:\n"); + printf("sizeof(long long) = %d\n", sizeof(long long)); + ia = -1; + ua = -2; + a = ia; + b = ua; + printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b); + printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n", + (long long)1, + (long long)-2, + 1LL, + 0x1234567812345679); + a = llfunc1(-3); + printf(LONG_LONG_FORMAT "\n", a); + + lloptest(1000, 23); + lloptest(0xff, 0x1234); + b = 0x72345678 << 10; + lloptest(-3, b); + llshift(0x123, 5); + llshift(-23, 5); + b = 0x72345678LL << 10; + llshift(b, 47); + + llfloat(); +#if 1 + b = 0x12345678; + a = -1; + c = a + b; + printf("%Lx\n", c); +#endif + + /* long long reg spill test */ + { + struct S a; + + a.item = 3; + printf("%lld\n", value(&a)); + } + lloptest(0x80000000, 0); + + { + long long *p, v, **pp; + v = 1; + p = &v; + p[0]++; + printf("another long long spill test : %lld\n", *p); + pp = &p; + + v = llfunc2(**pp, **pp, ia); + printf("a long long function (arm-)reg-args test : %lld\n", v); + } + a = 68719476720LL; + b = 4294967295LL; + printf("%d %d %d %d\n", a > b, a < b, a >= b, a <= b); + + printf(LONG_LONG_FORMAT "\n", 0x123456789LLU); + + /* long long pointer deref in argument passing test */ + a = 0x123; + long long *p = &a; + llshift(*p, 5); +} + +void manyarg_test(void) +{ + LONG_DOUBLE ld = 1234567891234LL; + printf("manyarg_test:\n"); + printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n", + 1, 2, 3, 4, 5, 6, 7, 8, + 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0); + printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " + LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n", + 1, 2, 3, 4, 5, 6, 7, 8, + 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, + 1234567891234LL, 987654321986LL, + 42.0, 43.0); + printf("%Lf %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " + LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n", + ld, 1, 2, 3, 4, 5, 6, 7, 8, + 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, + 1234567891234LL, 987654321986LL, + 42.0, 43.0); + printf("%d %d %d %d %d %d %d %d %Lf\n", + 1, 2, 3, 4, 5, 6, 7, 8, ld); + printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " + LONG_LONG_FORMAT " " LONG_LONG_FORMAT "%f %f %Lf\n", + 1, 2, 3, 4, 5, 6, 7, 8, + 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, + 1234567891234LL, 987654321986LL, + 42.0, 43.0, ld); + printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " + "%Lf " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f %Lf\n", + 1, 2, 3, 4, 5, 6, 7, 8, + 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, + ld, 1234567891234LL, 987654321986LL, + 42.0, 43.0, ld); +} + +void vprintf1(const char *fmt, ...) +{ + va_list ap, aq; + const char *p; + int c, i; + double d; + long long ll; + LONG_DOUBLE ld; + + va_start(aq, fmt); + va_copy(ap, aq); + + p = fmt; + for(;;) { + c = *p; + if (c == '\0') + break; + p++; + if (c == '%') { + c = *p; + switch(c) { + case '\0': + goto the_end; + case 'd': + i = va_arg(ap, int); + printf("%d", i); + break; + case 'f': + d = va_arg(ap, double); + printf("%f", d); + break; + case 'l': + ll = va_arg(ap, long long); + printf(LONG_LONG_FORMAT, ll); + break; + case 'F': + ld = va_arg(ap, LONG_DOUBLE); + printf("%Lf", ld); + break; + } + p++; + } else { + putchar(c); + } + } + the_end: + va_end(aq); + va_end(ap); +} + +struct myspace { + short int profile; +}; + +void stdarg_for_struct(struct myspace bob, ...) +{ + struct myspace george, bill; + va_list ap; + short int validate; + + va_start(ap, bob); + bill = va_arg(ap, struct myspace); + george = va_arg(ap, struct myspace); + validate = va_arg(ap, int); + printf("stdarg_for_struct: %d %d %d %d\n", + bob.profile, bill.profile, george.profile, validate); + va_end(ap); +} + +void stdarg_for_libc(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +} + +void stdarg_test(void) +{ + LONG_DOUBLE ld = 1234567891234LL; + struct myspace bob; + + vprintf1("%d %d %d\n", 1, 2, 3); + vprintf1("%f %d %f\n", 1.0, 2, 3.0); + vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0); + vprintf1("%F %F %F\n", LONG_DOUBLE_LITERAL(1.2), LONG_DOUBLE_LITERAL(2.3), LONG_DOUBLE_LITERAL(3.4)); + vprintf1("%d %f %l %F %d %f %l %F\n", + 1, 1.2, 3LL, LONG_DOUBLE_LITERAL(4.5), 6, 7.8, 9LL, LONG_DOUBLE_LITERAL(0.1)); + vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f\n", + 1, 2, 3, 4, 5, 6, 7, 8, + 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8); + vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n", + 1, 2, 3, 4, 5, 6, 7, 8, + 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0); + vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " + "%l %l %f %f\n", + 1, 2, 3, 4, 5, 6, 7, 8, + 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, + 1234567891234LL, 987654321986LL, + 42.0, 43.0); + vprintf1("%F %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " + "%l %l %f %f\n", + ld, 1, 2, 3, 4, 5, 6, 7, 8, + 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, + 1234567891234LL, 987654321986LL, + 42.0, 43.0); + vprintf1("%d %d %d %d %d %d %d %d %F\n", + 1, 2, 3, 4, 5, 6, 7, 8, ld); + vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " + "%l %l %f %f %F\n", + 1, 2, 3, 4, 5, 6, 7, 8, + 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, + 1234567891234LL, 987654321986LL, + 42.0, 43.0, ld); + vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " + "%F %l %l %f %f %F\n", + 1, 2, 3, 4, 5, 6, 7, 8, + 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, + ld, 1234567891234LL, 987654321986LL, + 42.0, 43.0, ld); + + bob.profile = 42; + stdarg_for_struct(bob, bob, bob, bob.profile); + stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456); +} + +void whitespace_test(void) +{ + char *str; + +
#if 1 + pri\ +ntf("whitspace:\n");
+#endif + pf("N=%d\n", 2); + +#ifdef CORRECT_CR_HANDLING + pri\
+ntf("aaa=%d\n", 3); +#endif + + pri\ +\ +ntf("min=%d\n", 4); + +#ifdef ACCEPT_CR_IN_STRINGS + printf("len1=%d\n", strlen(" +")); +#ifdef CORRECT_CR_HANDLING + str = "
+"; + printf("len1=%d str[0]=%d\n", strlen(str), str[0]); +#endif + printf("len1=%d\n", strlen("
a +")); +#endif /* ACCEPT_CR_IN_STRINGS */ +} + +int reltab[3] = { 1, 2, 3 }; + +int *rel1 = &reltab[1]; +int *rel2 = &reltab[2]; + +#ifdef _WIN64 +void relocation_test(void) {} +#else +void getmyaddress(void) +{ + printf("in getmyaddress\n"); +} + +#ifdef __LP64__ +long __pa_symbol(void) +{ + /* This 64bit constant was handled incorrectly, it was used as addend + (which can hold 64bit just fine) in connection with a symbol, + and TCC generates wrong code for that (displacements are 32bit only). + This effectively is "+ 0x80000000", and if addresses of globals + are below 2GB the result should be a number without high 32 bits set. */ + return ((long)(((unsigned long)(&rel1))) - (0xffffffff80000000UL)); +} +#endif + +unsigned long theaddress = (unsigned long)getmyaddress; +void relocation_test(void) +{ + void (*fptr)(void) = (void (*)(void))theaddress; + printf("*rel1=%d\n", *rel1); + printf("*rel2=%d\n", *rel2); + fptr(); +#ifdef __LP64__ + printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63); +#endif +} +#endif + +void old_style_f(a,b,c) + int a, b; + double c; +{ + printf("a=%d b=%d b=%f\n", a, b, c); +} + +void decl_func1(int cmpfn()) +{ + printf("cmpfn=%lx\n", (long)cmpfn); +} + +void decl_func2(cmpfn) +int cmpfn(); +{ + printf("cmpfn=%lx\n", (long)cmpfn); +} + +void old_style_function(void) +{ + old_style_f((void *)1, 2, 3.0); + decl_func1(NULL); + decl_func2(NULL); +} + +void alloca_test() +{ +#if defined __i386__ || defined __x86_64__ || defined __arm__ + char *p = alloca(16); + strcpy(p,"123456789012345"); + printf("alloca: p is %s\n", p); + char *demo = "This is only a test.\n"; + /* Test alloca embedded in a larger expression */ + printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) ); +#endif +} + +void *bounds_checking_is_enabled() +{ + char ca[10], *cp = ca-1; + return (ca != cp + 1) ? cp : NULL; +} + +typedef int constant_negative_array_size_as_compile_time_assertion_idiom[(1 ? 2 : 0) - 1]; + +void c99_vla_test(int size1, int size2) +{ +#if defined __i386__ || defined __x86_64__ + int size = size1 * size2; + int tab1[size][2], tab2[10][2]; + void *tab1_ptr, *tab2_ptr, *bad_ptr; + + /* "size" should have been 'captured' at tab1 declaration, + so modifying it should have no effect on VLA behaviour. */ + size = size-1; + + printf("Test C99 VLA 1 (sizeof): "); + printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED"); + tab1_ptr = tab1; + tab2_ptr = tab2; + printf("Test C99 VLA 2 (ptrs subtract): "); + printf("%s\n", (tab2 - tab1 == (tab2_ptr - tab1_ptr) / (sizeof(int) * 2)) ? "PASSED" : "FAILED"); + printf("Test C99 VLA 3 (ptr add): "); + printf("%s\n", &tab1[5][1] == (tab1_ptr + (5 * 2 + 1) * sizeof(int)) ? "PASSED" : "FAILED"); + printf("Test C99 VLA 4 (ptr access): "); + tab1[size1][1] = 42; + printf("%s\n", (*((int *) (tab1_ptr + (size1 * 2 + 1) * sizeof(int))) == 42) ? "PASSED" : "FAILED"); + + printf("Test C99 VLA 5 (bounds checking (might be disabled)): "); + if (bad_ptr = bounds_checking_is_enabled()) { + int *t1 = &tab1[size1 * size2 - 1][3]; + int *t2 = &tab2[9][3]; + printf("%s ", bad_ptr == t1 ? "PASSED" : "FAILED"); + printf("%s ", bad_ptr == t2 ? "PASSED" : "FAILED"); + + char*c1 = 1 + sizeof(tab1) + (char*)tab1; + char*c2 = 1 + sizeof(tab2) + (char*)tab2; + printf("%s ", bad_ptr == c1 ? "PASSED" : "FAILED"); + printf("%s ", bad_ptr == c2 ? "PASSED" : "FAILED"); + + int *i1 = tab1[-1]; + int *i2 = tab2[-1]; + printf("%s ", bad_ptr == i1 ? "PASSED" : "FAILED"); + printf("%s ", bad_ptr == i2 ? "PASSED" : "FAILED"); + + int *x1 = tab1[size1 * size2 + 1]; + int *x2 = tab2[10 + 1]; + printf("%s ", bad_ptr == x1 ? "PASSED" : "FAILED"); + printf("%s ", bad_ptr == x2 ? "PASSED" : "FAILED"); + } else { + printf("PASSED PASSED PASSED PASSED PASSED PASSED PASSED PASSED "); + } + printf("\n"); +#endif +} + +#ifndef __TINYC__ +typedef __SIZE_TYPE__ uintptr_t; +#endif + +void sizeof_test(void) +{ + int a; + int **ptr; + + printf("sizeof(int) = %d\n", sizeof(int)); + printf("sizeof(unsigned int) = %d\n", sizeof(unsigned int)); + printf("sizeof(long) = %d\n", sizeof(long)); + printf("sizeof(unsigned long) = %d\n", sizeof(unsigned long)); + printf("sizeof(short) = %d\n", sizeof(short)); + printf("sizeof(unsigned short) = %d\n", sizeof(unsigned short)); + printf("sizeof(char) = %d\n", sizeof(char)); + printf("sizeof(unsigned char) = %d\n", sizeof(unsigned char)); + printf("sizeof(func) = %d\n", sizeof sizeof_test()); + a = 1; + printf("sizeof(a++) = %d\n", sizeof a++); + printf("a=%d\n", a); + ptr = NULL; + printf("sizeof(**ptr) = %d\n", sizeof (**ptr)); + + /* The type of sizeof should be as large as a pointer, actually + it should be size_t. */ + printf("sizeof(sizeof(int) = %d\n", sizeof(sizeof(int))); + uintptr_t t = 1; + uintptr_t t2; + /* Effectively <<32, but defined also on 32bit machines. */ + t <<= 16; + t <<= 16; + t++; + /* This checks that sizeof really can be used to manipulate + uintptr_t objects, without truncation. */ + t2 = t & -sizeof(uintptr_t); + printf ("%lu %lu\n", t, t2); + + /* some alignof tests */ + printf("__alignof__(int) = %d\n", __alignof__(int)); + printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int)); + printf("__alignof__(short) = %d\n", __alignof__(short)); + printf("__alignof__(unsigned short) = %d\n", __alignof__(unsigned short)); + printf("__alignof__(char) = %d\n", __alignof__(char)); + printf("__alignof__(unsigned char) = %d\n", __alignof__(unsigned char)); + printf("__alignof__(func) = %d\n", __alignof__ sizeof_test()); + + /* sizes of VLAs need to be evaluated even inside sizeof: */ + a = 2; + printf("sizeof(char[1+2*a]) = %d\n", sizeof(char[1+2*a])); + /* And checking if sizeof compound literal works. Parenthesized: */ + printf("sizeof( (struct {int i; int j;}){4,5} ) = %d\n", + sizeof( (struct {int i; int j;}){4,5} )); + /* And as direct sizeof argument (as unary expression): */ + printf("sizeof (struct {short i; short j;}){4,5} = %d\n", + sizeof (struct {short i; short j;}){4,5} ); + + /* sizeof(x && y) should be sizeof(int), even if constant + evaluating is possible. */ + printf("sizeof(t && 0) = %d\n", sizeof(t && 0)); + printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1)); + printf("sizeof(t || 1) = %d\n", sizeof(t || 1)); + printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0)); +} + +void typeof_test(void) +{ + double a; + typeof(a) b; + typeof(float) c; + + a = 1.5; + b = 2.5; + c = 3.5; + printf("a=%f b=%f c=%f\n", a, b, c); +} + + +struct hlist_node; +struct hlist_head { + struct hlist_node *first, *last; +}; + +void consume_ulong (unsigned long i) +{ + i = 0; +} + +void statement_expr_test(void) +{ + int a, i; + + /* Basic stmt expr test */ + a = 0; + for(i=0;i<10;i++) { + a += 1 + + ( { int b, j; + b = 0; + for(j=0;j<5;j++) + b += j; b; + } ); + } + printf("a=%d\n", a); + + /* Test that symbols aren't freed prematurely. + With SYM_DEBUG valgrind will show a read from a freed + symbol, and tcc will show an (invalid) warning on the initialization + of 'ptr' below, if symbols are popped after the stmt expr. */ + void *v = (void*)39; + typeof(({ + (struct hlist_node *)v; + })) x; + typeof (x) + ptr = (struct hlist_node *)v; + + /* This part used to segfault when symbols were popped prematurely. + The symbols for the static local would be overwritten with + helper symbols from the pre-processor expansions in between. */ +#define some_attr __attribute__((aligned(1))) +#define tps(str) ({ \ + static const char *t some_attr = str; \ + t; \ + }) + printf ("stmtexpr: %s %s\n", + tps("somerandomlongstring"), + tps("anotherlongstring")); + + /* Test that the three decls of 't' don't interact. */ + int t = 40; + int b = ({ int t = 41; t; }); + int c = ({ int t = 42; t; }); + + /* Test that aggregate return values work. */ + struct hlist_head h + = ({ + typedef struct hlist_head T; + long pre = 48; + T t = { (void*)43, (void*)44 }; + long post = 49; + t; + }); + printf ("stmtexpr: %d %d %d\n", t, b, c); + printf ("stmtexpr: %ld %ld\n", (long)h.first, (long)h.last); + + /* Test that we can give out addresses of local labels. */ + consume_ulong(({ __label__ __here; __here: (unsigned long)&&__here; })); +} + +void local_label_test(void) +{ + int a; + goto l1; + l2: + a = 1 + ({ + __label__ l1, l2, l3, l4; + goto l1; + l4: + printf("aa1\n"); + goto l3; + l2: + printf("aa3\n"); + goto l4; + l1: + printf("aa2\n"); + goto l2; + l3:; + 1; + }); + printf("a=%d\n", a); + return; + l4: + printf("bb1\n"); + goto l2; + l1: + printf("bb2\n"); + goto l4; +} + +/* inline assembler test */ +#if defined(__i386__) || defined(__x86_64__) + +/* from linux kernel */ +static char * strncat1(char * dest,const char * src,size_t count) +{ +long d0, d1, d2, d3; +__asm__ __volatile__( + "repne\n\t" + "scasb\n\t" + "dec %1\n\t" + "mov %8,%3\n" + "1:\tdec %3\n\t" + "js 2f\n\t" + "lodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n" + "2:\txor %2,%2\n\t" + "stosb" + : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) + : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) + : "memory"); +return dest; +} + +static char * strncat2(char * dest,const char * src,size_t count) +{ +long d0, d1, d2, d3; +__asm__ __volatile__( + "repne scasb\n\t" /* one-line repne prefix + string op */ + "dec %1\n\t" + "mov %8,%3\n" + "1:\tdec %3\n\t" + "js 2f\n\t" + "lodsb\n\t" + "stosb\n\t" + "testb %%al,%%al\n\t" + "jne 1b\n" + "2:\txor %2,%2\n\t" + "stosb" + : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) + : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) + : "memory"); +return dest; +} + +static inline void * memcpy1(void * to, const void * from, size_t n) +{ +long d0, d1, d2; +__asm__ __volatile__( + "rep ; movsl\n\t" + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" + "2:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) + : "memory"); +return (to); +} + +static inline void * memcpy2(void * to, const void * from, size_t n) +{ +long d0, d1, d2; +__asm__ __volatile__( + "rep movsl\n\t" /* one-line rep prefix + string op */ + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" + "2:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) + : "memory"); +return (to); +} + +static __inline__ void sigaddset1(unsigned int *set, int _sig) +{ + __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); +} + +static __inline__ void sigdelset1(unsigned int *set, int _sig) +{ + asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc", "flags"); +} + +static __inline__ __const__ unsigned int swab32(unsigned int x) +{ + __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ + "rorl $16,%0\n\t" /* swap words */ + "xchgb %b0,%h0" /* swap higher bytes */ + :"=" "q" (x) + : "0" (x)); + return x; +} + +static __inline__ unsigned long long mul64(unsigned int a, unsigned int b) +{ + unsigned long long res; +#ifdef __x86_64__ + /* Using the A constraint is wrong (it means rdx:rax, which is too large) + but still test the 32bit->64bit mull. */ + unsigned int resh, resl; + __asm__("mull %2" : "=a" (resl), "=d" (resh) : "a" (a), "r" (b)); + res = ((unsigned long long)resh << 32) | resl; +#else + __asm__("mull %2" : "=A" (res) : "a" (a), "r" (b)); +#endif + return res; +} + +static __inline__ unsigned long long inc64(unsigned long long a) +{ + unsigned long long res; +#ifdef __x86_64__ + /* Using the A constraint is wrong, and increments are tested + elsewhere. */ + res = a + 1; +#else + __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a)); +#endif + return res; +} + +struct struct123 { + int a; + int b; +}; +struct struct1231 { + unsigned long addr; +}; + +unsigned long mconstraint_test(struct struct1231 *r) +{ + unsigned long ret; + unsigned int a[2]; + a[0] = 0; + __asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1" + : "=&r" (ret), "=m" (a) + : "m" (*(struct struct123 *)r->addr)); + return ret + a[0]; +} + +#ifdef __x86_64__ +int fls64(unsigned long long x) +{ + int bitpos = -1; + asm("bsrq %1,%q0" + : "+r" (bitpos) + : "rm" (x)); + return bitpos + 1; +} +#endif + +void other_constraints_test(void) +{ + unsigned long ret; + int var; +#ifndef _WIN64 + __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var)); + printf ("oc1: %d\n", ret == (unsigned long)&var); +#endif +} + +#ifndef _WIN32 +/* Test global asm blocks playing with aliases. */ +void base_func(void) +{ + printf ("asmc: base\n"); +} + +extern void override_func1 (void); +extern void override_func2 (void); + +asm(".weak override_func1\n.set override_func1, base_func"); +asm(".set override_func1, base_func"); +asm(".set override_func2, base_func"); + +void override_func2 (void) +{ + printf ("asmc: override2\n"); +} + +/* This checks a construct used by the linux kernel to encode + references to strings by PC relative references. */ +extern int bug_table[] __attribute__((section("__bug_table"))); +char * get_asm_string (void) +{ + extern int some_symbol; + asm volatile (".globl some_symbol\n" + "jmp .+6\n" + "1:\n" + "some_symbol: .long 0\n" + ".pushsection __bug_table, \"a\"\n" + ".globl bug_table\n" + "bug_table:\n" + /* The first entry (1b-2b) is unused in this test, + but we include it to check if cross-section + PC-relative references work. */ + "2:\t.long 1b - 2b, %c0 - 2b\n" + ".popsection\n" : : "i" ("A string")); + char * str = ((char*)bug_table) + bug_table[1]; + return str; +} + +/* This checks another constructs with local labels. */ +extern unsigned char alld_stuff[]; +asm(".data\n" + ".byte 41\n" + "alld_stuff:\n" + "661:\n" + ".byte 42\n" + "662:\n" + ".pushsection .data.ignore\n" + ".long 661b - .\n" /* This reference to 661 generates an external sym + which shouldn't somehow overwrite the offset that's + already determined for it. */ + ".popsection\n" + ".byte 662b - 661b\n" /* So that this value is undeniably 1. */); + +void asm_local_label_diff (void) +{ + printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]); +} + +/* This checks that static local variables are available from assembler. */ +void asm_local_statics (void) +{ + static int localint = 41; + asm("incl %0" : "+m" (localint)); + printf ("asm_local_statics: %d\n", localint); +} +#endif + +static +unsigned int set; + +void fancy_copy (unsigned *in, unsigned *out) +{ + asm volatile ("" : "=r" (*out) : "0" (*in)); +} + +void fancy_copy2 (unsigned *in, unsigned *out) +{ + asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory"); +} + +#if defined __x86_64__ && !defined _WIN64 +void clobber_r12(void) +{ + asm volatile("mov $1, %%r12" ::: "r12"); +} +#endif + +void test_high_clobbers(void) +{ +#if defined __x86_64__ && !defined _WIN64 + register long val asm("r12"); + long val2; + /* This tests if asm clobbers correctly save/restore callee saved + registers if they are clobbered and if it's the high 8 x86-64 + registers. This is fragile for GCC as the constraints do not + correctly capture the data flow, but good enough for us. */ + asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory"); + clobber_r12(); + asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory"); + printf("asmhc: 0x%x\n", val2); +#endif +} + +static long cpu_number; +void trace_console(long len, long len2) +{ +#ifdef __x86_64__ + /* This generated invalid code when the emission of the switch + table isn't disabled. The asms are necessary to show the bug, + normal statements don't work (they need to generate some code + even under nocode_wanted, which normal statements don't do, + but asms do). Also at least these number of cases is necessary + to generate enough "random" bytes. They ultimately are enough + to create invalid instruction patterns to which the first + skip-to-decision-table jump jumps. If decision table emission + is disabled all of this is no problem. + + It also is necessary that the switches are in a statement expression + (which has the property of not being enterable from outside. no + matter what). */ + if (0 + && + ({ + long pscr_ret__; + switch(len) { + case 4: + { + long pfo_ret__; + switch (len2) { + case 8: printf("bla"); pfo_ret__ = 42; break; + } + pscr_ret__ = pfo_ret__; + } + break; + case 8: + { + long pfo_ret__; + switch (len2) { + case 1:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break; + case 2:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break; + case 4:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break; + case 8:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break; + default: printf("impossible\n"); + } + pscr_ret__ = pfo_ret__; + }; + break; + } + pscr_ret__; + })) + { + printf("huh?\n"); + } +#endif +} + +void test_asm_dead_code(void) +{ + long rdi; + /* Try to make sure that xdi contains a zero, and hence will + lead to a segfault if the next asm is evaluated without + arguments being set up. */ + asm volatile ("" : "=D" (rdi) : "0" (0)); + (void)sizeof (({ + int var; + /* This shouldn't trigger a segfault, either the argument + registers need to be set up and the asm emitted despite + this being in an unevaluated context, or both the argument + setup _and_ the asm emission need to be suppressed. The latter + is better. Disabling asm code gen when suppression is on + also fixes the above trace_console bug, but that came earlier + than asm suppression. */ + asm volatile ("movl $0,(%0)" : : "D" (&var) : "memory"); + var; + })); +} + +void test_asm_call(void) +{ +#if defined __x86_64__ && !defined _WIN64 + static char str[] = "PATH"; + char *s; + /* This tests if a reference to an undefined symbol from an asm + block, which isn't otherwise referenced in this file, is correctly + regarded as global symbol, so that it's resolved by other object files + or libraries. We chose getenv here, which isn't used anywhere else + in this file. (If we used e.g. printf, which is used we already + would have a global symbol entry, not triggering the bug which is + tested here). */ + /* two pushes so stack remains aligned */ + asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;" +#if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__)) + "call getenv@plt;" +#else + "call getenv;" +#endif + "pop %%rdi; pop %%rdi" + : "=a" (s) : "r" (str)); + printf("asmd: %s\n", s); +#endif +} + +#if defined __x86_64__ +# define RX "(%rip)" +#else +# define RX +#endif + +void asm_dot_test(void) +{ + int x; + for (x = 1;; ++x) { + int r = x; + switch (x) { + case 1: + asm(".text; lea S"RX",%eax; lea ."RX",%ecx; sub %ecx,%eax; S=.; jmp p0"); + case 2: + asm(".text; jmp .+6; .int 123; mov .-4"RX",%eax; jmp p0"); + case 3: + asm(".data; Y=.; .int 999; X=Y; .int 456; X=.-4"); + asm(".text; mov X"RX",%eax; jmp p0"); + case 4: + asm(".data; X=.; .int 789; Y=.; .int 999"); + asm(".text; mov X"RX",%eax; X=Y; jmp p0"); + case 0: + asm(".text; p0=.; mov %%eax,%0;" : "=m"(r)); break; + } + if (r == x) + break; + printf("asm_dot_test %d: %d\n", x, r); + } +} + +void asm_test(void) +{ + char buf[128]; + unsigned int val, val2; + struct struct123 s1; + struct struct1231 s2 = { (unsigned long)&s1 }; + /* Hide the outer base_func, but check later that the inline + asm block gets the outer one. */ + int base_func = 42; + void override_func3 (void); + unsigned long asmret; +#ifdef BOOL_ISOC99 + _Bool somebool; +#endif + register int regvar asm("%esi"); + + printf("inline asm:\n"); + + // parse 0x1E-1 as 3 tokens in asm mode + asm volatile ("mov $0x1E-1,%eax"); + + /* test the no operand case */ + asm volatile ("xorl %eax, %eax"); + + memcpy1(buf, "hello", 6); + strncat1(buf, " worldXXXXX", 3); + printf("%s\n", buf); + + memcpy2(buf, "hello", 6); + strncat2(buf, " worldXXXXX", 3); + printf("%s\n", buf); + + /* 'A' constraint test */ + printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234)); + printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff)); + + s1.a = 42; + s1.b = 43; + printf("mconstraint: %d", mconstraint_test(&s2)); + printf(" %d %d\n", s1.a, s1.b); + other_constraints_test(); + set = 0xff; + sigdelset1(&set, 2); + sigaddset1(&set, 16); + /* NOTE: we test here if C labels are correctly restored after the + asm statement */ + goto label1; + label2: + __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc"); + printf("set=0x%x\n", set); + val = 0x01020304; + printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val)); +#ifndef _WIN32 + override_func1(); + override_func2(); + /* The base_func ref from the following inline asm should find + the global one, not the local decl from this function. */ + asm volatile(".weak override_func3\n.set override_func3, base_func"); + override_func3(); + printf("asmstr: %s\n", get_asm_string()); + asm_local_label_diff(); + asm_local_statics(); +#endif + /* Check that we can also load structs of appropriate layout + into registers. */ + asm volatile("" : "=r" (asmret) : "0"(s2)); + if (asmret != s2.addr) + printf("asmstr: failed\n"); +#ifdef BOOL_ISOC99 + /* Check that the typesize correctly sets the register size to + 8 bit. */ + asm volatile("cmp %1,%2; sete %0" : "=a"(somebool) : "r"(1), "r"(2)); + if (!somebool) + printf("asmbool: failed\n"); +#endif + val = 43; + fancy_copy (&val, &val2); + printf ("fancycpy(%d)=%d\n", val, val2); + val = 44; + fancy_copy2 (&val, &val2); + printf ("fancycpy2(%d)=%d\n", val, val2); + asm volatile ("mov $0x4243, %%esi" : "=r" (regvar)); + printf ("regvar=%x\n", regvar); + test_high_clobbers(); + trace_console(8, 8); + test_asm_dead_code(); + test_asm_call(); + asm_dot_test(); + return; + label1: + goto label2; +} + +#else + +void asm_test(void) +{ +} + +#endif + +#define COMPAT_TYPE(type1, type2) \ +{\ + printf("__builtin_types_compatible_p(%s, %s) = %d\n", #type1, #type2, \ + __builtin_types_compatible_p (type1, type2));\ +} + +int constant_p_var; + +void builtin_test(void) +{ + short s; + int i; + long long ll; +#if GCC_MAJOR >= 3 + COMPAT_TYPE(int, int); + COMPAT_TYPE(int, unsigned int); + COMPAT_TYPE(int, char); + COMPAT_TYPE(int, const int); + COMPAT_TYPE(int, volatile int); + COMPAT_TYPE(int *, int *); + COMPAT_TYPE(int *, void *); + COMPAT_TYPE(int *, const int *); + COMPAT_TYPE(char *, unsigned char *); + COMPAT_TYPE(char *, signed char *); + COMPAT_TYPE(char *, char *); +/* space is needed because tcc preprocessor introduces a space between each token */ + COMPAT_TYPE(char * *, void *); +#endif + printf("res = %d\n", __builtin_constant_p(1)); + printf("res = %d\n", __builtin_constant_p(1 + 2)); + printf("res = %d\n", __builtin_constant_p(&constant_p_var)); + printf("res = %d\n", __builtin_constant_p(constant_p_var)); + printf("res = %d\n", __builtin_constant_p(100000 / constant_p_var)); + s = 1; + ll = 2; + i = __builtin_choose_expr (1 != 0, ll, s); + printf("bce: %d\n", i); + i = __builtin_choose_expr (1 != 1, ll, s); + printf("bce: %d\n", i); + i = sizeof (__builtin_choose_expr (1, ll, s)); + printf("bce: %d\n", i); + i = sizeof (__builtin_choose_expr (0, ll, s)); + printf("bce: %d\n", i); + + //printf("bera: %p\n", __builtin_extract_return_addr((void*)43)); +} + +#ifndef _WIN32 +extern int __attribute__((weak)) weak_f1(void); +extern int __attribute__((weak)) weak_f2(void); +extern int weak_f3(void); +extern int __attribute__((weak)) weak_v1; +extern int __attribute__((weak)) weak_v2; +extern int weak_v3; + +extern int (*weak_fpa)() __attribute__((weak)); +extern int __attribute__((weak)) (*weak_fpb)(); +extern __attribute__((weak)) int (*weak_fpc)(); + +extern int weak_asm_f1(void) asm("weak_asm_f1x") __attribute((weak)); +extern int __attribute((weak)) weak_asm_f2(void) asm("weak_asm_f2x") ; +extern int __attribute((weak)) weak_asm_f3(void) asm("weak_asm_f3x") __attribute((weak)); +extern int weak_asm_v1 asm("weak_asm_v1x") __attribute((weak)); +extern int __attribute((weak)) weak_asm_v2 asm("weak_asm_v2x") ; +extern int __attribute((weak)) weak_asm_v3(void) asm("weak_asm_v3x") __attribute((weak)); + +static const size_t dummy = 0; +extern __typeof(dummy) weak_dummy1 __attribute__((weak, alias("dummy"))); +extern __typeof(dummy) __attribute__((weak, alias("dummy"))) weak_dummy2; +extern __attribute__((weak, alias("dummy"))) __typeof(dummy) weak_dummy3; + +int some_lib_func(void); +int dummy_impl_of_slf(void) { return 444; } +int some_lib_func(void) __attribute__((weak, alias("dummy_impl_of_slf"))); + +int weak_toolate() __attribute__((weak)); +int weak_toolate() { return 0; } + +void __attribute__((weak)) weak_test(void) +{ + printf("weak_f1=%d\n", weak_f1 ? weak_f1() : 123); + printf("weak_f2=%d\n", weak_f2 ? weak_f2() : 123); + printf("weak_f3=%d\n", weak_f3 ? weak_f3() : 123); + printf("weak_v1=%d\n",&weak_v1 ? weak_v1 : 123); + printf("weak_v2=%d\n",&weak_v2 ? weak_v2 : 123); + printf("weak_v3=%d\n",&weak_v3 ? weak_v3 : 123); + + printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123); + printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123); + printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123); + + printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL); + printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL); + printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL); + printf("weak_asm_v1=%d\n",&weak_asm_v1 != NULL); + printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL); + printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL); + printf("some_lib_func=%d\n", &some_lib_func ? some_lib_func() : 0); +} + +int __attribute__((weak)) weak_f2() { return 222; } +int __attribute__((weak)) weak_f3() { return 333; } +int __attribute__((weak)) weak_v2 = 222; +int __attribute__((weak)) weak_v3 = 333; +#endif + +void const_func(const int a) +{ +} + +void const_warn_test(void) +{ + const_func(1); +} + +struct condstruct { + int i; +}; + +int getme (struct condstruct *s, int i) +{ + int i1 = (i == 0 ? 0 : s)->i; + int i2 = (i == 0 ? s : 0)->i; + int i3 = (i == 0 ? (void*)0 : s)->i; + int i4 = (i == 0 ? s : (void*)0)->i; + return i1 + i2 + i3 + i4; +} + +struct global_data +{ + int a[40]; + int *b[40]; +}; + +struct global_data global_data; + +int global_data_getstuff (int *, int); + +void global_data_callit (int i) +{ + *global_data.b[i] = global_data_getstuff (global_data.b[i], 1); +} + +int global_data_getstuff (int *p, int i) +{ + return *p + i; +} + +void global_data_test (void) +{ + global_data.a[0] = 42; + global_data.b[0] = &global_data.a[0]; + global_data_callit (0); + printf ("%d\n", global_data.a[0]); +} + +struct cmpcmpS +{ + unsigned char fill : 3; + unsigned char b1 : 1; + unsigned char b2 : 1; + unsigned char fill2 : 3; +}; + +int glob1, glob2, glob3; + +void compare_comparisons (struct cmpcmpS *s) +{ + if (s->b1 != (glob1 == glob2) + || (s->b2 != (glob1 == glob3))) + printf ("comparing comparisons broken\n"); +} + +void cmp_comparison_test(void) +{ + struct cmpcmpS s; + s.b1 = 1; + glob1 = 42; glob2 = 42; + s.b2 = 0; + glob3 = 43; + compare_comparisons (&s); +} + +int fcompare (double a, double b, int code) +{ + switch (code) { + case 0: return a == b; + case 1: return a != b; + case 2: return a < b; + case 3: return a >= b; + case 4: return a > b; + case 5: return a <= b; + } +} + +void math_cmp_test(void) +{ + double nan = 0.0/0.0; + double one = 1.0; + double two = 2.0; + int comp = 0; +#define bug(a,b,op,iop,part) printf("Test broken: %s %s %s %s %d\n", #a, #b, #op, #iop, part) + + /* This asserts that "a op b" is _not_ true, but "a iop b" is true. + And it does this in various ways so that all code generation paths + are checked (generating inverted tests, or non-inverted tests, or + producing a 0/1 value without jumps (that's done in the fcompare + function). */ +#define FCMP(a,b,op,iop,code) \ + if (fcompare (a,b,code)) \ + bug (a,b,op,iop,1); \ + if (a op b) \ + bug (a,b,op,iop,2); \ + if (a iop b) \ + ; \ + else \ + bug (a,b,op,iop,3); \ + if ((a op b) || comp) \ + bug (a,b,op,iop,4); \ + if ((a iop b) || comp) \ + ; \ + else \ + bug (a,b,op,iop,5); + + /* Equality tests. */ + FCMP(nan, nan, ==, !=, 0); + FCMP(one, two, ==, !=, 0); + FCMP(one, one, !=, ==, 1); + /* Non-equality is a bit special. */ + if (!fcompare (nan, nan, 1)) + bug (nan, nan, !=, ==, 6); + + /* Relational tests on numbers. */ + FCMP(two, one, <, >=, 2); + FCMP(one, two, >=, <, 3); + FCMP(one, two, >, <=, 4); + FCMP(two, one, <=, >, 5); + + /* Relational tests on NaNs. Note that the inverse op here is + always !=, there's no operator in C that is equivalent to !(a < b), + when NaNs are involved, same for the other relational ops. */ + FCMP(nan, nan, <, !=, 2); + FCMP(nan, nan, >=, !=, 3); + FCMP(nan, nan, >, !=, 4); + FCMP(nan, nan, <=, !=, 5); +} + +double get100 () { return 100.0; } + +void callsave_test(void) +{ +#if defined __i386__ || defined __x86_64__ || defined __arm__ + int i, s; double *d; double t; + s = sizeof (double); + printf ("callsavetest: %d\n", s); + d = alloca (sizeof(double)); + d[0] = 10.0; + /* x86-64 had a bug were the next call to get100 would evict + the lvalue &d[0] as VT_LLOCAL, and the reload would be done + in int type, not pointer type. When alloca returns a pointer + with the high 32 bit set (which is likely on x86-64) the access + generates a segfault. */ + i = d[0] > get100 (); + printf ("%d\n", i); +#endif +} + + +void bfa3(ptrdiff_t str_offset) +{ + printf("bfa3: %s\n", (char *)__builtin_frame_address(3) + str_offset); +} +void bfa2(ptrdiff_t str_offset) +{ + printf("bfa2: %s\n", (char *)__builtin_frame_address(2) + str_offset); + bfa3(str_offset); +} +void bfa1(ptrdiff_t str_offset) +{ + printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset); + bfa2(str_offset); +} + +void builtin_frame_address_test(void) +{ +/* builtin_frame_address fails on ARM with gcc which make test3 fail */ +#ifndef __arm__ + char str[] = "__builtin_frame_address"; + char *fp0 = __builtin_frame_address(0); + + printf("str: %s\n", str); + bfa1(str-fp0); +#endif +} + +char via_volatile (char i) +{ + char volatile vi; + vi = i; + return vi; +} + +struct __attribute__((__packed__)) Spacked { + char a; + short b; + int c; +}; +struct Spacked spacked; +typedef struct __attribute__((__packed__)) { + char a; + short b; + int c; +} Spacked2; +Spacked2 spacked2; +typedef struct Spacked3_s { + char a; + short b; + int c; +} __attribute__((__packed__)) Spacked3; +Spacked3 spacked3; +struct gate_struct64 { + unsigned short offset_low; + unsigned short segment; + unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1; + unsigned short offset_middle; + unsigned offset_high; + unsigned zero1; +} __attribute__((packed)); +typedef struct gate_struct64 gate_desc; +gate_desc a_gate_desc; +void attrib_test(void) +{ +#ifndef _WIN32 + printf("attr: %d %d %d %d\n", sizeof(struct Spacked), + sizeof(spacked), sizeof(Spacked2), sizeof(spacked2)); + printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3)); + printf("attr: %d %d\n", sizeof(gate_desc), sizeof(a_gate_desc)); +#endif +} +extern __attribute__((__unused__)) char * __attribute__((__unused__)) * +strange_attrib_placement (void); + +void * __attribute__((__unused__)) get_void_ptr (void *a) +{ + return a; +} + +/* This part checks for a bug in TOK_GET (used for inline expansion), + where the large long long constant left the the high bits set for + the integer constant token. */ +static inline +int __get_order(unsigned long long size) +{ + int order; + size -= 0xffff880000000000ULL; // this const left high bits set in the token + { + struct S { int i : 1; } s; // constructed for this '1' + } + order = size; + return order; +} + +/* This just forces the above inline function to be actually emitted. */ +int force_get_order(unsigned long s) +{ + return __get_order(s); +} diff --git a/05/tcc-0.9.27/tests/tcctest.h b/05/tcc-0.9.27/tests/tcctest.h new file mode 100644 index 0000000..b301c7c --- /dev/null +++ b/05/tcc-0.9.27/tests/tcctest.h @@ -0,0 +1,9 @@ +static inline const char *get_basefile_from_header(void) +{ + return __BASE_FILE__; +} + +static inline const char *get_file_from_header(void) +{ + return __FILE__; +} diff --git a/05/tcc-0.9.27/tests/testfp.c b/05/tcc-0.9.27/tests/testfp.c new file mode 100644 index 0000000..63342b4 --- /dev/null +++ b/05/tcc-0.9.27/tests/testfp.c @@ -0,0 +1,510 @@ +/* + * Test 128-bit floating-point arithmetic on arm64: + * build with two different compilers and compare the output. + * + * Copyright (c) 2015 Edmund Grimley Evans + * + * Copying and distribution of this file, with or without modification, + * are permitted in any medium without royalty provided the copyright + * notice and this notice are preserved. This file is offered as-is, + * without any warranty. + */ + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define check(x) ((x) ? (void)0 : check_fail(#x, __FILE__, __LINE__)) + +void check_fail(const char *assertion, const char *file, unsigned int line) +{ + printf("%s:%d: Check (%s) failed.", file, line, assertion); + exit(1); +} + +typedef struct { + unsigned long long x0, x1; +} u128_t; + +float copy_fi(uint32_t x) +{ + float f; + memcpy(&f, &x, 4); + return f; +} + +double copy_di(uint64_t x) +{ + double f; + memcpy(&f, &x, 8); + return f; +} + +long double copy_ldi(u128_t x) +{ + long double f; + memcpy(&f, &x, 16); + return f; +} + +uint32_t copy_if(float f) +{ + uint32_t x; + memcpy(&x, &f, 4); + return x; +} + +uint64_t copy_id(double f) +{ + uint64_t x; + memcpy(&x, &f, 8); + return x; +} + +u128_t copy_ild(long double f) +{ + u128_t x; + memcpy(&x, &f, 16); + return x; +} + +long double make(int sgn, int exp, uint64_t high, uint64_t low) +{ + u128_t x = { low, + (0x0000ffffffffffff & high) | + (0x7fff000000000000 & (uint64_t)exp << 48) | + (0x8000000000000000 & (uint64_t)sgn << 63) }; + return copy_ldi(x); +} + +void cmp(long double a, long double b) +{ + u128_t ax = copy_ild(a); + u128_t bx = copy_ild(b); + int eq = (a == b); + int ne = (a != b); + int lt = (a < b); + int le = (a <= b); + int gt = (a > b); + int ge = (a >= b); + + check(eq == 0 || eq == 1); + check(lt == 0 || lt == 1); + check(gt == 0 || gt == 1); + check(ne == !eq && le == (lt | eq) && ge == (gt | eq)); + check(eq + lt + gt < 2); + + printf("cmp %016llx%016llx %016llx%016llx %d %d %d\n", + ax.x1, ax.x0, bx.x1, bx.x0, lt, eq, gt); +} + +void cmps(void) +{ + int i, j; + + for (i = 0; i < 2; i++) + for (j = 0; j < 2; j++) + cmp(make(i, 0, 0, 0), make(j, 0, 0, 0)); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 64; j++) { + long double f1 = make(i, 32767, (uint64_t)1 << j, 0); + long double f2 = make(i, 32767, 0, (uint64_t)1 << j); + cmp(f1, 0); + cmp(f2, 0); + cmp(0, f1); + cmp(0, f2); + } + } + + for (i = 0; i < 6; i++) + for (j = 0; j < 6; j++) + cmp(make(i & 1, i >> 1, 0, 0), + make(j & 1, j >> 1, 0, 0)); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + int a, b; + for (a = 0; a < 2; a++) { + for (b = 0; b < 2; b++) { + cmp(make(i, j, a, b), make(i, j, 0, 0)); + cmp(make(i, j, 0, 0), make(i, j, a, b)); + } + } + } + } +} + +void xop(const char *name, long double a, long double b, long double c) +{ + u128_t ax = copy_ild(a); + u128_t bx = copy_ild(b); + u128_t cx = copy_ild(c); + printf("%s %016llx%016llx %016llx%016llx %016llx%016llx\n", + name, ax.x1, ax.x0, bx.x1, bx.x0, cx.x1, cx.x0); +} + +void fadd(long double a, long double b) +{ + xop("add", a, b, a + b); +} + +void fsub(long double a, long double b) +{ + xop("sub", a, b, a - b); +} + +void fmul(long double a, long double b) +{ + xop("mul", a, b, a * b); +} + +void fdiv(long double a, long double b) +{ + xop("div", a, b, a / b); +} + +void nanz(void) +{ + // Check NaNs: + { + long double x[7]; + int i, j, n = 0; + x[n++] = make(0, 32000, 0x95132b76effc, 0xd79035214b4f8d53); + x[n++] = make(1, 32001, 0xbe71d7a51587, 0x30601c6815d6c3ac); + x[n++] = make(0, 32767, 0, 1); + x[n++] = make(0, 32767, (uint64_t)1 << 46, 0); + x[n++] = make(1, 32767, (uint64_t)1 << 47, 0); + x[n++] = make(1, 32767, 0x7596c7099ad5, 0xe25fed2c58f73fc9); + x[n++] = make(0, 32767, 0x835d143360f9, 0x5e315efb35630666); + check(n == sizeof(x) / sizeof(*x)); + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + fadd(x[i], x[j]); + fsub(x[i], x[j]); + fmul(x[i], x[j]); + fdiv(x[i], x[j]); + } + } + } + + // Check infinities and zeroes: + { + long double x[6]; + int i, j, n = 0; + x[n++] = make(1, 32000, 0x62acda85f700, 0x47b6c9f35edc4044); + x[n++] = make(0, 32001, 0x94b7abf55af7, 0x9f425fe354428e19); + x[n++] = make(0, 32767, 0, 0); + x[n++] = make(1, 32767, 0, 0); + x[n++] = make(0, 0, 0, 0); + x[n++] = make(1, 0, 0, 0); + check(n == sizeof(x) / sizeof(*x)); + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + fadd(x[i], x[j]); + fsub(x[i], x[j]); + fmul(x[i], x[j]); + fdiv(x[i], x[j]); + } + } + } +} + +void adds(void) +{ + // Check shifting and add/sub: + { + int i; + for (i = -130; i <= 130; i++) { + int s1 = (uint32_t)i % 3 < 1; + int s2 = (uint32_t)i % 5 < 2; + fadd(make(s1, 16384 , 0x502c065e4f71a65d, 0xd2f9bdb031f4f031), + make(s2, 16384 + i, 0xae267395a9bc1033, 0xb56b5800da1ba448)); + } + } + + // Check normalisation: + { + uint64_t a0 = 0xc6bab0a6afbef5ed; + uint64_t a1 = 0x4f84136c4a2e9b52; + int ee[] = { 0, 1, 10000 }; + int e, i; + for (e = 0; e < sizeof(ee) / sizeof(*ee); e++) { + int exp = ee[e]; + fsub(make(0, exp, a1, a0), make(0, 0, 0, 0)); + for (i = 63; i >= 0; i--) + fsub(make(0, exp, a1 | (uint64_t)1 << i >> 1, a0), + make(0, exp, a1 >> i << i, 0)); + for (i = 63; i >=0; i--) + fsub(make(0, exp, a1, a0 | (uint64_t)1 << i >> 1), + make(0, exp, a1, a0 >> i << i)); + } + } + + // Carry/overflow from rounding: + { + fadd(make(0, 114, -1, -1), make(0, 1, 0, 0)); + fadd(make(0, 32766, -1, -1), make(0, 32653, 0, 0)); + fsub(make(1, 32766, -1, -1), make(0, 32653, 0, 0)); + } +} + +void muls(void) +{ + int i, j; + + { + long double max = make(0, 32766, -1, -1); + long double min = make(0, 0, 0, 1); + fmul(max, max); + fmul(max, min); + fmul(min, min); + } + + for (i = 117; i > 0; i--) + fmul(make(0, 16268, 0x643dcea76edc, 0xe0877a598403627a), + make(i & 1, i, 0, 0)); + + fmul(make(0, 16383, -1, -3), make(0, 16383, 0, 1)); + // Round to next exponent: + fmul(make(0, 16383, -1, -2), make(0, 16383, 0, 1)); + // Round from subnormal to normal: + fmul(make(0, 1, -1, -1), make(0, 16382, 0, 0)); + + for (i = 0; i < 2; i++) + for (j = 0; j < 112; j++) + fmul(make(0, 16383, (uint64_t)1 << i, 0), + make(0, 16383, + j < 64 ? 0 : (uint64_t)1 << (j - 64), + j < 64 ? (uint64_t)1 << j : 0)); +} + +void divs(void) +{ + int i; + + { + long double max = make(0, 32766, -1, -1); + long double min = make(0, 0, 0, 1); + fdiv(max, max); + fdiv(max, min); + fdiv(min, max); + fdiv(min, min); + } + + for (i = 0; i < 64; i++) + fdiv(make(0, 16383, -1, -1), make(0, 16383, -1, -(uint64_t)1 << i)); + for (i = 0; i < 48; i++) + fdiv(make(0, 16383, -1, -1), make(0, 16383, -(uint64_t)1 << i, 0)); +} + +void cvtlsw(int32_t a) +{ + long double f = a; + u128_t x = copy_ild(f); + printf("cvtlsw %08lx %016llx%016llx\n", (long)(uint32_t)a, x.x1, x.x0); +} + +void cvtlsx(int64_t a) +{ + long double f = a; + u128_t x = copy_ild(f); + printf("cvtlsx %016llx %016llx%016llx\n", + (long long)(uint64_t)a, x.x1, x.x0); +} + +void cvtluw(uint32_t a) +{ + long double f = a; + u128_t x = copy_ild(f); + printf("cvtluw %08lx %016llx%016llx\n", (long)a, x.x1, x.x0); +} + +void cvtlux(uint64_t a) +{ + long double f = a; + u128_t x = copy_ild(f); + printf("cvtlux %016llx %016llx%016llx\n", (long long)a, x.x1, x.x0); +} + +void cvtil(long double a) +{ + u128_t x = copy_ild(a); + int32_t b1 = a; + int64_t b2 = a; + uint32_t b3 = a; + uint64_t b4 = a; + printf("cvtswl %016llx%016llx %08lx\n", + x.x1, x.x0, (long)(uint32_t)b1); + printf("cvtsxl %016llx%016llx %016llx\n", + x.x1, x.x0, (long long)(uint64_t)b2); + printf("cvtuwl %016llx%016llx %08lx\n", + x.x1, x.x0, (long)b3); + printf("cvtuxl %016llx%016llx %016llx\n", + x.x1, x.x0, (long long)b4); +} + +void cvtlf(float a) +{ + uint32_t ax = copy_if(a); + long double b = a; + u128_t bx = copy_ild(b); + printf("cvtlf %08lx %016llx%016llx\n", (long)ax, bx.x1, bx.x0); +} + +void cvtld(double a) +{ + uint64_t ax = copy_id(a); + long double b = a; + u128_t bx = copy_ild(b); + printf("cvtld %016llx %016llx%016llx\n", (long long)ax, bx.x1, bx.x0); +} + +void cvtfl(long double a) +{ + u128_t ax = copy_ild(a); + float b = a; + uint32_t bx = copy_if(b); + printf("cvtfl %016llx%016llx %08lx\n", ax.x1, ax.x0, (long)bx); +} + +void cvtdl(long double a) +{ + u128_t ax = copy_ild(a); + double b = a; + uint64_t bx = copy_id(b); + printf("cvtdl %016llx%016llx %016llx\n", ax.x1, ax.x0, (long long)bx); +} + +void cvts(void) +{ + int i, j; + + { + uint32_t x = 0xad040c5b; + cvtlsw(0); + for (i = 0; i < 31; i++) + cvtlsw(x >> (31 - i)); + for (i = 0; i < 31; i++) + cvtlsw(-(x >> (31 - i))); + cvtlsw(0x80000000); + } + { + uint64_t x = 0xb630a248cad9afd2; + cvtlsx(0); + for (i = 0; i < 63; i++) + cvtlsx(x >> (63 - i)); + for (i = 0; i < 63; i++) + cvtlsx(-(x >> (63 - i))); + cvtlsx(0x8000000000000000); + } + { + uint32_t x = 0xad040c5b; + cvtluw(0); + for (i = 0; i < 32; i++) + cvtluw(x >> (31 - i)); + } + { + uint64_t x = 0xb630a248cad9afd2; + cvtlux(0); + for (i = 0; i < 64; i++) + cvtlux(x >> (63 - i)); + } + + for (i = 0; i < 2; i++) { + cvtil(make(i, 32767, 0, 1)); + cvtil(make(i, 32767, (uint64_t)1 << 47, 0)); + cvtil(make(i, 32767, 123, 456)); + cvtil(make(i, 32767, 0, 0)); + cvtil(make(i, 16382, -1, -1)); + cvtil(make(i, 16383, -1, -1)); + cvtil(make(i, 16384, 0x7fffffffffff, -1)); + cvtil(make(i, 16384, 0x800000000000, 0)); + for (j = 0; j < 68; j++) + cvtil(make(i, 16381 + j, 0xd4822c0a10ec, 0x1fe2f8b2669f5c9d)); + } + + cvtlf(copy_fi(0x00000000)); + cvtlf(copy_fi(0x456789ab)); + cvtlf(copy_fi(0x7f800000)); + cvtlf(copy_fi(0x7f923456)); + cvtlf(copy_fi(0x7fdbcdef)); + cvtlf(copy_fi(0x80000000)); + cvtlf(copy_fi(0xabcdef12)); + cvtlf(copy_fi(0xff800000)); + cvtlf(copy_fi(0xff923456)); + cvtlf(copy_fi(0xffdbcdef)); + + cvtld(copy_di(0x0000000000000000)); + cvtld(copy_di(0x456789abcdef0123)); + cvtld(copy_di(0x7ff0000000000000)); + cvtld(copy_di(0x7ff123456789abcd)); + cvtld(copy_di(0x7ffabcdef1234567)); + cvtld(copy_di(0x8000000000000000)); + cvtld(copy_di(0xcdef123456789abc)); + cvtld(copy_di(0xfff0000000000000)); + cvtld(copy_di(0xfff123456789abcd)); + cvtld(copy_di(0xfffabcdef1234567)); + + for (i = 0; i < 2; i++) { \ + cvtfl(make(i, 0, 0, 0)); + cvtfl(make(i, 16232, -1, -1)); + cvtfl(make(i, 16233, 0, 0)); + cvtfl(make(i, 16233, 0, 1)); + cvtfl(make(i, 16383, 0xab0ffd000000, 0)); + cvtfl(make(i, 16383, 0xab0ffd000001, 0)); + cvtfl(make(i, 16383, 0xab0ffeffffff, 0)); + cvtfl(make(i, 16383, 0xab0fff000000, 0)); + cvtfl(make(i, 16383, 0xab0fff000001, 0)); + cvtfl(make(i, 16510, 0xfffffeffffff, -1)); + cvtfl(make(i, 16510, 0xffffff000000, 0)); + cvtfl(make(i, 16511, 0, 0)); + cvtfl(make(i, 32767, 0, 0)); + cvtfl(make(i, 32767, 0, 1)); + cvtfl(make(i, 32767, 0x4cbe01ac5f40, 0x75cee3c6afbb00b5)); + cvtfl(make(i, 32767, 0x800000000000, 1)); + cvtfl(make(i, 32767, 0xa11caaaf6a52, 0x696033e871eab099)); + } + + for (i = 0; i < 2; i++) { + cvtdl(make(i, 0, 0, 0)); + cvtdl(make(i, 15307, -1, -1)); + cvtdl(make(i, 15308, 0, 0)); + cvtdl(make(i, 15308, 0, 1)); + cvtdl(make(i, 16383, 0xabc123abc0ff, 0xe800000000000000)); + cvtdl(make(i, 16383, 0xabc123abc0ff, 0xe800000000000001)); + cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf7ffffffffffffff)); + cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf800000000000000)); + cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf800000000000001)); + cvtdl(make(i, 17406, 0xffffffffffff, 0xf7ffffffffffffff)); + cvtdl(make(i, 17406, 0xffffffffffff, 0xf800000000000000)); + cvtdl(make(i, 17407, 0, 0)); + cvtdl(make(i, 32767, 0, 0)); + cvtdl(make(i, 32767, 0, 1)); + cvtdl(make(i, 32767, 0x4cbe01ac5f40, 0x75cee3c6afbb00b5)); + cvtdl(make(i, 32767, 0x800000000000, 1)); + cvtdl(make(i, 32767, 0xa11caaaf6a52, 0x696033e871eab099)); + } +} + +void tests(void) +{ + cmps(); + nanz(); + adds(); + muls(); + divs(); + cvts(); +} + +int main() +{ +#ifdef __aarch64__ + tests(); +#else + printf("This test program is intended for a little-endian architecture\n" + "with an IEEE-standard 128-bit long double.\n"); +#endif + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/00_assignment.c b/05/tcc-0.9.27/tests/tests2/00_assignment.c new file mode 100644 index 0000000..c96109f --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/00_assignment.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +int main() +{ + int a; + a = 42; + printf("%d\n", a); + + int b = 64; + printf("%d\n", b); + + int c = 12, d = 34; + printf("%d, %d\n", c, d); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/05/tcc-0.9.27/tests/tests2/00_assignment.expect b/05/tcc-0.9.27/tests/tests2/00_assignment.expect new file mode 100644 index 0000000..d4407f3 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/00_assignment.expect @@ -0,0 +1,3 @@ +42 +64 +12, 34 diff --git a/05/tcc-0.9.27/tests/tests2/01_comment.c b/05/tcc-0.9.27/tests/tests2/01_comment.c new file mode 100644 index 0000000..a2e6bc6 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/01_comment.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +int main() +{ + printf("Hello\n"); + printf("Hello\n"); /* this is a comment */ printf("Hello\n"); + printf("Hello\n"); + // this is also a comment sayhello(); + printf("Hello\n"); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/05/tcc-0.9.27/tests/tests2/01_comment.expect b/05/tcc-0.9.27/tests/tests2/01_comment.expect new file mode 100644 index 0000000..b1387ad --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/01_comment.expect @@ -0,0 +1,5 @@ +Hello +Hello +Hello +Hello +Hello diff --git a/05/tcc-0.9.27/tests/tests2/02_printf.c b/05/tcc-0.9.27/tests/tests2/02_printf.c new file mode 100644 index 0000000..4c34dd8 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/02_printf.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +int main() +{ + printf("Hello world\n"); + + int Count; + for (Count = -5; Count <= 5; Count++) + printf("Count = %d\n", Count); + + printf("String 'hello', 'there' is '%s', '%s'\n", "hello", "there"); + printf("Character 'A' is '%c'\n", 65); + printf("Character 'a' is '%c'\n", 'a'); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/05/tcc-0.9.27/tests/tests2/02_printf.expect b/05/tcc-0.9.27/tests/tests2/02_printf.expect new file mode 100644 index 0000000..f67a0f6 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/02_printf.expect @@ -0,0 +1,15 @@ +Hello world +Count = -5 +Count = -4 +Count = -3 +Count = -2 +Count = -1 +Count = 0 +Count = 1 +Count = 2 +Count = 3 +Count = 4 +Count = 5 +String 'hello', 'there' is 'hello', 'there' +Character 'A' is 'A' +Character 'a' is 'a' diff --git a/05/tcc-0.9.27/tests/tests2/03_struct.c b/05/tcc-0.9.27/tests/tests2/03_struct.c new file mode 100644 index 0000000..c5d48c5 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/03_struct.c @@ -0,0 +1,31 @@ +#include <stdio.h> + +struct fred +{ + int boris; + int natasha; +}; + +int main() +{ + struct fred bloggs; + + bloggs.boris = 12; + bloggs.natasha = 34; + + printf("%d\n", bloggs.boris); + printf("%d\n", bloggs.natasha); + + struct fred jones[2]; + jones[0].boris = 12; + jones[0].natasha = 34; + jones[1].boris = 56; + jones[1].natasha = 78; + + printf("%d\n", jones[0].boris); + printf("%d\n", jones[0].natasha); + printf("%d\n", jones[1].boris); + printf("%d\n", jones[1].natasha); + + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/03_struct.expect b/05/tcc-0.9.27/tests/tests2/03_struct.expect new file mode 100644 index 0000000..ecbf589 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/03_struct.expect @@ -0,0 +1,6 @@ +12 +34 +12 +34 +56 +78 diff --git a/05/tcc-0.9.27/tests/tests2/04_for.c b/05/tcc-0.9.27/tests/tests2/04_for.c new file mode 100644 index 0000000..312fed8 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/04_for.c @@ -0,0 +1,15 @@ +#include <stdio.h> + +int main() +{ + int Count; + + for (Count = 1; Count <= 10; Count++) + { + printf("%d\n", Count); + } + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/05/tcc-0.9.27/tests/tests2/04_for.expect b/05/tcc-0.9.27/tests/tests2/04_for.expect new file mode 100644 index 0000000..f00c965 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/04_for.expect @@ -0,0 +1,10 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 diff --git a/05/tcc-0.9.27/tests/tests2/05_array.c b/05/tcc-0.9.27/tests/tests2/05_array.c new file mode 100644 index 0000000..c218f31 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/05_array.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int main() +{ + int Count; + int Array[10]; + + for (Count = 1; Count <= 10; Count++) + { + Array[Count-1] = Count * Count; + } + + for (Count = 0; Count < 10; Count++) + { + printf("%d\n", Array[Count]); + } + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/05/tcc-0.9.27/tests/tests2/05_array.expect b/05/tcc-0.9.27/tests/tests2/05_array.expect new file mode 100644 index 0000000..bc7257c --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/05_array.expect @@ -0,0 +1,10 @@ +1 +4 +9 +16 +25 +36 +49 +64 +81 +100 diff --git a/05/tcc-0.9.27/tests/tests2/06_case.c b/05/tcc-0.9.27/tests/tests2/06_case.c new file mode 100644 index 0000000..c0191e2 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/06_case.c @@ -0,0 +1,29 @@ +#include <stdio.h> + +int main() +{ + int Count; + + for (Count = 0; Count < 4; Count++) + { + printf("%d\n", Count); + switch (Count) + { + case 1: + printf("%d\n", 1); + break; + + case 2: + printf("%d\n", 2); + break; + + default: + printf("%d\n", 0); + break; + } + } + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/05/tcc-0.9.27/tests/tests2/06_case.expect b/05/tcc-0.9.27/tests/tests2/06_case.expect new file mode 100644 index 0000000..fab2c20 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/06_case.expect @@ -0,0 +1,8 @@ +0 +0 +1 +1 +2 +2 +3 +0 diff --git a/05/tcc-0.9.27/tests/tests2/07_function.c b/05/tcc-0.9.27/tests/tests2/07_function.c new file mode 100644 index 0000000..0477ce1 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/07_function.c @@ -0,0 +1,30 @@ +#include <stdio.h> + +int myfunc(int x) +{ + return x * x; +} + +void vfunc(int a) +{ + printf("a=%d\n", a); +} + +void qfunc() +{ + printf("qfunc()\n"); +} + +int main() +{ + printf("%d\n", myfunc(3)); + printf("%d\n", myfunc(4)); + + vfunc(1234); + + qfunc(); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/05/tcc-0.9.27/tests/tests2/07_function.expect b/05/tcc-0.9.27/tests/tests2/07_function.expect new file mode 100644 index 0000000..8ffb0a7 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/07_function.expect @@ -0,0 +1,4 @@ +9 +16 +a=1234 +qfunc() diff --git a/05/tcc-0.9.27/tests/tests2/08_while.c b/05/tcc-0.9.27/tests/tests2/08_while.c new file mode 100644 index 0000000..602ffc7 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/08_while.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +int main() +{ + int a; + int p; + int t; + + a = 1; + p = 0; + t = 0; + + while (a < 100) + { + printf("%d\n", a); + t = a; + a = t + p; + p = t; + } + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/05/tcc-0.9.27/tests/tests2/08_while.expect b/05/tcc-0.9.27/tests/tests2/08_while.expect new file mode 100644 index 0000000..702d4c0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/08_while.expect @@ -0,0 +1,11 @@ +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 diff --git a/05/tcc-0.9.27/tests/tests2/09_do_while.c b/05/tcc-0.9.27/tests/tests2/09_do_while.c new file mode 100644 index 0000000..1d3315d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/09_do_while.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +int main() +{ + int a; + int p; + int t; + + a = 1; + p = 0; + t = 0; + + do + { + printf("%d\n", a); + t = a; + a = t + p; + p = t; + } while (a < 100); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/05/tcc-0.9.27/tests/tests2/09_do_while.expect b/05/tcc-0.9.27/tests/tests2/09_do_while.expect new file mode 100644 index 0000000..702d4c0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/09_do_while.expect @@ -0,0 +1,11 @@ +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 diff --git a/05/tcc-0.9.27/tests/tests2/10_pointer.c b/05/tcc-0.9.27/tests/tests2/10_pointer.c new file mode 100644 index 0000000..0177f4d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/10_pointer.c @@ -0,0 +1,40 @@ +#include <stdio.h> + +struct ziggy +{ + int a; + int b; + int c; +} bolshevic; + +int main() +{ + int a; + int *b; + int c; + + a = 42; + b = &a; + printf("a = %d\n", *b); + + bolshevic.a = 12; + bolshevic.b = 34; + bolshevic.c = 56; + + printf("bolshevic.a = %d\n", bolshevic.a); + printf("bolshevic.b = %d\n", bolshevic.b); + printf("bolshevic.c = %d\n", bolshevic.c); + + struct ziggy *tsar = &bolshevic; + + printf("tsar->a = %d\n", tsar->a); + printf("tsar->b = %d\n", tsar->b); + printf("tsar->c = %d\n", tsar->c); + + b = &(bolshevic.b); + printf("bolshevic.b = %d\n", *b); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/05/tcc-0.9.27/tests/tests2/10_pointer.expect b/05/tcc-0.9.27/tests/tests2/10_pointer.expect new file mode 100644 index 0000000..1e3c473 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/10_pointer.expect @@ -0,0 +1,8 @@ +a = 42 +bolshevic.a = 12 +bolshevic.b = 34 +bolshevic.c = 56 +tsar->a = 12 +tsar->b = 34 +tsar->c = 56 +bolshevic.b = 34 diff --git a/05/tcc-0.9.27/tests/tests2/11_precedence.c b/05/tcc-0.9.27/tests/tests2/11_precedence.c new file mode 100644 index 0000000..db2049d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/11_precedence.c @@ -0,0 +1,40 @@ +#include <stdio.h> + +int main() +{ + int a; + int b; + int c; + int d; + int e; + int f; + int x; + int y; + + a = 12; + b = 34; + c = 56; + d = 78; + e = 0; + f = 1; + + printf("%d\n", c + d); + printf("%d\n", (y = c + d)); + printf("%d\n", e || e && f); + printf("%d\n", e || f && f); + printf("%d\n", e && e || f); + printf("%d\n", e && f || f); + printf("%d\n", a && f | f); + printf("%d\n", a | b ^ c & d); + printf("%d, %d\n", a == a, a == b); + printf("%d, %d\n", a != a, a != b); + printf("%d\n", a != b && c != d); + printf("%d\n", a + b * c / f); + printf("%d\n", a + b * c / f); + printf("%d\n", (4 << 4)); + printf("%d\n", (64 >> 4)); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/05/tcc-0.9.27/tests/tests2/11_precedence.expect b/05/tcc-0.9.27/tests/tests2/11_precedence.expect new file mode 100644 index 0000000..b692396 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/11_precedence.expect @@ -0,0 +1,15 @@ +134 +134 +0 +1 +1 +1 +1 +46 +1, 0 +0, 1 +1 +1916 +1916 +64 +4 diff --git a/05/tcc-0.9.27/tests/tests2/12_hashdefine.c b/05/tcc-0.9.27/tests/tests2/12_hashdefine.c new file mode 100644 index 0000000..5c521e0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/12_hashdefine.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +#define FRED 12 +#define BLOGGS(x) (12*(x)) + +int main() +{ + printf("%d\n", FRED); + printf("%d, %d, %d\n", BLOGGS(1), BLOGGS(2), BLOGGS(3)); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/05/tcc-0.9.27/tests/tests2/12_hashdefine.expect b/05/tcc-0.9.27/tests/tests2/12_hashdefine.expect new file mode 100644 index 0000000..99f2ed5 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/12_hashdefine.expect @@ -0,0 +1,2 @@ +12 +12, 24, 36 diff --git a/05/tcc-0.9.27/tests/tests2/13_integer_literals.c b/05/tcc-0.9.27/tests/tests2/13_integer_literals.c new file mode 100644 index 0000000..7cee98b --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/13_integer_literals.c @@ -0,0 +1,20 @@ +#include <stdio.h> + +int main() +{ + int a = 24680; + int b = 01234567; + int c = 0x2468ac; + int d = 0x2468AC; + int e = 0b010101010101; + + printf("%d\n", a); + printf("%d\n", b); + printf("%d\n", c); + printf("%d\n", d); + printf("%d\n", e); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/05/tcc-0.9.27/tests/tests2/13_integer_literals.expect b/05/tcc-0.9.27/tests/tests2/13_integer_literals.expect new file mode 100644 index 0000000..f5aca06 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/13_integer_literals.expect @@ -0,0 +1,5 @@ +24680 +342391 +2386092 +2386092 +1365 diff --git a/05/tcc-0.9.27/tests/tests2/14_if.c b/05/tcc-0.9.27/tests/tests2/14_if.c new file mode 100644 index 0000000..2bd2550 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/14_if.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int main() +{ + int a = 1; + + if (a) + printf("a is true\n"); + else + printf("a is false\n"); + + int b = 0; + if (b) + printf("b is true\n"); + else + printf("b is false\n"); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/05/tcc-0.9.27/tests/tests2/14_if.expect b/05/tcc-0.9.27/tests/tests2/14_if.expect new file mode 100644 index 0000000..c32c415 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/14_if.expect @@ -0,0 +1,2 @@ +a is true +b is false diff --git a/05/tcc-0.9.27/tests/tests2/15_recursion.c b/05/tcc-0.9.27/tests/tests2/15_recursion.c new file mode 100644 index 0000000..f79a00d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/15_recursion.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int factorial(int i) +{ + if (i < 2) + return i; + else + return i * factorial(i - 1); +} + +int main() +{ + int Count; + + for (Count = 1; Count <= 10; Count++) + printf("%d\n", factorial(Count)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/15_recursion.expect b/05/tcc-0.9.27/tests/tests2/15_recursion.expect new file mode 100644 index 0000000..db47b28 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/15_recursion.expect @@ -0,0 +1,10 @@ +1 +2 +6 +24 +120 +720 +5040 +40320 +362880 +3628800 diff --git a/05/tcc-0.9.27/tests/tests2/16_nesting.c b/05/tcc-0.9.27/tests/tests2/16_nesting.c new file mode 100644 index 0000000..2b72cc0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/16_nesting.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int main() +{ + int x, y, z; + + for (x = 0; x < 2; x++) + { + for (y = 0; y < 3; y++) + { + for (z = 0; z < 3; z++) + { + printf("%d %d %d\n", x, y, z); + } + } + } + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/16_nesting.expect b/05/tcc-0.9.27/tests/tests2/16_nesting.expect new file mode 100644 index 0000000..5a3431e --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/16_nesting.expect @@ -0,0 +1,18 @@ +0 0 0 +0 0 1 +0 0 2 +0 1 0 +0 1 1 +0 1 2 +0 2 0 +0 2 1 +0 2 2 +1 0 0 +1 0 1 +1 0 2 +1 1 0 +1 1 1 +1 1 2 +1 2 0 +1 2 1 +1 2 2 diff --git a/05/tcc-0.9.27/tests/tests2/17_enum.c b/05/tcc-0.9.27/tests/tests2/17_enum.c new file mode 100644 index 0000000..e2bc736 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/17_enum.c @@ -0,0 +1,72 @@ +#include <stdio.h> + +enum fred +{ + a, + b, + c, + d, + e = 54, + f = 73, + g, + h +}; + +/* All following uses of enum efoo should compile + without warning. While forward enums aren't ISO C, + it's accepted by GCC also in strict mode, and only warned + about with -pedantic. This happens in the real world. */ +/* Strict ISO C doesn't allow this kind of forward declaration of + enums, but GCC accepts it (and gives only pedantic warning), and + it occurs in the wild. */ +enum efoo; +struct Sforward_use { + int (*fmember) (enum efoo x); +}; + +extern enum efoo it_real_fn(void); +enum efoo { + ONE, + TWO, +}; +struct S2 { + enum efoo (*f2) (void); +}; +void should_compile(struct S2 *s) +{ + s->f2 = it_real_fn; +} + +enum efoo it_real_fn(void) +{ + return TWO; +} + +static unsigned int deref_uintptr(unsigned int *p) +{ + return *p; +} + +enum Epositive { + epos_one, epos_two +}; + +int main() +{ + enum fred frod; + enum Epositive epos = epos_two; + + printf("%d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h); + /* printf("%d\n", frod); */ + frod = 12; + printf("%d\n", frod); + frod = e; + printf("%d\n", frod); + + /* Following should compile without warning. */ + printf ("enum to int: %u\n", deref_uintptr(&epos)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/17_enum.expect b/05/tcc-0.9.27/tests/tests2/17_enum.expect new file mode 100644 index 0000000..d453a61 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/17_enum.expect @@ -0,0 +1,4 @@ +0 1 2 3 54 73 74 75 +12 +54 +enum to int: 1 diff --git a/05/tcc-0.9.27/tests/tests2/18_include.c b/05/tcc-0.9.27/tests/tests2/18_include.c new file mode 100644 index 0000000..dbae3aa --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/18_include.c @@ -0,0 +1,12 @@ +#include <stdio.h> + +int main() +{ + printf("including\n"); +#include "18_include.h" + printf("done\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/18_include.expect b/05/tcc-0.9.27/tests/tests2/18_include.expect new file mode 100644 index 0000000..58c6d29 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/18_include.expect @@ -0,0 +1,3 @@ +including +included +done diff --git a/05/tcc-0.9.27/tests/tests2/18_include.h b/05/tcc-0.9.27/tests/tests2/18_include.h new file mode 100644 index 0000000..dc86080 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/18_include.h @@ -0,0 +1 @@ +printf("included\n"); diff --git a/05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.c b/05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.c new file mode 100644 index 0000000..aff65e5 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.c @@ -0,0 +1,28 @@ +#include <stdio.h> + +int main() +{ + int a; + int *b; + int *c; + + a = 42; + b = &a; + c = NULL; + + printf("%d\n", *b); + + if (b == NULL) + printf("b is NULL\n"); + else + printf("b is not NULL\n"); + + if (c == NULL) + printf("c is NULL\n"); + else + printf("c is not NULL\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.expect b/05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.expect new file mode 100644 index 0000000..0cf781b --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.expect @@ -0,0 +1,3 @@ +42 +b is not NULL +c is NULL diff --git a/05/tcc-0.9.27/tests/tests2/20_pointer_comparison.c b/05/tcc-0.9.27/tests/tests2/20_pointer_comparison.c new file mode 100644 index 0000000..825f778 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/20_pointer_comparison.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +int main() +{ + int a; + int b; + int *d; + int *e; + d = &a; + e = &b; + a = 12; + b = 34; + printf("%d\n", *d); + printf("%d\n", *e); + printf("%d\n", d == e); + printf("%d\n", d != e); + d = e; + printf("%d\n", d == e); + printf("%d\n", d != e); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/20_pointer_comparison.expect b/05/tcc-0.9.27/tests/tests2/20_pointer_comparison.expect new file mode 100644 index 0000000..5d1e5f5 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/20_pointer_comparison.expect @@ -0,0 +1,6 @@ +12 +34 +0 +1 +1 +0 diff --git a/05/tcc-0.9.27/tests/tests2/21_char_array.c b/05/tcc-0.9.27/tests/tests2/21_char_array.c new file mode 100644 index 0000000..f22f527 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/21_char_array.c @@ -0,0 +1,33 @@ +#include <stdio.h> + +int main() +{ + int x = 'a'; + char y = x; + + char *a = "hello"; + + printf("%s\n", a); + + int c; + c = *a; + + char *b; + for (b = a; *b != 0; b++) + printf("%c: %d\n", *b, *b); + + char destarray[10]; + char *dest = &destarray[0]; + char *src = a; + + while (*src != 0) + *dest++ = *src++; + + *dest = 0; + + printf("copied string is %s\n", destarray); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/21_char_array.expect b/05/tcc-0.9.27/tests/tests2/21_char_array.expect new file mode 100644 index 0000000..dbc6068 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/21_char_array.expect @@ -0,0 +1,7 @@ +hello +h: 104 +e: 101 +l: 108 +l: 108 +o: 111 +copied string is hello diff --git a/05/tcc-0.9.27/tests/tests2/22_floating_point.c b/05/tcc-0.9.27/tests/tests2/22_floating_point.c new file mode 100644 index 0000000..e3491f5 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/22_floating_point.c @@ -0,0 +1,50 @@ +#include <stdio.h> +#include <math.h> + +int main() +{ + // variables + float a = 12.34 + 56.78; + printf("%f\n", a); + + // infix operators + printf("%f\n", 12.34 + 56.78); + printf("%f\n", 12.34 - 56.78); + printf("%f\n", 12.34 * 56.78); + printf("%f\n", 12.34 / 56.78); + + // comparison operators + printf("%d %d %d %d %d %d\n", 12.34 < 56.78, 12.34 <= 56.78, 12.34 == 56.78, 12.34 >= 56.78, 12.34 > 56.78, 12.34 != 56.78); + printf("%d %d %d %d %d %d\n", 12.34 < 12.34, 12.34 <= 12.34, 12.34 == 12.34, 12.34 >= 12.34, 12.34 > 12.34, 12.34 != 12.34); + printf("%d %d %d %d %d %d\n", 56.78 < 12.34, 56.78 <= 12.34, 56.78 == 12.34, 56.78 >= 12.34, 56.78 > 12.34, 56.78 != 12.34); + + // assignment operators + a = 12.34; + a += 56.78; + printf("%f\n", a); + + a = 12.34; + a -= 56.78; + printf("%f\n", a); + + a = 12.34; + a *= 56.78; + printf("%f\n", a); + + a = 12.34; + a /= 56.78; + printf("%f\n", a); + + // prefix operators + printf("%f\n", +12.34); + printf("%f\n", -12.34); + + // type coercion + a = 2; + printf("%f\n", a); + printf("%f\n", sin(2)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/22_floating_point.expect b/05/tcc-0.9.27/tests/tests2/22_floating_point.expect new file mode 100644 index 0000000..75ea3a7 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/22_floating_point.expect @@ -0,0 +1,16 @@ +69.120003 +69.120000 +-44.440000 +700.665200 +0.217330 +1 1 0 0 0 1 +0 1 1 1 0 0 +0 0 0 1 1 1 +69.120003 +-44.439999 +700.665222 +0.217330 +12.340000 +-12.340000 +2.000000 +0.909297 diff --git a/05/tcc-0.9.27/tests/tests2/23_type_coercion.c b/05/tcc-0.9.27/tests/tests2/23_type_coercion.c new file mode 100644 index 0000000..1fcc335 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/23_type_coercion.c @@ -0,0 +1,54 @@ +#include <stdio.h> + +void charfunc(char a) +{ + printf("char: %c\n", a); +} + +void intfunc(int a) +{ + printf("int: %d\n", a); +} + +void floatfunc(float a) +{ + printf("float: %f\n", a); +} + +int main() +{ + charfunc('a'); + charfunc(98); + charfunc(99.0); + + intfunc('a'); + intfunc(98); + intfunc(99.0); + + floatfunc('a'); + floatfunc(98); + floatfunc(99.0); + + /* printf("%c %d %f\n", 'a', 'b', 'c'); */ + /* printf("%c %d %f\n", 97, 98, 99); */ + /* printf("%c %d %f\n", 97.0, 98.0, 99.0); */ + + char b = 97; + char c = 97.0; + + printf("%d %d\n", b, c); + + int d = 'a'; + int e = 97.0; + + printf("%d %d\n", d, e); + + float f = 'a'; + float g = 97; + + printf("%f %f\n", f, g); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/23_type_coercion.expect b/05/tcc-0.9.27/tests/tests2/23_type_coercion.expect new file mode 100644 index 0000000..d9076f0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/23_type_coercion.expect @@ -0,0 +1,12 @@ +char: a +char: b +char: c +int: 97 +int: 98 +int: 99 +float: 97.000000 +float: 98.000000 +float: 99.000000 +97 97 +97 97 +97.000000 97.000000 diff --git a/05/tcc-0.9.27/tests/tests2/24_math_library.c b/05/tcc-0.9.27/tests/tests2/24_math_library.c new file mode 100644 index 0000000..514a25f --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/24_math_library.c @@ -0,0 +1,30 @@ +#define _ISOC99_SOURCE 1 + +#include <stdio.h> +#include <math.h> + +int main() +{ + printf("%f\n", sin(0.12)); + printf("%f\n", cos(0.12)); + printf("%f\n", tan(0.12)); + printf("%f\n", asin(0.12)); + printf("%f\n", acos(0.12)); + printf("%f\n", atan(0.12)); + printf("%f\n", sinh(0.12)); + printf("%f\n", cosh(0.12)); + printf("%f\n", tanh(0.12)); + printf("%f\n", exp(0.12)); + printf("%f\n", fabs(-0.12)); + printf("%f\n", log(0.12)); + printf("%f\n", log10(0.12)); + printf("%f\n", pow(0.12, 0.12)); + printf("%f\n", sqrt(0.12)); + printf("%f\n", round(12.34)); + printf("%f\n", ceil(12.34)); + printf("%f\n", floor(12.34)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/24_math_library.expect b/05/tcc-0.9.27/tests/tests2/24_math_library.expect new file mode 100644 index 0000000..99f7299 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/24_math_library.expect @@ -0,0 +1,18 @@ +0.119712 +0.992809 +0.120579 +0.120290 +1.450506 +0.119429 +0.120288 +1.007209 +0.119427 +1.127497 +0.120000 +-2.120264 +-0.920819 +0.775357 +0.346410 +12.000000 +13.000000 +12.000000 diff --git a/05/tcc-0.9.27/tests/tests2/25_quicksort.c b/05/tcc-0.9.27/tests/tests2/25_quicksort.c new file mode 100644 index 0000000..5cc08bd --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/25_quicksort.c @@ -0,0 +1,83 @@ +#include <stdio.h> + +int array[16]; + +//Swap integer values by array indexes +void swap(int a, int b) +{ + int tmp = array[a]; + array[a] = array[b]; + array[b] = tmp; +} + +//Partition the array into two halves and return the +//index about which the array is partitioned +int partition(int left, int right) +{ + int pivotIndex = left; + int pivotValue = array[pivotIndex]; + int index = left; + int i; + + swap(pivotIndex, right); + for(i = left; i < right; i++) + { + if(array[i] < pivotValue) + { + swap(i, index); + index += 1; + } + } + swap(right, index); + + return index; +} + +//Quicksort the array +void quicksort(int left, int right) +{ + if(left >= right) + return; + + int index = partition(left, right); + quicksort(left, index - 1); + quicksort(index + 1, right); +} + +int main() +{ + int i; + + array[0] = 62; + array[1] = 83; + array[2] = 4; + array[3] = 89; + array[4] = 36; + array[5] = 21; + array[6] = 74; + array[7] = 37; + array[8] = 65; + array[9] = 33; + array[10] = 96; + array[11] = 38; + array[12] = 53; + array[13] = 16; + array[14] = 74; + array[15] = 55; + + for (i = 0; i < 16; i++) + printf("%d ", array[i]); + + printf("\n"); + + quicksort(0, 15); + + for (i = 0; i < 16; i++) + printf("%d ", array[i]); + + printf("\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/25_quicksort.expect b/05/tcc-0.9.27/tests/tests2/25_quicksort.expect new file mode 100644 index 0000000..2d39cd3 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/25_quicksort.expect @@ -0,0 +1,2 @@ +62 83 4 89 36 21 74 37 65 33 96 38 53 16 74 55 +4 16 21 33 36 37 38 53 55 62 65 74 74 83 89 96 diff --git a/05/tcc-0.9.27/tests/tests2/26_character_constants.c b/05/tcc-0.9.27/tests/tests2/26_character_constants.c new file mode 100644 index 0000000..95c4423 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/26_character_constants.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +int main() +{ + printf("%d\n", '\1'); + printf("%d\n", '\10'); + printf("%d\n", '\100'); + printf("%d\n", '\x01'); + printf("%d\n", '\x0e'); + printf("%d\n", '\x10'); + printf("%d\n", '\x40'); + printf("test \x40\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/26_character_constants.expect b/05/tcc-0.9.27/tests/tests2/26_character_constants.expect new file mode 100644 index 0000000..8f8bfa4 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/26_character_constants.expect @@ -0,0 +1,8 @@ +1 +8 +64 +1 +14 +16 +64 +test @ diff --git a/05/tcc-0.9.27/tests/tests2/27_sizeof.c b/05/tcc-0.9.27/tests/tests2/27_sizeof.c new file mode 100644 index 0000000..5ae0ede --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/27_sizeof.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +int main() +{ + char a; + int b; + double c; + + printf("%d\n", sizeof(a)); + printf("%d\n", sizeof(b)); + printf("%d\n", sizeof(c)); + + printf("%d\n", sizeof(!a)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/27_sizeof.expect b/05/tcc-0.9.27/tests/tests2/27_sizeof.expect new file mode 100644 index 0000000..a47ea3a --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/27_sizeof.expect @@ -0,0 +1,4 @@ +1 +4 +8 +4 diff --git a/05/tcc-0.9.27/tests/tests2/28_strings.c b/05/tcc-0.9.27/tests/tests2/28_strings.c new file mode 100644 index 0000000..2db2298 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/28_strings.c @@ -0,0 +1,45 @@ +#include <stdio.h> +#include <string.h> + +int main() +{ + char a[10]; + + strcpy(a, "hello"); + printf("%s\n", a); + + strncpy(a, "gosh", 2); + printf("%s\n", a); + + printf("%d\n", strcmp(a, "apple") > 0); + printf("%d\n", strcmp(a, "goere") > 0); + printf("%d\n", strcmp(a, "zebra") < 0); + + printf("%d\n", strlen(a)); + + strcat(a, "!"); + printf("%s\n", a); + + printf("%d\n", strncmp(a, "apple", 2) > 0); + printf("%d\n", strncmp(a, "goere", 2) == 0); + printf("%d\n", strncmp(a, "goerg", 2) == 0); + printf("%d\n", strncmp(a, "zebra", 2) < 0); + + printf("%s\n", strchr(a, 'o')); + printf("%s\n", strrchr(a, 'l')); + printf("%d\n", strrchr(a, 'x') == NULL); + + memset(&a[1], 'r', 4); + printf("%s\n", a); + + memcpy(&a[2], a, 2); + printf("%s\n", a); + + printf("%d\n", memcmp(a, "apple", 4) > 0); + printf("%d\n", memcmp(a, "grgr", 4) == 0); + printf("%d\n", memcmp(a, "zebra", 4) < 0); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/28_strings.expect b/05/tcc-0.9.27/tests/tests2/28_strings.expect new file mode 100644 index 0000000..fd9217a --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/28_strings.expect @@ -0,0 +1,19 @@ +hello +gollo +1 +1 +1 +5 +gollo! +1 +1 +1 +1 +ollo! +lo! +1 +grrrr! +grgrr! +1 +1 +1 diff --git a/05/tcc-0.9.27/tests/tests2/29_array_address.c b/05/tcc-0.9.27/tests/tests2/29_array_address.c new file mode 100644 index 0000000..bda5ddd --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/29_array_address.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include <string.h> + +int main() +{ + char a[10]; + strcpy(a, "abcdef"); + printf("%s\n", &a[1]); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/29_array_address.expect b/05/tcc-0.9.27/tests/tests2/29_array_address.expect new file mode 100644 index 0000000..9bc8683 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/29_array_address.expect @@ -0,0 +1 @@ +bcdef diff --git a/05/tcc-0.9.27/tests/tests2/30_hanoi.c b/05/tcc-0.9.27/tests/tests2/30_hanoi.c new file mode 100644 index 0000000..7c0893b --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/30_hanoi.c @@ -0,0 +1,122 @@ +/* example from http://barnyard.syr.edu/quickies/hanoi.c */ + +/* hanoi.c: solves the tower of hanoi problem. (Programming exercise.) */ +/* By Terry R. McConnell (12/2/97) */ +/* Compile: cc -o hanoi hanoi.c */ + +/* This program does no error checking. But then, if it's right, + it's right ... right ? */ + + +/* The original towers of hanoi problem seems to have been originally posed + by one M. Claus in 1883. There is a popular legend that goes along with + it that has been often repeated and paraphrased. It goes something like this: + In the great temple at Benares there are 3 golden spikes. On one of them, + God placed 64 disks increasing in size from bottom to top, at the beginning + of time. Since then, and to this day, the priest on duty constantly transfers + disks, one at a time, in such a way that no larger disk is ever put on top + of a smaller one. When the disks have been transferred entirely to another + spike the Universe will come to an end in a large thunderclap. + + This paraphrases the original legend due to DeParville, La Nature, Paris 1884, + Part I, 285-286. For this and further information see: Mathematical + Recreations & Essays, W.W. Rouse Ball, MacMillan, NewYork, 11th Ed. 1967, + 303-305. + * + * + */ + +#include <stdio.h> +#include <stdlib.h> + +#define TRUE 1 +#define FALSE 0 + +/* This is the number of "disks" on tower A initially. Taken to be 64 in the + * legend. The number of moves required, in general, is 2^N - 1. For N = 64, + * this is 18,446,744,073,709,551,615 */ +#define N 4 + +/* These are the three towers. For example if the state of A is 0,1,3,4, that + * means that there are three discs on A of sizes 1, 3, and 4. (Think of right + * as being the "down" direction.) */ +int A[N], B[N], C[N]; + +void Hanoi(int,int*,int*,int*); + +/* Print the current configuration of A, B, and C to the screen */ +void PrintAll() +{ + int i; + + printf("A: "); + for(i=0;i<N;i++)printf(" %d ",A[i]); + printf("\n"); + + printf("B: "); + for(i=0;i<N;i++)printf(" %d ",B[i]); + printf("\n"); + + printf("C: "); + for(i=0;i<N;i++)printf(" %d ",C[i]); + printf("\n"); + printf("------------------------------------------\n"); + return; +} + +/* Move the leftmost nonzero element of source to dest, leave behind 0. */ +/* Returns the value moved (not used.) */ +int Move(int *source, int *dest) +{ + int i = 0, j = 0; + + while (i<N && (source[i])==0) i++; + while (j<N && (dest[j])==0) j++; + + dest[j-1] = source[i]; + source[i] = 0; + PrintAll(); /* Print configuration after each move. */ + return dest[j-1]; +} + + +/* Moves first n nonzero numbers from source to dest using the rules of Hanoi. + Calls itself recursively. + */ +void Hanoi(int n,int *source, int *dest, int *spare) +{ + int i; + if(n==1){ + Move(source,dest); + return; + } + + Hanoi(n-1,source,spare,dest); + Move(source,dest); + Hanoi(n-1,spare,dest,source); + return; +} + +int main() +{ + int i; + + /* initialize the towers */ + for(i=0;i<N;i++)A[i]=i+1; + for(i=0;i<N;i++)B[i]=0; + for(i=0;i<N;i++)C[i]=0; + + printf("Solution of Tower of Hanoi Problem with %d Disks\n\n",N); + + /* Print the starting state */ + printf("Starting state:\n"); + PrintAll(); + printf("\n\nSubsequent states:\n\n"); + + /* Do it! Use A = Source, B = Destination, C = Spare */ + Hanoi(N,A,B,C); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/30_hanoi.expect b/05/tcc-0.9.27/tests/tests2/30_hanoi.expect new file mode 100644 index 0000000..7798ee0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/30_hanoi.expect @@ -0,0 +1,71 @@ +Solution of Tower of Hanoi Problem with 4 Disks + +Starting state: +A: 1 2 3 4 +B: 0 0 0 0 +C: 0 0 0 0 +------------------------------------------ + + +Subsequent states: + +A: 0 2 3 4 +B: 0 0 0 0 +C: 0 0 0 1 +------------------------------------------ +A: 0 0 3 4 +B: 0 0 0 2 +C: 0 0 0 1 +------------------------------------------ +A: 0 0 3 4 +B: 0 0 1 2 +C: 0 0 0 0 +------------------------------------------ +A: 0 0 0 4 +B: 0 0 1 2 +C: 0 0 0 3 +------------------------------------------ +A: 0 0 1 4 +B: 0 0 0 2 +C: 0 0 0 3 +------------------------------------------ +A: 0 0 1 4 +B: 0 0 0 0 +C: 0 0 2 3 +------------------------------------------ +A: 0 0 0 4 +B: 0 0 0 0 +C: 0 1 2 3 +------------------------------------------ +A: 0 0 0 0 +B: 0 0 0 4 +C: 0 1 2 3 +------------------------------------------ +A: 0 0 0 0 +B: 0 0 1 4 +C: 0 0 2 3 +------------------------------------------ +A: 0 0 0 2 +B: 0 0 1 4 +C: 0 0 0 3 +------------------------------------------ +A: 0 0 1 2 +B: 0 0 0 4 +C: 0 0 0 3 +------------------------------------------ +A: 0 0 1 2 +B: 0 0 3 4 +C: 0 0 0 0 +------------------------------------------ +A: 0 0 0 2 +B: 0 0 3 4 +C: 0 0 0 1 +------------------------------------------ +A: 0 0 0 0 +B: 0 2 3 4 +C: 0 0 0 1 +------------------------------------------ +A: 0 0 0 0 +B: 1 2 3 4 +C: 0 0 0 0 +------------------------------------------ diff --git a/05/tcc-0.9.27/tests/tests2/31_args.c b/05/tcc-0.9.27/tests/tests2/31_args.c new file mode 100644 index 0000000..dcafed5 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/31_args.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +int main(int argc, char **argv) +{ + int Count; + + printf("hello world %d\n", argc); + for (Count = 1; Count < argc; Count++) + printf("arg %d: %s\n", Count, argv[Count]); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/31_args.expect b/05/tcc-0.9.27/tests/tests2/31_args.expect new file mode 100644 index 0000000..8c60bfc --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/31_args.expect @@ -0,0 +1,6 @@ +hello world 6 +arg 1: arg1 +arg 2: arg2 +arg 3: arg3 +arg 4: arg4 +arg 5: arg5 diff --git a/05/tcc-0.9.27/tests/tests2/32_led.c b/05/tcc-0.9.27/tests/tests2/32_led.c new file mode 100644 index 0000000..5596cbf --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/32_led.c @@ -0,0 +1,266 @@ +/* example from http://barnyard.syr.edu/quickies/led.c */ + +/* led.c: print out number as if on 7 line led display. I.e., write integer + given on command line like this: + _ _ _ + | _| _| |_| |_ + | |_ _| | _| etc. + + We assume the terminal behaves like a classical teletype. So the top + lines of all digits have to be printed first, then the middle lines of + all digits, etc. + + By Terry R. McConnell + +compile: cc -o led led.c + +If you just want to link in the subroutine print_led that does all the +work, compile with -DNO_MAIN, and declare the following in any source file +that uses the call: + +extern void print_led(unsigned long x, char *buf); + +Bug: you cannot call repeatedly to print more than one number to a line. +That would require curses or some other terminal API that allows moving the +cursor to a previous line. + +*/ + + + +#include <stdlib.h> +#include <stdio.h> + +#define MAX_DIGITS 32 +#define NO_MAIN + + +/* Print the top line of the digit d into buffer. + Does not null terminate buffer. */ + +void topline(int d, char *p){ + + *p++ = ' '; + switch(d){ + + /* all these have _ on top line */ + + case 0: + case 2: + case 3: + case 5: + case 7: + case 8: + case 9: + *p++ = '_'; + break; + default: + *p++=' '; + + } + *p++=' '; +} + +/* Print the middle line of the digit d into the buffer. + Does not null terminate. */ + +void midline(int d, char *p){ + + switch(d){ + + /* those that have leading | on middle line */ + + case 0: + case 4: + case 5: + case 6: + case 8: + case 9: + *p++='|'; + break; + default: + *p++=' '; + } + switch(d){ + + /* those that have _ on middle line */ + + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + *p++='_'; + break; + default: + *p++=' '; + + } + switch(d){ + + /* those that have closing | on middle line */ + + case 0: + case 1: + case 2: + case 3: + case 4: + case 7: + case 8: + case 9: + *p++='|'; + break; + default: + *p++=' '; + + } +} + +/* Print the bottom line of the digit d. Does not null terminate. */ + +void botline(int d, char *p){ + + + switch(d){ + + /* those that have leading | on bottom line */ + + case 0: + case 2: + case 6: + case 8: + *p++='|'; + break; + default: + *p++=' '; + } + switch(d){ + + /* those that have _ on bottom line */ + + case 0: + case 2: + case 3: + case 5: + case 6: + case 8: + *p++='_'; + break; + default: + *p++=' '; + + } + switch(d){ + + /* those that have closing | on bottom line */ + + case 0: + case 1: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + *p++='|'; + break; + default: + *p++=' '; + + } +} + +/* Write the led representation of integer to string buffer. */ + +void print_led(unsigned long x, char *buf) +{ + + int i=0,n; + static int d[MAX_DIGITS]; + + + /* extract digits from x */ + + n = ( x == 0L ? 1 : 0 ); /* 0 is a digit, hence a special case */ + + while(x){ + d[n++] = (int)(x%10L); + if(n >= MAX_DIGITS)break; + x = x/10L; + } + + /* print top lines of all digits */ + + for(i=n-1;i>=0;i--){ + topline(d[i],buf); + buf += 3; + *buf++=' '; + } + *buf++='\n'; /* move teletype to next line */ + + /* print middle lines of all digits */ + + for(i=n-1;i>=0;i--){ + midline(d[i],buf); + buf += 3; + *buf++=' '; + } + *buf++='\n'; + + /* print bottom lines of all digits */ + + for(i=n-1;i>=0;i--){ + botline(d[i],buf); + buf += 3; + *buf++=' '; + } + *buf++='\n'; + *buf='\0'; +} + +int main() +{ + char buf[5*MAX_DIGITS]; + print_led(1234567, buf); + printf("%s\n",buf); + + return 0; +} + +#ifndef NO_MAIN +int main(int argc, char **argv) +{ + + int i=0,n; + long x; + static int d[MAX_DIGITS]; + char buf[5*MAX_DIGITS]; + + if(argc != 2){ + fprintf(stderr,"led: usage: led integer\n"); + return 1; + } + + /* fetch argument from command line */ + + x = atol(argv[1]); + + /* sanity check */ + + if(x<0){ + fprintf(stderr,"led: %d must be non-negative\n",x); + return 1; + } + + print_led(x,buf); + printf("%s\n",buf); + + return 0; + +} +#endif + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/32_led.expect b/05/tcc-0.9.27/tests/tests2/32_led.expect new file mode 100644 index 0000000..c53b58a --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/32_led.expect @@ -0,0 +1,4 @@ + _ _ _ _ + | _| _| |_| |_ |_ | + | |_ _| | _| |_| | + diff --git a/05/tcc-0.9.27/tests/tests2/33_ternary_op.c b/05/tcc-0.9.27/tests/tests2/33_ternary_op.c new file mode 100644 index 0000000..8579b50 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/33_ternary_op.c @@ -0,0 +1,15 @@ +#include <stdio.h> + +int main() +{ + int Count; + + for (Count = 0; Count < 10; Count++) + { + printf("%d\n", (Count < 5) ? (Count*Count) : (Count * 3)); + } + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/33_ternary_op.expect b/05/tcc-0.9.27/tests/tests2/33_ternary_op.expect new file mode 100644 index 0000000..45ea507 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/33_ternary_op.expect @@ -0,0 +1,10 @@ +0 +1 +4 +9 +16 +15 +18 +21 +24 +27 diff --git a/05/tcc-0.9.27/tests/tests2/34_array_assignment.c b/05/tcc-0.9.27/tests/tests2/34_array_assignment.c new file mode 100644 index 0000000..5885c97 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/34_array_assignment.c @@ -0,0 +1,23 @@ +#include <stdio.h> + +int main() +{ + int a[4]; + + a[0] = 12; + a[1] = 23; + a[2] = 34; + a[3] = 45; + + printf("%d %d %d %d\n", a[0], a[1], a[2], a[3]); + + int b[4]; + + b = a; + + printf("%d %d %d %d\n", b[0], b[1], b[2], b[3]); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/34_array_assignment.expect b/05/tcc-0.9.27/tests/tests2/34_array_assignment.expect new file mode 100644 index 0000000..9736bf5 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/34_array_assignment.expect @@ -0,0 +1,2 @@ +12 23 34 45 +12 23 34 45 diff --git a/05/tcc-0.9.27/tests/tests2/35_sizeof.c b/05/tcc-0.9.27/tests/tests2/35_sizeof.c new file mode 100644 index 0000000..672e87e --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/35_sizeof.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +int main() +{ + char a; + short b; + + printf("%d %d\n", sizeof(char), sizeof(a)); + printf("%d %d\n", sizeof(short), sizeof(b)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/35_sizeof.expect b/05/tcc-0.9.27/tests/tests2/35_sizeof.expect new file mode 100644 index 0000000..534fb83 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/35_sizeof.expect @@ -0,0 +1,2 @@ +1 1 +2 2 diff --git a/05/tcc-0.9.27/tests/tests2/36_array_initialisers.c b/05/tcc-0.9.27/tests/tests2/36_array_initialisers.c new file mode 100644 index 0000000..1bc8ee0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/36_array_initialisers.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int main() +{ + int Count; + + int Array[10] = { 12, 34, 56, 78, 90, 123, 456, 789, 8642, 9753 }; + + for (Count = 0; Count < 10; Count++) + printf("%d: %d\n", Count, Array[Count]); + + int Array2[10] = { 12, 34, 56, 78, 90, 123, 456, 789, 8642, 9753, }; + + for (Count = 0; Count < 10; Count++) + printf("%d: %d\n", Count, Array2[Count]); + + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/36_array_initialisers.expect b/05/tcc-0.9.27/tests/tests2/36_array_initialisers.expect new file mode 100644 index 0000000..3ac6c77 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/36_array_initialisers.expect @@ -0,0 +1,20 @@ +0: 12 +1: 34 +2: 56 +3: 78 +4: 90 +5: 123 +6: 456 +7: 789 +8: 8642 +9: 9753 +0: 12 +1: 34 +2: 56 +3: 78 +4: 90 +5: 123 +6: 456 +7: 789 +8: 8642 +9: 9753 diff --git a/05/tcc-0.9.27/tests/tests2/37_sprintf.c b/05/tcc-0.9.27/tests/tests2/37_sprintf.c new file mode 100644 index 0000000..1dd1dce --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/37_sprintf.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +int main() +{ + char Buf[100]; + int Count; + + for (Count = 1; Count <= 20; Count++) + { + sprintf(Buf, "->%02d<-\n", Count); + printf("%s", Buf); + } + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/37_sprintf.expect b/05/tcc-0.9.27/tests/tests2/37_sprintf.expect new file mode 100644 index 0000000..a643da8 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/37_sprintf.expect @@ -0,0 +1,20 @@ +->01<- +->02<- +->03<- +->04<- +->05<- +->06<- +->07<- +->08<- +->09<- +->10<- +->11<- +->12<- +->13<- +->14<- +->15<- +->16<- +->17<- +->18<- +->19<- +->20<- diff --git a/05/tcc-0.9.27/tests/tests2/38_multiple_array_index.c b/05/tcc-0.9.27/tests/tests2/38_multiple_array_index.c new file mode 100644 index 0000000..4e1868e --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/38_multiple_array_index.c @@ -0,0 +1,32 @@ +#include <stdio.h> + +int main() +{ + int a[4][4]; + int b = 0; + int x; + int y; + + for (x = 0; x < 4; x++) + { + for (y = 0; y < 4; y++) + { + b++; + a[x][y] = b; + } + } + + for (x = 0; x < 4; x++) + { + printf("x=%d: ", x); + for (y = 0; y < 4; y++) + { + printf("%d ", a[x][y]); + } + printf("\n"); + } + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/38_multiple_array_index.expect b/05/tcc-0.9.27/tests/tests2/38_multiple_array_index.expect new file mode 100644 index 0000000..747ad75 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/38_multiple_array_index.expect @@ -0,0 +1,4 @@ +x=0: 1 2 3 4 +x=1: 5 6 7 8 +x=2: 9 10 11 12 +x=3: 13 14 15 16 diff --git a/05/tcc-0.9.27/tests/tests2/39_typedef.c b/05/tcc-0.9.27/tests/tests2/39_typedef.c new file mode 100644 index 0000000..da73f71 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/39_typedef.c @@ -0,0 +1,65 @@ +#include <stdio.h> + +typedef int MyInt; + +struct FunStruct +{ + int i; + int j; +}; + +typedef struct FunStruct MyFunStruct; + +typedef MyFunStruct *MoreFunThanEver; + +int main() +{ + MyInt a = 1; + printf("%d\n", a); + + MyFunStruct b; + b.i = 12; + b.j = 34; + printf("%d,%d\n", b.i, b.j); + + MoreFunThanEver c = &b; + printf("%d,%d\n", c->i, c->j); + + return 0; +} + +/* "If the specification of an array type includes any type qualifiers, + the element type is so-qualified, not the array type." */ + +typedef int A[3]; +extern A const ca; +extern const A ca; +extern const int ca[3]; + +typedef A B[1][2]; +extern B const cb; +extern const B cb; +extern const int cb[1][2][3]; + +extern B b; +extern int b[1][2][3]; + +/* Funny but valid function declaration. */ +typedef int functype (int); +extern functype func; +int func(int i) +{ + return i + 1; +} + +/* Even funnier function decl and definition using typeof. */ +int set_anon_super(void); +int set_anon_super(void) +{ + return 42; +} +typedef int sas_type (void); +extern typeof(set_anon_super) set_anon_super; +extern sas_type set_anon_super; + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/39_typedef.expect b/05/tcc-0.9.27/tests/tests2/39_typedef.expect new file mode 100644 index 0000000..b9050a9 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/39_typedef.expect @@ -0,0 +1,3 @@ +1 +12,34 +12,34 diff --git a/05/tcc-0.9.27/tests/tests2/40_stdio.c b/05/tcc-0.9.27/tests/tests2/40_stdio.c new file mode 100644 index 0000000..b986093 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/40_stdio.c @@ -0,0 +1,52 @@ +#include <stdio.h> + +int main() +{ + FILE *f = fopen("fred.txt", "w"); + fwrite("hello\nhello\n", 1, 12, f); + fclose(f); + + char freddy[7]; + f = fopen("fred.txt", "r"); + if (fread(freddy, 1, 6, f) != 6) + printf("couldn't read fred.txt\n"); + + freddy[6] = '\0'; + fclose(f); + + printf("%s", freddy); + + int InChar; + char ShowChar; + f = fopen("fred.txt", "r"); + while ( (InChar = fgetc(f)) != EOF) + { + ShowChar = InChar; + if (ShowChar < ' ') + ShowChar = '.'; + + printf("ch: %d '%c'\n", InChar, ShowChar); + } + fclose(f); + + f = fopen("fred.txt", "r"); + while ( (InChar = getc(f)) != EOF) + { + ShowChar = InChar; + if (ShowChar < ' ') + ShowChar = '.'; + + printf("ch: %d '%c'\n", InChar, ShowChar); + } + fclose(f); + + f = fopen("fred.txt", "r"); + while (fgets(freddy, sizeof(freddy), f) != NULL) + printf("x: %s", freddy); + + fclose(f); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/40_stdio.expect b/05/tcc-0.9.27/tests/tests2/40_stdio.expect new file mode 100644 index 0000000..e08167a --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/40_stdio.expect @@ -0,0 +1,27 @@ +hello +ch: 104 'h' +ch: 101 'e' +ch: 108 'l' +ch: 108 'l' +ch: 111 'o' +ch: 10 '.' +ch: 104 'h' +ch: 101 'e' +ch: 108 'l' +ch: 108 'l' +ch: 111 'o' +ch: 10 '.' +ch: 104 'h' +ch: 101 'e' +ch: 108 'l' +ch: 108 'l' +ch: 111 'o' +ch: 10 '.' +ch: 104 'h' +ch: 101 'e' +ch: 108 'l' +ch: 108 'l' +ch: 111 'o' +ch: 10 '.' +x: hello +x: hello diff --git a/05/tcc-0.9.27/tests/tests2/41_hashif.c b/05/tcc-0.9.27/tests/tests2/41_hashif.c new file mode 100644 index 0000000..cb37b9e --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/41_hashif.c @@ -0,0 +1,85 @@ +#include <stdio.h> + +int main() +{ + printf("#include test\n"); + +#if 1 +#if 0 + printf("a\n"); +#else + printf("b\n"); +#endif +#else +#if 0 + printf("c\n"); +#else + printf("d\n"); +#endif +#endif + +#if 0 +#if 1 + printf("e\n"); +#else + printf("f\n"); +#endif +#else +#if 1 + printf("g\n"); +#else + printf("h\n"); +#endif +#endif + +#define DEF + +#ifdef DEF +#ifdef DEF + printf("i\n"); +#else + printf("j\n"); +#endif +#else +#ifdef DEF + printf("k\n"); +#else + printf("l\n"); +#endif +#endif + +#ifndef DEF +#ifndef DEF + printf("m\n"); +#else + printf("n\n"); +#endif +#else +#ifndef DEF + printf("o\n"); +#else + printf("p\n"); +#endif +#endif + +#define ONE 1 +#define ZERO 0 + +#if ONE +#if ZERO + printf("q\n"); +#else + printf("r\n"); +#endif +#else +#if ZERO + printf("s\n"); +#else + printf("t\n"); +#endif +#endif + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/41_hashif.expect b/05/tcc-0.9.27/tests/tests2/41_hashif.expect new file mode 100644 index 0000000..5fd414b --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/41_hashif.expect @@ -0,0 +1,6 @@ +#include test +b +g +i +p +r diff --git a/05/tcc-0.9.27/tests/tests2/42_function_pointer.c b/05/tcc-0.9.27/tests/tests2/42_function_pointer.c new file mode 100644 index 0000000..697bd79 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/42_function_pointer.c @@ -0,0 +1,22 @@ +#include <stdio.h> + +int fred(int p) +{ + printf("yo %d\n", p); + return 42; +} + +int (*f)(int) = &fred; + +/* To test what this is supposed to test the destination function + (fprint here) must not be called directly anywhere in the test. */ +int (*fprintfptr)(FILE *, const char *, ...) = &fprintf; + +int main() +{ + fprintfptr(stdout, "%d\n", (*f)(24)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/42_function_pointer.expect b/05/tcc-0.9.27/tests/tests2/42_function_pointer.expect new file mode 100644 index 0000000..6c8b6ce --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/42_function_pointer.expect @@ -0,0 +1,2 @@ +yo 24 +42 diff --git a/05/tcc-0.9.27/tests/tests2/43_void_param.c b/05/tcc-0.9.27/tests/tests2/43_void_param.c new file mode 100644 index 0000000..de17098 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/43_void_param.c @@ -0,0 +1,15 @@ +#include <stdio.h> + +void fred(void) +{ + printf("yo\n"); +} + +int main() +{ + fred(); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/43_void_param.expect b/05/tcc-0.9.27/tests/tests2/43_void_param.expect new file mode 100644 index 0000000..092bfb9 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/43_void_param.expect @@ -0,0 +1 @@ +yo diff --git a/05/tcc-0.9.27/tests/tests2/44_scoped_declarations.c b/05/tcc-0.9.27/tests/tests2/44_scoped_declarations.c new file mode 100644 index 0000000..f38664f --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/44_scoped_declarations.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +int main() +{ + int a; + + for (a = 0; a < 2; a++) + { + int b = a; + } + + printf("it's all good\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/44_scoped_declarations.expect b/05/tcc-0.9.27/tests/tests2/44_scoped_declarations.expect new file mode 100644 index 0000000..231ccc0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/44_scoped_declarations.expect @@ -0,0 +1 @@ +it's all good diff --git a/05/tcc-0.9.27/tests/tests2/45_empty_for.c b/05/tcc-0.9.27/tests/tests2/45_empty_for.c new file mode 100644 index 0000000..7cef513 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/45_empty_for.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +int main() +{ + int Count = 0; + + for (;;) + { + Count++; + printf("%d\n", Count); + if (Count >= 10) + break; + } + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/45_empty_for.expect b/05/tcc-0.9.27/tests/tests2/45_empty_for.expect new file mode 100644 index 0000000..f00c965 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/45_empty_for.expect @@ -0,0 +1,10 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 diff --git a/05/tcc-0.9.27/tests/tests2/46_grep.c b/05/tcc-0.9.27/tests/tests2/46_grep.c new file mode 100644 index 0000000..049dfb1 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/46_grep.c @@ -0,0 +1,568 @@ +/* + * The information in this document is subject to change + * without notice and should not be construed as a commitment + * by Digital Equipment Corporation or by DECUS. + * + * Neither Digital Equipment Corporation, DECUS, nor the authors + * assume any responsibility for the use or reliability of this + * document or the described software. + * + * Copyright (C) 1980, DECUS + * + * General permission to copy or modify, but not for profit, is + * hereby granted, provided that the above copyright notice is + * included and reference made to the fact that reproduction + * privileges were granted by DECUS. + */ +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> // tolower() + +/* + * grep + * + * Runs on the Decus compiler or on vms, On vms, define as: + * grep :== "$disk:[account]grep" (native) + * grep :== "$disk:[account]grep grep" (Decus) + * See below for more information. + */ + +char *documentation[] = { + "grep searches a file for a given pattern. Execute by", + " grep [flags] regular_expression file_list\n", + "Flags are single characters preceded by '-':", + " -c Only a count of matching lines is printed", + " -f Print file name for matching lines switch, see below", + " -n Each line is preceded by its line number", + " -v Only print non-matching lines\n", + "The file_list is a list of files (wildcards are acceptable on RSX modes).", + "\nThe file name is normally printed if there is a file given.", + "The -f flag reverses this action (print name no file, not if more).\n", + 0 }; + +char *patdoc[] = { + "The regular_expression defines the pattern to search for. Upper- and", + "lower-case are always ignored. Blank lines never match. The expression", + "should be quoted to prevent file-name translation.", + "x An ordinary character (not mentioned below) matches that character.", + "'\\' The backslash quotes any character. \"\\$\" matches a dollar-sign.", + "'^' A circumflex at the beginning of an expression matches the", + " beginning of a line.", + "'$' A dollar-sign at the end of an expression matches the end of a line.", + "'.' A period matches any character except \"new-line\".", + "':a' A colon matches a class of characters described by the following", + "':d' character. \":a\" matches any alphabetic, \":d\" matches digits,", + "':n' \":n\" matches alphanumerics, \": \" matches spaces, tabs, and", + "': ' other control characters, such as new-line.", + "'*' An expression followed by an asterisk matches zero or more", + " occurrences of that expression: \"fo*\" matches \"f\", \"fo\"", + " \"foo\", etc.", + "'+' An expression followed by a plus sign matches one or more", + " occurrences of that expression: \"fo+\" matches \"fo\", etc.", + "'-' An expression followed by a minus sign optionally matches", + " the expression.", + "'[]' A string enclosed in square brackets matches any character in", + " that string, but no others. If the first character in the", + " string is a circumflex, the expression matches any character", + " except \"new-line\" and the characters in the string. For", + " example, \"[xyz]\" matches \"xx\" and \"zyx\", while \"[^xyz]\"", + " matches \"abc\" but not \"axb\". A range of characters may be", + " specified by two characters separated by \"-\". Note that,", + " [a-z] matches alphabetics, while [z-a] never matches.", + "The concatenation of regular expressions is a regular expression.", + 0}; + +#define LMAX 512 +#define PMAX 256 + +#define CHAR 1 +#define BOL 2 +#define EOL 3 +#define ANY 4 +#define CLASS 5 +#define NCLASS 6 +#define STAR 7 +#define PLUS 8 +#define MINUS 9 +#define ALPHA 10 +#define DIGIT 11 +#define NALPHA 12 +#define PUNCT 13 +#define RANGE 14 +#define ENDPAT 15 + +int cflag=0, fflag=0, nflag=0, vflag=0, nfile=0, debug=0; + +char *pp, lbuf[LMAX], pbuf[PMAX]; + +char *cclass(); +char *pmatch(); +void store(int); +void error(char *); +void badpat(char *, char *, char *); +int match(void); + + +/*** Display a file name *******************************/ +void file(char *s) +{ + printf("File %s:\n", s); +} + +/*** Report unopenable file ****************************/ +void cant(char *s) +{ + fprintf(stderr, "%s: cannot open\n", s); +} + +/*** Give good help ************************************/ +void help(char **hp) +{ + char **dp; + + for (dp = hp; *dp; ++dp) + printf("%s\n", *dp); +} + +/*** Display usage summary *****************************/ +void usage(char *s) +{ + fprintf(stderr, "?GREP-E-%s\n", s); + fprintf(stderr, + "Usage: grep [-cfnv] pattern [file ...]. grep ? for help\n"); + exit(1); +} + +/*** Compile the pattern into global pbuf[] ************/ +void compile(char *source) +{ + char *s; /* Source string pointer */ + char *lp; /* Last pattern pointer */ + int c; /* Current character */ + int o; /* Temp */ + char *spp; /* Save beginning of pattern */ + + s = source; + if (debug) + printf("Pattern = \"%s\"\n", s); + pp = pbuf; + while (c = *s++) { + /* + * STAR, PLUS and MINUS are special. + */ + if (c == '*' || c == '+' || c == '-') { + if (pp == pbuf || + (o=pp[-1]) == BOL || + o == EOL || + o == STAR || + o == PLUS || + o == MINUS) + badpat("Illegal occurrence op.", source, s); + store(ENDPAT); + store(ENDPAT); + spp = pp; /* Save pattern end */ + while (--pp > lp) /* Move pattern down */ + *pp = pp[-1]; /* one byte */ + *pp = (c == '*') ? STAR : + (c == '-') ? MINUS : PLUS; + pp = spp; /* Restore pattern end */ + continue; + } + /* + * All the rest. + */ + lp = pp; /* Remember start */ + switch(c) { + + case '^': + store(BOL); + break; + + case '$': + store(EOL); + break; + + case '.': + store(ANY); + break; + + case '[': + s = cclass(source, s); + break; + + case ':': + if (*s) { + switch(tolower(c = *s++)) { + + case 'a': + case 'A': + store(ALPHA); + break; + + case 'd': + case 'D': + store(DIGIT); + break; + + case 'n': + case 'N': + store(NALPHA); + break; + + case ' ': + store(PUNCT); + break; + + default: + badpat("Unknown : type", source, s); + + } + break; + } + else badpat("No : type", source, s); + + case '\\': + if (*s) + c = *s++; + + default: + store(CHAR); + store(tolower(c)); + } + } + store(ENDPAT); + store(0); /* Terminate string */ + if (debug) { + for (lp = pbuf; lp < pp;) { + if ((c = (*lp++ & 0377)) < ' ') + printf("\\%o ", c); + else printf("%c ", c); + } + printf("\n"); + } +} + +/*** Compile a class (within []) ***********************/ +char *cclass(char *source, char *src) + /* char *source; // Pattern start -- for error msg. */ + /* char *src; // Class start */ +{ + char *s; /* Source pointer */ + char *cp; /* Pattern start */ + int c; /* Current character */ + int o; /* Temp */ + + s = src; + o = CLASS; + if (*s == '^') { + ++s; + o = NCLASS; + } + store(o); + cp = pp; + store(0); /* Byte count */ + while ((c = *s++) && c!=']') { + if (c == '\\') { /* Store quoted char */ + if ((c = *s++) == '\0') /* Gotta get something */ + badpat("Class terminates badly", source, s); + else store(tolower(c)); + } + else if (c == '-' && + (pp - cp) > 1 && *s != ']' && *s != '\0') { + c = pp[-1]; /* Range start */ + pp[-1] = RANGE; /* Range signal */ + store(c); /* Re-store start */ + c = *s++; /* Get end char and*/ + store(tolower(c)); /* Store it */ + } + else { + store(tolower(c)); /* Store normal char */ + } + } + if (c != ']') + badpat("Unterminated class", source, s); + if ((c = (pp - cp)) >= 256) + badpat("Class too large", source, s); + if (c == 0) + badpat("Empty class", source, s); + *cp = c; + return(s); +} + +/*** Store an entry in the pattern buffer **************/ +void store(int op) +{ + if (pp >= &pbuf[PMAX]) + error("Pattern too complex\n"); + *pp++ = op; +} + +/*** Report a bad pattern specification ****************/ +void badpat(char *message, char *source, char *stop) + /* char *message; // Error message */ + /* char *source; // Pattern start */ + /* char *stop; // Pattern end */ +{ + fprintf(stderr, "-GREP-E-%s, pattern is\"%s\"\n", message, source); + fprintf(stderr, "-GREP-E-Stopped at byte %ld, '%c'\n", + stop-source, stop[-1]); + error("?GREP-E-Bad pattern\n"); +} + +/*** Scan the file for the pattern in pbuf[] ***********/ +void grep(FILE *fp, char *fn) + /* FILE *fp; // File to process */ + /* char *fn; // File name (for -f option) */ +{ + int lno, count, m; + + lno = 0; + count = 0; + while (fgets(lbuf, LMAX, fp)) { + ++lno; + m = match(); + if ((m && !vflag) || (!m && vflag)) { + ++count; + if (!cflag) { + if (fflag && fn) { + file(fn); + fn = 0; + } + if (nflag) + printf("%d\t", lno); + printf("%s\n", lbuf); + } + } + } + if (cflag) { + if (fflag && fn) + file(fn); + printf("%d\n", count); + } +} + +/*** Match line (lbuf) with pattern (pbuf) return 1 if match ***/ +int match() +{ + char *l; /* Line pointer */ + + for (l = lbuf; *l; ++l) { + if (pmatch(l, pbuf)) + return(1); + } + return(0); +} + +/*** Match partial line with pattern *******************/ +char *pmatch(char *line, char *pattern) + /* char *line; // (partial) line to match */ + /* char *pattern; // (partial) pattern to match */ +{ + char *l; /* Current line pointer */ + char *p; /* Current pattern pointer */ + char c; /* Current character */ + char *e; /* End for STAR and PLUS match */ + int op; /* Pattern operation */ + int n; /* Class counter */ + char *are; /* Start of STAR match */ + + l = line; + if (debug > 1) + printf("pmatch(\"%s\")\n", line); + p = pattern; + while ((op = *p++) != ENDPAT) { + if (debug > 1) + printf("byte[%ld] = 0%o, '%c', op = 0%o\n", + l-line, *l, *l, op); + switch(op) { + + case CHAR: + if (tolower(*l++) != *p++) + return(0); + break; + + case BOL: + if (l != lbuf) + return(0); + break; + + case EOL: + if (*l != '\0') + return(0); + break; + + case ANY: + if (*l++ == '\0') + return(0); + break; + + case DIGIT: + if ((c = *l++) < '0' || (c > '9')) + return(0); + break; + + case ALPHA: + c = tolower(*l++); + if (c < 'a' || c > 'z') + return(0); + break; + + case NALPHA: + c = tolower(*l++); + if (c >= 'a' && c <= 'z') + break; + else if (c < '0' || c > '9') + return(0); + break; + + case PUNCT: + c = *l++; + if (c == 0 || c > ' ') + return(0); + break; + + case CLASS: + case NCLASS: + c = tolower(*l++); + n = *p++ & 0377; + do { + if (*p == RANGE) { + p += 3; + n -= 2; + if (c >= p[-2] && c <= p[-1]) + break; + } + else if (c == *p++) + break; + } while (--n > 1); + if ((op == CLASS) == (n <= 1)) + return(0); + if (op == CLASS) + p += n - 2; + break; + + case MINUS: + e = pmatch(l, p); /* Look for a match */ + while (*p++ != ENDPAT); /* Skip over pattern */ + if (e) /* Got a match? */ + l = e; /* Yes, update string */ + break; /* Always succeeds */ + + case PLUS: /* One or more ... */ + if ((l = pmatch(l, p)) == 0) + return(0); /* Gotta have a match */ + case STAR: /* Zero or more ... */ + are = l; /* Remember line start */ + while (*l && (e = pmatch(l, p))) + l = e; /* Get longest match */ + while (*p++ != ENDPAT); /* Skip over pattern */ + while (l >= are) { /* Try to match rest */ + if (e = pmatch(l, p)) + return(e); + --l; /* Nope, try earlier */ + } + return(0); /* Nothing else worked */ + + default: + printf("Bad op code %d\n", op); + error("Cannot happen -- match\n"); + } + } + return(l); +} + +/*** Report an error ***********************************/ +void error(char *s) +{ + fprintf(stderr, "%s", s); + exit(1); +} + +/*** Main program - parse arguments & grep *************/ +int main(int argc, char **argv) +{ + char *p; + int c, i; + int gotpattern; + + FILE *f; + + if (argc <= 1) + usage("No arguments"); + if (argc == 2 && argv[1][0] == '?' && argv[1][1] == 0) { + help(documentation); + help(patdoc); + return 0; + } + nfile = argc-1; + gotpattern = 0; + for (i=1; i < argc; ++i) { + p = argv[i]; + if (*p == '-') { + ++p; + while (c = *p++) { + switch(tolower(c)) { + + case '?': + help(documentation); + break; + + case 'C': + case 'c': + ++cflag; + break; + + case 'D': + case 'd': + ++debug; + break; + + case 'F': + case 'f': + ++fflag; + break; + + case 'n': + case 'N': + ++nflag; + break; + + case 'v': + case 'V': + ++vflag; + break; + + default: + usage("Unknown flag"); + } + } + argv[i] = 0; + --nfile; + } else if (!gotpattern) { + compile(p); + argv[i] = 0; + ++gotpattern; + --nfile; + } + } + if (!gotpattern) + usage("No pattern"); + if (nfile == 0) + grep(stdin, 0); + else { + fflag = fflag ^ (nfile > 0); + for (i=1; i < argc; ++i) { + if (p = argv[i]) { + if ((f=fopen(p, "r")) == NULL) + cant(p); + else { + grep(f, p); + fclose(f); + } + } + } + } + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/46_grep.expect b/05/tcc-0.9.27/tests/tests2/46_grep.expect new file mode 100644 index 0000000..e8a6791 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/46_grep.expect @@ -0,0 +1,3 @@ +File 46_grep.c: +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ + diff --git a/05/tcc-0.9.27/tests/tests2/47_switch_return.c b/05/tcc-0.9.27/tests/tests2/47_switch_return.c new file mode 100644 index 0000000..1ec7924 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/47_switch_return.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +void fred(int x) +{ + switch (x) + { + case 1: printf("1\n"); return; + case 2: printf("2\n"); break; + case 3: printf("3\n"); return; + } + + printf("out\n"); +} + +int main() +{ + fred(1); + fred(2); + fred(3); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/47_switch_return.expect b/05/tcc-0.9.27/tests/tests2/47_switch_return.expect new file mode 100644 index 0000000..b6deb7e --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/47_switch_return.expect @@ -0,0 +1,4 @@ +1 +2 +out +3 diff --git a/05/tcc-0.9.27/tests/tests2/48_nested_break.c b/05/tcc-0.9.27/tests/tests2/48_nested_break.c new file mode 100644 index 0000000..5bc5ba4 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/48_nested_break.c @@ -0,0 +1,26 @@ +#include <stdio.h> + +int main() +{ + int a; + char b; + + a = 0; + while (a < 2) + { + printf("%d", a++); + break; + + b = 'A'; + while (b < 'C') + { + printf("%c", b++); + } + printf("e"); + } + printf("\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/48_nested_break.expect b/05/tcc-0.9.27/tests/tests2/48_nested_break.expect new file mode 100644 index 0000000..573541a --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/48_nested_break.expect @@ -0,0 +1 @@ +0 diff --git a/05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.c b/05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.c new file mode 100644 index 0000000..0cbe57d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.c @@ -0,0 +1,23 @@ +#include <stdio.h> + +struct point +{ + double x; + double y; +}; + +struct point point_array[100]; + +int main() +{ + int my_point = 10; + + point_array[my_point].x = 12.34; + point_array[my_point].y = 56.78; + + printf("%f, %f\n", point_array[my_point].x, point_array[my_point].y); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.expect b/05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.expect new file mode 100644 index 0000000..1da66db --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/49_bracket_evaluation.expect @@ -0,0 +1 @@ +12.340000, 56.780000 diff --git a/05/tcc-0.9.27/tests/tests2/50_logical_second_arg.c b/05/tcc-0.9.27/tests/tests2/50_logical_second_arg.c new file mode 100644 index 0000000..ddec08c --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/50_logical_second_arg.c @@ -0,0 +1,29 @@ +#include <stdio.h> + +int fred() +{ + printf("fred\n"); + return 0; +} + +int joe() +{ + printf("joe\n"); + return 1; +} + +int main() +{ + printf("%d\n", fred() && joe()); + printf("%d\n", fred() || joe()); + printf("%d\n", joe() && fred()); + printf("%d\n", joe() || fred()); + printf("%d\n", fred() && (1 + joe())); + printf("%d\n", fred() || (0 + joe())); + printf("%d\n", joe() && (0 + fred())); + printf("%d\n", joe() || (1 + fred())); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/50_logical_second_arg.expect b/05/tcc-0.9.27/tests/tests2/50_logical_second_arg.expect new file mode 100644 index 0000000..d6174ae --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/50_logical_second_arg.expect @@ -0,0 +1,20 @@ +fred +0 +fred +joe +1 +joe +fred +0 +joe +1 +fred +0 +fred +joe +1 +joe +fred +0 +joe +1 diff --git a/05/tcc-0.9.27/tests/tests2/51_static.c b/05/tcc-0.9.27/tests/tests2/51_static.c new file mode 100644 index 0000000..d6c0917 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/51_static.c @@ -0,0 +1,30 @@ +#include <stdio.h> + +static int fred = 1234; +static int joe; + +void henry() +{ + static int fred = 4567; + + printf("%d\n", fred); + fred++; +} + +int main() +{ + printf("%d\n", fred); + henry(); + henry(); + henry(); + henry(); + printf("%d\n", fred); + fred = 8901; + joe = 2345; + printf("%d\n", fred); + printf("%d\n", joe); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/51_static.expect b/05/tcc-0.9.27/tests/tests2/51_static.expect new file mode 100644 index 0000000..18224fa --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/51_static.expect @@ -0,0 +1,8 @@ +1234 +4567 +4568 +4569 +4570 +1234 +8901 +2345 diff --git a/05/tcc-0.9.27/tests/tests2/52_unnamed_enum.c b/05/tcc-0.9.27/tests/tests2/52_unnamed_enum.c new file mode 100644 index 0000000..d0395b2 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/52_unnamed_enum.c @@ -0,0 +1,27 @@ +#include <stdio.h> + +enum fred { a, b, c }; + +int main() +{ + printf("a=%d\n", a); + printf("b=%d\n", b); + printf("c=%d\n", c); + + enum fred d; + + typedef enum { e, f, g } h; + typedef enum { i, j, k } m; + + printf("e=%d\n", e); + printf("f=%d\n", f); + printf("g=%d\n", g); + + printf("i=%d\n", i); + printf("j=%d\n", j); + printf("k=%d\n", k); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/52_unnamed_enum.expect b/05/tcc-0.9.27/tests/tests2/52_unnamed_enum.expect new file mode 100644 index 0000000..84f2ac8 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/52_unnamed_enum.expect @@ -0,0 +1,9 @@ +a=0 +b=1 +c=2 +e=0 +f=1 +g=2 +i=0 +j=1 +k=2 diff --git a/05/tcc-0.9.27/tests/tests2/54_goto.c b/05/tcc-0.9.27/tests/tests2/54_goto.c new file mode 100644 index 0000000..2e151bb --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/54_goto.c @@ -0,0 +1,56 @@ +#include <stdio.h> + +void fred() +{ + printf("In fred()\n"); + goto done; + printf("In middle\n"); +done: + printf("At end\n"); +} + +void joe() +{ + int b = 5678; + + printf("In joe()\n"); + + { + int c = 1234; + printf("c = %d\n", c); + goto outer; + printf("uh-oh\n"); + } + +outer: + + printf("done\n"); +} + +void henry() +{ + int a; + + printf("In henry()\n"); + goto inner; + + { + int b; +inner: + b = 1234; + printf("b = %d\n", b); + } + + printf("done\n"); +} + +int main() +{ + fred(); + joe(); + henry(); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/54_goto.expect b/05/tcc-0.9.27/tests/tests2/54_goto.expect new file mode 100644 index 0000000..8e553fa --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/54_goto.expect @@ -0,0 +1,8 @@ +In fred() +At end +In joe() +c = 1234 +done +In henry() +b = 1234 +done diff --git a/05/tcc-0.9.27/tests/tests2/55_lshift_type.c b/05/tcc-0.9.27/tests/tests2/55_lshift_type.c new file mode 100644 index 0000000..aa3e51a --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/55_lshift_type.c @@ -0,0 +1,52 @@ +/* $Id: lshift-type.c 53089 2012-07-06 11:18:26Z vinc17/ypig $ + +Tests on left-shift type, written by Vincent Lefevre <vincent@vinc17.net>. + +ISO C99 TC3 says: [6.5.7#3] "The integer promotions are performed on +each of the operands. The type of the result is that of the promoted +left operand." +*/ + +#include <stdio.h> + +#define PTYPE(M) ((M) < 0 || -(M) < 0 ? -1 : 1) * (int) sizeof((M)+0) +#define CHECK(X,T) check(#X, PTYPE(X), PTYPE((X) << (T) 1)) +#define TEST1(X,T) do { CHECK(X,T); CHECK(X,unsigned T); } while (0) +#define TEST2(X) \ + do \ + { \ + TEST1((X),short); \ + TEST1((X),int); \ + TEST1((X),long); \ + TEST1((X),long long); \ + } \ + while (0) +#define TEST3(X,T) do { TEST2((T)(X)); TEST2((unsigned T)(X)); } while (0) +#define TEST4(X) \ + do \ + { \ + TEST3((X),short); \ + TEST3((X),int); \ + TEST3((X),long); \ + TEST3((X),long long); \ + } \ + while (0) + +static int debug, nfailed = 0; + +static void check (const char *s, int arg1, int shift) +{ + int failed = arg1 != shift; + if (debug || failed) + printf ("%s %d %d\n", s, arg1, shift); + nfailed += failed; +} + +int main (int argc, char **argv) +{ + debug = argc > 1; + TEST4(1); + TEST4(-1); + printf ("%d test(s) failed\n", nfailed); + return nfailed != 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/55_lshift_type.expect b/05/tcc-0.9.27/tests/tests2/55_lshift_type.expect new file mode 100644 index 0000000..8523767 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/55_lshift_type.expect @@ -0,0 +1 @@ +0 test(s) failed diff --git a/05/tcc-0.9.27/tests/tests2/60_errors_and_warnings.c b/05/tcc-0.9.27/tests/tests2/60_errors_and_warnings.c new file mode 100644 index 0000000..0028caf --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/60_errors_and_warnings.c @@ -0,0 +1,51 @@ +#if defined test_56_btype_excess_1 +struct A {} int i; + +#elif defined test_57_btype_excess_2 +char int i; + +#elif defined test_58_function_redefinition +int f(void) { return 0; } +int f(void) { return 1; } + +#elif defined test_global_redefinition +int xxx = 1; +int xxx; +int xxx = 2; + +#elif defined test_59_function_array +int (*fct)[42](int x); + +#elif defined test_60_enum_redefinition +enum color { RED, GREEN, BLUE }; +enum color { R, G, B }; +enum color c; + +#elif defined test_62_enumerator_redefinition +enum color { RED, GREEN, BLUE }; +enum rgb { RED, G, B}; +enum color c = RED; + +#elif defined test_63_local_enumerator_redefinition +enum { + FOO, + BAR +}; + +int main(void) +{ + enum { + FOO = 2, + BAR + }; + + return BAR - FOO; +} + +#elif defined test_61_undefined_enum +enum rgb3 c = 42; + +#elif defined test_74_non_const_init +int i = i++; + +#endif diff --git a/05/tcc-0.9.27/tests/tests2/60_errors_and_warnings.expect b/05/tcc-0.9.27/tests/tests2/60_errors_and_warnings.expect new file mode 100644 index 0000000..ed6a690 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/60_errors_and_warnings.expect @@ -0,0 +1,28 @@ +[test_56_btype_excess_1] +60_errors_and_warnings.c:2: error: too many basic types + +[test_57_btype_excess_2] +60_errors_and_warnings.c:5: error: too many basic types + +[test_58_function_redefinition] +60_errors_and_warnings.c:9: error: redefinition of 'f' + +[test_global_redefinition] +60_errors_and_warnings.c:14: error: redefinition of 'xxx' + +[test_59_function_array] +60_errors_and_warnings.c:17: error: declaration of an array of functions + +[test_60_enum_redefinition] +60_errors_and_warnings.c:21: error: struct/union/enum already defined + +[test_62_enumerator_redefinition] +60_errors_and_warnings.c:26: error: redefinition of enumerator 'RED' + +[test_63_local_enumerator_redefinition] + +[test_61_undefined_enum] +60_errors_and_warnings.c:46: error: unknown type size + +[test_74_non_const_init] +60_errors_and_warnings.c:49: error: initializer element is not constant diff --git a/05/tcc-0.9.27/tests/tests2/64_macro_nesting.c b/05/tcc-0.9.27/tests/tests2/64_macro_nesting.c new file mode 100644 index 0000000..676e5d3 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/64_macro_nesting.c @@ -0,0 +1,12 @@ +#include <stdio.h> // printf() + +#define CAT2(a,b) a##b +#define CAT(a,b) CAT2(a,b) +#define AB(x) CAT(x,y) + +int main(void) +{ + int xy = 42; + printf("%d\n", CAT(A,B)(x)); + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/64_macro_nesting.expect b/05/tcc-0.9.27/tests/tests2/64_macro_nesting.expect new file mode 100644 index 0000000..d81cc07 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/64_macro_nesting.expect @@ -0,0 +1 @@ +42 diff --git a/05/tcc-0.9.27/tests/tests2/67_macro_concat.c b/05/tcc-0.9.27/tests/tests2/67_macro_concat.c new file mode 100644 index 0000000..c580d3a --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/67_macro_concat.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +#define P(A,B) A ## B ; bob +#define Q(A,B) A ## B+ + +int main(void) +{ + int bob, jim = 21; + bob = P(jim,) *= 2; + printf("jim: %d, bob: %d\n", jim, bob); + jim = 60 Q(+,)3; + printf("jim: %d\n", jim); + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/67_macro_concat.expect b/05/tcc-0.9.27/tests/tests2/67_macro_concat.expect new file mode 100644 index 0000000..8386c2d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/67_macro_concat.expect @@ -0,0 +1,2 @@ +jim: 21, bob: 42 +jim: 63 diff --git a/05/tcc-0.9.27/tests/tests2/70_floating_point_literals.c b/05/tcc-0.9.27/tests/tests2/70_floating_point_literals.c new file mode 100644 index 0000000..012fb4f --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/70_floating_point_literals.c @@ -0,0 +1,77 @@ +#include <stdio.h> + +int main() +{ + /* decimal floating constant */ + float fa0 = .123f; + float fa1 = .123E12F; + float fa2 = .123e-12f; + float fa3 = .123e+12f; + printf("%f\n%f\n%f\n%f\n\n", fa0, fa1, fa2, fa3); + + float fb0 = 123.123f; + float fb1 = 123.123E12F; + float fb2 = 123.123e-12f; + float fb3 = 123.123e+12f; + printf("%f\n%f\n%f\n%f\n\n", fb0, fb1, fb2, fb3); + + float fc0 = 123.f; + float fc1 = 123.E12F; + float fc2 = 123.e-12f; + float fc3 = 123.e+12f; + printf("%f\n%f\n%f\n%f\n\n", fc0, fc1, fc2, fc3); + + float fd0 = 123E12F; + float fd1 = 123e-12f; + float fd2 = 123e+12f; + printf("%f\n%f\n%f\n\n", fd0, fd1, fd2); + printf("\n"); + + /* hexadecimal floating constant */ + double da0 = 0X.1ACP12; + double da1 = 0x.1acp-12; + double da2 = 0x.1acp+12; + printf("%f\n%f\n%f\n\n", da0, da1, da2); + + double db0 = 0X1AC.BDP12; + double db1 = 0x1ac.bdp-12; + double db2 = 0x1ac.dbp+12; + printf("%f\n%f\n%f\n\n", db0, db1, db2); + + double dc0 = 0X1AC.P12; + double dc1 = 0x1ac.p-12; + double dc2 = 0x1ac.p+12; + printf("%f\n%f\n%f\n\n", dc0, dc1, dc2); + + double dd0 = 0X1ACP12; + double dd1 = 0x1acp-12; + double dd2 = 0x1acp+12; + printf("%f\n%f\n%f\n\n", dd0, dd1, dd2); + printf("\n"); + +#ifdef __TINYC__ + /* TCC extension + binary floating constant */ + long double la0 = 0B.110101100P12L; + long double la1 = 0b.110101100p-12l; + long double la2 = 0b.110101100p+12l; + printf("%Lf\n%Lf\n%Lf\n\n", la0, la1, la2); + + long double lb0 = 0B110101100.10111101P12L; + long double lb1 = 0b110101100.10111101p-12l; + long double lb2 = 0b110101100.10111101p+12l; + printf("%Lf\n%Lf\n%Lf\n\n", lb0, lb1, lb2); + + long double lc0 = 0B110101100.P12L; + long double lc1 = 0b110101100.p-12l; + long double lc2 = 0b110101100.p+12l; + printf("%Lf\n%Lf\n%Lf\n\n", lc0, lc1, lc2); + + long double ld0 = 0B110101100P12L; + long double ld1 = 0b110101100p-12l; + long double ld2 = 0b110101100p+12l; + printf("%Lf\n%Lf\n%Lf\n\n", ld0, ld1, ld2); +#endif + + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/70_floating_point_literals.expect b/05/tcc-0.9.27/tests/tests2/70_floating_point_literals.expect new file mode 100644 index 0000000..7eb1efb --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/70_floating_point_literals.expect @@ -0,0 +1,53 @@ +0.123000 +122999996416.000000 +0.000000 +122999996416.000000 + +123.123001 +123122997002240.000000 +0.000000 +123122997002240.000000 + +123.000000 +123000003231744.000000 +0.000000 +123000003231744.000000 + +123000003231744.000000 +0.000000 +123000003231744.000000 + + +428.000000 +0.000026 +428.000000 + +1756112.000000 +0.104672 +1756592.000000 + +1753088.000000 +0.104492 +1753088.000000 + +1753088.000000 +0.104492 +1753088.000000 + + +3424.000000 +0.000204 +3424.000000 + +1756112.000000 +0.104672 +1756112.000000 + +1753088.000000 +0.104492 +1753088.000000 + +1753088.000000 +0.104492 +1753088.000000 + diff --git a/05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.c b/05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.c new file mode 100644 index 0000000..f0d3511 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +#define T(a,b,c) a b c + +int main(void) +{ + printf("%d", T(1,+,2) T(+,,) T(,2,*) T(,7,) T(,,)); + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.expect b/05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.expect new file mode 100644 index 0000000..98d9bcb --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/71_macro_empty_arg.expect @@ -0,0 +1 @@ +17 diff --git a/05/tcc-0.9.27/tests/tests2/72_long_long_constant.c b/05/tcc-0.9.27/tests/tests2/72_long_long_constant.c new file mode 100644 index 0000000..6608213 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/72_long_long_constant.c @@ -0,0 +1,19 @@ +#include <stdio.h> + +int main() +{ + long long int res = 0; + + if (res < -2147483648LL) { + printf("Error: 0 < -2147483648\n"); + return 1; + } + else + if (2147483647LL < res) { + printf("Error: 2147483647 < 0\n"); + return 2; + } + else + printf("long long constant test ok.\n"); + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/72_long_long_constant.expect b/05/tcc-0.9.27/tests/tests2/72_long_long_constant.expect new file mode 100644 index 0000000..dda9e66 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/72_long_long_constant.expect @@ -0,0 +1 @@ +long long constant test ok. diff --git a/05/tcc-0.9.27/tests/tests2/73_arm64.c b/05/tcc-0.9.27/tests/tests2/73_arm64.c new file mode 100644 index 0000000..8de61b3 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/73_arm64.c @@ -0,0 +1,527 @@ +// This program is designed to test some arm64-specific things, such as the +// calling convention, but should give the same results on any architecture. + +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> + +struct s1 { char x[1]; } s1 = { "0" }; +struct s2 { char x[2]; } s2 = { "12" }; +struct s3 { char x[3]; } s3 = { "345" }; +struct s4 { char x[4]; } s4 = { "6789" }; +struct s5 { char x[5]; } s5 = { "abcde" }; +struct s6 { char x[6]; } s6 = { "fghijk" }; +struct s7 { char x[7]; } s7 = { "lmnopqr" }; +struct s8 { char x[8]; } s8 = { "stuvwxyz" }; +struct s9 { char x[9]; } s9 = { "ABCDEFGHI" }; +struct s10 { char x[10]; } s10 = { "JKLMNOPQRS" }; +struct s11 { char x[11]; } s11 = { "TUVWXYZ0123" }; +struct s12 { char x[12]; } s12 = { "456789abcdef" }; +struct s13 { char x[13]; } s13 = { "ghijklmnopqrs" }; +struct s14 { char x[14]; } s14 = { "tuvwxyzABCDEFG" }; +struct s15 { char x[15]; } s15 = { "HIJKLMNOPQRSTUV" }; +struct s16 { char x[16]; } s16 = { "WXYZ0123456789ab" }; +struct s17 { char x[17]; } s17 = { "cdefghijklmnopqrs" }; + +struct hfa11 { float a; } hfa11 = { 11.1 }; +struct hfa12 { float a, b; } hfa12 = { 12.1, 12.2 }; +struct hfa13 { float a, b, c; } hfa13 = { 13.1, 13.2, 13.3 }; +struct hfa14 { float a, b, c, d; } hfa14 = { 14.1, 14.2, 14.3, 14.4 }; + +struct hfa21 { double a; } hfa21 = { 21.1 }; +struct hfa22 { double a, b; } hfa22 = { 22.1, 22.2 }; +struct hfa23 { double a, b, c; } hfa23 = { 23.1, 23.2, 23.3 }; +struct hfa24 { double a, b, c, d; } hfa24 = { 24.1, 24.2, 24.3, 24.4 }; + +struct hfa31 { long double a; } hfa31 = { 31.1 }; +struct hfa32 { long double a, b; } hfa32 = { 32.1, 32.2 }; +struct hfa33 { long double a, b, c; } hfa33 = { 33.1, 33.2, 33.3 }; +struct hfa34 { long double a, b, c, d; } hfa34 = { 34.1, 34.2, 34.3, 34.4 }; + +void fa_s1(struct s1 a) { printf("%.1s\n", a.x); } +void fa_s2(struct s2 a) { printf("%.2s\n", a.x); } +void fa_s3(struct s3 a) { printf("%.3s\n", a.x); } +void fa_s4(struct s4 a) { printf("%.4s\n", a.x); } +void fa_s5(struct s5 a) { printf("%.5s\n", a.x); } +void fa_s6(struct s6 a) { printf("%.6s\n", a.x); } +void fa_s7(struct s7 a) { printf("%.7s\n", a.x); } +void fa_s8(struct s8 a) { printf("%.8s\n", a.x); } +void fa_s9(struct s9 a) { printf("%.9s\n", a.x); } +void fa_s10(struct s10 a) { printf("%.10s\n", a.x); } +void fa_s11(struct s11 a) { printf("%.11s\n", a.x); } +void fa_s12(struct s12 a) { printf("%.12s\n", a.x); } +void fa_s13(struct s13 a) { printf("%.13s\n", a.x); } +void fa_s14(struct s14 a) { printf("%.14s\n", a.x); } +void fa_s15(struct s15 a) { printf("%.15s\n", a.x); } +void fa_s16(struct s16 a) { printf("%.16s\n", a.x); } +void fa_s17(struct s17 a) { printf("%.17s\n", a.x); } + +void fa_hfa11(struct hfa11 a) +{ printf("%.1f\n", a.a); } +void fa_hfa12(struct hfa12 a) +{ printf("%.1f %.1f\n", a.a, a.a); } +void fa_hfa13(struct hfa13 a) +{ printf("%.1f %.1f %.1f\n", a.a, a.b, a.c); } +void fa_hfa14(struct hfa14 a) +{ printf("%.1f %.1f %.1f %.1f\n", a.a, a.b, a.c, a.d); } + +void fa_hfa21(struct hfa21 a) +{ printf("%.1f\n", a.a); } +void fa_hfa22(struct hfa22 a) +{ printf("%.1f %.1f\n", a.a, a.a); } +void fa_hfa23(struct hfa23 a) +{ printf("%.1f %.1f %.1f\n", a.a, a.b, a.c); } +void fa_hfa24(struct hfa24 a) +{ printf("%.1f %.1f %.1f %.1f\n", a.a, a.b, a.c, a.d); } + +void fa_hfa31(struct hfa31 a) +{ printf("%.1Lf\n", a.a); } +void fa_hfa32(struct hfa32 a) +{ printf("%.1Lf %.1Lf\n", a.a, a.a); } +void fa_hfa33(struct hfa33 a) +{ printf("%.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c); } +void fa_hfa34(struct hfa34 a) +{ printf("%.1Lf %.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c, a.d); } + +void fa1(struct s8 a, struct s9 b, struct s10 c, struct s11 d, + struct s12 e, struct s13 f) +{ + printf("%.3s %.3s %.3s %.3s %.3s %.3s\n", a.x, b.x, c.x, d.x, e.x, f.x); +} + +void fa2(struct s9 a, struct s10 b, struct s11 c, struct s12 d, + struct s13 e, struct s14 f) +{ + printf("%.3s %.3s %.3s %.3s %.3s %.3s\n", a.x, b.x, c.x, d.x, e.x, f.x); +} + +void fa3(struct hfa14 a, struct hfa23 b, struct hfa32 c) +{ + printf("%.1f %.1f %.1f %.1f %.1Lf %.1Lf\n", + a.a, a.d, b.a, b.c, c.a, c.b); +} + +void fa4(struct s1 a, struct hfa14 b, struct s2 c, struct hfa24 d, + struct s3 e, struct hfa34 f) +{ + printf("%.1s %.1f %.1f %.2s %.1f %.1f %.3s %.1Lf %.1Lf\n", + a.x, b.a, b.d, c.x, d.a, d.d, e.x, f.a, f.d); +} + +void arg(void) +{ + printf("Arguments:\n"); + fa_s1(s1); + fa_s2(s2); + fa_s3(s3); + fa_s4(s4); + fa_s5(s5); + fa_s6(s6); + fa_s7(s7); + fa_s8(s8); + fa_s9(s9); + fa_s10(s10); + fa_s11(s11); + fa_s12(s12); + fa_s13(s13); + fa_s14(s14); + fa_s15(s15); + fa_s16(s16); + fa_s17(s17); + fa_hfa11(hfa11); + fa_hfa12(hfa12); + fa_hfa13(hfa13); + fa_hfa14(hfa14); + fa_hfa21(hfa21); + fa_hfa22(hfa22); + fa_hfa23(hfa23); + fa_hfa24(hfa24); + fa_hfa31(hfa31); + fa_hfa32(hfa32); + fa_hfa33(hfa33); + fa_hfa34(hfa34); + fa1(s8, s9, s10, s11, s12, s13); + fa2(s9, s10, s11, s12, s13, s14); + fa3(hfa14, hfa23, hfa32); + fa4(s1, hfa14, s2, hfa24, s3, hfa34); +} + +struct s1 fr_s1(void) { return s1; } +struct s2 fr_s2(void) { return s2; } +struct s3 fr_s3(void) { return s3; } +struct s4 fr_s4(void) { return s4; } +struct s5 fr_s5(void) { return s5; } +struct s6 fr_s6(void) { return s6; } +struct s7 fr_s7(void) { return s7; } +struct s8 fr_s8(void) { return s8; } +struct s9 fr_s9(void) { return s9; } +struct s10 fr_s10(void) { return s10; } +struct s11 fr_s11(void) { return s11; } +struct s12 fr_s12(void) { return s12; } +struct s13 fr_s13(void) { return s13; } +struct s14 fr_s14(void) { return s14; } +struct s15 fr_s15(void) { return s15; } +struct s16 fr_s16(void) { return s16; } +struct s17 fr_s17(void) { return s17; } + +struct hfa11 fr_hfa11(void) { return hfa11; } +struct hfa12 fr_hfa12(void) { return hfa12; } +struct hfa13 fr_hfa13(void) { return hfa13; } +struct hfa14 fr_hfa14(void) { return hfa14; } + +struct hfa21 fr_hfa21(void) { return hfa21; } +struct hfa22 fr_hfa22(void) { return hfa22; } +struct hfa23 fr_hfa23(void) { return hfa23; } +struct hfa24 fr_hfa24(void) { return hfa24; } + +struct hfa31 fr_hfa31(void) { return hfa31; } +struct hfa32 fr_hfa32(void) { return hfa32; } +struct hfa33 fr_hfa33(void) { return hfa33; } +struct hfa34 fr_hfa34(void) { return hfa34; } + +void ret(void) +{ + struct s1 t1 = fr_s1(); + struct s2 t2 = fr_s2(); + struct s3 t3 = fr_s3(); + struct s4 t4 = fr_s4(); + struct s5 t5 = fr_s5(); + struct s6 t6 = fr_s6(); + struct s7 t7 = fr_s7(); + struct s8 t8 = fr_s8(); + struct s9 t9 = fr_s9(); + struct s10 t10 = fr_s10(); + struct s11 t11 = fr_s11(); + struct s12 t12 = fr_s12(); + struct s13 t13 = fr_s13(); + struct s14 t14 = fr_s14(); + struct s15 t15 = fr_s15(); + struct s16 t16 = fr_s16(); + struct s17 t17 = fr_s17(); + printf("Return values:\n"); + printf("%.1s\n", t1.x); + printf("%.2s\n", t2.x); + printf("%.3s\n", t3.x); + printf("%.4s\n", t4.x); + printf("%.5s\n", t5.x); + printf("%.6s\n", t6.x); + printf("%.7s\n", t7.x); + printf("%.8s\n", t8.x); + printf("%.9s\n", t9.x); + printf("%.10s\n", t10.x); + printf("%.11s\n", t11.x); + printf("%.12s\n", t12.x); + printf("%.13s\n", t13.x); + printf("%.14s\n", t14.x); + printf("%.15s\n", t15.x); + printf("%.16s\n", t16.x); + printf("%.17s\n", t17.x); + printf("%.1f\n", fr_hfa11().a); + printf("%.1f %.1f\n", fr_hfa12().a, fr_hfa12().b); + printf("%.1f %.1f\n", fr_hfa13().a, fr_hfa13().c); + printf("%.1f %.1f\n", fr_hfa14().a, fr_hfa14().d); + printf("%.1f\n", fr_hfa21().a); + printf("%.1f %.1f\n", fr_hfa22().a, fr_hfa22().b); + printf("%.1f %.1f\n", fr_hfa23().a, fr_hfa23().c); + printf("%.1f %.1f\n", fr_hfa24().a, fr_hfa24().d); + printf("%.1Lf\n", fr_hfa31().a); + printf("%.1Lf %.1Lf\n", fr_hfa32().a, fr_hfa32().b); + printf("%.1Lf %.1Lf\n", fr_hfa33().a, fr_hfa33().c); + printf("%.1Lf %.1Lf\n", fr_hfa34().a, fr_hfa34().d); +} + +int match(const char **s, const char *f) +{ + const char *p = *s; + for (p = *s; *f && *f == *p; f++, p++) + ; + if (!*f) { + *s = p - 1; + return 1; + } + return 0; +} + +void myprintf(const char *format, ...) +{ + const char *s; + va_list ap; + va_start(ap, format); + for (s = format; *s; s++) { + if (match(&s, "%7s")) { + struct s7 t7 = va_arg(ap, struct s7); + printf("%.7s", t7.x); + } + else if (match(&s, "%9s")) { + struct s9 t9 = va_arg(ap, struct s9); + printf("%.9s", t9.x); + } + else if (match(&s, "%hfa11")) { + struct hfa11 x = va_arg(ap, struct hfa11); + printf("%.1f,%.1f", x.a, x.a); + } + else if (match(&s, "%hfa12")) { + struct hfa12 x = va_arg(ap, struct hfa12); + printf("%.1f,%.1f", x.a, x.b); + } + else if (match(&s, "%hfa13")) { + struct hfa13 x = va_arg(ap, struct hfa13); + printf("%.1f,%.1f", x.a, x.c); + } + else if (match(&s, "%hfa14")) { + struct hfa14 x = va_arg(ap, struct hfa14); + printf("%.1f,%.1f", x.a, x.d); + } + else if (match(&s, "%hfa21")) { + struct hfa21 x = va_arg(ap, struct hfa21); + printf("%.1f,%.1f", x.a, x.a); + } + else if (match(&s, "%hfa22")) { + struct hfa22 x = va_arg(ap, struct hfa22); + printf("%.1f,%.1f", x.a, x.b); + } + else if (match(&s, "%hfa23")) { + struct hfa23 x = va_arg(ap, struct hfa23); + printf("%.1f,%.1f", x.a, x.c); + } + else if (match(&s, "%hfa24")) { + struct hfa24 x = va_arg(ap, struct hfa24); + printf("%.1f,%.1f", x.a, x.d); + } + else if (match(&s, "%hfa31")) { + struct hfa31 x = va_arg(ap, struct hfa31); + printf("%.1Lf,%.1Lf", x.a, x.a); + } + else if (match(&s, "%hfa32")) { + struct hfa32 x = va_arg(ap, struct hfa32); + printf("%.1Lf,%.1Lf", x.a, x.b); + } + else if (match(&s, "%hfa33")) { + struct hfa33 x = va_arg(ap, struct hfa33); + printf("%.1Lf,%.1Lf", x.a, x.c); + } + else if (match(&s, "%hfa34")) { + struct hfa34 x = va_arg(ap, struct hfa34); + printf("%.1Lf,%.1Lf", x.a, x.d); + } + else + putchar(*s); + } + putchar('\n'); +} + +void stdarg(void) +{ + printf("stdarg:\n"); + myprintf("%9s %9s %9s %9s %9s %9s", s9, s9, s9, s9, s9, s9); + myprintf("%7s %9s %9s %9s %9s %9s", s7, s9, s9, s9, s9, s9); + + myprintf("HFA long double:"); + myprintf("%hfa34 %hfa34 %hfa34 %hfa34", hfa34, hfa34, hfa34, hfa34); + myprintf("%hfa33 %hfa34 %hfa34 %hfa34", hfa33, hfa34, hfa34, hfa34); + myprintf("%hfa32 %hfa34 %hfa34 %hfa34", hfa32, hfa34, hfa34, hfa34); + myprintf("%hfa31 %hfa34 %hfa34 %hfa34", hfa31, hfa34, hfa34, hfa34); + + myprintf("%hfa32 %hfa33 %hfa33 %hfa33 %hfa33", + hfa32, hfa33, hfa33, hfa33, hfa33); + myprintf("%hfa31 %hfa33 %hfa33 %hfa33 %hfa33", + hfa31, hfa33, hfa33, hfa33, hfa33); + myprintf("%hfa33 %hfa33 %hfa33 %hfa33", + hfa33, hfa33, hfa33, hfa33); + + myprintf("%hfa34 %hfa32 %hfa32 %hfa32 %hfa32", + hfa34, hfa32, hfa32, hfa32, hfa32); + myprintf("%hfa33 %hfa32 %hfa32 %hfa32 %hfa32", + hfa33, hfa32, hfa32, hfa32, hfa32); + + myprintf("%hfa34 %hfa32 %hfa31 %hfa31 %hfa31 %hfa31", + hfa34, hfa32, hfa31, hfa31, hfa31, hfa31); + + myprintf("HFA double:"); + myprintf("%hfa24 %hfa24 %hfa24 %hfa24", hfa24, hfa24, hfa24, hfa24); + myprintf("%hfa23 %hfa24 %hfa24 %hfa24", hfa23, hfa24, hfa24, hfa24); + myprintf("%hfa22 %hfa24 %hfa24 %hfa24", hfa22, hfa24, hfa24, hfa24); + myprintf("%hfa21 %hfa24 %hfa24 %hfa24", hfa21, hfa24, hfa24, hfa24); + + myprintf("%hfa22 %hfa23 %hfa23 %hfa23 %hfa23", + hfa22, hfa23, hfa23, hfa23, hfa23); + myprintf("%hfa21 %hfa23 %hfa23 %hfa23 %hfa23", + hfa21, hfa23, hfa23, hfa23, hfa23); + myprintf("%hfa23 %hfa23 %hfa23 %hfa23", + hfa23, hfa23, hfa23, hfa23); + + myprintf("%hfa24 %hfa22 %hfa22 %hfa22 %hfa22", + hfa24, hfa22, hfa22, hfa22, hfa22); + myprintf("%hfa23 %hfa22 %hfa22 %hfa22 %hfa22", + hfa23, hfa22, hfa22, hfa22, hfa22); + + myprintf("%hfa24 %hfa22 %hfa21 %hfa21 %hfa21 %hfa21", + hfa24, hfa22, hfa21, hfa21, hfa21, hfa21); + + myprintf("HFA float:"); + myprintf("%hfa14 %hfa14 %hfa14 %hfa14", hfa14, hfa14, hfa14, hfa14); + myprintf("%hfa13 %hfa14 %hfa14 %hfa14", hfa13, hfa14, hfa14, hfa14); + myprintf("%hfa12 %hfa14 %hfa14 %hfa14", hfa12, hfa14, hfa14, hfa14); + myprintf("%hfa11 %hfa14 %hfa14 %hfa14", hfa11, hfa14, hfa14, hfa14); + + myprintf("%hfa12 %hfa13 %hfa13 %hfa13 %hfa13", + hfa12, hfa13, hfa13, hfa13, hfa13); + myprintf("%hfa11 %hfa13 %hfa13 %hfa13 %hfa13", + hfa11, hfa13, hfa13, hfa13, hfa13); + myprintf("%hfa13 %hfa13 %hfa13 %hfa13", + hfa13, hfa13, hfa13, hfa13); + + myprintf("%hfa14 %hfa12 %hfa12 %hfa12 %hfa12", + hfa14, hfa12, hfa12, hfa12, hfa12); + myprintf("%hfa13 %hfa12 %hfa12 %hfa12 %hfa12", + hfa13, hfa12, hfa12, hfa12, hfa12); + + myprintf("%hfa14 %hfa12 %hfa11 %hfa11 %hfa11 %hfa11", + hfa14, hfa12, hfa11, hfa11, hfa11, hfa11); +} + +void pll(unsigned long long x) +{ + printf("%llx\n", x); +} + +void movi(void) +{ + printf("MOVI:\n"); + pll(0); + pll(0xabcd); + pll(0xabcd0000); + pll(0xabcd00000000); + pll(0xabcd000000000000); + pll(0xffffabcd); + pll(0xabcdffff); + pll(0xffffffffffffabcd); + pll(0xffffffffabcdffff); + pll(0xffffabcdffffffff); + pll(0xabcdffffffffffff); + pll(0xaaaaaaaa); + pll(0x5555555555555555); + pll(0x77777777); + pll(0x3333333333333333); + pll(0xf8f8f8f8); + pll(0x1e1e1e1e1e1e1e1e); + pll(0x3f803f80); + pll(0x01ff01ff01ff01ff); + pll(0x007fffc0); + pll(0x03fff80003fff800); + pll(0x0007fffffffffe00); + + pll(0xabcd1234); + pll(0xabcd00001234); + pll(0xabcd000000001234); + pll(0xabcd12340000); + pll(0xabcd000012340000); + pll(0xabcd123400000000); + pll(0xffffffffabcd1234); + pll(0xffffabcdffff1234); + pll(0xabcdffffffff1234); + pll(0xffffabcd1234ffff); + pll(0xabcdffff1234ffff); + pll(0xabcd1234ffffffff); + + pll(0xffffef0123456789); + pll(0xabcdef012345ffff); + + pll(0xabcdef0123456789); +} + +static uint32_t addip0(uint32_t x) { return x + 0; } +static uint64_t sublp0(uint64_t x) { return x - 0; } +static uint32_t addip123(uint32_t x) { return x + 123; } +static uint64_t addlm123(uint64_t x) { return x + -123; } +static uint64_t sublp4095(uint64_t x) { return x - 4095; } +static uint32_t subim503808(uint32_t x) { return x - -503808; } +static uint64_t addp12345(uint64_t x) { return x + 12345; } +static uint32_t subp12345(uint32_t x) { return x - 12345; } + +static uint32_t mvni(uint32_t x) { return 0xffffffff - x; } +static uint64_t negl(uint64_t x) { return 0 - x; } +static uint32_t rsbi123(uint32_t x) { return 123 - x; } +static uint64_t rsbl123(uint64_t x) { return 123 - x; } + +static uint32_t andi0(uint32_t x) { return x & 0; } +static uint64_t andlm1(uint64_t x) { return x & -1; } +static uint64_t orrl0(uint64_t x) { return x | 0; } +static uint32_t orrim1(uint32_t x) { return x | -1; } +static uint32_t eori0(uint32_t x) { return x ^ 0; } +static uint64_t eorlm1(uint64_t x) { return x ^ -1; } +static uint32_t and0xf0(uint32_t x) { return x & 0xf0; } +static uint64_t orr0xf0(uint64_t x) { return x | 0xf0; } +static uint64_t eor0xf0(uint64_t x) { return x ^ 0xf0; } + +static uint32_t lsli0(uint32_t x) { return x << 0; } +static uint32_t lsri0(uint32_t x) { return x >> 0; } +static int64_t asrl0(int64_t x) { return x >> 0; } +static uint32_t lsli1(uint32_t x) { return x << 1; } +static uint32_t lsli31(uint32_t x) { return x << 31; } +static uint64_t lsll1(uint64_t x) { return x << 1; } +static uint64_t lsll63(uint64_t x) { return x << 63; } +static uint32_t lsri1(uint32_t x) { return x >> 1; } +static uint32_t lsri31(uint32_t x) { return x >> 31; } +static uint64_t lsrl1(uint64_t x) { return x >> 1; } +static uint64_t lsrl63(uint64_t x) { return x >> 63; } +static int32_t asri1(int32_t x) { return x >> 1; } +static int32_t asri31(int32_t x) { return x >> 31; } +static int64_t asrl1(int64_t x) { return x >> 1; } +static int64_t asrl63(int64_t x) { return x >> 63; } + +void opi(void) +{ + int x = 1000; + pll(addip0(x)); + pll(sublp0(x)); + pll(addip123(x)); + pll(addlm123(x)); + pll(sublp4095(x)); + pll(subim503808(x)); + pll(addp12345(x)); + pll(subp12345(x)); + pll(mvni(x)); + pll(negl(x)); + pll(rsbi123(x)); + pll(rsbl123(x)); + pll(andi0(x)); + pll(andlm1(x)); + pll(orrl0(x)); + pll(orrim1(x)); + pll(eori0(x)); + pll(eorlm1(x)); + pll(and0xf0(x)); + pll(orr0xf0(x)); + pll(eor0xf0(x)); + pll(lsli0(x)); + pll(lsri0(x)); + pll(asrl0(x)); + pll(lsli1(x)); + pll(lsli31(x)); + pll(lsll1(x)); + pll(lsll63(x)); + pll(lsri1(x)); + pll(lsri31(x)); + pll(lsrl1(x)); + pll(lsrl63(x)); + pll(asri1(x)); + pll(asri31(x)); + pll(asrl1(x)); + pll(asrl63(x)); +} + +void pcs(void) +{ + arg(); + ret(); + stdarg(); + movi(); + opi(); +} + +int main() +{ + pcs(); + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/73_arm64.expect b/05/tcc-0.9.27/tests/tests2/73_arm64.expect new file mode 100644 index 0000000..7bdebd3 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/73_arm64.expect @@ -0,0 +1,174 @@ +Arguments: +0 +12 +345 +6789 +abcde +fghijk +lmnopqr +stuvwxyz +ABCDEFGHI +JKLMNOPQRS +TUVWXYZ0123 +456789abcdef +ghijklmnopqrs +tuvwxyzABCDEFG +HIJKLMNOPQRSTUV +WXYZ0123456789ab +cdefghijklmnopqrs +11.1 +12.1 12.1 +13.1 13.2 13.3 +14.1 14.2 14.3 14.4 +21.1 +22.1 22.1 +23.1 23.2 23.3 +24.1 24.2 24.3 24.4 +31.1 +32.1 32.1 +33.1 33.2 33.3 +34.1 34.2 34.3 34.4 +stu ABC JKL TUV 456 ghi +ABC JKL TUV 456 ghi tuv +14.1 14.4 23.1 23.3 32.1 32.2 +0 14.1 14.4 12 24.1 24.4 345 34.1 34.4 +Return values: +0 +12 +345 +6789 +abcde +fghijk +lmnopqr +stuvwxyz +ABCDEFGHI +JKLMNOPQRS +TUVWXYZ0123 +456789abcdef +ghijklmnopqrs +tuvwxyzABCDEFG +HIJKLMNOPQRSTUV +WXYZ0123456789ab +cdefghijklmnopqrs +11.1 +12.1 12.2 +13.1 13.3 +14.1 14.4 +21.1 +22.1 22.2 +23.1 23.3 +24.1 24.4 +31.1 +32.1 32.2 +33.1 33.3 +34.1 34.4 +stdarg: +ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI +lmnopqr ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI +HFA long double: +34.1,34.4 34.1,34.4 34.1,34.4 34.1,34.4 +33.1,33.3 34.1,34.4 34.1,34.4 34.1,34.4 +32.1,32.2 34.1,34.4 34.1,34.4 34.1,34.4 +31.1,31.1 34.1,34.4 34.1,34.4 34.1,34.4 +32.1,32.2 33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3 +31.1,31.1 33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3 +33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3 +34.1,34.4 32.1,32.2 32.1,32.2 32.1,32.2 32.1,32.2 +33.1,33.3 32.1,32.2 32.1,32.2 32.1,32.2 32.1,32.2 +34.1,34.4 32.1,32.2 31.1,31.1 31.1,31.1 31.1,31.1 31.1,31.1 +HFA double: +24.1,24.4 24.1,24.4 24.1,24.4 24.1,24.4 +23.1,23.3 24.1,24.4 24.1,24.4 24.1,24.4 +22.1,22.2 24.1,24.4 24.1,24.4 24.1,24.4 +21.1,21.1 24.1,24.4 24.1,24.4 24.1,24.4 +22.1,22.2 23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3 +21.1,21.1 23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3 +23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3 +24.1,24.4 22.1,22.2 22.1,22.2 22.1,22.2 22.1,22.2 +23.1,23.3 22.1,22.2 22.1,22.2 22.1,22.2 22.1,22.2 +24.1,24.4 22.1,22.2 21.1,21.1 21.1,21.1 21.1,21.1 21.1,21.1 +HFA float: +14.1,14.4 14.1,14.4 14.1,14.4 14.1,14.4 +13.1,13.3 14.1,14.4 14.1,14.4 14.1,14.4 +12.1,12.2 14.1,14.4 14.1,14.4 14.1,14.4 +11.1,11.1 14.1,14.4 14.1,14.4 14.1,14.4 +12.1,12.2 13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3 +11.1,11.1 13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3 +13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3 +14.1,14.4 12.1,12.2 12.1,12.2 12.1,12.2 12.1,12.2 +13.1,13.3 12.1,12.2 12.1,12.2 12.1,12.2 12.1,12.2 +14.1,14.4 12.1,12.2 11.1,11.1 11.1,11.1 11.1,11.1 11.1,11.1 +MOVI: +0 +abcd +abcd0000 +abcd00000000 +abcd000000000000 +ffffabcd +abcdffff +ffffffffffffabcd +ffffffffabcdffff +ffffabcdffffffff +abcdffffffffffff +aaaaaaaa +5555555555555555 +77777777 +3333333333333333 +f8f8f8f8 +1e1e1e1e1e1e1e1e +3f803f80 +1ff01ff01ff01ff +7fffc0 +3fff80003fff800 +7fffffffffe00 +abcd1234 +abcd00001234 +abcd000000001234 +abcd12340000 +abcd000012340000 +abcd123400000000 +ffffffffabcd1234 +ffffabcdffff1234 +abcdffffffff1234 +ffffabcd1234ffff +abcdffff1234ffff +abcd1234ffffffff +ffffef0123456789 +abcdef012345ffff +abcdef0123456789 +3e8 +3e8 +463 +36d +fffffffffffff3e9 +7b3e8 +3421 +ffffd3af +fffffc17 +fffffffffffffc18 +fffffc93 +fffffffffffffc93 +0 +3e8 +3e8 +ffffffff +3e8 +fffffffffffffc17 +e0 +3f8 +318 +3e8 +3e8 +3e8 +7d0 +0 +7d0 +0 +1f4 +0 +1f4 +0 +1f4 +0 +1f4 +0 diff --git a/05/tcc-0.9.27/tests/tests2/75_array_in_struct_init.c b/05/tcc-0.9.27/tests/tests2/75_array_in_struct_init.c new file mode 100644 index 0000000..234e3c4 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/75_array_in_struct_init.c @@ -0,0 +1,33 @@ +#include <stdio.h> + +/* This test is a snippet from the J interpreter */ + +typedef long I; +typedef struct{I c[4];I b,e,k;} PT; + +PT cases[] = { + ((I)4194304L +(I)2097152L +(I)67108864L), (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), -1L, 1,2,1, + ((I)+4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L, (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 2,3,2, + ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 1,3,2, + ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)524288L, -1L, 1,2,1, + ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)1048576L, (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 1,3,1, + ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)262144L, (I)262144L, 1,3,1, + ((I)4194304L +(I)2097152L +(I)67108864L), ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), -1L, 1,2,1, + (I)33554432L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)2097152L, ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), -1L, 0,2,1, + (I)67108864L, ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)134217728L, -1L, 0,2,0, +}; + +int main() { + int i, j; + + for(j=0; j < sizeof(cases)/sizeof(cases[0]); j++) { + for(i=0; i < sizeof(cases->c)/sizeof(cases->c[0]); i++) + printf("cases[%d].c[%d]=%ld\n", j, i, cases[j].c[i]); + + printf("cases[%d].b=%ld\n", j, cases[j].b); + printf("cases[%d].e=%ld\n", j, cases[j].e); + printf("cases[%d].k=%ld\n", j, cases[j].k); + printf("\n"); + } + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/75_array_in_struct_init.expect b/05/tcc-0.9.27/tests/tests2/75_array_in_struct_init.expect new file mode 100644 index 0000000..2b75aa5 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/75_array_in_struct_init.expect @@ -0,0 +1,72 @@ +cases[0].c[0]=73400320 +cases[0].c[1]=262144 +cases[0].c[2]=805567999 +cases[0].c[3]=-1 +cases[0].b=1 +cases[0].e=2 +cases[0].k=1 + +cases[1].c[0]=879754751 +cases[1].c[1]=262144 +cases[1].c[2]=262144 +cases[1].c[3]=805567999 +cases[1].b=2 +cases[1].e=3 +cases[1].k=2 + +cases[2].c[0]=879754751 +cases[2].c[1]=805567999 +cases[2].c[2]=262144 +cases[2].c[3]=805567999 +cases[2].b=1 +cases[2].e=3 +cases[2].k=2 + +cases[3].c[0]=879754751 +cases[3].c[1]=805830143 +cases[3].c[2]=524288 +cases[3].c[3]=-1 +cases[3].b=1 +cases[3].e=2 +cases[3].k=1 + +cases[4].c[0]=879754751 +cases[4].c[1]=805830143 +cases[4].c[2]=1048576 +cases[4].c[3]=805830143 +cases[4].b=1 +cases[4].e=3 +cases[4].k=1 + +cases[5].c[0]=879754751 +cases[5].c[1]=805830143 +cases[5].c[2]=262144 +cases[5].c[3]=262144 +cases[5].b=1 +cases[5].e=3 +cases[5].k=1 + +cases[6].c[0]=73400320 +cases[6].c[1]=807403007 +cases[6].c[2]=807403007 +cases[6].c[3]=-1 +cases[6].b=1 +cases[6].e=2 +cases[6].k=1 + +cases[7].c[0]=839122431 +cases[7].c[1]=2097152 +cases[7].c[2]=807403007 +cases[7].c[3]=-1 +cases[7].b=0 +cases[7].e=2 +cases[7].k=1 + +cases[8].c[0]=67108864 +cases[8].c[1]=807403007 +cases[8].c[2]=134217728 +cases[8].c[3]=-1 +cases[8].b=0 +cases[8].e=2 +cases[8].k=0 + diff --git a/05/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.c b/05/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.c new file mode 100644 index 0000000..c5fcf99 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.c @@ -0,0 +1,41 @@ +#include <stdio.h> + +#define $(x) x +#define $fred 10 +#define joe$ 20 +#define hen$y 30 + +#define $10(x) x*10 +#define _$10(x) x/10 + +int main() +{ + printf("fred=%d\n", $fred); + printf("joe=%d\n", joe$); + printf("henry=%d\n", hen$y); + + printf("fred2=%d\n", $($fred)); + printf("joe2=%d\n", $(joe$)); + printf("henry2=%d\n", $(hen$y)); + + printf("fred10=%d\n", $10($fred)); + printf("joe_10=%d\n", _$10(joe$)); + + int $ = 10; + int a100$ = 100; + int a$$ = 1000; + int a$c$b = 2121; + int $100 = 10000; + const char *$$$ = "money"; + + printf("local=%d\n", $); + printf("a100$=%d\n", a100$); + printf("a$$=%d\n", a$$); + printf("a$c$b=%d\n", a$c$b); + printf("$100=%d\n", $100); + printf("$$$=%s", $$$); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/05/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.expect b/05/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.expect new file mode 100644 index 0000000..4a20a52 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.expect @@ -0,0 +1,14 @@ +fred=10 +joe=20 +henry=30 +fred2=10 +joe2=20 +henry2=30 +fred10=100 +joe_10=2 +local=10 +a100$=100 +a$$=1000 +a$c$b=2121 +$100=10000 +$$$=money diff --git a/05/tcc-0.9.27/tests/tests2/77_push_pop_macro.c b/05/tcc-0.9.27/tests/tests2/77_push_pop_macro.c new file mode 100644 index 0000000..d38e0bf --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/77_push_pop_macro.c @@ -0,0 +1,30 @@ +#include <stdio.h> + +int main() +{ + /* must not affect how #pragma ppop_macro works */ + #define pop_macro foobar1 + + /* must not affect how #pragma push_macro works */ + #define push_macro foobar2 + + #undef abort + #define abort "111" + printf("abort = %s\n", abort); + + #pragma push_macro("abort") + #undef abort + #define abort "222" + printf("abort = %s\n", abort); + + #pragma push_macro("abort") + #undef abort + #define abort "333" + printf("abort = %s\n", abort); + + #pragma pop_macro("abort") + printf("abort = %s\n", abort); + + #pragma pop_macro("abort") + printf("abort = %s\n", abort); +} diff --git a/05/tcc-0.9.27/tests/tests2/77_push_pop_macro.expect b/05/tcc-0.9.27/tests/tests2/77_push_pop_macro.expect new file mode 100644 index 0000000..d8a5530 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/77_push_pop_macro.expect @@ -0,0 +1,5 @@ +abort = 111 +abort = 222 +abort = 333 +abort = 222 +abort = 111 diff --git a/05/tcc-0.9.27/tests/tests2/78_vla_label.c b/05/tcc-0.9.27/tests/tests2/78_vla_label.c new file mode 100644 index 0000000..4096495 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/78_vla_label.c @@ -0,0 +1,45 @@ +#include <stdio.h> + +/* This test segfaults as of April 27, 2015. */ +void f1(int argc) +{ + char test[argc]; + if(0) + label: + printf("boom!\n"); + if(argc-- == 0) + return; + goto label; +} + +/* This segfaulted on 2015-11-19. */ +void f2(void) +{ + goto start; + { + int a[1 && 1]; /* not a variable-length array */ + int b[1 || 1]; /* not a variable-length array */ + int c[1 ? 1 : 1]; /* not a variable-length array */ + start: + a[0] = 0; + b[0] = 0; + c[0] = 0; + } +} + +void f3(void) +{ + printf("%d\n", 0 ? printf("x1\n") : 11); + printf("%d\n", 1 ? 12 : printf("x2\n")); + printf("%d\n", 0 && printf("x3\n")); + printf("%d\n", 1 || printf("x4\n")); +} + +int main() +{ + f1(2); + f2(); + f3(); + + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/78_vla_label.expect b/05/tcc-0.9.27/tests/tests2/78_vla_label.expect new file mode 100644 index 0000000..3f4063b --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/78_vla_label.expect @@ -0,0 +1,6 @@ +boom! +boom! +11 +12 +0 +1 diff --git a/05/tcc-0.9.27/tests/tests2/79_vla_continue.c b/05/tcc-0.9.27/tests/tests2/79_vla_continue.c new file mode 100644 index 0000000..91215c9 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/79_vla_continue.c @@ -0,0 +1,116 @@ +#include <stdio.h> + +int f(void) +{ + return 5; +} + +void test1() +{ + int count = 10; + void *addr[10]; + for(;count--;) { + int a[f()]; + + addr[count] = a; + + continue; + } + + if(addr[9] == addr[0]) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +void test2() +{ + int count = 10; + void *addr[count]; + for(;count--;) { + int a[f()]; + + addr[count] = a; + + continue; + } + + if(addr[9] == addr[0]) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +void test3() +{ + int count = 10; + void *addr[count]; + while(count--) { + int a[f()]; + + addr[count] = a; + + continue; + } + + if(addr[9] == addr[0]) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +void test4() +{ + int count = 10; + void *addr[count]; + do { + int a[f()]; + + addr[--count] = a; + + continue; + } while (count); + + if(addr[9] == addr[0]) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +void test5() +{ + int count = 10; + int a[f()]; + int c[f()]; + + c[0] = 42; + + for(;count--;) { + int b[f()]; + int i; + for (i=0; i<f(); i++) { + b[i] = count; + } + } + + if (c[0] == 42) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +int main(void) +{ + test1(); + test2(); + test3(); + test4(); + test5(); + + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/79_vla_continue.expect b/05/tcc-0.9.27/tests/tests2/79_vla_continue.expect new file mode 100644 index 0000000..21da4d2 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/79_vla_continue.expect @@ -0,0 +1,5 @@ +OK +OK +OK +OK +OK diff --git a/05/tcc-0.9.27/tests/tests2/80_flexarray.c b/05/tcc-0.9.27/tests/tests2/80_flexarray.c new file mode 100644 index 0000000..1fc1a60 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/80_flexarray.c @@ -0,0 +1,25 @@ +#include <stdio.h> +struct wchar { + char *data; char mem[]; +}; +struct wint { + char *data; int mem[]; +}; +int f1char (void) { + char s[9]="nonono"; + struct wchar q = {"bugs"}; + return !s[0]; +} +int f1int (void) { + char s[9]="nonono"; + struct wint q = {"bugs"}; + return !s[0]; +} +int main (void) { + char s[9]="nonono"; + static struct wchar q = {"bugs", {'c'}}; + //printf ("tcc has %s %s\n", s, q.data); + if (f1char() || f1int()) + printf ("bla\n"); + return !s[0]; +} diff --git a/05/tcc-0.9.27/tests/tests2/80_flexarray.expect b/05/tcc-0.9.27/tests/tests2/80_flexarray.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/80_flexarray.expect diff --git a/05/tcc-0.9.27/tests/tests2/81_types.c b/05/tcc-0.9.27/tests/tests2/81_types.c new file mode 100644 index 0000000..fd6d71b --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/81_types.c @@ -0,0 +1,43 @@ +/* The following are all valid decls, even though some subtypes + are incomplete. */ +enum E *e; +const enum E *e1; +enum E const *e2; +struct S *s; +const struct S *s1; +struct S const *s2; + +/* Various strangely looking declarators, which are all valid + and have to map to the same numbered typedefs. */ +typedef int (*fptr1)(); +int f1 (int (), int); +typedef int (*fptr2)(int x); +int f2 (int (int x), int); +typedef int (*fptr3)(int); +int f3 (int (int), int); +typedef int (*fptr4[4])(int); +int f4 (int (*[4])(int), int); +typedef int (*fptr5)(fptr1); +int f5 (int (int()), fptr1); +int f1 (fptr1 fp, int i) +{ + return (*fp)(i); +} +int f2 (fptr2 fp, int i) +{ + return (*fp)(i); +} +int f3 (fptr3 fp, int i) +{ + return (*fp)(i); +} +int f4 (fptr4 fp, int i) +{ + return (*fp[i])(i); +} +int f5 (fptr5 fp, fptr1 i) +{ + return fp(i); +} +int f8 (int ([4]), int); +int main () { return 0; } diff --git a/05/tcc-0.9.27/tests/tests2/81_types.expect b/05/tcc-0.9.27/tests/tests2/81_types.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/81_types.expect diff --git a/05/tcc-0.9.27/tests/tests2/82_attribs_position.c b/05/tcc-0.9.27/tests/tests2/82_attribs_position.c new file mode 100644 index 0000000..7c9f987 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/82_attribs_position.c @@ -0,0 +1,19 @@ +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; + +typedef union Unaligned16a { + uint16_t u; + uint8_t b[2]; +} __attribute__((packed)) Unaligned16a; + +typedef union __attribute__((packed)) Unaligned16b { + uint16_t u; + uint8_t b[2]; +} Unaligned16b; + +extern void foo (void) __attribute__((stdcall)); +void __attribute__((stdcall)) foo (void) +{ +} + +int main () { return 0; } diff --git a/05/tcc-0.9.27/tests/tests2/82_attribs_position.expect b/05/tcc-0.9.27/tests/tests2/82_attribs_position.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/82_attribs_position.expect diff --git a/05/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.c b/05/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.c new file mode 100644 index 0000000..1f86095 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.c @@ -0,0 +1,9 @@ +#include <stdio.h> +double привет=0.1; +int Lefèvre=2; +int main(){ + printf("привет=%g\n",привет); + printf("Lefèvre=%d\n",Lefèvre); + return 0; +} +// pcc & tcc only diff --git a/05/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.expect b/05/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.expect new file mode 100644 index 0000000..1553f5f --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.expect @@ -0,0 +1,2 @@ +привет=0.1 +Lefèvre=2 diff --git a/05/tcc-0.9.27/tests/tests2/84_hex-float.c b/05/tcc-0.9.27/tests/tests2/84_hex-float.c new file mode 100644 index 0000000..0ef09bf --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/84_hex-float.c @@ -0,0 +1,12 @@ +extern int printf(const char *format, ...); + +#define ACPI_TYPE_INVALID 0x1E +#define NUM_NS_TYPES ACPI_TYPE_INVALID+1 +int array[NUM_NS_TYPES]; + +#define n 0xe +int main() +{ + printf("n+1 = %d\n", n+1); +// printf("n+1 = %d\n", 0xe+1); +} diff --git a/05/tcc-0.9.27/tests/tests2/84_hex-float.expect b/05/tcc-0.9.27/tests/tests2/84_hex-float.expect new file mode 100644 index 0000000..2175385 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/84_hex-float.expect @@ -0,0 +1 @@ +n+1 = 15 diff --git a/05/tcc-0.9.27/tests/tests2/85_asm-outside-function.c b/05/tcc-0.9.27/tests/tests2/85_asm-outside-function.c new file mode 100644 index 0000000..dc5639a --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/85_asm-outside-function.c @@ -0,0 +1,9 @@ +extern int printf (const char *, ...); +extern void vide(void); +__asm__("vide: ret"); + +int main() { + vide(); + printf ("okay\n"); + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/85_asm-outside-function.expect b/05/tcc-0.9.27/tests/tests2/85_asm-outside-function.expect new file mode 100644 index 0000000..dcf02b2 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/85_asm-outside-function.expect @@ -0,0 +1 @@ +okay diff --git a/05/tcc-0.9.27/tests/tests2/86_memory-model.c b/05/tcc-0.9.27/tests/tests2/86_memory-model.c new file mode 100644 index 0000000..744c3e2 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/86_memory-model.c @@ -0,0 +1,38 @@ +#include <stdio.h> + +int +main() +{ +#if defined(__LLP64__) + if (sizeof(short) == 2 + && sizeof(int) == 4 + && sizeof(long int) == 4 + && sizeof(long long int) == 8 + && sizeof(void*) == 8) { + (void)printf("Ok\n"); + } else { + (void)printf("KO __LLP64__\n"); + } +#elif defined(__LP64__) + if (sizeof(short) == 2 + && sizeof(int) == 4 + && sizeof(long int) == 8 + && sizeof(long long int) == 8 + && sizeof(void*) == 8) { + (void)printf("Ok\n"); + } else { + (void)printf("KO __LP64__\n"); + } +#elif defined(__ILP32__) + if (sizeof(short) == 2 + && sizeof(int) == 4 + && sizeof(long int) == 4 + && sizeof(void*) == 4) { + (void)printf("Ok\n"); + } else { + (void)printf("KO __ILP32__\n"); + } +#else + (void)printf("KO no __*LP*__ defined.\n"); +#endif +} diff --git a/05/tcc-0.9.27/tests/tests2/86_memory-model.expect b/05/tcc-0.9.27/tests/tests2/86_memory-model.expect new file mode 100644 index 0000000..7326d96 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/86_memory-model.expect @@ -0,0 +1 @@ +Ok diff --git a/05/tcc-0.9.27/tests/tests2/87_dead_code.c b/05/tcc-0.9.27/tests/tests2/87_dead_code.c new file mode 100644 index 0000000..98d4566 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/87_dead_code.c @@ -0,0 +1,122 @@ +/* This checks various ways of dead code inside if statements + where there are non-obvious ways of how the code is actually + not dead due to reachable by labels. */ +extern int printf (const char *, ...); +static void kb_wait_1(void) +{ + unsigned long timeout = 2; + do { + /* Here the else arm is a statement expression that's supposed + to be suppressed. The label inside the while would unsuppress + code generation again if not handled correctly. And that + would wreak havoc to the cond-expression because there's no + jump-around emitted, the whole statement expression really + needs to not generate code (perhaps except useless forward jumps). */ + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + int i = 1; + while (1) + while (i--) + some_label: + printf("error\n"); + goto some_label; + }) + ); + timeout--; + } while (timeout); +} +int main (void) +{ + int i = 1; + kb_wait_1(); + + /* Simple test of dead code at first sight which isn't actually dead. */ + if (0) { +yeah: + printf ("yeah\n"); + } else { + printf ("boo\n"); + } + if (i--) + goto yeah; + + /* Some more non-obvious uses where the problems are loops, so that even + the first loop statements aren't actually dead. */ + i = 1; + if (0) { + while (i--) { + printf ("once\n"); +enterloop: + printf ("twice\n"); + } + } + if (i >= 0) + goto enterloop; + + /* The same with statement expressions. One might be tempted to + handle them specially by counting if inside statement exprs and + not unsuppressing code at loops at all then. + See kb_wait_1 for the other side of the medal where that wouldn't work. */ + i = ({ + int j = 1; + if (0) { + while (j--) { + printf ("SEonce\n"); + enterexprloop: + printf ("SEtwice\n"); + } + } + if (j >= 0) + goto enterexprloop; + j; }); + + /* The other two loop forms: */ + i = 1; + if (0) { + for (i = 1; i--;) { + printf ("once2\n"); +enterloop2: + printf ("twice2\n"); + } + } + if (i > 0) + goto enterloop2; + + i = 1; + if (0) { + do { + printf ("once3\n"); +enterloop3: + printf ("twice3\n"); + } while (i--); + } + if (i > 0) + goto enterloop3; + + /* And check that case and default labels have the same effect + of disabling code suppression. */ + i = 41; + switch (i) { + if (0) { + printf ("error\n"); + case 42: + printf ("error2\n"); + case 41: + printf ("caseok\n"); + } + } + + i = 41; + switch (i) { + if (0) { + printf ("error3\n"); + default: + printf ("caseok2\n"); + break; + case 42: + printf ("error4\n"); + } + } + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/87_dead_code.expect b/05/tcc-0.9.27/tests/tests2/87_dead_code.expect new file mode 100644 index 0000000..0b3ec1d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/87_dead_code.expect @@ -0,0 +1,18 @@ +timeout=2 +timeout=1 +boo +yeah +twice +once +twice +SEtwice +SEonce +SEtwice +twice2 +once2 +twice2 +twice3 +once3 +twice3 +caseok +caseok2 diff --git a/05/tcc-0.9.27/tests/tests2/88_codeopt.c b/05/tcc-0.9.27/tests/tests2/88_codeopt.c new file mode 100644 index 0000000..647626f --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/88_codeopt.c @@ -0,0 +1,68 @@ +/* Check some way in where code suppression caused various + miscompilations. */ +extern int printf (const char *, ...); +typedef unsigned long size_t; + +size_t _brk_start, _brk_end; +void * extend_brk(size_t size, size_t align) +{ + size_t mask = align - 1; + void *ret = 0; + + do { + if (__builtin_expect(!!(_brk_start == 0), 0)) + do { + printf("wrong1\n"); + } while (0); + } while (0); + _brk_end = (_brk_end + mask) & ~mask; + ret = (void *)_brk_end; + _brk_end += size; + + return ret; +} + +static void get_args (int a, int b) +{ + if (a != 1) + printf("wrong2\n"); + else + printf("okay\n"); +} + +void bla(void) +{ + int __ret = 42; + ({ + if (__builtin_expect(!!(0), 0)) { + if (__builtin_expect(!!__ret, 0)) + printf("wrong3\n"); + int x = !!(__ret); + } + __ret; + }); + get_args(!!__ret, sizeof(__ret)); +} + +_Bool chk(unsigned long addr, unsigned long limit, unsigned long size) +{ + _Bool ret; + /* This just needs to compile, no runtime test. (And it doesn't compile + only with certain internal checking added that's not committed). */ + if (0) + ret = 0 != (!!(addr > limit - size)); +} + +int main() +{ + void *r; + _brk_start = 1024; + _brk_end = 1024; + r = extend_brk (4096, 16); + if (!r) + printf("wrong4\n"); + else + printf("okay\n"); + bla(); + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/88_codeopt.expect b/05/tcc-0.9.27/tests/tests2/88_codeopt.expect new file mode 100644 index 0000000..439edfd --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/88_codeopt.expect @@ -0,0 +1,2 @@ +okay +okay diff --git a/05/tcc-0.9.27/tests/tests2/89_nocode_wanted.c b/05/tcc-0.9.27/tests/tests2/89_nocode_wanted.c new file mode 100644 index 0000000..73e0a4b --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/89_nocode_wanted.c @@ -0,0 +1,112 @@ +extern int printf(const char *format, ...); +static void kb_wait_1(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + while (1) + printf("error\n"); + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_2(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + for (;;) + printf("error\n"); + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_2_1(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + do { + printf("error\n"); + } while (1); + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_2_2(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + label: + printf("error\n"); + goto label; + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_3(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + int i = 1; + goto label; + i = i + 2; + label: + i = i + 3; + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_4(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + switch(timeout) { + case 2: + printf("timeout is 2"); + break; + case 1: + printf("timeout is 1"); + break; + default: + printf("timeout is 0?"); + break; + }; + // return; + }) + ); + timeout--; + } while (timeout); +} +int main() +{ + printf("begin\n"); + kb_wait_1(); + kb_wait_2(); + kb_wait_2_1(); + kb_wait_2_2(); + kb_wait_3(); + kb_wait_4(); + printf("end\n"); + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/89_nocode_wanted.expect b/05/tcc-0.9.27/tests/tests2/89_nocode_wanted.expect new file mode 100644 index 0000000..c44d4ea --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/89_nocode_wanted.expect @@ -0,0 +1,14 @@ +begin +timeout=2 +timeout=1 +timeout=2 +timeout=1 +timeout=2 +timeout=1 +timeout=2 +timeout=1 +timeout=2 +timeout=1 +timeout=2 +timeout=1 +end diff --git a/05/tcc-0.9.27/tests/tests2/90_struct-init.c b/05/tcc-0.9.27/tests/tests2/90_struct-init.c new file mode 100644 index 0000000..d931e23 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/90_struct-init.c @@ -0,0 +1,282 @@ +typedef unsigned char u8; +typedef struct {} empty_s; +struct contains_empty { + u8 a; + empty_s empty; + u8 b; +}; +struct contains_empty ce = { { (1) }, (empty_s){}, 022, }; +/* The following decl of 'q' would demonstrate the TCC bug in init_putv when + handling copying compound literals. (Compound literals + aren't acceptable constant initializers in isoc99, but + we accept them like gcc, except for this case) +//char *q = (char *){ "trara" }; */ +struct SS {u8 a[3], b; }; +struct SS sinit16[] = { { 1 }, 2 }; +struct S +{ + u8 a,b; + u8 c[2]; +}; + +struct T +{ + u8 s[16]; + u8 a; +}; + +struct U +{ + u8 a; + struct S s; + u8 b; + struct T t; +}; + +struct V +{ + struct S s; + struct T t; + u8 a; +}; + +struct W +{ + struct V t; + struct S s[]; +}; + +struct S gs = ((struct S){1, 2, 3, 4}); +struct S gs2 = {1, 2, {3, 4}}; +struct T gt = {"hello", 42}; +struct U gu = {3, 5,6,7,8, 4, "huhu", 43}; +struct U gu2 = {3, {5,6,7,8}, 4, {"huhu", 43}}; +/* Optional braces around scalar initializers. Accepted, but with + a warning. */ +struct U gu3 = { {3}, {5,6,7,8,}, 4, {"huhu", 43}}; +/* Many superfluous braces and leaving out one initializer for U.s.c[1] */ +struct U gu4 = { 3, {5,6,7,}, 5, { "bla", {44}} }; +/* Superfluous braces and useless parens around values */ +struct S gs3 = { (1), {(2)}, {(((3))), {4}}}; +/* Superfluous braces, and leaving out braces for V.t, plus cast */ +struct V gv = {{{3},4,{5,6}}, "haha", (u8)45, 46}; +/* Compound literal */ +struct V gv2 = {(struct S){7,8,{9,10}}, {"hihi", 47}, 48}; +/* Parens around compound literal */ +struct V gv3 = {((struct S){7,8,{9,10}}), {"hoho", 49}, 50}; +/* Initialization of a flex array member (warns in GCC) */ +struct W gw = {{1,2,3,4}, {1,2,3,4,5}}; + +union UU { + u8 a; + u8 b; +}; +struct SU { + union UU u; + u8 c; +}; +struct SU gsu = {5,6}; + +/* Unnamed struct/union members aren't ISO C, but it's a widely accepted + extension. See below for further extensions to that under -fms-extension.*/ +union UV { + struct {u8 a,b;}; + struct S s; +}; +union UV guv = {{6,5}}; +union UV guv2 = {{.b = 7, .a = 8}}; +union UV guv3 = {.b = 8, .a = 7}; + +/* Under -fms-extensions also the following is valid: +union UV2 { + struct Anon {u8 a,b;}; // unnamed member, but tagged struct, ... + struct S s; +}; +struct Anon gan = { 10, 11 }; // ... which makes it available here. +union UV2 guv4 = {{4,3}}; // and the other inits from above as well +*/ + +struct in6_addr { + union { + u8 u6_addr8[16]; + unsigned short u6_addr16[8]; + } u; +}; +struct flowi6 { + struct in6_addr saddr, daddr; +}; +struct pkthdr { + struct in6_addr daddr, saddr; +}; +struct pkthdr phdr = { { { 6,5,4,3 } }, { { 9,8,7,6 } } }; + +struct Wrap { + void *func; +}; +int global; +void inc_global (void) +{ + global++; +} + +struct Wrap global_wrap[] = { + ((struct Wrap) {inc_global}), + inc_global, +}; + +#include <stdio.h> +void print_ (const char *name, const u8 *p, long size) +{ + printf ("%s:", name); + while (size--) { + printf (" %x", *p++); + } + printf ("\n"); +} +#define print(x) print_(#x, (u8*)&x, sizeof (x)) +#if 1 +void foo (struct W *w, struct pkthdr *phdr_) +{ + struct S ls = {1, 2, 3, 4}; + struct S ls2 = {1, 2, {3, 4}}; + struct T lt = {"hello", 42}; + struct U lu = {3, 5,6,7,8, 4, "huhu", 43}; + struct U lu1 = {3, ls, 4, {"huhu", 43}}; + struct U lu2 = {3, (ls), 4, {"huhu", 43}}; + const struct S *pls = &ls; + struct S ls21 = *pls; + struct U lu22 = {3, *pls, 4, {"huhu", 43}}; + /* Incomplete bracing. */ + struct U lu21 = {3, ls, 4, "huhu", 43}; + /* Optional braces around scalar initializers. Accepted, but with + a warning. */ + struct U lu3 = { 3, {5,6,7,8,}, 4, {"huhu", 43}}; + /* Many superfluous braces and leaving out one initializer for U.s.c[1] */ + struct U lu4 = { 3, {5,6,7,}, 5, { "bla", 44} }; + /* Superfluous braces and useless parens around values */ + struct S ls3 = { (1), (2), {(((3))), 4}}; + /* Superfluous braces, and leaving out braces for V.t, plus cast */ + struct V lv = {{3,4,{5,6}}, "haha", (u8)45, 46}; + /* Compound literal */ + struct V lv2 = {(struct S)w->t.s, {"hihi", 47}, 48}; + /* Parens around compound literal */ + struct V lv3 = {((struct S){7,8,{9,10}}), ((const struct W *)w)->t.t, 50}; + const struct pkthdr *phdr = phdr_; + struct flowi6 flow = { .daddr = phdr->daddr, .saddr = phdr->saddr }; + int elt = 0x42; + /* Range init, overlapping */ + struct T lt2 = { { [1 ... 5] = 9, [6 ... 10] = elt, [4 ... 7] = elt+1 }, 1 }; + print(ls); + print(ls2); + print(lt); + print(lu); + print(lu1); + print(lu2); + print(ls21); + print(lu21); + print(lu22); + print(lu3); + print(lu4); + print(ls3); + print(lv); + print(lv2); + print(lv3); + print(lt2); + print(flow); +} +#endif + +void test_compound_with_relocs (void) +{ + struct Wrap local_wrap[] = { + ((struct Wrap) {inc_global}), + inc_global, + }; + void (*p)(void); + p = global_wrap[0].func; p(); + p = global_wrap[1].func; p(); + p = local_wrap[0].func; p(); + p = local_wrap[1].func; p(); +} + +void sys_ni(void) { printf("ni\n"); } +void sys_one(void) { printf("one\n"); } +void sys_two(void) { printf("two\n"); } +void sys_three(void) { printf("three\n"); } +typedef void (*fptr)(void); +const fptr table[3] = { + [0 ... 2] = &sys_ni, + [0] = sys_one, + [1] = sys_two, + [2] = sys_three, +}; + +void test_multi_relocs(void) +{ + int i; + for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) + table[i](); +} + +/* Following is from GCC gcc.c-torture/execute/20050613-1.c. */ + +struct SEA { int i; int j; int k; int l; }; +struct SEB { struct SEA a; int r[1]; }; +struct SEC { struct SEA a; int r[0]; }; +struct SED { struct SEA a; int r[]; }; + +static void +test_correct_filling (struct SEA *x) +{ + static int i; + if (x->i != 0 || x->j != 5 || x->k != 0 || x->l != 0) + printf("sea_fill%d: wrong\n", i); + else + printf("sea_fill%d: okay\n", i); + i++; +} + +int +test_zero_init (void) +{ + /* The peculiarity here is that only a.j is initialized. That + means that all other members must be zero initialized. TCC + once didn't do that for sub-level designators. */ + struct SEB b = { .a.j = 5 }; + struct SEC c = { .a.j = 5 }; + struct SED d = { .a.j = 5 }; + test_correct_filling (&b.a); + test_correct_filling (&c.a); + test_correct_filling (&d.a); + return 0; +} + +int main() +{ + print(ce); + print(gs); + print(gs2); + print(gt); + print(gu); + print(gu2); + print(gu3); + print(gu4); + print(gs3); + print(gv); + print(gv2); + print(gv3); + print(sinit16); + print(gw); + print(gsu); + print(guv); + print(guv.b); + print(guv2); + print(guv3); + print(phdr); + foo(&gw, &phdr); + //printf("q: %s\n", q); + test_compound_with_relocs(); + test_multi_relocs(); + test_zero_init(); + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/90_struct-init.expect b/05/tcc-0.9.27/tests/tests2/90_struct-init.expect new file mode 100644 index 0000000..e366121 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/90_struct-init.expect @@ -0,0 +1,43 @@ +ce: 1 12 +gs: 1 2 3 4 +gs2: 1 2 3 4 +gt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a +gu: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +gu2: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +gu3: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +gu4: 3 5 6 7 0 5 62 6c 61 0 0 0 0 0 0 0 0 0 0 0 0 0 2c +gs3: 1 2 3 4 +gv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e +gv2: 7 8 9 a 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30 +gv3: 7 8 9 a 68 6f 68 6f 0 0 0 0 0 0 0 0 0 0 0 0 31 32 +sinit16: 1 0 0 0 2 0 0 0 +gw: 1 2 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +gsu: 5 6 +guv: 6 5 0 0 +guv.b: 5 +guv2: 8 7 0 0 +guv3: 7 8 0 0 +phdr: 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0 9 8 7 6 0 0 0 0 0 0 0 0 0 0 0 0 +ls: 1 2 3 4 +ls2: 1 2 3 4 +lt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a +lu: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu1: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu2: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +ls21: 1 2 3 4 +lu21: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu22: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu3: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu4: 3 5 6 7 0 5 62 6c 61 0 0 0 0 0 0 0 0 0 0 0 0 0 2c +ls3: 1 2 3 4 +lv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e +lv2: 1 2 3 4 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30 +lv3: 7 8 9 a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 +lt2: 0 9 9 9 43 43 43 43 42 42 42 0 0 0 0 0 1 +flow: 9 8 7 6 0 0 0 0 0 0 0 0 0 0 0 0 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0 +one +two +three +sea_fill0: okay +sea_fill1: okay +sea_fill2: okay diff --git a/05/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.c b/05/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.c new file mode 100644 index 0000000..bf07915 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.c @@ -0,0 +1,15 @@ +int printf(const char *, ...); +char t[] = "012345678"; + +int main(void) +{ + char *data = t; + unsigned long long r = 4; + unsigned a = 5; + unsigned long long b = 12; + + *(unsigned*)(data + r) += a - b; + + printf("data = \"%s\"\n", data); + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.expect b/05/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.expect new file mode 100644 index 0000000..f91e4b4 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.expect @@ -0,0 +1 @@ +data = "0123-5678" diff --git a/05/tcc-0.9.27/tests/tests2/92_enum_bitfield.c b/05/tcc-0.9.27/tests/tests2/92_enum_bitfield.c new file mode 100644 index 0000000..bb6dc35 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/92_enum_bitfield.c @@ -0,0 +1,57 @@ +/* This checks if enums needing 8 bit but only having positive + values are correctly zero extended (instead of sign extended) + when stored into/loaded from a 8 bit bit-field of enum type (which + itself is implementation defined, so isn't necessarily supported by all + other compilers). */ +enum tree_code { + SOME_CODE = 148, /* has bit 7 set, and hence all further enum values as well */ + LAST_AND_UNUSED_TREE_CODE +}; +typedef union tree_node *tree; +struct tree_common +{ + union tree_node *chain; + union tree_node *type; + enum tree_code code : 8; + unsigned side_effects_flag : 1; +}; +union tree_node +{ + struct tree_common common; + }; +enum c_tree_code { + C_DUMMY_TREE_CODE = LAST_AND_UNUSED_TREE_CODE, + STMT_EXPR, + LAST_C_TREE_CODE +}; +enum cplus_tree_code { + CP_DUMMY_TREE_CODE = LAST_C_TREE_CODE, + AMBIG_CONV, + LAST_CPLUS_TREE_CODE +}; + +extern int printf(const char *, ...); +int blah(){return 0;} + +int convert_like_real (tree convs) +{ + switch (((enum tree_code) (convs)->common.code)) + { + case AMBIG_CONV: /* This has bit 7 set, which must not be the sign + bit in tree_common.code, i.e. the bitfield must + be somehow marked unsigned. */ + return blah(); + default: + break; + }; + printf("unsigned enum bit-fields broken\n"); +} + +int main() +{ + union tree_node convs; + + convs.common.code = AMBIG_CONV; + convert_like_real (&convs); + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/92_enum_bitfield.expect b/05/tcc-0.9.27/tests/tests2/92_enum_bitfield.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/92_enum_bitfield.expect diff --git a/05/tcc-0.9.27/tests/tests2/93_integer_promotion.c b/05/tcc-0.9.27/tests/tests2/93_integer_promotion.c new file mode 100644 index 0000000..a1176fc --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/93_integer_promotion.c @@ -0,0 +1,71 @@ +/* integer promotion */ + +int printf(const char*, ...); +#define promote(s) printf(" %ssigned : %s\n", (s) - 100 < 0 ? " " : "un", #s); + +int main (void) +{ + struct { + unsigned ub:3; + unsigned u:32; + unsigned long long ullb:35; + unsigned long long ull:64; + unsigned char c; + } s = { 1, 1, 1 }; + + promote(s.ub); + promote(s.u); + promote(s.ullb); + promote(s.ull); + promote(s.c); + printf("\n"); + + promote((1 ? s.ub : 1)); + promote((1 ? s.u : 1)); + promote((1 ? s.ullb : 1)); + promote((1 ? s.ull : 1)); + promote((1 ? s.c : 1)); + printf("\n"); + + promote(s.ub << 1); + promote(s.u << 1); + promote(s.ullb << 1); + promote(s.ull << 1); + promote(s.c << 1); + printf("\n"); + + promote(+s.ub); + promote(+s.u); + promote(+s.ullb); + promote(+s.ull); + promote(+s.c); + printf("\n"); + + promote(-s.ub); + promote(-s.u); + promote(-s.ullb); + promote(-s.ull); + promote(-s.c); + printf("\n"); + + promote(~s.ub); + promote(~s.u); + promote(~s.ullb); + promote(~s.ull); + promote(~s.c); + printf("\n"); + + promote(!s.ub); + promote(!s.u); + promote(!s.ullb); + promote(!s.ull); + promote(!s.c); + printf("\n"); + + promote(+(unsigned)s.ub); + promote(-(unsigned)s.ub); + promote(~(unsigned)s.ub); + promote(!(unsigned)s.ub); + + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/93_integer_promotion.expect b/05/tcc-0.9.27/tests/tests2/93_integer_promotion.expect new file mode 100644 index 0000000..34b9c14 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/93_integer_promotion.expect @@ -0,0 +1,46 @@ + signed : s.ub + unsigned : s.u + signed : s.ullb + unsigned : s.ull + signed : s.c + + signed : (1 ? s.ub : 1) + unsigned : (1 ? s.u : 1) + signed : (1 ? s.ullb : 1) + unsigned : (1 ? s.ull : 1) + signed : (1 ? s.c : 1) + + signed : s.ub << 1 + unsigned : s.u << 1 + signed : s.ullb << 1 + unsigned : s.ull << 1 + signed : s.c << 1 + + signed : +s.ub + unsigned : +s.u + signed : +s.ullb + unsigned : +s.ull + signed : +s.c + + signed : -s.ub + unsigned : -s.u + signed : -s.ullb + unsigned : -s.ull + signed : -s.c + + signed : ~s.ub + unsigned : ~s.u + signed : ~s.ullb + unsigned : ~s.ull + signed : ~s.c + + signed : !s.ub + signed : !s.u + signed : !s.ullb + signed : !s.ull + signed : !s.c + + unsigned : +(unsigned)s.ub + unsigned : -(unsigned)s.ub + unsigned : ~(unsigned)s.ub + signed : !(unsigned)s.ub diff --git a/05/tcc-0.9.27/tests/tests2/94_generic.c b/05/tcc-0.9.27/tests/tests2/94_generic.c new file mode 100644 index 0000000..d7fb5fc --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/94_generic.c @@ -0,0 +1,64 @@ +#include <stdio.h> + +const int a = 0; + +struct a { + int a; +}; + +struct b { + int a; +}; + +int a_f() +{ + return 20; +} + +int b_f() +{ + return 10; +} + +typedef int int_type1; + +#define gen_sw(a) _Generic(a, const char *: 1, default: 8, int: 123); + +int main() +{ + int i = 0; + signed long int l = 2; + struct b titi; + const int * const ptr; + const char *ti; + int_type1 i2; + + i = _Generic(a, int: a_f, const int: b_f)(); + printf("%d\n", i); + i = _Generic(a, int: a_f() / 2, const int: b_f() / 2); + printf("%d\n", i); + i = _Generic(ptr, int *:1, int * const:2, default:20); + printf("%d\n", i); + i = gen_sw(a); + printf("%d\n", i); + i = _Generic(titi, struct a:1, struct b:2, default:20); + printf("%d\n", i); + i = _Generic(i2, char: 1, int : 0); + printf("%d\n", i); + i = _Generic(a, char:1, int[4]:2, default:5); + printf("%d\n", i); + i = _Generic(17, int :1, int **:2); + printf("%d\n", i); + i = _Generic(17L, int :1, long :2, long long : 3); + printf("%d\n", i); + i = _Generic("17, io", char *: 3, const char *: 1); + printf("%d\n", i); + i = _Generic(ti, const unsigned char *:1, const char *:4, char *:3, + const signed char *:2); + printf("%d\n", i); + printf("%s\n", _Generic(i + 2L, long: "long", int: "int", + long long: "long long")); + i = _Generic(l, long: 1, int: 2); + printf("%d\n", i); + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/94_generic.expect b/05/tcc-0.9.27/tests/tests2/94_generic.expect new file mode 100644 index 0000000..9aa9275 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/94_generic.expect @@ -0,0 +1,13 @@ +20 +10 +20 +123 +2 +0 +5 +1 +2 +3 +4 +long +1
\ No newline at end of file diff --git a/05/tcc-0.9.27/tests/tests2/95_bitfields.c b/05/tcc-0.9.27/tests/tests2/95_bitfields.c new file mode 100644 index 0000000..f025c57 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/95_bitfields.c @@ -0,0 +1,218 @@ +/* ----------------------------------------------------------------------- */ +#if TEST == 1 +{ + struct M P A __s + { + unsigned x : 12; + unsigned char y : 7; + unsigned z : 28; + unsigned a: 4; + unsigned b: 5; + }; + TEST_STRUCT(0x333,0x44,0x555555,6,7); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 2 +{ + struct M P __s + { + int x: 12; + char y: 6; + long long z:63; + A char a:4; + long long b:2; + + }; + TEST_STRUCT(3,30,0x123456789abcdef0LL,5,2); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 3 +{ + struct M P __s + { + unsigned x:5, y:5, :0, z:5; char a:5; A short b:5; + }; + TEST_STRUCT(21,23,25,6,14); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 4 +{ + struct M P __s { + int x : 3; + int : 2; + int y : 1; + int : 0; + int z : 5; + int a : 7; + unsigned int b : 7; + }; + TEST_STRUCT(3,1,15,120,120); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 5 +{ + struct M P __s { + long long x : 45; + long long : 2; + long long y : 30; + unsigned long long z : 38; + char a; short b; + }; + TEST_STRUCT(0x123456789ULL, 120<<25, 120, 0x44, 0x77); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 6 +{ + struct M P __s { + int a; + signed char b; + int x : 12, y : 4, : 0, : 4, z : 3; + char d; + }; + TEST_STRUCT(1,2,3,4,-3); +} + +/* ----------------------------------------------------------------------- */ +#elif defined PACK + +#if PACK +# pragma pack(push,1) +# define P //_P +#else +# define P +#endif + +printf("\n\n" + 2*top); +#define TEST 1 +#include SELF +top = 0; +#define TEST 2 +#include SELF +#define TEST 3 +#include SELF +#define TEST 4 +#include SELF +#define TEST 5 +#include SELF +#define TEST 6 +#include SELF + +#if PACK +# pragma pack(pop) +#endif + +#undef P +#undef PACK + +/* ----------------------------------------------------------------------- */ +#elif defined ALIGN + +#if ALIGN +# define A _A(16) +#else +# define A +#endif + +#define PACK 0 +#include SELF +#define PACK 1 +#include SELF + +#undef A +#undef ALIGN + +/* ----------------------------------------------------------------------- */ +#elif defined MS_BF + +#if MS_BF +# ifdef __TINYC__ +# pragma comment(option, "-mms-bitfields") +# elif defined __GNUC__ +# define M __attribute__((ms_struct)) +# endif +#else +# ifdef __TINYC__ +# pragma comment(option, "-mno-ms-bitfields") +# elif defined __GNUC__ +# define M __attribute__((gcc_struct)) +# endif +#endif +#ifndef M +# define M +#endif + +#define ALIGN 0 +#include SELF +#define ALIGN 1 +#include SELF + +#undef M +#undef MS_BF + +/* ----------------------------------------------------------------------- */ +#else + +#include <stdio.h> +#include <string.h> +/* some gcc headers #define __attribute__ to empty if it's not gcc */ +#undef __attribute__ + +void dump(void *p, int s) +{ + int i; + for (i = s; --i >= 0;) + printf("%02X", ((unsigned char*)p)[i]); + printf("\n"); +} + +#define pv(m) \ + printf(sizeof (s->m + 0) == 8 ? " %016llx" : " %02x", s->m) + +#define TEST_STRUCT(v1,v2,v3,v4,v5) { \ + struct __s _s, *s = & _s; \ + printf("\n---- TEST %d%s%s%s ----\n" + top, \ + TEST, MS_BF?" - MS-BITFIELDS":"", \ + PACK?" - PACKED":"", \ + ALIGN?" - WITH ALIGN":""); \ + memset(s, 0, sizeof *s); \ + s->x = -1, s->y = -1, s->z = -1, s->a = -1, s->b = -1; \ + printf("bits in use : "), dump(s, sizeof *s); \ + s->x = v1, s->y = v2, s->z = v3, s->a += v4, ++s->a, s->b = v5; \ + printf("bits as set : "), dump(s, sizeof *s); \ + printf("values :"), pv(x), pv(y), pv(z), pv(a), pv(b), printf("\n"); \ + printf("align/size : %d %d\n", alignof(struct __s),sizeof(struct __s)); \ + } + +#ifdef _MSC_VER +# define _A(n) __declspec(align(n)) +# define _P +# define alignof(x) __alignof(x) +#else +# define _A(n) __attribute__((aligned(n))) +# define _P __attribute__((packed)) +# define alignof(x) __alignof__(x) +#endif + +#ifndef MS_BITFIELDS +# define MS_BITFIELDS 0 +#endif + +#define SELF "95_bitfields.c" + +int top = 1; + +int main() +{ +#define MS_BF MS_BITFIELDS +#include SELF + return 0; +} + +/* ----------------------------------------------------------------------- */ +#endif +#undef TEST diff --git a/05/tcc-0.9.27/tests/tests2/95_bitfields.expect b/05/tcc-0.9.27/tests/tests2/95_bitfields.expect new file mode 100644 index 0000000..6a8fd9a --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/95_bitfields.expect @@ -0,0 +1,149 @@ +---- TEST 1 ---- +bits in use : 0000001FFFFFFFFF007F0FFF +bits as set : 000000076055555500440333 +values : 333 44 555555 06 07 +align/size : 4 12 + +---- TEST 2 ---- +bits in use : 000000000000003F7FFFFFFFFFFFFFFF00000000003F0FFF +bits as set : 0000000000000025123456789ABCDEF000000000001E0003 +values : 03 1e 123456789abcdef0 05 fffffffe +align/size : 8 24 + +---- TEST 3 ---- +bits in use : 001F1F1F000003FF +bits as set : 000E0619000002F5 +values : 15 17 19 06 0e +align/size : 4 8 + +---- TEST 4 ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 4 8 + +---- TEST 5 ---- +bits in use : FFFFFF3FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 007744000000007800000000300000000000000123456789 +values : 0000000123456789 f0000000 0000000000000078 44 77 +align/size : 8 24 + +---- TEST 6 ---- +bits in use : 0000007000FFFFFFFFFFFFFF +bits as set : 00000030002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 4 12 + + + +---- TEST 1 - PACKED ---- +bits in use : FFFFFFFFFFFFFF +bits as set : 3B02AAAAAC4333 +values : 333 44 555555 06 07 +align/size : 1 7 + +---- TEST 2 - PACKED ---- +bits in use : 7FFFFFFFFFFFFFFFFFFFFF +bits as set : 4A48D159E26AF37BC1E003 +values : 03 1e 123456789abcdef0 05 fffffffe +align/size : 1 11 + +---- TEST 3 - PACKED ---- +bits in use : 7FFF000003FF +bits as set : 38D9000002F5 +values : 15 17 19 06 0e +align/size : 1 6 + +---- TEST 4 - PACKED ---- +bits in use : 07FFFF00000027 +bits as set : 078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 1 7 + +---- TEST 5 - PACKED ---- +bits in use : FFFFFF07FFFFFFFFFFFFFFFF9FFFFFFFFFFF +bits as set : 007744000000000F18000000000123456789 +values : 0000000123456789 f0000000 0000000000000078 44 77 +align/size : 1 18 + +---- TEST 6 - PACKED ---- +bits in use : 007000FFFFFFFFFFFFFF +bits as set : 0030002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 1 10 + + + +---- TEST 1 - WITH ALIGN ---- +bits in use : 000000000000001FFFFFFFFF007F0FFF +bits as set : 00000000000000076055555500440333 +values : 333 44 555555 06 07 +align/size : 16 16 + +---- TEST 2 - WITH ALIGN ---- +bits in use : 0000000000000000000000000000003F7FFFFFFFFFFFFFFF00000000003F0FFF +bits as set : 00000000000000000000000000000025123456789ABCDEF000000000001E0003 +values : 03 1e 123456789abcdef0 05 fffffffe +align/size : 16 32 + +---- TEST 3 - WITH ALIGN ---- +bits in use : 0000000000000000000000000000001F000000000000000000001F1F000003FF +bits as set : 0000000000000000000000000000000E000000000000000000000619000002F5 +values : 15 17 19 06 0e +align/size : 16 32 + +---- TEST 4 - WITH ALIGN ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 4 8 + +---- TEST 5 - WITH ALIGN ---- +bits in use : FFFFFF3FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 007744000000007800000000300000000000000123456789 +values : 0000000123456789 f0000000 0000000000000078 44 77 +align/size : 8 24 + +---- TEST 6 - WITH ALIGN ---- +bits in use : 0000007000FFFFFFFFFFFFFF +bits as set : 00000030002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 4 12 + + + +---- TEST 1 - PACKED - WITH ALIGN ---- +bits in use : 000000000000000000FFFFFFFFFFFFFF +bits as set : 0000000000000000003B02AAAAAC4333 +values : 333 44 555555 06 07 +align/size : 16 16 + +---- TEST 2 - PACKED - WITH ALIGN ---- +bits in use : 3F01FFFFFFFFFFFFFFFFFFFF +bits as set : 250048D159E26AF37BC1E003 +values : 03 1e 123456789abcdef0 05 fffffffe +align/size : 1 12 + +---- TEST 3 - PACKED - WITH ALIGN ---- +bits in use : 1F03FF000003FF +bits as set : 0E00D9000002F5 +values : 15 17 19 06 0e +align/size : 1 7 + +---- TEST 4 - PACKED - WITH ALIGN ---- +bits in use : 07FFFF00000027 +bits as set : 078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 1 7 + +---- TEST 5 - PACKED - WITH ALIGN ---- +bits in use : FFFFFF07FFFFFFFFFFFFFFFF9FFFFFFFFFFF +bits as set : 007744000000000F18000000000123456789 +values : 0000000123456789 f0000000 0000000000000078 44 77 +align/size : 1 18 + +---- TEST 6 - PACKED - WITH ALIGN ---- +bits in use : 007000FFFFFFFFFFFFFF +bits as set : 0030002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 1 10 diff --git a/05/tcc-0.9.27/tests/tests2/95_bitfields_ms.c b/05/tcc-0.9.27/tests/tests2/95_bitfields_ms.c new file mode 100644 index 0000000..b196fbd --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/95_bitfields_ms.c @@ -0,0 +1,2 @@ +#define MS_BITFIELDS 1 +#include "95_bitfields.c" diff --git a/05/tcc-0.9.27/tests/tests2/95_bitfields_ms.expect b/05/tcc-0.9.27/tests/tests2/95_bitfields_ms.expect new file mode 100644 index 0000000..8ccafb7 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/95_bitfields_ms.expect @@ -0,0 +1,149 @@ +---- TEST 1 - MS-BITFIELDS ---- +bits in use : 0000001FFFFFFFFF0000007F00000FFF +bits as set : 00000007605555550000004400000333 +values : 333 44 555555 06 07 +align/size : 4 16 + +---- TEST 2 - MS-BITFIELDS ---- +bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF +bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003 +values : 03 1e 123456789abcdef0 05 fffffffffffffffe +align/size : 8 32 + +---- TEST 3 - MS-BITFIELDS ---- +bits in use : 001F001F0000001F000003FF +bits as set : 000E000600000019000002F5 +values : 15 17 19 06 0e +align/size : 4 12 + +---- TEST 4 - MS-BITFIELDS ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 4 8 + +---- TEST 5 - MS-BITFIELDS ---- +bits in use : 00000000FFFF00FF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 0000000000770044000000000000007800000000300000000000000123456789 +values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 +align/size : 8 32 + +---- TEST 6 - MS-BITFIELDS ---- +bits in use : 00000000000000700000FFFF000000FFFFFFFFFF +bits as set : 000000000000003000002001000000FD00000004 +values : 01 02 03 04 fffffffd +align/size : 4 20 + + + +---- TEST 1 - MS-BITFIELDS - PACKED ---- +bits in use : 0000001FFFFFFFFF7F00000FFF +bits as set : 00000007605555554400000333 +values : 333 44 555555 06 07 +align/size : 1 13 + +---- TEST 2 - MS-BITFIELDS - PACKED ---- +bits in use : 00000000000000030F7FFFFFFFFFFFFFFF3F00000FFF +bits as set : 000000000000000205123456789ABCDEF01E00000003 +values : 03 1e 123456789abcdef0 05 fffffffffffffffe +align/size : 1 22 + +---- TEST 3 - MS-BITFIELDS - PACKED ---- +bits in use : 001F1F0000001F000003FF +bits as set : 000E0600000019000002F5 +values : 15 17 19 06 0e +align/size : 1 11 + +---- TEST 4 - MS-BITFIELDS - PACKED ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 1 8 + +---- TEST 5 - MS-BITFIELDS - PACKED ---- +bits in use : FFFFFF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 007744000000000000007800000000300000000000000123456789 +values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 +align/size : 1 27 + +---- TEST 6 - MS-BITFIELDS - PACKED ---- +bits in use : 00000000700000FFFFFFFFFFFFFF +bits as set : 000000003000002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 1 14 + + + +---- TEST 1 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 0000001FFFFFFFFF0000007F00000FFF +bits as set : 00000007605555550000004400000333 +values : 333 44 555555 06 07 +align/size : 16 16 + +---- TEST 2 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF +bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003 +values : 03 1e 123456789abcdef0 05 fffffffffffffffe +align/size : 16 32 + +---- TEST 3 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 0000000000000000000000000000001F000000000000001F0000001F000003FF +bits as set : 0000000000000000000000000000000E000000000000000600000019000002F5 +values : 15 17 19 06 0e +align/size : 16 32 + +---- TEST 4 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 4 8 + +---- TEST 5 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 00000000FFFF00FF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 0000000000770044000000000000007800000000300000000000000123456789 +values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 +align/size : 8 32 + +---- TEST 6 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 00000000000000700000FFFF000000FFFFFFFFFF +bits as set : 000000000000003000002001000000FD00000004 +values : 01 02 03 04 fffffffd +align/size : 4 20 + + + +---- TEST 1 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 0000000000001FFFFFFFFF7F00000FFF +bits as set : 00000000000007605555554400000333 +values : 333 44 555555 06 07 +align/size : 16 16 + +---- TEST 2 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 00000000000000030F0000007FFFFFFFFFFFFFFF3F00000FFF +bits as set : 000000000000000205000000123456789ABCDEF01E00000003 +values : 03 1e 123456789abcdef0 05 fffffffffffffffe +align/size : 16 25 + +---- TEST 3 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 001F000000000000001F0000001F000003FF +bits as set : 000E000000000000000600000019000002F5 +values : 15 17 19 06 0e +align/size : 16 18 + +---- TEST 4 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 1 8 + +---- TEST 5 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : FFFFFF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 007744000000000000007800000000300000000000000123456789 +values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 +align/size : 1 27 + +---- TEST 6 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 00000000700000FFFFFFFFFFFFFF +bits as set : 000000003000002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 1 14 diff --git a/05/tcc-0.9.27/tests/tests2/96_nodata_wanted.c b/05/tcc-0.9.27/tests/tests2/96_nodata_wanted.c new file mode 100644 index 0000000..cc211d3 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/96_nodata_wanted.c @@ -0,0 +1,84 @@ +/*****************************************************************************/ +/* test 'nodata_wanted' data output suppression */ + +#if defined test_static_data_error +void foo() { + if (1) { + static short w = (int)&foo; /* initializer not computable */ + } +} + +#elif defined test_static_nodata_error +void foo() { + if (0) { + static short w = (int)&foo; /* initializer not computable */ + } +} + +#elif defined test_global_data_error +void foo(); +static short w = (int)&foo; /* initializer not computable */ + + +#elif defined test_local_data_noerror +void foo() { + short w = &foo; /* 2 cast warnings */ +} + +#elif defined test_data_suppression_off || defined test_data_suppression_on + +#if defined test_data_suppression_on +# define SKIP 1 +#else +# define SKIP 0 +#endif + +#include <stdio.h> +/* some gcc headers #define __attribute__ to empty if it's not gcc */ +#undef __attribute__ + +int main() +{ + __label__ ts0, te0, ts1, te1; + int tl, dl; + + static char ds0 = 0; + static char de0 = 0; + /* get reference size of empty jmp */ +ts0:; + if (!SKIP) {} +te0:; + dl = -(&de0 - &ds0); + tl = -(&&te0 - &&ts0); + + /* test data and code suppression */ + static char ds1 = 0; +ts1:; + if (!SKIP) { + static void *p = (void*)&main; + static char cc[] = "static string"; + static double d = 8.0; + + static struct __attribute__((packed)) { + unsigned x : 12; + unsigned char y : 7; + unsigned z : 28, a: 4, b: 5; + } s = { 0x333,0x44,0x555555,6,7 }; + + printf("data:\n"); + printf(" %d - %.1f - %.1f - %s - %s\n", + sizeof 8.0, 8.0, d, __FUNCTION__, cc); + printf(" %x %x %x %x %x\n", + s.x, s.y, s.z, s.a, s.b); + } +te1:; + static char de1 = 0; + + dl += &de1 - &ds1; + tl += &&te1 - &&ts1; + printf("size of data/text:\n %s/%s\n", + dl ? "non-zero":"zero", tl ? "non-zero":"zero"); + /*printf("# %d/%d\n", dl, tl);*/ +} + +#endif diff --git a/05/tcc-0.9.27/tests/tests2/96_nodata_wanted.expect b/05/tcc-0.9.27/tests/tests2/96_nodata_wanted.expect new file mode 100644 index 0000000..2749109 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/96_nodata_wanted.expect @@ -0,0 +1,23 @@ +[test_static_data_error] +96_nodata_wanted.c:7: error: initializer element is not computable at load time + +[test_static_nodata_error] +96_nodata_wanted.c:14: error: initializer element is not computable at load time + +[test_global_data_error] +96_nodata_wanted.c:20: error: initializer element is not computable at load time + +[test_local_data_noerror] +96_nodata_wanted.c:25: warning: assignment makes integer from pointer without a cast +96_nodata_wanted.c:25: warning: nonportable conversion from pointer to char/short + +[test_data_suppression_off] +data: + 8 - 8.0 - 8.0 - main - static string + 333 44 555555 6 7 +size of data/text: + non-zero/non-zero + +[test_data_suppression_on] +size of data/text: + zero/zero diff --git a/05/tcc-0.9.27/tests/tests2/97_utf8_string_literal.c b/05/tcc-0.9.27/tests/tests2/97_utf8_string_literal.c new file mode 100644 index 0000000..96fbab0 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/97_utf8_string_literal.c @@ -0,0 +1,12 @@ +// this file contains BMP chars encoded in UTF-8 +#include <stdio.h> +#include <wchar.h> + +int main() +{ + wchar_t s[] = L"hello$$你好¢¢世界€€world"; + wchar_t *p; + for (p = s; *p; p++) printf("%04X ", (unsigned) *p); + printf("\n"); + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/97_utf8_string_literal.expect b/05/tcc-0.9.27/tests/tests2/97_utf8_string_literal.expect new file mode 100644 index 0000000..9a1593c --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/97_utf8_string_literal.expect @@ -0,0 +1 @@ +0068 0065 006C 006C 006F 0024 0024 4F60 597D 00A2 00A2 4E16 754C 20AC 20AC 0077 006F 0072 006C 0064 diff --git a/05/tcc-0.9.27/tests/tests2/98_al_ax_extend.c b/05/tcc-0.9.27/tests/tests2/98_al_ax_extend.c new file mode 100644 index 0000000..9b4e02f --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/98_al_ax_extend.c @@ -0,0 +1,41 @@ +#include <stdio.h> +#include <stdlib.h> +asm ( + ".text;" + ".globl _us;.globl _ss;.globl _uc;.globl _sc;" + "_us:;_ss:;_uc:;_sc:;" + "movl $0x1234ABCD, %eax;" + "ret;" +); + +#if 1 +#define us _us +#define ss _ss +#define uc _uc +#define sc _sc +#endif + +int main() +{ + unsigned short us(void); + short ss(void); + unsigned char uc(void); + signed char sc(void); + + unsigned short (*fpus)(void) = us; + short (*fpss)(void) = ss; + unsigned char (*fpuc)(void) = uc; + signed char (*fpsc)(void) = sc; + + printf("%08X %08X\n", us() + 1, fpus() + 1); + printf("%08X %08X\n", ss() + 1, fpss() + 1); + printf("%08X %08X\n", uc() + 1, fpuc() + 1); + printf("%08X %08X\n", sc() + 1, fpsc() + 1); + printf("\n"); + printf("%08X %08X\n", fpus() + 1, us() + 1); + printf("%08X %08X\n", fpss() + 1, ss() + 1); + printf("%08X %08X\n", fpuc() + 1, uc() + 1); + printf("%08X %08X\n", fpsc() + 1, sc() + 1); + + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/98_al_ax_extend.expect b/05/tcc-0.9.27/tests/tests2/98_al_ax_extend.expect new file mode 100644 index 0000000..c5752e8 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/98_al_ax_extend.expect @@ -0,0 +1,9 @@ +0000ABCE 0000ABCE +FFFFABCE FFFFABCE +000000CE 000000CE +FFFFFFCE FFFFFFCE + +0000ABCE 0000ABCE +FFFFABCE FFFFABCE +000000CE 000000CE +FFFFFFCE FFFFFFCE diff --git a/05/tcc-0.9.27/tests/tests2/99_fastcall.c b/05/tcc-0.9.27/tests/tests2/99_fastcall.c new file mode 100644 index 0000000..ee4b67d --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/99_fastcall.c @@ -0,0 +1,276 @@ +#include <stdio.h> +#include <assert.h> + +#ifndef _WIN32 +#define __fastcall __attribute((fastcall)) +#endif + +#if 1 +#define SYMBOL(x) _##x +#else +#define SYMBOL(x) x +#endif + +///////////////////////////////////////////////////////////////////////// +////////// TRAP FRAMEWORK +///////////////////////////////////////////////////////////////////////// +// if you cast 'TRAP' to a function pointer and call it, +// it will save all 8 registers, +// and jump into C-code (previously set using 'SET_TRAP_HANDLER(x)'), +// in C-code you can pop DWORDs from stack and modify registers +// + +void *SYMBOL(trap_handler); + +extern unsigned char SYMBOL(trap)[]; +asm ( + ".text;" + "_trap:;" + "pushl %esp;" + "pusha;" + "addl $0x4, 0xc(%esp);" + "pushl %esp;" + "call *_trap_handler;" + "addl $0x4, %esp;" + "movl 0xc(%esp), %eax;" + "movl %eax, 0x20(%esp);" + "popa;" + "popl %esp;" + "ret;" +); + +struct trapframe { + unsigned edi, esi, ebp, esp, ebx, edx, ecx, eax; +}; + + +#define M_FLOAT(addr) (*(float *)(addr)) +#define M_DWORD(addr) (*(unsigned *)(addr)) +#define M_WORD(addr) (*(unsigned short *)(addr)) +#define M_BYTE(addr) (*(unsigned char *)(addr)) +#define R_EAX ((tf)->eax) +#define R_ECX ((tf)->ecx) +#define R_EDX ((tf)->edx) +#define R_EBX ((tf)->ebx) +#define R_ESP ((tf)->esp) +#define R_EBP ((tf)->ebp) +#define R_ESI ((tf)->esi) +#define R_EDI ((tf)->edi) + +#define ARG(x) (M_DWORD(R_ESP + (x) * 4)) + +#define RETN(x) do { \ + M_DWORD(R_ESP + (x)) = M_DWORD(R_ESP); \ + R_ESP += (x); \ +} while (0) + +#define DUMP() do { \ + unsigned i; \ + printf("EAX: %08X\n", R_EAX); \ + printf("ECX: %08X\n", R_ECX); \ + printf("EDX: %08X\n", R_EDX); \ + printf("EBX: %08X\n", R_EBX); \ + printf("ESP: %08X\n", R_ESP); \ + printf("EBP: %08X\n", R_EBP); \ + printf("ESI: %08X\n", R_ESI); \ + printf("EDI: %08X\n", R_EDI); \ + printf("\n"); \ + printf("[RETADDR]: %08X\n", M_DWORD(R_ESP)); \ + for (i = 1; i <= 8; i++) { \ + printf("[ARG%4d]: %08X\n", i, ARG(i)); \ + } \ +} while (0) + +#define SET_TRAP_HANDLER(x) ((SYMBOL(trap_handler)) = (x)) +#define TRAP ((void *) &SYMBOL(trap)) + + + +///////////////////////////////////////////////////////////////////////// +////////// SAFECALL FRAMEWORK +///////////////////////////////////////////////////////////////////////// +// this framework will convert any calling convention to cdecl +// usage: first set call target with 'SET_SAFECALL_TARGET(x)' +// then cast 'SAFECALL' to target function pointer type and invoke it +// after calling, 'ESPDIFF' is the difference of old and new esp + +void *SYMBOL(sc_call_target); +unsigned SYMBOL(sc_retn_addr); +unsigned SYMBOL(sc_old_esp); +unsigned SYMBOL(sc_new_esp); + +extern unsigned char SYMBOL(safecall)[]; +asm ( + ".text;" + "_safecall:;" + "popl _sc_retn_addr;" + "movl %esp, _sc_old_esp;" + "call *_sc_call_target;" + "movl %esp, _sc_new_esp;" + "movl _sc_old_esp, %esp;" + "jmp *_sc_retn_addr;" +); + +#define SET_SAFECALL_TARGET(x) ((SYMBOL(sc_call_target)) = (x)) +#define SAFECALL ((void *) &SYMBOL(safecall)) +#define ESPDIFF (SYMBOL(sc_new_esp) - SYMBOL(sc_old_esp)) + + +///////////////////////////////////////////////////////////////////////// +////////// TEST FASTCALL INVOKE +///////////////////////////////////////////////////////////////////////// + +void check_fastcall_invoke_0(struct trapframe *tf) +{ + //DUMP(); + RETN(0); +} + +void check_fastcall_invoke_1(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + RETN(0); +} +void check_fastcall_invoke_2(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + RETN(0); +} +void check_fastcall_invoke_3(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + assert(ARG(1) == 0x33333333); + RETN(1*4); +} +void check_fastcall_invoke_4(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + assert(ARG(1) == 0x33333333); + assert(ARG(2) == 0x44444444); + RETN(2*4); +} + +void check_fastcall_invoke_5(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + assert(ARG(1) == 0x33333333); + assert(ARG(2) == 0x44444444); + assert(ARG(3) == 0x55555555); + RETN(3*4); +} + +void test_fastcall_invoke() +{ + SET_TRAP_HANDLER(check_fastcall_invoke_0); + ((void __fastcall (*)(void)) TRAP)(); + + SET_TRAP_HANDLER(check_fastcall_invoke_1); + ((void __fastcall (*)(unsigned)) TRAP)(0x11111111); + + SET_TRAP_HANDLER(check_fastcall_invoke_2); + ((void __fastcall (*)(unsigned, unsigned)) TRAP)(0x11111111, 0x22222222); + + SET_TRAP_HANDLER(check_fastcall_invoke_3); + ((void __fastcall (*)(unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333); + + SET_TRAP_HANDLER(check_fastcall_invoke_4); + ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444); + + SET_TRAP_HANDLER(check_fastcall_invoke_5); + ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555); +} + + +///////////////////////////////////////////////////////////////////////// +////////// TEST FUNCTION CODE GENERATION +///////////////////////////////////////////////////////////////////////// + +int __fastcall check_fastcall_espdiff_0(void) +{ + return 0; +} + +int __fastcall check_fastcall_espdiff_1(int a) +{ + return a; +} + +int __fastcall check_fastcall_espdiff_2(int a, int b) +{ + return a + b; +} + +int __fastcall check_fastcall_espdiff_3(int a, int b, int c) +{ + return a + b + c; +} + +int __fastcall check_fastcall_espdiff_4(int a, int b, int c, int d) +{ + return a + b + c + d; +} + +int __fastcall check_fastcall_espdiff_5(int a, int b, int c, int d, int e) +{ + return a + b + c + d + e; +} + +void test_fastcall_espdiff() +{ + int x; + SET_SAFECALL_TARGET(check_fastcall_espdiff_0); + x = ((typeof(&check_fastcall_espdiff_0))SAFECALL)(); + assert(x == 0); + assert(ESPDIFF == 0); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_1); + x = ((typeof(&check_fastcall_espdiff_1))SAFECALL)(1); + assert(x == 1); + assert(ESPDIFF == 0); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_2); + x = ((typeof(&check_fastcall_espdiff_2))SAFECALL)(1, 2); + assert(x == 1 + 2); + assert(ESPDIFF == 0); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_3); + x = ((typeof(&check_fastcall_espdiff_3))SAFECALL)(1, 2, 3); + assert(x == 1 + 2 + 3); + assert(ESPDIFF == 1*4); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_4); + x = ((typeof(&check_fastcall_espdiff_4))SAFECALL)(1, 2, 3, 4); + assert(x == 1 + 2 + 3 + 4); + assert(ESPDIFF == 2*4); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_5); + x = ((typeof(&check_fastcall_espdiff_5))SAFECALL)(1, 2, 3, 4, 5); + assert(x == 1 + 2 + 3 + 4 + 5); + assert(ESPDIFF == 3*4); +} + +int main() +{ +#define N 10000 + int i; + + for (i = 1; i <= N; i++) { + test_fastcall_espdiff(); + } + + for (i = 1; i <= N; i++) { + test_fastcall_invoke(); + } + + puts("TEST OK"); + return 0; +} diff --git a/05/tcc-0.9.27/tests/tests2/99_fastcall.expect b/05/tcc-0.9.27/tests/tests2/99_fastcall.expect new file mode 100644 index 0000000..3835d63 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/99_fastcall.expect @@ -0,0 +1 @@ +TEST OK diff --git a/05/tcc-0.9.27/tests/tests2/LICENSE b/05/tcc-0.9.27/tests/tests2/LICENSE new file mode 100644 index 0000000..b08a652 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/LICENSE @@ -0,0 +1,37 @@ +The tests in this directory are either directly copied from the picoc project or +are subsequently modified and added to for the purpose of TinyCC project. All +these modifications are licensed under the same terms as TinyCC as specified in +the file COPYING. + +=== picoc license === + +Copyright (c) 2009-2011, Zik Saleeba +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of the Zik Saleeba nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/05/tcc-0.9.27/tests/tests2/Makefile b/05/tcc-0.9.27/tests/tests2/Makefile new file mode 100644 index 0000000..190b2d9 --- /dev/null +++ b/05/tcc-0.9.27/tests/tests2/Makefile @@ -0,0 +1,112 @@ +TOP = ../.. +include $(TOP)/Makefile +SRC = $(TOPSRC)/tests/tests2 +VPATH = $(SRC) + +TESTS = $(patsubst %.c,%.test,$(sort $(notdir $(wildcard $(SRC)/*.c)))) + +# some tests do not pass on all platforms, remove them for now +SKIP = 34_array_assignment.test # array assignment is not in C standard +ifeq ($(CONFIG_arm_eabi),yes) # not ARM soft-float + SKIP += 22_floating_point.test +endif +ifdef CONFIG_OSX + SKIP += 40_stdio.test 42_function_pointer.test + FLAGS += -w +endif +ifeq ($(ARCH),x86_64) + SKIP += 73_arm64.test +endif +ifeq (,$(filter i386,$(ARCH))) + SKIP += 98_al_ax_extend.test 99_fastcall.test +endif +ifeq (,$(filter i386 x86_64,$(ARCH))) + SKIP += 85_asm-outside-function.test +endif +ifeq (-$(findstring gcc,$(CC))-,--) + SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS)) +endif +ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-) + SKIP += 95_bitfields%.test # type_align is different on 32bit-non-windows +endif + +# Some tests might need arguments +ARGS = +31_args.test : ARGS = arg1 arg2 arg3 arg4 arg5 +46_grep.test : ARGS = '[^* ]*[:a:d: ]+\:\*-/: $$' $(SRC)/46_grep.c + +# And some tests don't test the right thing with -run +NORUN = +42_function_pointer.test : NORUN = true + +# Some tests might need different flags +FLAGS = +76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers + +# These tests run several snippets from the same file one by one +60_errors_and_warnings.test : FLAGS += -dt +96_nodata_wanted.test : FLAGS += -dt + +# Always generate certain .expects (don't put these in the GIT), +GEN-ALWAYS = +# GEN-ALWAYS += 95_bitfields.expect # does not work + +# using the ms compiler for the really ms-compatible bitfields +95_bitfields_ms.test : GEN = $(GEN-MSC) + +# Filter source directory in warnings/errors (out-of-tree builds) +FILTER = 2>&1 | sed 's,$(SRC)/,,g' +# Filter some always-warning +ifeq (-$(findstring arm,$(ARCH))-,-arm-) +FILTER += 2>&1 | grep -v 'warning: soft float ABI currently not supported' +endif + +all test tests2.all: $(filter-out $(SKIP),$(TESTS)) ; + +%.test: %.c %.expect + @echo Test: $*... + @$(if $(NORUN),$(T1),$(T2)) $(if $(NODIFF),,$(T3)) + +T1 = $(TCC) $(FLAGS) $< -o a.exe && ./a.exe $(ARGS) +T2 = $(TCC) $(FLAGS) -run $< $(ARGS) +T3 = $(FILTER) >$*.output 2>&1 || true \ + && diff -Nbu $(filter %.expect,$^) $*.output \ + && rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS)) + +# run single test and update .expect file, e.g. "make tests2.37+" +tests2.%+: + @$(MAKE) $(call F2,$(call F1,$*)) --no-print-directory + +# just run tcc to see the output, e.g. "make tests2.37-" +tests2.%-: + @$(MAKE) $(call F1,$*) NODIFF=true --no-print-directory + +# run single test, e.g. "make tests2.37" +tests2.%: + @$(MAKE) $(call F1,$*) --no-print-directory + +F1 = $(or $(filter $1_%,$(TESTS)),$1_???.test) +F2 = $1 UPDATE="$(patsubst %.test,%.expect,$1)" + +# automatically generate .expect files with gcc: +%.expect : + @echo Generating: $@ + @$(call GEN,$(SRC)/$*.c) $(FILTER) >$@ 2>&1 + @rm -f *.exe *.obj *.pdb + +# using TCC for .expect if -dt in FLAGS +GEN = $(if $(filter -dt,$(FLAGS)),$(GEN-TCC),$(GEN-CC)) +GEN-CC = $(CC) -w -std=gnu99 $(FLAGS) $1 -o a.exe && ./a.exe $(ARGS) +GEN-TCC = $(TCC) $(FLAGS) -run $1 $(ARGS) +GEN-MSC = $(MS-CC) $1 && ./$(basename $@).exe +MS-CC = cl + +# tell make not to delete +.PRECIOUS: %.expect + +# force .expect generation for these files +$(sort $(GEN-ALWAYS) $(UPDATE)) : force +force: + +clean: + rm -f fred.txt *.output a.exe $(GEN-ALWAYS) diff --git a/05/tcc-0.9.27/tests/vla_test.c b/05/tcc-0.9.27/tests/vla_test.c new file mode 100644 index 0000000..3616c46 --- /dev/null +++ b/05/tcc-0.9.27/tests/vla_test.c @@ -0,0 +1,84 @@ +/* + * Test that allocating a variable length array in a loop + * does not use up a linear amount of memory + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#define LOOP_COUNT 1000 +#define ARRAY_SIZE 100 + +/* Overwrite a VLA. This will overwrite the return address if SP is incorrect */ +void smash(char *p, int n) { + memset(p, 0, n); +} + +int test1(int n) { + int i; + char *array_ptrs[LOOP_COUNT]; + + for (i = 0; i < LOOP_COUNT; ++i) { + char test[n]; + smash(test, n); + array_ptrs[i] = test; + } + + return (array_ptrs[0]-array_ptrs[LOOP_COUNT-1] < n) ? 0 : 1; +} + +/* ensure goto does not circumvent array free */ +int test2(int n) { + char *array_ptrs[LOOP_COUNT]; + + int i = 0; +loop:; + char test[n]; + smash(test, n); + if (i >= LOOP_COUNT) + goto end; + array_ptrs[i] = test; + ++i; + goto loop; + +end: + smash(test, n); + char test2[n]; + smash(test2, n); + return (array_ptrs[0] - array_ptrs[LOOP_COUNT-1] < n) ? 0 : 1; +} + +int test3(int n) { + char test[n]; + smash(test, n); + goto label; +label: + smash(test, n); + char test2[n]; + smash(test2, n); + return (test-test2 >= n) ? 0 : 1; +} + +#define RUN_TEST(t) \ + if (!testname || (strcmp(#t, testname) == 0)) { \ + fputs(#t "... ", stdout); \ + fflush(stdout); \ + if (t(ARRAY_SIZE) == 0) { \ + fputs("success\n", stdout); \ + } else { \ + fputs("failure\n", stdout); \ + retval = EXIT_FAILURE; \ + } \ + } + +int main(int argc, char **argv) { + const char *testname = NULL; + int retval = EXIT_SUCCESS; + if (argc > 1) + testname = argv[1]; + RUN_TEST(test1) + RUN_TEST(test2) + RUN_TEST(test3) + return retval; +} |