add clang
This commit is contained in:
parent
4715742aa8
commit
9a4b261179
890 changed files with 229323 additions and 20 deletions
13
05/tcc-final/tests/42test.h
Normal file
13
05/tcc-final/tests/42test.h
Normal file
|
@ -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
|
336
05/tcc-final/tests/Makefile
Normal file
336
05/tcc-final/tests/Makefile
Normal file
|
@ -0,0 +1,336 @@
|
|||
#
|
||||
# Tiny C Compiler Makefile - tests
|
||||
#
|
||||
|
||||
TOP = ..
|
||||
include $(TOP)/Makefile
|
||||
VPATH = $(TOPSRC)/tests $(TOPSRC) $(TOP)
|
||||
CFLAGS := $(filter-out -g% -O%,$(CFLAGS)) -I$(TOPSRC) $(LDFLAGS)
|
||||
|
||||
# what tests to run
|
||||
TESTS = \
|
||||
hello-exe \
|
||||
hello-run \
|
||||
libtest \
|
||||
libtest_mt \
|
||||
test3 \
|
||||
memtest \
|
||||
dlltest \
|
||||
abitest \
|
||||
asm-c-connect-test \
|
||||
vla_test-run \
|
||||
cross-test \
|
||||
tests2-dir \
|
||||
pp-dir
|
||||
|
||||
# test4_static -- Not all relocation types are implemented yet.
|
||||
# asmtest / asmtest2 -- minor differences with gcc
|
||||
|
||||
ifneq ($(CONFIG_bcheck),no)
|
||||
TESTS += btest test1b
|
||||
endif
|
||||
ifeq ($(CONFIG_dll),no)
|
||||
TESTS := $(filter-out dlltest, $(TESTS))
|
||||
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 asm-c-connect-test,$(TESTS))
|
||||
endif
|
||||
ifeq ($(OS),Windows_NT) # for libtcc_test to find libtcc.dll
|
||||
PATH := $(CURDIR)/$(TOP)$(if $(findstring ;,$(PATH)),;,:)$(PATH)
|
||||
endif
|
||||
ifdef CONFIG_OSX
|
||||
LIBS += $(LINK_LIBTCC)
|
||||
endif
|
||||
ifeq ($(ARCH),arm)
|
||||
# tcctest refers to the alignment of functions, and with thumb mode
|
||||
# the low bit of code addresses selects the mode, so the "alignment"
|
||||
# of functions via bit masking comes out as 1. Just disable thumb.
|
||||
test.ref: CFLAGS+=-marm
|
||||
endif
|
||||
ifeq ($(ARCH)$(CONFIG_WIN32),i386)
|
||||
# tcctest.c:get_asm_string uses a construct that is checked too strictly
|
||||
# by GCC in 32bit mode when PIC is enabled.
|
||||
test.ref: CFLAGS+=-fno-PIC -fno-PIE -Wl,-z,notext
|
||||
endif
|
||||
ifeq ($(CC_NAME),msvc)
|
||||
test.ref abitest : CC = gcc
|
||||
endif
|
||||
ifeq ($(TARGETOS),OpenBSD)
|
||||
dlltest: CFLAGS+=-fno-stack-protector
|
||||
endif
|
||||
ifneq (,$(filter FreeBSD NetBSD,$(TARGETOS)))
|
||||
# test3 has dlsym problems
|
||||
TESTS := $(filter-out test3,$(TESTS))
|
||||
TESTS += test1
|
||||
endif
|
||||
|
||||
RUN_TCC = $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS)
|
||||
DISAS = objdump -d
|
||||
ifdef CONFIG_OSX
|
||||
DUMPTCC = (set -x; $(TOP)/tcc -vv; otool -L $(TOP)/tcc; exit 1)
|
||||
else
|
||||
DUMPTCC = (set -x; $(TOP)/tcc -vv; ldd $(TOP)/tcc; exit 1)
|
||||
endif
|
||||
|
||||
all test :
|
||||
@$(MAKE) --no-print-directory -s clean
|
||||
@$(MAKE) --no-print-directory -s -r $(TESTS)
|
||||
|
||||
hello-exe: ../examples/ex1.c
|
||||
@echo ------------ $@ ------------
|
||||
$(TCC) $< -o hello$(EXESUF) && ./hello$(EXESUF) || $(DUMPTCC)
|
||||
|
||||
hello-run: ../examples/ex1.c
|
||||
@echo ------------ $@ ------------
|
||||
$(TCC) -run $< || $(DUMPTCC)
|
||||
|
||||
libtes%: libtcc_tes%$(EXESUF)
|
||||
@echo ------------ $@ ------------
|
||||
./libtcc_tes$*$(EXESUF) $(TOPSRC)/tcc.c $(TCCFLAGS) $(NATIVE_DEFINES)
|
||||
|
||||
libtcc_test$(EXESUF): libtcc_test.c $(LIBTCC)
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
libtcc_test_mt$(EXESUF): libtcc_test_mt.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_TCC) -w -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) -w -run $< > test.out2
|
||||
@diff -u test.ref test.out2 && echo "$(AUTO_TEST)2 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) -w -run $< > test.out3
|
||||
@diff -u test.ref test.out3 && echo "$(AUTO_TEST)3 OK"
|
||||
|
||||
AUTO_TEST = Auto Test
|
||||
test%b : TCCFLAGS += -b -bt1
|
||||
test%b : AUTO_TEST = Auto Bound-Test
|
||||
|
||||
# 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
|
||||
|
||||
test4_static: tcctest.c test.ref
|
||||
@echo ------------ $@ ------------
|
||||
# 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) -w $(TOPSRC)/tests/tcctest.c
|
||||
@echo OK
|
||||
|
||||
# memory and bound check auto test
|
||||
BOUNDS_OK = 1 4 8 10 14 16
|
||||
BOUNDS_FAIL= 2 5 6 7 9 11 12 13 15 17 18
|
||||
|
||||
btest: boundtest.c
|
||||
@echo ------------ $@ ------------
|
||||
@for i in $(BOUNDS_OK); do \
|
||||
if $(TCC) -b -run $< $$i >/dev/null 2>&1 ; then \
|
||||
echo "Test $$i succeeded as expected" ; \
|
||||
else\
|
||||
echo "Failed positive test $$i" ; exit 1 ; \
|
||||
fi ;\
|
||||
done ;\
|
||||
for i in $(BOUNDS_FAIL); do \
|
||||
if $(TCC) -b -bt1 -run $< $$i >/dev/null 2>&1 ; then \
|
||||
echo "Failed negative test $$i" ; exit 1 ;\
|
||||
else\
|
||||
echo "Test $$i failed as expected" ; \
|
||||
fi ;\
|
||||
done ;\
|
||||
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
|
||||
@echo ------------ $@ ------------
|
||||
$(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
|
||||
|
||||
ifeq ($(ARCH),arm)
|
||||
asmtest asmtest2:
|
||||
TCC="${TCC}" ./arm-asm-testsuite.sh
|
||||
else
|
||||
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
|
||||
endif
|
||||
|
||||
# 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.exe: abitest.c $(LIBTCC)
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) -w
|
||||
|
||||
abitest-tcc.exe: abitest.c libtcc.c
|
||||
$(TCC) -o $@ $^ $(NATIVE_DEFINES) $(LIBS)
|
||||
|
||||
abitest-% : abitest-%.exe
|
||||
@echo ------------ $@ ------------
|
||||
./$< $(TCCFLAGS)
|
||||
|
||||
abitest: abitest-cc
|
||||
ifneq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
|
||||
abitest: abitest-tcc
|
||||
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 "error"; exit 1)
|
||||
|
||||
# quick sanity check for cross-compilers
|
||||
cross-test : tcctest.c examples/ex3.c
|
||||
@echo ------------ $@ ------------
|
||||
$(foreach T,$(CROSS-TGTS),$(call CROSS-COMPILE,$T))
|
||||
|
||||
CROSS-TGTS = \
|
||||
i386 \
|
||||
i386-win32 \
|
||||
i386-OpenBSD \
|
||||
x86_64 \
|
||||
x86_64-win32 \
|
||||
x86_64-osx \
|
||||
x86_64-FreeBSD \
|
||||
x86_64-NetBSD \
|
||||
x86_64-OpenBSD \
|
||||
arm-fpa \
|
||||
arm-eabihf \
|
||||
arm-NetBSD \
|
||||
arm-wince \
|
||||
arm64 \
|
||||
arm64-osx \
|
||||
arm64-FreeBSD \
|
||||
arm64-NetBSD \
|
||||
arm64-OpenBSD \
|
||||
riscv64 \
|
||||
c67
|
||||
|
||||
define CROSS-COMPILE
|
||||
@echo " . $(1)"
|
||||
$(TCC) $(DEF-$1) -DTCC_CROSS_TEST -run $(TOPSRC)/tcc.c \
|
||||
-c $(if $(findstring c67,$1),$(filter %/ex3.c,$^),$<) -w $(TCCFLAGS)
|
||||
|
||||
endef
|
||||
|
||||
# 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) asm-c-connect-sep$(EXESUF)
|
||||
rm -f ex? tcc_g weaktest.*.txt *.def *.pdb *.obj libtcc_test_mt
|
||||
@$(MAKE) -C tests2 $@
|
||||
@$(MAKE) -C pp $@
|
||||
|
691
05/tcc-final/tests/abitest.c
Normal file
691
05/tcc-final/tests/abitest.c
Normal file
|
@ -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;
|
||||
}
|
243
05/tcc-final/tests/arm-asm-testsuite.sh
Executable file
243
05/tcc-final/tests/arm-asm-testsuite.sh
Executable file
|
@ -0,0 +1,243 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
# Note: "{r3}" is definitely different--but would complicate the assembler.
|
||||
|
||||
state="`mktemp -d`"
|
||||
cat ../arm-tok.h | \
|
||||
grep DEF_ASM | \
|
||||
grep -v 'not useful' | \
|
||||
grep -v '#define' | \
|
||||
grep -v '/[*]' | \
|
||||
grep -v 'DEF_ASM_CONDED_WITH_SUFFIX(x' | \
|
||||
sed -e 's;^[ ]*DEF_ASM_CONDED_VFP_F32_F64[^(]*(\(.*\)).*$; DEF_ASM_CONDED(\1.f32)\
|
||||
DEF_ASM_CONDED(\1.f64);g' | \
|
||||
sed -e 's;^[ ]*DEF_ASM[^(]*(\(.*\)).*$;\1;g' -e 's;, ;.;g' | \
|
||||
egrep -v '^((r|c|p|s|d)[0-9]+|fp|ip|sp|lr|pc|asl|apsr_nzcv|fpsid|fpscr|fpexc)$' | while read s
|
||||
do
|
||||
as_opts=""
|
||||
if [ "${s#v}" != "${s}" ]
|
||||
then
|
||||
if grep -q "CONFIG_arm_vfp=yes" ../config.mak
|
||||
then
|
||||
as_opts="${as_opts} -mfpu=vfp"
|
||||
else
|
||||
echo "note: skipping VFP instruction: $s (because VFP is disabled)">&2
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
ok=0
|
||||
for args in "r3, r4, r5, r6" \
|
||||
"r3, r4, r5" \
|
||||
"r3, r4, r5, asl #7" \
|
||||
"r3, r4, r5, lsl #7" \
|
||||
"r3, r4, r5, asr #7" \
|
||||
"r3, r4, r5, lsr #7" \
|
||||
"r3, r4, r5, ror #7" \
|
||||
"r3, r4, r5, rrx" \
|
||||
"r3, r4, r5, asl r6" \
|
||||
"r3, r4, r5, lsl r6" \
|
||||
"r3, r4, r5, asr r6" \
|
||||
"r3, r4, r5, lsr r6" \
|
||||
"r3, r4, r5, ror r6" \
|
||||
"r3, r4, #5, asl #7" \
|
||||
"r3, r4, #5, lsl #7" \
|
||||
"r3, r4, #5, asr #7" \
|
||||
"r3, r4, #5, lsr #7" \
|
||||
"r3, r4, #5, ror #7" \
|
||||
"r3, r4, #5, rrx" \
|
||||
"r3, #5, r4" \
|
||||
"r3, #4, #8" \
|
||||
"r3, r4, asl #5" \
|
||||
"r3, r4, lsl #5" \
|
||||
"r3, r4, asr #5" \
|
||||
"r3, r4, lsr #5" \
|
||||
"r3, r4, ror #5" \
|
||||
"r3, r4, ror #8" \
|
||||
"r3, r4, asl r5" \
|
||||
"r3, r4, lsl r5" \
|
||||
"r3, r4, asr r5" \
|
||||
"r3, r4, lsr r5" \
|
||||
"r3, r4, ror r5" \
|
||||
"r3, r4, ror #8" \
|
||||
"r3, r4, ror #16" \
|
||||
"r3, r4, ror #24" \
|
||||
"r3, r4, rrx" \
|
||||
"r3, #4, asl #5" \
|
||||
"r3, #4, lsl #5" \
|
||||
"r3, #4, asr #5" \
|
||||
"r3, #4, lsr #5" \
|
||||
"r3, #4, ror #5" \
|
||||
"r3, r4, rrx" \
|
||||
"r3, r4" \
|
||||
"r3" \
|
||||
"{r3,r4,r5}" \
|
||||
"{r3,r5,r4}" \
|
||||
"r2!, {r3,r4,r5}" \
|
||||
"r2!, {r3,r5,r4}" \
|
||||
"r2, {r3,r4,r5}" \
|
||||
"r2, {r3,r5,r4}" \
|
||||
"r2, [r3, r4]" \
|
||||
"r2, [r3, r4]!" \
|
||||
"r2, [r3, -r4]" \
|
||||
"r2, [r3, -r4]!" \
|
||||
"r2, [r3], r4" \
|
||||
"r2, [r3], -r4" \
|
||||
"r2, [r3]" \
|
||||
"r2, r3, [r4, lsl# 2]" \
|
||||
"r2, [r3, r4, lsr# 1]" \
|
||||
"r2, [r3, r4, lsr# 2]!" \
|
||||
"r2, [r3, -r4, ror# 3]" \
|
||||
"r2, [r3, -r4, lsl# 1]!" \
|
||||
"r2, [r3], r4, lsl# 3" \
|
||||
"r2, [r3], -r4, asr# 31" \
|
||||
"r2, [r3], -r4, asl# 1" \
|
||||
"r2, [r3], -r4, rrx" \
|
||||
"r2, [r3]" \
|
||||
"r2, r3, [r4]" \
|
||||
"r2, [r3, #4]" \
|
||||
"r2, [r3, #-4]" \
|
||||
"r2, [r3, #0x45]" \
|
||||
"r2, [r3, #-0x45]" \
|
||||
"r2, r3, #4" \
|
||||
"r2, r3, #-4" \
|
||||
"p10, #7, c2, c0, c1, #4" \
|
||||
"p10, #7, r2, c0, c1, #4" \
|
||||
"p10, #0, c2, c0, c1, #4" \
|
||||
"p10, #0, r2, c0, c1, #4" \
|
||||
"r2, #4" \
|
||||
"r2, #-4" \
|
||||
"r2, #0xEFFF" \
|
||||
"r3, #0x0000" \
|
||||
"r4, #0x0201" \
|
||||
"r4, #0xFFFFFF00" \
|
||||
"r2, #-4" \
|
||||
"p10, #7, c2, c0, c1, #4" \
|
||||
"p10, #7, r2, c0, c1, #4" \
|
||||
"#4" \
|
||||
"#-4" \
|
||||
"p5, c2, [r3]" \
|
||||
"p5, c3, [r4]" \
|
||||
"p5, c2, [r3, #4]" \
|
||||
"p5, c2, [r3, #-4]" \
|
||||
"p5, c2, [r3, #0x45]" \
|
||||
"p5, c2, [r3, #-0x45]" \
|
||||
"s2, [r3]" \
|
||||
"s3, [r4]" \
|
||||
"s2, [r3, #4]" \
|
||||
"s2, [r3, #-4]" \
|
||||
"s2, [r3, #0x45]" \
|
||||
"s2, [r3, #-0x45]" \
|
||||
"r1, {d3-d4}" \
|
||||
"r1!, {d3-d4}" \
|
||||
"r2, {d4-d15}" \
|
||||
"r3!, {d4-d15}" \
|
||||
"r3!, {d4}" \
|
||||
"r2, {s4-s31}" \
|
||||
"r3!, {s4}" \
|
||||
"{d3-d4}" \
|
||||
"{d4-d15}" \
|
||||
"{d4}" \
|
||||
"{s4-s31}" \
|
||||
"{s4}" \
|
||||
"s2, s3, s4" \
|
||||
"s2, s3" \
|
||||
"d2, d3, d4" \
|
||||
"d2, d3" \
|
||||
"s2, #0" \
|
||||
"d2, #0" \
|
||||
"s3, #0.0" \
|
||||
"d3, #0.0" \
|
||||
"s4, #-0.1796875" \
|
||||
"d4, #0.1796875" \
|
||||
"r2, r3, d1" \
|
||||
"d1, r2, r3" \
|
||||
"s1, r2" \
|
||||
"r2, s1" \
|
||||
"r2, fpexc" \
|
||||
"r2, fpscr" \
|
||||
"r2, fpsid" \
|
||||
"apsr_nzcv, fpscr" \
|
||||
"fpexc, r2" \
|
||||
"fpscr, r2" \
|
||||
"fpsid, r2" \
|
||||
"s3, d4" \
|
||||
"d4, s3" \
|
||||
""
|
||||
do
|
||||
#echo ".syntax unified" > a.s
|
||||
err="`mktemp --suffix=-stderr.log`"
|
||||
as_object="${state}/as-$s $args.o"
|
||||
tcc_object="${state}/tcc-$s $args.o"
|
||||
expected="${state}/expected-$s $args"
|
||||
got="${state}/got-$s $args"
|
||||
if echo "$s $args" | "${CROSS_COMPILE}as" -mlittle-endian ${as_opts} -o "${as_object}" - 2>"${err}"
|
||||
then
|
||||
cat "${err}"
|
||||
rm -f "${err}"
|
||||
total_count=`expr $total_count + 1`
|
||||
"${CROSS_COMPILE}objdump" -S "${as_object}" |grep "^[ ]*0:" >"${expected}"
|
||||
|
||||
#echo '__asm__("'"$s ${args}"'");' > "${csource}"
|
||||
if echo '__asm__("'"$s ${args}"'");'| ${TCC} -o "${tcc_object}" -c -
|
||||
then
|
||||
"${CROSS_COMPILE}objdump" -S "${tcc_object}" |grep "^[ ]*0:" >"${got}"
|
||||
if diff -u "${got}" "${expected}"
|
||||
then
|
||||
touch "${state}/ok-$s $args"
|
||||
else
|
||||
echo "warning: '$s $args' did not work in tcc (see above)">&2
|
||||
fi
|
||||
else
|
||||
rm -f "${tcc_object}"
|
||||
echo "warning: '$s $args' did not work in tcc">&2
|
||||
fi
|
||||
ok=1
|
||||
else # GNU as can't do it either--so we don't care
|
||||
rm -f "${as_object}"
|
||||
fi
|
||||
rm -f "${err}"
|
||||
done
|
||||
if [ "${ok}" -eq "0" ]
|
||||
then
|
||||
echo "warning: $s could not be used.">&2
|
||||
continue
|
||||
fi
|
||||
done
|
||||
|
||||
successful_count="$(ls -1 "${state}/ok-"* |wc -l)"
|
||||
total_count="$(ls -1 "${state}/as-"*.o |wc -l)"
|
||||
echo "${successful_count} of ${total_count} tests succeeded.">&2
|
||||
if [ "${successful_count}" -eq "${total_count}" ]
|
||||
then
|
||||
rm -rf "${state}"
|
||||
exit 0
|
||||
else
|
||||
status=0
|
||||
for s in "${state}/as-"*.o
|
||||
do
|
||||
test="$(basename "$s")"
|
||||
test="${test%.o}"
|
||||
test="${test#as-}"
|
||||
t="${state}/ok-${test}"
|
||||
if [ ! -f "$t" ]
|
||||
then
|
||||
case "${test}" in
|
||||
"bl r3"|"b r3"|"mov r2, #0xEFFF"|"mov r4, #0x0201")
|
||||
known_failure=" (known failure)"
|
||||
;;
|
||||
"vmov.f32 r2, r3, d1"|"vmov.f32 d1, r2, r3") # GNU as bug
|
||||
known_failure=" (known failure)"
|
||||
;;
|
||||
*)
|
||||
known_failure=""
|
||||
status=1
|
||||
;;
|
||||
esac
|
||||
echo "Failed test: ${test}${known_failure}">&2
|
||||
fi
|
||||
done
|
||||
rm -rf "${state}"
|
||||
exit "${status}"
|
||||
fi
|
69
05/tcc-final/tests/asm-c-connect-1.c
Normal file
69
05/tcc-final/tests/asm-c-connect-1.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#if (defined _WIN32 || defined __APPLE__) && (!defined __TINYC__ || defined __leading_underscore)
|
||||
# define _ "_"
|
||||
#else
|
||||
# define _
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
/* clang needs some help tp not throw functions away even at -O0 */
|
||||
#define __USED __attribute__((__used__))
|
||||
#else
|
||||
#define __USED
|
||||
#endif
|
||||
|
||||
static int __USED x1_c (void)
|
||||
{
|
||||
printf(" x1");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if __i386__
|
||||
asm(".text;"_"x1: call "_"x1_c; ret");
|
||||
#else
|
||||
/* Keep stack aligned */
|
||||
asm(".text;"_"x1: sub $8,%rsp; call "_"x1_c; add $8,%rsp; ret");
|
||||
#endif
|
||||
|
||||
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 __USED x2(void)
|
||||
{
|
||||
printf(" x2");
|
||||
return 2;
|
||||
}
|
||||
|
||||
extern int x3(void);
|
||||
|
||||
void x4(void)
|
||||
{
|
||||
printf(" x4");
|
||||
}
|
||||
|
||||
void x5(void);
|
||||
void x5(void)
|
||||
{
|
||||
printf(" x5");
|
||||
}
|
48
05/tcc-final/tests/asm-c-connect-2.c
Normal file
48
05/tcc-final/tests/asm-c-connect-2.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#if (defined _WIN32 || defined __APPLE__) && (!defined __TINYC__ || defined __leading_underscore)
|
||||
# define _ "_"
|
||||
#else
|
||||
# define _
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
/* clang needs some help tp not throw functions away even at -O0 */
|
||||
#define __USED __attribute__((__used__))
|
||||
#else
|
||||
#define __USED
|
||||
#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);
|
||||
#if __i386__
|
||||
__asm__(_"callx4: call "_"x4; ret;"
|
||||
#else
|
||||
/* Keep stack aligned */
|
||||
__asm__(_"callx4: sub $8,%rsp; call "_"x4; add $8,%rsp; ret;"
|
||||
#endif
|
||||
#ifndef __TINYC__
|
||||
" .global "_"callx4"
|
||||
#endif
|
||||
);
|
||||
|
||||
extern void x5(void);
|
||||
|
||||
void callx5_again(void);
|
||||
void callx5_again(void)
|
||||
{
|
||||
x5();
|
||||
asm("call "_"x6");
|
||||
}
|
||||
|
||||
static void __USED x6()
|
||||
{
|
||||
printf(" x6-2");
|
||||
}
|
978
05/tcc-final/tests/asmtest.S
Normal file
978
05/tcc-final/tests/asmtest.S
Normal file
|
@ -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)
|
309
05/tcc-final/tests/boundtest.c
Normal file
309
05/tcc-final/tests/boundtest.c
Normal file
|
@ -0,0 +1,309 @@
|
|||
#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;
|
||||
|
||||
tab4 = malloc(20 * sizeof(int));
|
||||
for(i=0;i<20;i++) {
|
||||
sum += tab4[i];
|
||||
}
|
||||
free(tab4);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* error */
|
||||
int test5(void)
|
||||
{
|
||||
int i, sum = 0;
|
||||
int *tab4;
|
||||
|
||||
tab4 = malloc(20 * sizeof(int));
|
||||
for(i=0;i<21;i++) {
|
||||
sum += tab4[i];
|
||||
}
|
||||
free(tab4);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* error */
|
||||
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);
|
||||
}
|
||||
|
||||
#if defined __i386__ || defined __x86_64__
|
||||
#define allocf(x)
|
||||
#else
|
||||
#undef alloca
|
||||
#define alloca(x) malloc(x)
|
||||
#define allocf(x) free(x)
|
||||
#endif
|
||||
|
||||
int test14(void)
|
||||
{
|
||||
char *p = alloca(TAB_SIZE);
|
||||
size_t ret;
|
||||
memset(p, 'a', TAB_SIZE);
|
||||
p[TAB_SIZE-1] = 0;
|
||||
ret = strlen(p);
|
||||
allocf(p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* error */
|
||||
int test15(void)
|
||||
{
|
||||
char *p = alloca(TAB_SIZE-1);
|
||||
size_t ret;
|
||||
memset(p, 'a', TAB_SIZE);
|
||||
p[TAB_SIZE-1] = 0;
|
||||
ret = strlen(p);
|
||||
allocf(p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ok */
|
||||
int test16()
|
||||
{
|
||||
char *demo = "This is only a test.";
|
||||
char *p;
|
||||
|
||||
p = alloca(16);
|
||||
strcpy(p,"12345678901234");
|
||||
|
||||
/* Test alloca embedded in a larger expression */
|
||||
printf("alloca : %s : %s\n", p, strcpy(alloca(strlen(demo)+1),demo) );
|
||||
allocf(p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* error */
|
||||
int test17()
|
||||
{
|
||||
char *demo = "This is only a test.";
|
||||
char *p;
|
||||
|
||||
p = alloca(16);
|
||||
strcpy(p,"12345678901234");
|
||||
|
||||
/* Test alloca embedded in a larger expression */
|
||||
printf("alloca : %s : %s\n", p, strcpy(alloca(strlen(demo)),demo) );
|
||||
allocf(p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test18(void)
|
||||
{
|
||||
int i, sum = 0, n = TAB_SIZE;
|
||||
int tab[n];
|
||||
for(i=0;i<TAB_SIZE+1;i++) {
|
||||
sum += tab[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
int (*table_test[])(void) = {
|
||||
test1,
|
||||
test2,
|
||||
test3,
|
||||
test4,
|
||||
test5,
|
||||
test6,
|
||||
test7,
|
||||
test8,
|
||||
test9,
|
||||
test10,
|
||||
test11,
|
||||
test12,
|
||||
test13,
|
||||
test14,
|
||||
test15,
|
||||
test16,
|
||||
test17,
|
||||
test18
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
char *cp;
|
||||
int index;
|
||||
int (*ftest)(void);
|
||||
int index_max = sizeof(table_test)/sizeof(table_test[0]);
|
||||
|
||||
/* check bounds checking main arg */
|
||||
for (i = 0; i < argc; i++) {
|
||||
cp = argv[i];
|
||||
while (*cp) {
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
41
05/tcc-final/tests/bug.c
Normal file
41
05/tcc-final/tests/bug.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
int compile_errors(void)
|
||||
{
|
||||
#if TEST == 1
|
||||
{
|
||||
/* Not constant */
|
||||
static int i = (&"Foobar"[1] - &"Foobar"[0]);
|
||||
}
|
||||
#endif
|
||||
#if TEST == 2
|
||||
{
|
||||
/* Not constant */
|
||||
struct{int c;}v;
|
||||
static long i=((char*)&(v.c)-(char*)&v);
|
||||
}
|
||||
#endif
|
||||
#if TEST == 3
|
||||
{
|
||||
/* Not constant */
|
||||
static const short ar[] = { &&l1 - &&l1, &&l2 - &&l1 };
|
||||
void *p = &&l1 + ar[0];
|
||||
goto *p;
|
||||
l1: return 1;
|
||||
l2: return 2;
|
||||
}
|
||||
#endif
|
||||
#if TEST == 4
|
||||
{
|
||||
/* Only integer allowed */
|
||||
__builtin_return_address(0 + 1) != NULL;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
}
|
48
05/tcc-final/tests/gcctestsuite.sh
Normal file
48
05/tcc-final/tests/gcctestsuite.sh
Normal file
|
@ -0,0 +1,48 @@
|
|||
#!/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.fail
|
||||
nb_ok="0"
|
||||
nb_failed="0"
|
||||
nb_exe_failed="0"
|
||||
|
||||
for src in $TESTSUITE_PATH/compile/*.c ; do
|
||||
echo $TCC -o /tmp/tst.o -c $src
|
||||
$TCC -o /tmp/tst.o -c $src >> tcc.fail 2>&1
|
||||
if [ "$?" = "0" ] ; then
|
||||
result="PASS"
|
||||
nb_ok=$(( $nb_ok + 1 ))
|
||||
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 -o /tmp/tst -lm
|
||||
$TCC $src -o /tmp/tst -lm >> tcc.fail 2>&1
|
||||
if [ "$?" = "0" ] ; then
|
||||
result="PASS"
|
||||
if /tmp/tst >> tcc.fail 2>&1
|
||||
then
|
||||
result="PASS"
|
||||
nb_ok=$(( $nb_ok + 1 ))
|
||||
else
|
||||
result="FAILEXE"
|
||||
nb_exe_failed=$(( $nb_exe_failed + 1 ))
|
||||
fi
|
||||
else
|
||||
result="FAIL"
|
||||
nb_failed=$(( $nb_failed + 1 ))
|
||||
fi
|
||||
echo "$result: $src" >> tcc.sum
|
||||
done
|
||||
|
||||
echo "$nb_ok test(s) ok." >> tcc.sum
|
||||
echo "$nb_ok test(s) ok."
|
||||
echo "$nb_failed test(s) failed." >> tcc.sum
|
||||
echo "$nb_failed test(s) failed."
|
||||
echo "$nb_exe_failed test(s) exe failed." >> tcc.sum
|
||||
echo "$nb_exe_failed test(s) exe failed."
|
110
05/tcc-final/tests/libtcc_test.c
Normal file
110
05/tcc-final/tests/libtcc_test.c
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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 <assert.h>
|
||||
|
||||
#include "libtcc.h"
|
||||
|
||||
void handle_error(void *opaque, const char *msg)
|
||||
{
|
||||
fprintf(opaque, "%s\n", msg);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
assert(tcc_get_error_func(s) == NULL);
|
||||
assert(tcc_get_error_opaque(s) == NULL);
|
||||
|
||||
tcc_set_error_func(s, stderr, handle_error);
|
||||
|
||||
assert(tcc_get_error_func(s) == handle_error);
|
||||
assert(tcc_get_error_opaque(s) == stderr);
|
||||
|
||||
/* 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;
|
||||
}
|
301
05/tcc-final/tests/libtcc_test_mt.c
Normal file
301
05/tcc-final/tests/libtcc_test_mt.c
Normal file
|
@ -0,0 +1,301 @@
|
|||
/*
|
||||
* Multi-thread Test for libtcc
|
||||
*/
|
||||
|
||||
#ifndef FIB
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "libtcc.h"
|
||||
|
||||
#define M 20 /* number of states */
|
||||
#define F(n) (n % 20 + 2) /* fib argument */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#define TF_TYPE(func, param) DWORD WINAPI func(void *param)
|
||||
typedef TF_TYPE(ThreadFunc, x);
|
||||
HANDLE hh[M];
|
||||
void create_thread(ThreadFunc f, int n)
|
||||
{
|
||||
DWORD tid;
|
||||
hh[n] = CreateThread(NULL, 0, f, (void*)(size_t)n, 0, &tid);
|
||||
}
|
||||
void wait_threads(int n)
|
||||
{
|
||||
WaitForMultipleObjects(n, hh, TRUE, INFINITE);
|
||||
while (n)
|
||||
CloseHandle(hh[--n]);
|
||||
}
|
||||
void sleep_ms(unsigned n)
|
||||
{
|
||||
Sleep(n);
|
||||
}
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#define TF_TYPE(func, param) void* func(void *param)
|
||||
typedef TF_TYPE(ThreadFunc, x);
|
||||
pthread_t hh[M];
|
||||
void create_thread(ThreadFunc f, int n)
|
||||
{
|
||||
pthread_create(&hh[n], NULL, f, (void*)(size_t)n);
|
||||
}
|
||||
void wait_threads(int n)
|
||||
{
|
||||
while (n)
|
||||
pthread_join(hh[--n], NULL);
|
||||
|
||||
}
|
||||
void sleep_ms(unsigned n)
|
||||
{
|
||||
usleep(n * 1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
void handle_error(void *opaque, const char *msg)
|
||||
{
|
||||
fprintf(opaque, "%s\n", msg);
|
||||
}
|
||||
|
||||
/* this function is called by the generated code */
|
||||
int add(int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
#define _str(s) #s
|
||||
#define str(s) _str(s)
|
||||
/* as a trick, prepend #line directive for better error/warning messages */
|
||||
#define PROG(lbl) \
|
||||
char lbl[] = "#line " str(__LINE__) " " str(__FILE__) "\n\n"
|
||||
|
||||
PROG(my_program)
|
||||
"#include <tcclib.h>\n" /* include the "Simple libc header for TCC" */
|
||||
"int add(int a, int b);\n"
|
||||
"int fib(int n)\n"
|
||||
"{\n"
|
||||
" if (n <= 2)\n"
|
||||
" return 1;\n"
|
||||
" else\n"
|
||||
" return add(fib(n-1),fib(n-2));\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"int foo(int n)\n"
|
||||
"{\n"
|
||||
" printf(\" %d\", fib(n));\n"
|
||||
" return 0;\n"
|
||||
"# warning is this the correct file:line...\n"
|
||||
"}\n";
|
||||
|
||||
int g_argc; char **g_argv;
|
||||
|
||||
void parse_args(TCCState *s)
|
||||
{
|
||||
int i;
|
||||
/* if tcclib.h and libtcc1.a are not installed, where can we find them */
|
||||
for (i = 1; i < g_argc; ++i) {
|
||||
char *a = g_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);
|
||||
else if (a[1] == 'D')
|
||||
tcc_define_symbol(s, a+2, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TCCState *new_state(int w)
|
||||
{
|
||||
TCCState *s = tcc_new();
|
||||
if (!s) {
|
||||
fprintf(stderr, __FILE__ ": could not create tcc state\n");
|
||||
exit(1);
|
||||
}
|
||||
tcc_set_error_func(s, stdout, handle_error);
|
||||
parse_args(s);
|
||||
if (!w) tcc_set_options(s, "-w");
|
||||
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
|
||||
return s;
|
||||
}
|
||||
|
||||
void *reloc_state(TCCState *s, const char *entry)
|
||||
{
|
||||
void *func;
|
||||
tcc_add_symbol(s, "add", add);
|
||||
if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0) {
|
||||
fprintf(stderr, __FILE__ ": could not relocate tcc state.\n");
|
||||
return NULL;
|
||||
}
|
||||
func = tcc_get_symbol(s, entry);
|
||||
if (!func)
|
||||
fprintf(stderr, __FILE__ ": could not get entry symbol.\n");
|
||||
return func;
|
||||
}
|
||||
|
||||
/* work with several states at the same time */
|
||||
int state_test(void)
|
||||
{
|
||||
TCCState *s[M];
|
||||
int (*func[M])(int);
|
||||
int n;
|
||||
|
||||
for (n = 0; n < M + 4; ++n) {
|
||||
unsigned a = n, b = n - 1, c = n - 2, d = n - 3, e = n - 4;
|
||||
if (a < M)
|
||||
s[a] = new_state(0);
|
||||
if (b < M)
|
||||
if (tcc_compile_string(s[b], my_program) == -1)
|
||||
break;
|
||||
if (c < M)
|
||||
func[c] = reloc_state(s[c], "foo");
|
||||
if (d < M && func[d])
|
||||
func[d](F(d));
|
||||
if (e < M)
|
||||
tcc_delete(s[e]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* simple compilation in threads */
|
||||
TF_TYPE(thread_test_simple, vn)
|
||||
{
|
||||
TCCState *s;
|
||||
int (*func)(int);
|
||||
int ret;
|
||||
int n = (size_t)vn;
|
||||
|
||||
s = new_state(0);
|
||||
sleep_ms(1);
|
||||
ret = tcc_compile_string(s, my_program);
|
||||
sleep_ms(1);
|
||||
if (ret >= 0) {
|
||||
func = reloc_state(s, "foo");
|
||||
if (func)
|
||||
func(F(n));
|
||||
}
|
||||
tcc_delete(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* more complex compilation in threads */
|
||||
TF_TYPE(thread_test_complex, vn)
|
||||
{
|
||||
TCCState *s;
|
||||
int ret;
|
||||
int n = (size_t)vn;
|
||||
char *argv[30], b[10];
|
||||
int argc = 0, i;
|
||||
|
||||
sprintf(b, "%d", F(n));
|
||||
|
||||
for (i = 1; i < g_argc; ++i) argv[argc++] = g_argv[i];
|
||||
#if 0
|
||||
argv[argc++] = "-run";
|
||||
for (i = 1; i < g_argc; ++i) argv[argc++] = g_argv[i];
|
||||
#endif
|
||||
argv[argc++] = "-DFIB";
|
||||
argv[argc++] = "-run";
|
||||
argv[argc++] = __FILE__;
|
||||
argv[argc++] = b;
|
||||
argv[argc] = NULL;
|
||||
|
||||
s = new_state(1);
|
||||
sleep_ms(2);
|
||||
ret = tcc_add_file(s, argv[0]);
|
||||
sleep_ms(3);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
tcc_run(s, argc, argv);
|
||||
tcc_delete(s);
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void time_tcc(int n, const char *src)
|
||||
{
|
||||
TCCState *s;
|
||||
int ret, i = 0;
|
||||
while (i++ < n) {
|
||||
s = new_state(1);
|
||||
printf(" %d", i), fflush(stdout);
|
||||
ret = tcc_add_file(s, src);
|
||||
tcc_delete(s);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned getclock_ms(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return GetTickCount();
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv.tv_sec*1000 + (tv.tv_usec+500)/1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int n;
|
||||
unsigned t;
|
||||
|
||||
g_argc = argc;
|
||||
g_argv = argv;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: libtcc_test_mt tcc.c <options>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 1
|
||||
printf("running fib with mixed calls\n "), fflush(stdout);
|
||||
t = getclock_ms();
|
||||
state_test();
|
||||
printf("\n (%u ms)\n", getclock_ms() - t);
|
||||
#endif
|
||||
#if 1
|
||||
printf("running fib in threads\n "), fflush(stdout);
|
||||
t = getclock_ms();
|
||||
for (n = 0; n < M; ++n)
|
||||
create_thread(thread_test_simple, n);
|
||||
wait_threads(n);
|
||||
printf("\n (%u ms)\n", getclock_ms() - t);
|
||||
#endif
|
||||
#if 1
|
||||
printf("running tcc.c in threads to run fib\n "), fflush(stdout);
|
||||
t = getclock_ms();
|
||||
for (n = 0; n < M; ++n)
|
||||
create_thread(thread_test_complex, n);
|
||||
wait_threads(n);
|
||||
printf("\n (%u ms)\n", getclock_ms() - t);
|
||||
#endif
|
||||
#if 1
|
||||
printf("compiling tcc.c 10 times\n "), fflush(stdout);
|
||||
t = getclock_ms();
|
||||
time_tcc(10, argv[1]);
|
||||
printf("\n (%u ms)\n", getclock_ms() - t), fflush(stdout);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#include <tcclib.h>
|
||||
int fib(n)
|
||||
{
|
||||
return (n <= 2) ? 1 : fib(n-1) + fib(n-2);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
printf(" %d", fib(atoi(argv[1]), 2));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
6
05/tcc-final/tests/pp/01.c
Normal file
6
05/tcc-final/tests/pp/01.c
Normal file
|
@ -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";
|
1
05/tcc-final/tests/pp/01.expect
Normal file
1
05/tcc-final/tests/pp/01.expect
Normal file
|
@ -0,0 +1 @@
|
|||
char p[] = "x ## y";
|
28
05/tcc-final/tests/pp/02.c
Normal file
28
05/tcc-final/tests/pp/02.c
Normal file
|
@ -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
|
5
05/tcc-final/tests/pp/02.expect
Normal file
5
05/tcc-final/tests/pp/02.expect
Normal file
|
@ -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);
|
15
05/tcc-final/tests/pp/03.c
Normal file
15
05/tcc-final/tests/pp/03.c
Normal file
|
@ -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)
|
5
05/tcc-final/tests/pp/03.expect
Normal file
5
05/tcc-final/tests/pp/03.expect
Normal file
|
@ -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"
|
4
05/tcc-final/tests/pp/04.c
Normal file
4
05/tcc-final/tests/pp/04.c
Normal file
|
@ -0,0 +1,4 @@
|
|||
#define foobar 1
|
||||
#define C(x,y) x##y
|
||||
#define D(x) (C(x,bar))
|
||||
D(foo)
|
1
05/tcc-final/tests/pp/04.expect
Normal file
1
05/tcc-final/tests/pp/04.expect
Normal file
|
@ -0,0 +1 @@
|
|||
(1)
|
7
05/tcc-final/tests/pp/05.c
Normal file
7
05/tcc-final/tests/pp/05.c
Normal file
|
@ -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)
|
3
05/tcc-final/tests/pp/05.expect
Normal file
3
05/tcc-final/tests/pp/05.expect
Normal file
|
@ -0,0 +1,3 @@
|
|||
int j[] = { 123, 45, 67, 89,
|
||||
10, 11, 12, };
|
||||
int j[] = { 123, 45, 67, 89, 10, 11, 12, };
|
5
05/tcc-final/tests/pp/06.c
Normal file
5
05/tcc-final/tests/pp/06.c
Normal file
|
@ -0,0 +1,5 @@
|
|||
#define X(a,b, \
|
||||
c,d) \
|
||||
foo
|
||||
|
||||
X(1,2,3,4)
|
1
05/tcc-final/tests/pp/06.expect
Normal file
1
05/tcc-final/tests/pp/06.expect
Normal file
|
@ -0,0 +1 @@
|
|||
foo
|
4
05/tcc-final/tests/pp/07.c
Normal file
4
05/tcc-final/tests/pp/07.c
Normal file
|
@ -0,0 +1,4 @@
|
|||
#define a() YES
|
||||
#define b() a
|
||||
b()
|
||||
b()()
|
2
05/tcc-final/tests/pp/07.expect
Normal file
2
05/tcc-final/tests/pp/07.expect
Normal file
|
@ -0,0 +1,2 @@
|
|||
a
|
||||
YES
|
4
05/tcc-final/tests/pp/08.c
Normal file
4
05/tcc-final/tests/pp/08.c
Normal file
|
@ -0,0 +1,4 @@
|
|||
// test macro expansion in arguments
|
||||
#define s_pos s_s.s_pos
|
||||
#define foo(x) (x)
|
||||
foo(hej.s_pos)
|
1
05/tcc-final/tests/pp/08.expect
Normal file
1
05/tcc-final/tests/pp/08.expect
Normal file
|
@ -0,0 +1 @@
|
|||
(hej.s_s.s_pos)
|
4
05/tcc-final/tests/pp/09.c
Normal file
4
05/tcc-final/tests/pp/09.c
Normal file
|
@ -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)
|
1
05/tcc-final/tests/pp/09.expect
Normal file
1
05/tcc-final/tests/pp/09.expect
Normal file
|
@ -0,0 +1 @@
|
|||
aaaaoooo
|
10
05/tcc-final/tests/pp/10.c
Normal file
10
05/tcc-final/tests/pp/10.c
Normal file
|
@ -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))))
|
5
05/tcc-final/tests/pp/10.expect
Normal file
5
05/tcc-final/tests/pp/10.expect
Normal file
|
@ -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))))
|
31
05/tcc-final/tests/pp/11.c
Normal file
31
05/tcc-final/tests/pp/11.c
Normal file
|
@ -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() ())
|
15
05/tcc-final/tests/pp/11.expect
Normal file
15
05/tcc-final/tests/pp/11.expect
Normal file
|
@ -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
|
8
05/tcc-final/tests/pp/12.S
Normal file
8
05/tcc-final/tests/pp/12.S
Normal file
|
@ -0,0 +1,8 @@
|
|||
#define SRC(y...) \
|
||||
9999: y; \
|
||||
.section __ex_table, "a"; \
|
||||
.long 9999b, 6001f ; \
|
||||
// .previous
|
||||
|
||||
SRC(1: movw (%esi), %bx)
|
||||
6001:
|
2
05/tcc-final/tests/pp/12.expect
Normal file
2
05/tcc-final/tests/pp/12.expect
Normal file
|
@ -0,0 +1,2 @@
|
|||
9999: 1: movw (%esi), %bx; .section __ex_table, "a"; .long 9999b, 6001f ;
|
||||
6001:
|
6
05/tcc-final/tests/pp/13.S
Normal file
6
05/tcc-final/tests/pp/13.S
Normal file
|
@ -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:
|
2
05/tcc-final/tests/pp/13.expect
Normal file
2
05/tcc-final/tests/pp/13.expect
Normal file
|
@ -0,0 +1,2 @@
|
|||
.text
|
||||
endtext:
|
13
05/tcc-final/tests/pp/14.c
Normal file
13
05/tcc-final/tests/pp/14.c
Normal file
|
@ -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;
|
3
05/tcc-final/tests/pp/14.expect
Normal file
3
05/tcc-final/tests/pp/14.expect
Normal file
|
@ -0,0 +1,3 @@
|
|||
return Z(Z(1,2),2);
|
||||
return Q(1,2);
|
||||
return ((A + A) * (A + A)) + ((B * B) + (B * B));
|
18
05/tcc-final/tests/pp/15.c
Normal file
18
05/tcc-final/tests/pp/15.c
Normal file
|
@ -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);
|
5
05/tcc-final/tests/pp/15.expect
Normal file
5
05/tcc-final/tests/pp/15.expect
Normal file
|
@ -0,0 +1,5 @@
|
|||
return (long double)d;
|
||||
return A+++B;
|
||||
return A+ ++B;
|
||||
return A+++ +B;
|
||||
return 0x1E -1;
|
3
05/tcc-final/tests/pp/16.c
Normal file
3
05/tcc-final/tests/pp/16.c
Normal file
|
@ -0,0 +1,3 @@
|
|||
/* The following should warn */
|
||||
#define A ...
|
||||
#define A <<=
|
2
05/tcc-final/tests/pp/16.expect
Normal file
2
05/tcc-final/tests/pp/16.expect
Normal file
|
@ -0,0 +1,2 @@
|
|||
|
||||
16.c:3: warning: A redefined
|
14
05/tcc-final/tests/pp/17.c
Normal file
14
05/tcc-final/tests/pp/17.c
Normal file
|
@ -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));
|
6
05/tcc-final/tests/pp/17.expect
Normal file
6
05/tcc-final/tests/pp/17.expect
Normal file
|
@ -0,0 +1,6 @@
|
|||
X162 "onetok"
|
||||
X161 "onetok"
|
||||
X163 "one##tok"
|
||||
X170 x ## y
|
||||
X171 x ## y
|
||||
X180 return Z(Z(1));
|
15
05/tcc-final/tests/pp/18.c
Normal file
15
05/tcc-final/tests/pp/18.c
Normal file
|
@ -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()
|
3
05/tcc-final/tests/pp/18.expect
Normal file
3
05/tcc-final/tests/pp/18.expect
Normal file
|
@ -0,0 +1,3 @@
|
|||
X181 1
|
||||
X182 0
|
||||
X183 yeah
|
101
05/tcc-final/tests/pp/19.c
Normal file
101
05/tcc-final/tests/pp/19.c
Normal file
|
@ -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"
|
14
05/tcc-final/tests/pp/19.expect
Normal file
14
05/tcc-final/tests/pp/19.expect
Normal file
|
@ -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
|
13
05/tcc-final/tests/pp/20.c
Normal file
13
05/tcc-final/tests/pp/20.c
Normal file
|
@ -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)
|
6
05/tcc-final/tests/pp/20.expect
Normal file
6
05/tcc-final/tests/pp/20.expect
Normal file
|
@ -0,0 +1,6 @@
|
|||
X1 printk(KERN_WARNING "pipapo",bla);
|
||||
X2 printk(KERN_WARNING "bla",foo);
|
||||
X2 twoopq
|
||||
X3 otwopq
|
||||
X4 optwoq
|
||||
X5 opqtwo
|
36
05/tcc-final/tests/pp/21.c
Normal file
36
05/tcc-final/tests/pp/21.c
Normal file
|
@ -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
|
8
05/tcc-final/tests/pp/21.expect
Normal file
8
05/tcc-final/tests/pp/21.expect
Normal file
|
@ -0,0 +1,8 @@
|
|||
----- 1 ------
|
||||
OK
|
||||
----- 2 ------
|
||||
OK
|
||||
----- 3 ------
|
||||
OK
|
||||
----- 4 ------
|
||||
OK
|
51
05/tcc-final/tests/pp/Makefile
Normal file
51
05/tcc-final/tests/pp/Makefile
Normal file
|
@ -0,0 +1,51 @@
|
|||
#
|
||||
# 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 testspp.all: $(sort $(TESTS))
|
||||
|
||||
DIFF_OPTS = -Nu -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
|
||||
|
||||
testspp.%: %.test ;
|
||||
|
||||
# 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
|
27
05/tcc-final/tests/pp/pp-counter.c
Normal file
27
05/tcc-final/tests/pp/pp-counter.c
Normal file
|
@ -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__)
|
15
05/tcc-final/tests/pp/pp-counter.expect
Normal file
15
05/tcc-final/tests/pp/pp-counter.expect
Normal file
|
@ -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
|
4363
05/tcc-final/tests/tcctest.c
Normal file
4363
05/tcc-final/tests/tcctest.c
Normal file
File diff suppressed because it is too large
Load diff
9
05/tcc-final/tests/tcctest.h
Normal file
9
05/tcc-final/tests/tcctest.h
Normal file
|
@ -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__;
|
||||
}
|
510
05/tcc-final/tests/testfp.c
Normal file
510
05/tcc-final/tests/testfp.c
Normal file
|
@ -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;
|
||||
}
|
18
05/tcc-final/tests/tests2/00_assignment.c
Normal file
18
05/tcc-final/tests/tests2/00_assignment.c
Normal file
|
@ -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 :
|
3
05/tcc-final/tests/tests2/00_assignment.expect
Normal file
3
05/tcc-final/tests/tests2/00_assignment.expect
Normal file
|
@ -0,0 +1,3 @@
|
|||
42
|
||||
64
|
||||
12, 34
|
14
05/tcc-final/tests/tests2/01_comment.c
Normal file
14
05/tcc-final/tests/tests2/01_comment.c
Normal file
|
@ -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 :
|
5
05/tcc-final/tests/tests2/01_comment.expect
Normal file
5
05/tcc-final/tests/tests2/01_comment.expect
Normal file
|
@ -0,0 +1,5 @@
|
|||
Hello
|
||||
Hello
|
||||
Hello
|
||||
Hello
|
||||
Hello
|
18
05/tcc-final/tests/tests2/02_printf.c
Normal file
18
05/tcc-final/tests/tests2/02_printf.c
Normal file
|
@ -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 :
|
15
05/tcc-final/tests/tests2/02_printf.expect
Normal file
15
05/tcc-final/tests/tests2/02_printf.expect
Normal file
|
@ -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'
|
38
05/tcc-final/tests/tests2/03_struct.c
Normal file
38
05/tcc-final/tests/tests2/03_struct.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
extern int printf(const char*, ...);
|
||||
|
||||
struct fred;
|
||||
|
||||
void fred$(struct fred* this)
|
||||
{
|
||||
printf("~fred()\n");
|
||||
}
|
||||
|
||||
struct __attribute__((__cleanup__(fred$))) fred
|
||||
{
|
||||
int boris;
|
||||
int natasha;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
struct fred __attribute__((__cleanup__(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;
|
||||
}
|
8
05/tcc-final/tests/tests2/03_struct.expect
Normal file
8
05/tcc-final/tests/tests2/03_struct.expect
Normal file
|
@ -0,0 +1,8 @@
|
|||
03_struct.c:14: warning: attribute '__cleanup__' ignored on type
|
||||
12
|
||||
34
|
||||
12
|
||||
34
|
||||
56
|
||||
78
|
||||
~fred()
|
15
05/tcc-final/tests/tests2/04_for.c
Normal file
15
05/tcc-final/tests/tests2/04_for.c
Normal file
|
@ -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 :
|
10
05/tcc-final/tests/tests2/04_for.expect
Normal file
10
05/tcc-final/tests/tests2/04_for.expect
Normal file
|
@ -0,0 +1,10 @@
|
|||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
21
05/tcc-final/tests/tests2/05_array.c
Normal file
21
05/tcc-final/tests/tests2/05_array.c
Normal file
|
@ -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 :
|
10
05/tcc-final/tests/tests2/05_array.expect
Normal file
10
05/tcc-final/tests/tests2/05_array.expect
Normal file
|
@ -0,0 +1,10 @@
|
|||
1
|
||||
4
|
||||
9
|
||||
16
|
||||
25
|
||||
36
|
||||
49
|
||||
64
|
||||
81
|
||||
100
|
29
05/tcc-final/tests/tests2/06_case.c
Normal file
29
05/tcc-final/tests/tests2/06_case.c
Normal file
|
@ -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 :
|
8
05/tcc-final/tests/tests2/06_case.expect
Normal file
8
05/tcc-final/tests/tests2/06_case.expect
Normal file
|
@ -0,0 +1,8 @@
|
|||
0
|
||||
0
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
3
|
||||
0
|
35
05/tcc-final/tests/tests2/07_function.c
Normal file
35
05/tcc-final/tests/tests2/07_function.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int myfunc(int x)
|
||||
{
|
||||
return x * x;
|
||||
}
|
||||
|
||||
void vfunc(int a)
|
||||
{
|
||||
printf("a=%d\n", a);
|
||||
}
|
||||
|
||||
void qfunc()
|
||||
{
|
||||
printf("qfunc()\n");
|
||||
}
|
||||
|
||||
void zfunc()
|
||||
{
|
||||
((void (*)(void))0) ();
|
||||
}
|
||||
|
||||
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 :
|
4
05/tcc-final/tests/tests2/07_function.expect
Normal file
4
05/tcc-final/tests/tests2/07_function.expect
Normal file
|
@ -0,0 +1,4 @@
|
|||
9
|
||||
16
|
||||
a=1234
|
||||
qfunc()
|
24
05/tcc-final/tests/tests2/08_while.c
Normal file
24
05/tcc-final/tests/tests2/08_while.c
Normal file
|
@ -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 :
|
11
05/tcc-final/tests/tests2/08_while.expect
Normal file
11
05/tcc-final/tests/tests2/08_while.expect
Normal file
|
@ -0,0 +1,11 @@
|
|||
1
|
||||
1
|
||||
2
|
||||
3
|
||||
5
|
||||
8
|
||||
13
|
||||
21
|
||||
34
|
||||
55
|
||||
89
|
24
05/tcc-final/tests/tests2/09_do_while.c
Normal file
24
05/tcc-final/tests/tests2/09_do_while.c
Normal file
|
@ -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 :
|
11
05/tcc-final/tests/tests2/09_do_while.expect
Normal file
11
05/tcc-final/tests/tests2/09_do_while.expect
Normal file
|
@ -0,0 +1,11 @@
|
|||
1
|
||||
1
|
||||
2
|
||||
3
|
||||
5
|
||||
8
|
||||
13
|
||||
21
|
||||
34
|
||||
55
|
||||
89
|
34
05/tcc-final/tests/tests2/100_c99array-decls.c
Normal file
34
05/tcc-final/tests/tests2/100_c99array-decls.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
void foo(int [5]);
|
||||
void fooc(int x[const 5]);
|
||||
void foos(int x[static 5]);
|
||||
void foov(int x[volatile 5]);
|
||||
void foor(int x[restrict 5]);
|
||||
void fooc(int [const 5]);
|
||||
void foos(int [static 5]);
|
||||
void foov(int [volatile 5]);
|
||||
void foor(int [restrict 5]);
|
||||
void fooc(int (* const x));
|
||||
void foos(int *x);
|
||||
void foov(int * volatile x);
|
||||
void foor(int * restrict x);
|
||||
void fooc(int x[volatile 5])
|
||||
{
|
||||
x[3] = 42;
|
||||
#ifdef INVALID
|
||||
x = 0;
|
||||
#endif
|
||||
}
|
||||
void foovm(int x[const *]);
|
||||
void foovm(int * const x);
|
||||
#ifdef INVALID
|
||||
void wrongc(int x[3][const 4]);
|
||||
void wrongvm(int x[static *]);
|
||||
void foovm(int x[const *])
|
||||
{
|
||||
x[2] = 1;
|
||||
}
|
||||
#endif
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
0
05/tcc-final/tests/tests2/100_c99array-decls.expect
Normal file
0
05/tcc-final/tests/tests2/100_c99array-decls.expect
Normal file
227
05/tcc-final/tests/tests2/101_cleanup.c
Normal file
227
05/tcc-final/tests/tests2/101_cleanup.c
Normal file
|
@ -0,0 +1,227 @@
|
|||
extern int printf(const char*, ...);
|
||||
static int glob_i = 0;
|
||||
|
||||
void incr_glob_i(int *i)
|
||||
{
|
||||
glob_i += *i;
|
||||
}
|
||||
|
||||
#define INCR_GI { \
|
||||
int i __attribute__ ((__cleanup__(incr_glob_i))) = 1; \
|
||||
}
|
||||
|
||||
#define INCR_GI0 INCR_GI INCR_GI INCR_GI INCR_GI
|
||||
#define INCR_GI1 INCR_GI0 INCR_GI0 INCR_GI0 INCR_GI0
|
||||
#define INCR_GI2 INCR_GI1 INCR_GI1 INCR_GI1 INCR_GI1
|
||||
#define INCR_GI3 INCR_GI2 INCR_GI2 INCR_GI2 INCR_GI2
|
||||
#define INCR_GI4 INCR_GI3 INCR_GI3 INCR_GI3 INCR_GI3
|
||||
#define INCR_GI5 INCR_GI4 INCR_GI4 INCR_GI4 INCR_GI4
|
||||
#define INCR_GI6 INCR_GI5 INCR_GI5 INCR_GI5 INCR_GI5
|
||||
#define INCR_GI7 INCR_GI6 INCR_GI6 INCR_GI6 INCR_GI6
|
||||
|
||||
|
||||
void check2(char **hum);
|
||||
|
||||
void check(int *j)
|
||||
{
|
||||
char * __attribute__ ((cleanup(check2))) stop_that = "wololo";
|
||||
int chk = 0;
|
||||
|
||||
{
|
||||
char * __attribute__ ((cleanup(check2))) stop_that = "plop";
|
||||
|
||||
{
|
||||
non_plopage:
|
||||
printf("---- %d\n", chk);
|
||||
}
|
||||
if (!chk) {
|
||||
chk = 1;
|
||||
goto non_plopage;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
char * __attribute__ ((cleanup(check2))) stop_that = "tata !";
|
||||
|
||||
goto out;
|
||||
stop_that = "titi";
|
||||
}
|
||||
again:
|
||||
chk = 2;
|
||||
{
|
||||
char * __attribute__ ((cleanup(check2))) cascade1 = "1";
|
||||
{
|
||||
char * __attribute__ ((cleanup(check2))) cascade2 = "2";
|
||||
{
|
||||
char * __attribute__ ((cleanup(check2))) cascade3 = "3";
|
||||
|
||||
goto out;
|
||||
cascade3 = "nope";
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
if (chk != 2)
|
||||
goto again;
|
||||
{
|
||||
{
|
||||
char * __attribute__ ((cleanup(check2))) out = "last goto out";
|
||||
++chk;
|
||||
if (chk != 3)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void check_oh_i(char *oh_i)
|
||||
{
|
||||
printf("c: %c\n", *oh_i);
|
||||
}
|
||||
|
||||
void goto_hell(double *f)
|
||||
{
|
||||
printf("oo: %f\n", *f);
|
||||
}
|
||||
|
||||
char *test()
|
||||
{
|
||||
char *__attribute__ ((cleanup(check2))) str = "I don't think this should be print(but gcc got it wrong too)";
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
void test_ret_subcall(char *that)
|
||||
{
|
||||
printf("should be print before\n");
|
||||
}
|
||||
|
||||
void test_ret()
|
||||
{
|
||||
char *__attribute__ ((cleanup(check2))) that = "that";
|
||||
return test_ret_subcall(that);
|
||||
}
|
||||
|
||||
void test_ret2()
|
||||
{
|
||||
char *__attribute__ ((cleanup(check2))) that = "-that";
|
||||
{
|
||||
char *__attribute__ ((cleanup(check2))) that = "this should appear only once";
|
||||
}
|
||||
{
|
||||
char *__attribute__ ((cleanup(check2))) that = "-that2";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void test2(void) {
|
||||
int chk = 0;
|
||||
again:
|
||||
if (!chk) {
|
||||
char * __attribute__ ((cleanup(check2))) stop_that = "test2";
|
||||
chk++;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
int test3(void) {
|
||||
char * __attribute__ ((cleanup(check2))) stop_that = "three";
|
||||
int chk = 0;
|
||||
|
||||
if (chk) {
|
||||
{
|
||||
outside:
|
||||
{
|
||||
char * __attribute__ ((cleanup(check2))) stop_that = "two";
|
||||
printf("---- %d\n", chk);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!chk)
|
||||
{
|
||||
char * __attribute__ ((cleanup(check2))) stop_that = "one";
|
||||
|
||||
if (!chk) {
|
||||
chk = 1;
|
||||
goto outside;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cl(int *ip)
|
||||
{
|
||||
printf("%d\n", *ip);
|
||||
}
|
||||
|
||||
void loop_cleanups(void)
|
||||
{
|
||||
__attribute__((cleanup(cl))) int l = 1000;
|
||||
|
||||
printf("-- loop 0 --\n");
|
||||
for ( __attribute__((cleanup(cl))) int i = 0; i < 10; ++i) {
|
||||
__attribute__((cleanup(cl))) int j = 100;
|
||||
}
|
||||
|
||||
printf("-- loop 1 --\n");
|
||||
for (__attribute__((cleanup(cl))) int i = 0; i < 10; ++i) {
|
||||
__attribute__((cleanup(cl))) int j = 200;
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("-- loop 2 --\n");
|
||||
for (__attribute__((cleanup(cl))) int i = 0; i < 10; ++i) {
|
||||
__attribute__((cleanup(cl))) int j = 300;
|
||||
break;
|
||||
}
|
||||
|
||||
printf("-- loop 3 --\n");
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
__attribute__((cleanup(cl))) int j = 400;
|
||||
switch (i) {
|
||||
case 0:
|
||||
continue;
|
||||
default:
|
||||
{
|
||||
__attribute__((cleanup(cl))) int jj = 500;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("after break\n");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int i __attribute__ ((__cleanup__(check))) = 0, not_i;
|
||||
int chk = 0;
|
||||
(void)not_i;
|
||||
|
||||
{
|
||||
__attribute__ ((__cleanup__(check_oh_i))) char oh_i = 'o', o = 'a';
|
||||
}
|
||||
|
||||
INCR_GI7;
|
||||
printf("glob_i: %d\n", glob_i);
|
||||
naaaaaaaa:
|
||||
if (!chk) {
|
||||
__attribute__ ((__cleanup__(check_oh_i))) char oh_i = 'f';
|
||||
double __attribute__ ((__cleanup__(goto_hell))) f = 2.6;
|
||||
|
||||
chk = 1;
|
||||
goto naaaaaaaa;
|
||||
}
|
||||
i = 105;
|
||||
printf("because what if free was call inside cleanup function %s\n", test());
|
||||
test_ret();
|
||||
test_ret2();
|
||||
test2();
|
||||
test3();
|
||||
loop_cleanups();
|
||||
return i;
|
||||
}
|
||||
|
||||
void check2(char **hum)
|
||||
{
|
||||
printf("str: %s\n", *hum);
|
||||
}
|
59
05/tcc-final/tests/tests2/101_cleanup.expect
Normal file
59
05/tcc-final/tests/tests2/101_cleanup.expect
Normal file
|
@ -0,0 +1,59 @@
|
|||
c: a
|
||||
c: o
|
||||
glob_i: 65536
|
||||
oo: 2.600000
|
||||
c: f
|
||||
str: I don't think this should be print(but gcc got it wrong too)
|
||||
because what if free was call inside cleanup function I don't think this should be print(but gcc got it wrong too)
|
||||
should be print before
|
||||
str: that
|
||||
str: this should appear only once
|
||||
str: -that2
|
||||
str: -that
|
||||
str: test2
|
||||
str: one
|
||||
---- 1
|
||||
str: two
|
||||
str: three
|
||||
-- loop 0 --
|
||||
100
|
||||
100
|
||||
100
|
||||
100
|
||||
100
|
||||
100
|
||||
100
|
||||
100
|
||||
100
|
||||
100
|
||||
10
|
||||
-- loop 1 --
|
||||
200
|
||||
200
|
||||
200
|
||||
200
|
||||
200
|
||||
200
|
||||
200
|
||||
200
|
||||
200
|
||||
200
|
||||
10
|
||||
-- loop 2 --
|
||||
300
|
||||
0
|
||||
-- loop 3 --
|
||||
400
|
||||
500
|
||||
400
|
||||
after break
|
||||
1000
|
||||
---- 0
|
||||
---- 1
|
||||
str: plop
|
||||
str: tata !
|
||||
str: 3
|
||||
str: 2
|
||||
str: 1
|
||||
str: last goto out
|
||||
str: wololo
|
29
05/tcc-final/tests/tests2/102_alignas.c
Normal file
29
05/tcc-final/tests/tests2/102_alignas.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
_Alignas(16) int i1;
|
||||
int _Alignas(16) i2;
|
||||
void _Alignas(16) *p2;
|
||||
_Alignas(16) i3;
|
||||
int _Alignas(double) i4;
|
||||
int _Alignas(int) i5;
|
||||
#if 0
|
||||
/* The following are currently wrongly accepted by TCC but really shouldn't. */
|
||||
int _Alignas(int _Alignas(16)) i6; //wrong, 'int _Alignas(16)' is no type-name
|
||||
typedef int _Alignas(16) int16aligned_t; //wrong, _Alignas invalid on typedef
|
||||
int16aligned_t i7;
|
||||
#endif
|
||||
/* i8 should get an alignment of 16, because unlike _Alignas the
|
||||
corresponding attribute _does_ apply to type-name, though not in
|
||||
some clang versions. */
|
||||
int _Alignas(int __attribute__((aligned(16)))) i8;
|
||||
extern int printf(const char*, ...);
|
||||
#ifdef _MSC_VER
|
||||
#define alignof(x) (int)__alignof(x)
|
||||
#else
|
||||
#define alignof(x) (int)__alignof__(x)
|
||||
#endif
|
||||
int main()
|
||||
{
|
||||
printf("%d %d %d %d\n",
|
||||
alignof(i1) == 16, alignof(i4) == alignof(double),
|
||||
alignof(i5) == alignof(int) , alignof(i8) == 16);
|
||||
return 0;
|
||||
}
|
2
05/tcc-final/tests/tests2/102_alignas.expect
Normal file
2
05/tcc-final/tests/tests2/102_alignas.expect
Normal file
|
@ -0,0 +1,2 @@
|
|||
102_alignas.c:4: warning: type defaults to int
|
||||
1 1 1 1
|
20
05/tcc-final/tests/tests2/103_implicit_memmove.c
Normal file
20
05/tcc-final/tests/tests2/103_implicit_memmove.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* Test that the memmove TCC is emitting for the struct copy
|
||||
and hence implicitely declares can be declared properly also
|
||||
later. */
|
||||
struct S { int a,b,c,d, e[1024];};
|
||||
int foo (struct S *a, struct S *b)
|
||||
{
|
||||
*a = *b;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *memmove(void*,const void*,__SIZE_TYPE__);
|
||||
void foo2 (struct S *a, struct S *b)
|
||||
{
|
||||
memmove(a, b, sizeof *a);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
0
05/tcc-final/tests/tests2/103_implicit_memmove.expect
Normal file
0
05/tcc-final/tests/tests2/103_implicit_memmove.expect
Normal file
54
05/tcc-final/tests/tests2/104+_inline.c
Normal file
54
05/tcc-final/tests/tests2/104+_inline.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
|
||||
#define GOT(f) \
|
||||
__attribute__((weak)) void f(void); \
|
||||
printf("%d %s\n", !!f, #f);
|
||||
|
||||
int printf(const char*, ...);
|
||||
|
||||
void check_exports()
|
||||
{
|
||||
// 0
|
||||
GOT(inline_inline_2decl_only)
|
||||
GOT(inline_inline_undeclared)
|
||||
GOT(inline_inline_predeclared)
|
||||
GOT(inline_inline_postdeclared)
|
||||
GOT(inline_inline_prepostdeclared)
|
||||
GOT(inline_inline_undeclared2)
|
||||
GOT(inline_inline_predeclared2)
|
||||
GOT(inline_inline_postdeclared2)
|
||||
GOT(inline_inline_prepostdeclared2)
|
||||
|
||||
// 1
|
||||
GOT(extern_extern_postdeclared)
|
||||
GOT(extern_extern_postdeclared2)
|
||||
GOT(extern_extern_predeclared)
|
||||
GOT(extern_extern_predeclared2)
|
||||
GOT(extern_extern_prepostdeclared)
|
||||
GOT(extern_extern_prepostdeclared2)
|
||||
GOT(extern_extern_undeclared)
|
||||
GOT(extern_extern_undeclared2)
|
||||
GOT(extern_postdeclared)
|
||||
GOT(extern_postdeclared2)
|
||||
GOT(extern_predeclared)
|
||||
GOT(extern_predeclared2)
|
||||
GOT(extern_prepostdeclared)
|
||||
GOT(extern_undeclared)
|
||||
GOT(extern_undeclared2)
|
||||
GOT(inst2_extern_inline_postdeclared)
|
||||
GOT(inst2_extern_inline_predeclared)
|
||||
GOT(inst3_extern_inline_predeclared)
|
||||
GOT(inst_extern_inline_postdeclared)
|
||||
GOT(inst_extern_inline_predeclared)
|
||||
GOT(main)
|
||||
GOT(noinst_extern_inline_func)
|
||||
GOT(noinst_extern_inline_postdeclared)
|
||||
GOT(noinst_extern_inline_postdeclared2)
|
||||
GOT(noinst_extern_inline_undeclared)
|
||||
|
||||
// 0
|
||||
GOT(noinst_static_inline_postdeclared)
|
||||
GOT(noinst2_static_inline_postdeclared)
|
||||
GOT(noinst_static_inline_predeclared)
|
||||
GOT(noinst2_static_inline_predeclared)
|
||||
GOT(static_func)
|
||||
}
|
132
05/tcc-final/tests/tests2/104_inline.c
Normal file
132
05/tcc-final/tests/tests2/104_inline.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
inline void inline_inline_2decl_only(void);
|
||||
inline void inline_inline_2decl_only(void);
|
||||
|
||||
inline void inline_inline_undeclared(void){}
|
||||
|
||||
inline void inline_inline_predeclared(void);
|
||||
inline void inline_inline_predeclared(void){}
|
||||
|
||||
inline void inline_inline_postdeclared(void){}
|
||||
inline void inline_inline_postdeclared(void);
|
||||
|
||||
inline void inline_inline_prepostdeclared(void);
|
||||
inline void inline_inline_prepostdeclared(void){}
|
||||
inline void inline_inline_prepostdeclared(void);
|
||||
|
||||
inline void inline_inline_undeclared2(void){}
|
||||
|
||||
inline void inline_inline_predeclared2(void);
|
||||
inline void inline_inline_predeclared2(void);
|
||||
inline void inline_inline_predeclared2(void){}
|
||||
|
||||
inline void inline_inline_postdeclared2(void){}
|
||||
inline void inline_inline_postdeclared2(void);
|
||||
inline void inline_inline_postdeclared2(void);
|
||||
|
||||
inline void inline_inline_prepostdeclared2(void);
|
||||
inline void inline_inline_prepostdeclared2(void);
|
||||
inline void inline_inline_prepostdeclared2(void){}
|
||||
inline void inline_inline_prepostdeclared2(void);
|
||||
inline void inline_inline_prepostdeclared2(void);
|
||||
|
||||
extern void extern_extern_undeclared(void){}
|
||||
|
||||
extern void extern_extern_predeclared(void);
|
||||
extern void extern_extern_predeclared(void){}
|
||||
|
||||
extern void extern_extern_postdeclared(void){}
|
||||
extern void extern_extern_postdeclared(void);
|
||||
|
||||
extern void extern_extern_prepostdeclared(void);
|
||||
extern void extern_extern_prepostdeclared(void){}
|
||||
extern void extern_extern_prepostdeclared(void);
|
||||
|
||||
extern void extern_extern_undeclared2(void){}
|
||||
|
||||
extern void extern_extern_predeclared2(void);
|
||||
extern void extern_extern_predeclared2(void);
|
||||
extern void extern_extern_predeclared2(void){}
|
||||
|
||||
extern void extern_extern_postdeclared2(void){}
|
||||
extern void extern_extern_postdeclared2(void);
|
||||
extern void extern_extern_postdeclared2(void);
|
||||
|
||||
extern void extern_extern_prepostdeclared2(void);
|
||||
extern void extern_extern_prepostdeclared2(void);
|
||||
extern void extern_extern_prepostdeclared2(void){}
|
||||
extern void extern_extern_prepostdeclared2(void);
|
||||
extern void extern_extern_prepostdeclared2(void);
|
||||
|
||||
void extern_undeclared(void){}
|
||||
|
||||
void extern_predeclared(void);
|
||||
void extern_predeclared(void){}
|
||||
|
||||
void extern_postdeclared(void){}
|
||||
void extern_postdeclared(void);
|
||||
|
||||
void extern_prepostdeclared(void);
|
||||
void extern_prepostdeclared(void){}
|
||||
void extern_prepostdeclared(void);
|
||||
|
||||
void extern_undeclared2(void){}
|
||||
|
||||
void extern_predeclared2(void);
|
||||
void extern_predeclared2(void);
|
||||
void extern_predeclared2(void){}
|
||||
|
||||
void extern_postdeclared2(void){}
|
||||
void extern_postdeclared2(void);
|
||||
void extern_postdeclared2(void);
|
||||
|
||||
|
||||
extern inline void noinst_extern_inline_undeclared(void){}
|
||||
|
||||
extern inline void noinst_extern_inline_postdeclared(void){}
|
||||
inline void noinst_extern_inline_postdeclared(void);
|
||||
|
||||
extern inline void noinst_extern_inline_postdeclared2(void){}
|
||||
inline void noinst_extern_inline_postdeclared2(void);
|
||||
inline void noinst_extern_inline_postdeclared2(void);
|
||||
|
||||
extern inline void inst_extern_inline_postdeclared(void){}
|
||||
extern inline void inst_extern_inline_postdeclared(void);
|
||||
inline void inst2_extern_inline_postdeclared(void){}
|
||||
void inst2_extern_inline_postdeclared(void);
|
||||
|
||||
void inst_extern_inline_predeclared(void);
|
||||
extern inline void inst_extern_inline_predeclared(void){}
|
||||
void inst2_extern_inline_predeclared(void);
|
||||
inline void inst2_extern_inline_predeclared(void){}
|
||||
extern inline void inst3_extern_inline_predeclared(void);
|
||||
inline void inst3_extern_inline_predeclared(void){}
|
||||
|
||||
static inline void noinst_static_inline_postdeclared(void){}
|
||||
static inline void noinst_static_inline_postdeclared(void);
|
||||
static inline void noinst2_static_inline_postdeclared(void){}
|
||||
static void noinst2_static_inline_postdeclared(void);
|
||||
|
||||
static void noinst_static_inline_predeclared(void);
|
||||
static inline void noinst_static_inline_predeclared(void){}
|
||||
static void noinst2_static_inline_predeclared(void);
|
||||
static inline void noinst2_static_inline_predeclared(void){}
|
||||
|
||||
static void static_func(void);
|
||||
void static_func(void) { }
|
||||
|
||||
inline void noinst_extern_inline_func(void);
|
||||
void noinst_extern_inline_func(void) { }
|
||||
|
||||
int main()
|
||||
{
|
||||
inline_inline_undeclared(); inline_inline_predeclared(); inline_inline_postdeclared();
|
||||
inline_inline_undeclared2(); inline_inline_predeclared2(); inline_inline_postdeclared2();
|
||||
noinst_static_inline_predeclared();
|
||||
noinst2_static_inline_predeclared();
|
||||
noinst_static_inline_predeclared();
|
||||
noinst2_static_inline_predeclared();
|
||||
|
||||
void check_exports();
|
||||
check_exports();
|
||||
return 0;
|
||||
}
|
39
05/tcc-final/tests/tests2/104_inline.expect
Normal file
39
05/tcc-final/tests/tests2/104_inline.expect
Normal file
|
@ -0,0 +1,39 @@
|
|||
0 inline_inline_2decl_only
|
||||
0 inline_inline_undeclared
|
||||
0 inline_inline_predeclared
|
||||
0 inline_inline_postdeclared
|
||||
0 inline_inline_prepostdeclared
|
||||
0 inline_inline_undeclared2
|
||||
0 inline_inline_predeclared2
|
||||
0 inline_inline_postdeclared2
|
||||
0 inline_inline_prepostdeclared2
|
||||
1 extern_extern_postdeclared
|
||||
1 extern_extern_postdeclared2
|
||||
1 extern_extern_predeclared
|
||||
1 extern_extern_predeclared2
|
||||
1 extern_extern_prepostdeclared
|
||||
1 extern_extern_prepostdeclared2
|
||||
1 extern_extern_undeclared
|
||||
1 extern_extern_undeclared2
|
||||
1 extern_postdeclared
|
||||
1 extern_postdeclared2
|
||||
1 extern_predeclared
|
||||
1 extern_predeclared2
|
||||
1 extern_prepostdeclared
|
||||
1 extern_undeclared
|
||||
1 extern_undeclared2
|
||||
1 inst2_extern_inline_postdeclared
|
||||
1 inst2_extern_inline_predeclared
|
||||
1 inst3_extern_inline_predeclared
|
||||
1 inst_extern_inline_postdeclared
|
||||
1 inst_extern_inline_predeclared
|
||||
1 main
|
||||
1 noinst_extern_inline_func
|
||||
1 noinst_extern_inline_postdeclared
|
||||
1 noinst_extern_inline_postdeclared2
|
||||
1 noinst_extern_inline_undeclared
|
||||
0 noinst_static_inline_postdeclared
|
||||
0 noinst2_static_inline_postdeclared
|
||||
0 noinst_static_inline_predeclared
|
||||
0 noinst2_static_inline_predeclared
|
||||
0 static_func
|
12
05/tcc-final/tests/tests2/105_local_extern.c
Normal file
12
05/tcc-final/tests/tests2/105_local_extern.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
extern int printf(const char *, ...);
|
||||
void f(void);
|
||||
void bar(void) { void f(void); f(); }
|
||||
void foo(void) { extern void f(void); f(); }
|
||||
void f(void) { printf("f\n"); }
|
||||
|
||||
int main()
|
||||
{
|
||||
bar();
|
||||
foo();
|
||||
return 0;
|
||||
}
|
2
05/tcc-final/tests/tests2/105_local_extern.expect
Normal file
2
05/tcc-final/tests/tests2/105_local_extern.expect
Normal file
|
@ -0,0 +1,2 @@
|
|||
f
|
||||
f
|
18
05/tcc-final/tests/tests2/106_versym.c
Normal file
18
05/tcc-final/tests/tests2/106_versym.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
int ret;
|
||||
pthread_condattr_t attr;
|
||||
pthread_cond_t condition;
|
||||
|
||||
/* This test fails if symbol versioning does not work */
|
||||
pthread_condattr_init (&attr);
|
||||
pthread_condattr_setpshared (&attr, PTHREAD_PROCESS_SHARED);
|
||||
printf ("%s\n", pthread_cond_init (&condition, &attr) ? "fail":"ok");
|
||||
pthread_condattr_destroy (&attr);
|
||||
return 0;
|
||||
}
|
1
05/tcc-final/tests/tests2/106_versym.expect
Normal file
1
05/tcc-final/tests/tests2/106_versym.expect
Normal file
|
@ -0,0 +1 @@
|
|||
ok
|
13
05/tcc-final/tests/tests2/107_stack_safe.c
Normal file
13
05/tcc-final/tests/tests2/107_stack_safe.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
extern int printf(const char *, ...);
|
||||
|
||||
static void func_ull_ull(unsigned long long l1,unsigned long long l2){
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int a,b,c,d;
|
||||
a=1;b=2;c=3;d=4;
|
||||
func_ull_ull((unsigned long long)a/1.0,(unsigned long long)b/1.0);
|
||||
printf("%d %d %d %d",a,b,c,d);
|
||||
return 0;
|
||||
}
|
1
05/tcc-final/tests/tests2/107_stack_safe.expect
Normal file
1
05/tcc-final/tests/tests2/107_stack_safe.expect
Normal file
|
@ -0,0 +1 @@
|
|||
1 2 3 4
|
20
05/tcc-final/tests/tests2/108_constructor.c
Normal file
20
05/tcc-final/tests/tests2/108_constructor.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
extern int write (int fd, void *buf, int len);
|
||||
|
||||
static void __attribute__ ((constructor))
|
||||
testc (void)
|
||||
{
|
||||
write (1, "constructor\n", 12);
|
||||
}
|
||||
|
||||
static void __attribute__ ((destructor))
|
||||
testd (void)
|
||||
{
|
||||
write (1, "destructor\n", 11);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
write (1, "main\n", 5);
|
||||
return 0;
|
||||
}
|
3
05/tcc-final/tests/tests2/108_constructor.expect
Normal file
3
05/tcc-final/tests/tests2/108_constructor.expect
Normal file
|
@ -0,0 +1,3 @@
|
|||
constructor
|
||||
main
|
||||
destructor
|
24
05/tcc-final/tests/tests2/109_float_struct_calling.c
Normal file
24
05/tcc-final/tests/tests2/109_float_struct_calling.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include <stdio.h>
|
||||
|
||||
/* This test used to fail on x86_64 on linux with sse registers */
|
||||
|
||||
struct Point {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct Rect {
|
||||
struct Point top_left;
|
||||
struct Point size;
|
||||
};
|
||||
|
||||
float foo(struct Point p, struct Rect r) {
|
||||
return r.size.x;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct Point p = {1, 2};
|
||||
struct Rect r = {{3, 4}, {5, 6}};
|
||||
printf("%f\n", foo(p, r));
|
||||
return 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue