compiler 0.9.26 release

git-svn-id: svn://kolibrios.org@6429 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
siemargl
2016-05-14 08:56:15 +00:00
parent a6ec7b35a4
commit b5e7b54c7a
432 changed files with 92632 additions and 16981 deletions
@@ -0,0 +1,138 @@
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
set(TCC_CFLAGS -I${CMAKE_SOURCE_DIR} -I${CMAKE_SOURCE_DIR}/include -B${CMAKE_BINARY_DIR})
if(WIN32)
set(TCC_CFLAGS ${TCC_CFLAGS} -I${CMAKE_SOURCE_DIR}/win32/include)
else()
set(TCC_MATH_LDFLAGS -lm)
set(LIBTCC_EXTRA_LIBS dl)
set(LIBTCC_LDFLAGS -ldl -lm -Wl,-rpath=${CMAKE_BINARY_DIR})
endif()
add_executable(abitest-cc abitest.c)
target_link_libraries(abitest-cc libtcc ${LIBTCC_EXTRA_LIBS})
add_test(NAME abitest-cc WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND abitest-cc lib_path=${CMAKE_BINARY_DIR} include=${CMAKE_SOURCE_DIR}/include)
set(ABITEST_TCC abitest-tcc${CMAKE_EXECUTABLE_SUFFIX})
get_property(LIBTCC_LIB TARGET libtcc PROPERTY LOCATION)
add_custom_command(OUTPUT ${ABITEST_TCC} COMMAND tcc ${TCC_CFLAGS} -g ${CMAKE_CURRENT_SOURCE_DIR}/abitest.c ${LIBTCC_LDFLAGS} ${LIBTCC_LIB} -o ${ABITEST_TCC} DEPENDS tcc ${CMAKE_CURRENT_SOURCE_DIR}/abitest.c)
add_custom_target(abitest-tcc-exe ALL DEPENDS ${ABITEST_TCC})
add_test(NAME abitest-tcc WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${ABITEST_TCC} lib_path=${CMAKE_BINARY_DIR} include=${CMAKE_SOURCE_DIR}/include)
set(VLA_TEST vla_test${CMAKE_EXECUTABLE_SUFFIX})
add_custom_command(OUTPUT ${VLA_TEST} COMMAND tcc ${TCC_CFLAGS} -g ${CMAKE_CURRENT_SOURCE_DIR}/vla_test.c -o ${VLA_TEST} DEPENDS tcc ${CMAKE_CURRENT_SOURCE_DIR}/vla_test.c)
add_custom_target(vla_test-exe ALL DEPENDS ${VLA_TEST})
add_test(vla_test vla_test)
add_executable(tcctest-cc tcctest.c)
target_link_libraries(tcctest-cc libtcc)
set_target_properties(tcctest-cc PROPERTIES COMPILE_FLAGS -std=gnu99)
find_package(PythonInterp)
if(PYTHONINTERP_FOUND)
set(TCC_TEST_CFLAGS ${TCC_CFLAGS} -B${CMAKE_BINARY_DIR} -I${CMAKE_BINARY_DIR})
if(WIN32)
set(TCC_TEST_CFLAGS ${TCC_TEST_CFLAGS} -I${CMAKE_SOURCE_DIR}/win32/include/winapi)
endif()
set(TCC_TEST_SOURCE ${TCC_TEST_CFLAGS} ${TCC_MATH_LDFLAGS} -run ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c)
set(TCC_TEST_RUN ${TCC_TEST_CFLAGS} ${TCC_NATIVE_FLAGS} -DONE_SOURCE -run ${CMAKE_SOURCE_DIR}/tcc.c)
get_property(TCC TARGET tcc PROPERTY LOCATION)
get_property(TCCTESTCC TARGET tcctest-cc PROPERTY LOCATION)
set(TCCTEST_PY ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.py ${TCCTESTCC})
add_test(test1 ${TCCTEST_PY} ${TCC} ${TCC_TEST_SOURCE})
add_test(test2 ${TCCTEST_PY} ${TCC} ${TCC_TEST_RUN} ${TCC_TEST_SOURCE})
add_test(test3 ${TCCTEST_PY} ${TCC} ${TCC_TEST_RUN} ${TCC_TEST_RUN} ${TCC_TEST_SOURCE})
# Object + link output
set(TEST4 test4${CMAKE_EXECUTABLE_SUFFIX})
add_custom_command(OUTPUT test4.o COMMAND tcc ${TCC_TEST_CFLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c -c -o test4.o DEPENDS tcc ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c)
add_custom_command(OUTPUT ${TEST4} COMMAND tcc ${TCC_TEST_CFLAGS} test4.o -o ${TEST4} DEPENDS tcc test4.o)
add_custom_target(test4-exe ALL DEPENDS ${TEST4})
add_test(test4 ${TCCTEST_PY} ${CMAKE_CURRENT_BINARY_DIR}/${TEST4})
# Dynamic output
set(TEST5 test5${CMAKE_EXECUTABLE_SUFFIX})
add_custom_command(OUTPUT ${TEST5} COMMAND tcc ${TCC_TEST_CFLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c -o ${TEST5} DEPENDS tcc ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c)
add_custom_target(test5-exe ALL DEPENDS ${TEST5})
add_test(test5 ${TCCTEST_PY} ${CMAKE_CURRENT_BINARY_DIR}/${TEST5})
if(TCC_BCHECK)
# Dynamic output + bound check
set(TEST6 test6${CMAKE_EXECUTABLE_SUFFIX})
add_custom_command(OUTPUT ${TEST6} COMMAND tcc ${TCC_TEST_CFLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c -b -o ${TEST6} DEPENDS tcc ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c)
add_custom_target(test6-exe ALL DEPENDS ${TEST6})
add_test(test6 ${TCCTEST_PY} ${CMAKE_CURRENT_BINARY_DIR}/${TEST6})
endif()
if(0)
# Static output
set(TEST7 test7${CMAKE_EXECUTABLE_SUFFIX})
add_custom_command(OUTPUT ${TEST7} COMMAND tcc ${TCC_TEST_CFLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c -static -o ${TEST7} DEPENDS tcc ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c)
add_custom_target(test7-exe ALL DEPENDS ${TEST7})
add_test(test7 ${TCCTEST_PY} ${CMAKE_CURRENT_BINARY_DIR}/${TEST7})
endif()
endif()
set(MORETESTS
00_assignment
01_comment
02_printf
03_struct
04_for
05_array
06_case
07_function
08_while
09_do_while
10_pointer
11_precedence
12_hashdefine
13_integer_literals
14_if
15_recursion
16_nesting
17_enum
18_include
19_pointer_arithmetic
20_pointer_comparison
21_char_array
22_floating_point
23_type_coercion
24_math_library
25_quicksort
26_character_constants
27_sizeof
28_strings
29_array_address
31_args
32_led
33_ternary_op
35_sizeof
36_array_initialisers
37_sprintf
38_multiple_array_index
39_typedef
40_stdio
41_hashif
42_function_pointer
43_void_param
44_scoped_declarations
45_empty_for
47_switch_return
48_nested_break
49_bracket_evaluation
50_logical_second_arg
51_static
52_unnamed_enum
54_goto
55_lshift_type
)
if(WIN32)
list(REMOVE_ITEM MORETESTS 24_math_library)
list(REMOVE_ITEM MORETESTS 28_strings)
endif()
foreach(testfile ${MORETESTS})
add_test(NAME ${testfile} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests2
COMMAND tcc ${TCC_CFLAGS} ${TCC_MATH_LDFLAGS} -run ${testfile}.c - arg1 arg2 arg3 arg4 | ${DIFF} - ${testfile}.expect)
endforeach()
@@ -0,0 +1,255 @@
#
# Tiny C Compiler Makefile - tests
#
TOP = ..
include $(TOP)/Makefile
SRCDIR = $(top_srcdir)/tests
VPATH = $(SRCDIR) $(top_srcdir)
# clear CFLAGS and LDFLAGS
CFLAGS :=
LDFLAGS :=
# what tests to run
TESTS = \
hello-exe \
hello-run \
libtest \
test3 \
abitest \
vla_test-run \
tests2-dir pp-dir
BTESTS = test1b test3b btest
ifdef CONFIG_CROSS
TESTS += hello-cross
endif
# test4 -- problem with -static
# asmtest -- minor differences with gcc
# btest -- works on i386 (including win32)
# bounds-checking is supported only on i386
ifneq ($(ARCH),i386)
TESTS := $(filter-out $(BTESTS),$(TESTS))
endif
ifdef CONFIG_WIN32
TESTS := $(filter-out $(BTESTS),$(TESTS))
endif
ifeq ($(TARGETOS),Darwin)
TESTS := $(filter-out hello-exe test3 $(BTESTS),$(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
ifdef DISABLE_STATIC
export LD_LIBRARY_PATH:=$(CURDIR)/..
endif
ifeq ($(TARGETOS),Darwin)
CFLAGS+=-Wl,-flat_namespace,-undefined,warning
export MACOSX_DEPLOYMENT_TARGET:=10.2
NATIVE_DEFINES+=-D_ANSI_SOURCE
endif
# run local version of tcc with local libraries and includes
TCCFLAGS = -B$(TOP) -I$(TOP) -I$(top_srcdir) -I$(top_srcdir)/include -L$(TOP)
ifdef CONFIG_WIN32
TCCFLAGS = -B$(top_srcdir)/win32 -I$(top_srcdir) -I$(top_srcdir)/include -L$(TOP)
endif
XTCCFLAGS = -B$(TOP) -B$(top_srcdir)/win32 -I$(TOP) -I$(top_srcdir) -I$(top_srcdir)/include
TCC = $(TOP)/tcc $(TCCFLAGS)
RUN_TCC = $(NATIVE_DEFINES) -DONE_SOURCE -run $(top_srcdir)/tcc.c $(TCCFLAGS)
DISAS = objdump -d
# libtcc test
ifdef LIBTCC1
ifdef CONFIG_WIN32
LIBTCC1:=$(TOP)/win32/libtcc/libtcc.a
else
LIBTCC1:=$(TOP)/$(LIBTCC1)
endif
endif
all test : $(TESTS)
hello-exe: ../examples/ex1.c
@echo ------------ $@ ------------
$(TCC) $< -o hello$(EXESUF) || ($(TOP)/tcc -vv; exit 1) && ./hello$(EXESUF)
hello-cross: ../examples/ex1.c
@echo ------------ $@ ------------
for XTCC in $(PROGS_CROSS) ; \
do echo -n "Test of $$XTCC... "; \
out=$$($(TOP)/$$XTCC $(XTCCFLAGS) -c $< 2>&1); \
test $$? -ne 0 && { echo "Failed\n$$out\n" ; $(TOP)/$$XTCC -vv; exit 1; } ; \
echo "Success"; \
done
hello-run: ../examples/ex1.c
@echo ------------ $@ ------------
$(TCC) -run $<
libtest: libtcc_test$(EXESUF) $(LIBTCC1)
@echo ------------ $@ ------------
./libtcc_test$(EXESUF) $(TCCFLAGS)
libtcc_test$(EXESUF): libtcc_test.c $(top_builddir)/$(LIBTCC)
$(CC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) $(LIBS) $(LINK_LIBTCC) $(LDFLAGS) -I$(top_srcdir)
%-dir:
@echo ------------ $@ ------------
$(MAKE) -k -C $*
# test.ref - generate using cc
test.ref: tcctest.c
$(CC) -o tcctest.cc $< -I$(top_srcdir) $(CPPFLAGS) -w $(CFLAGS) $(NATIVE_DEFINES) -std=gnu99 -O0 -fno-omit-frame-pointer $(LDFLAGS)
./tcctest.cc > $@
# auto test
test1 test1b: tcctest.c test.ref
@echo ------------ $@ ------------
$(TCC) -run $< > test.out1
@diff -u test.ref test.out1 && echo "Auto Test OK"
# iterated test2 (compile tcc then compile tcctest.c !)
test2 test2b: tcctest.c test.ref
@echo ------------ $@ ------------
$(TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out2
@diff -u test.ref test.out2 && echo "Auto Test2 OK"
# iterated test3 (compile tcc then compile tcc then compile tcctest.c !)
test3 test3b: tcctest.c test.ref
@echo ------------ $@ ------------
$(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out3
@diff -u test.ref test.out3 && echo "Auto Test3 OK"
test%b : TCCFLAGS += -b
# binary output test
test4: tcctest.c test.ref
@echo ------------ $@ ------------
# object + link output
$(TCC) -c -o tcctest3.o $<
$(TCC) -o tcctest3 tcctest3.o
./tcctest3 > test3.out
@if diff -u test.ref test3.out ; then echo "Object Auto Test OK"; fi
# dynamic output
$(TCC) -o tcctest1 $<
./tcctest1 > test1.out
@if diff -u test.ref test1.out ; then echo "Dynamic Auto Test OK"; fi
# dynamic output + bound check
$(TCC) -b -o tcctest4 $<
./tcctest4 > test4.out
@if diff -u test.ref test4.out ; then echo "BCheck Auto Test OK"; fi
# static output
$(TCC) -static -o tcctest2 $<
./tcctest2 > test2.out
@if diff -u test.ref test2.out ; then echo "Static Auto Test OK"; fi
# memory and bound check auto test
BOUNDS_OK = 1 4 8 10 14
BOUNDS_FAIL= 2 5 7 9 11 12 13 15
btest: boundtest.c
@echo ------------ $@ ------------
@for i in $(BOUNDS_OK); do \
echo ; echo --- boundtest $$i ---; \
if $(TCC) -b -run $< $$i ; then \
echo succeeded as expected; \
else\
echo Failed positive test $$i ; exit 1 ; \
fi ;\
done ;\
for i in $(BOUNDS_FAIL); do \
echo ; echo --- boundtest $$i ---; \
if $(TCC) -b -run $< $$i ; then \
echo Failed negative test $$i ; exit 1 ;\
else\
echo failed as expected; \
fi ;\
done ;\
echo; echo Bound test OK
# speed test
speedtest: ex2 ex3
@echo ------------ $@ ------------
time ./ex2 1238 2 3 4 10 13 4
time $(TCC) -run $(top_srcdir)/examples/ex2.c 1238 2 3 4 10 13 4
time ./ex3 35
time $(TCC) -run $(top_srcdir)/examples/ex3.c 35
weaktest: tcctest.c test.ref
$(TCC) -c $< -o weaktest.tcc.o $(CPPFLAGS) $(CFLAGS)
$(CC) -c $< -o weaktest.cc.o -I. $(CPPFLAGS) -w $(CFLAGS)
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.cc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.cc.o.txt
diff weaktest.cc.o.txt weaktest.tcc.o.txt && echo "Weak Auto Test OK"
ex%: $(top_srcdir)/examples/ex%.c
$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
# tiny assembler testing
asmtest.ref: asmtest.S
$(CC) -m32 -Wa,-W -o asmtest.ref.o -c asmtest.S
objdump -D asmtest.ref.o > asmtest.ref
asmtest: asmtest.ref
@echo ------------ $@ ------------
$(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
# Check that code generated by libtcc is binary compatible with
# that generated by CC
abitest-cc$(EXESUF): abitest.c $(top_builddir)/$(LIBTCC)
$(CC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) $(LIBS) $(LINK_LIBTCC) $(LDFLAGS) -I$(top_srcdir)
abitest-tcc$(EXESUF): abitest.c libtcc.c
$(TCC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) -DONE_SOURCE $(LIBS) $(LDFLAGS) -I$(top_srcdir)
ABITESTS := abitest-cc$(EXESUF)
ifneq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
ABITESTS += abitest-tcc$(EXESUF)
endif
abitest: $(ABITESTS)
@echo ------------ $@ ------------
./abitest-cc$(EXESUF) $(TCCFLAGS)
if [ "$(CONFIG_arm_eabi)" != "yes" ]; then ./abitest-tcc$(EXESUF) $(TCCFLAGS); fi
vla_test$(EXESUF): vla_test.c
$(TCC) -o $@ $^ $(CPPFLAGS) $(CFLAGS)
vla_test-run: vla_test$(EXESUF)
@echo ------------ $@ ------------
./vla_test$(EXESUF)
# 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:
$(MAKE) -C tests2 $@
rm -vf *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.cc \
*-cc *-tcc *.exe \
hello libtcc_test vla_test tcctest[1234] ex? tcc_g
@@ -0,0 +1,673 @@
#include "libtcc.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#define EXIT_SUCCESS 0
#define EXIT_FAILURE (-1)
// 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 convetntion 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);
}
/*
* 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; \
} \
}
*/
#define RUN_TEST(t) \
if (!testname || (strcmp(#t, testname) == 0)) { \
printf(#t "... \n"); \
if (t() == 0) { \
printf("success\n"); \
} else { \
printf("failure\n"); \
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); currently broken on x86_64 */
/* RUN_TEST(ret_6plus2longlong_test); currently broken on x86_64 */
/* RUN_TEST(ret_mixed_test); currently broken on x86_64 */
/* RUN_TEST(ret_mixed2_test); currently broken on x86_64 */
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_struct_test);
RUN_TEST(arg_align_test);
return retval;
}
@@ -0,0 +1,611 @@
# 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 */
.align 16, 0x91 /* 0x91 tests the non-clever behaviour */
.skip 3
.skip 15, 0x90
.string "hello\0world"
/* some label tests */
movl %eax, %ebx
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, %dl
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)
mov %eax, 0x12(,%edx,2)
mov %cr3, %edx
mov %ecx, %cr3
movl %cr3, %eax
movl %tr3, %eax
movl %db3, %ebx
movl %dr6, %eax
movl %fs, %ecx
movl %ebx, %fs
movsbl 0x1000, %eax
movsbw 0x1000, %ax
movswl 0x1000, %eax
movzbl 0x1000, %eax
movzbw 0x1000, %ax
movzwl 0x1000, %eax
movzb 0x1000, %eax
movzb 0x1000, %ax
pushl %eax
pushw %ax
push %eax
push %cs
push %gs
push $1
push $100
popl %eax
popw %ax
pop %eax
pop %ds
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
les 0x2000, %eax
lds 0x2000, %ebx
lfs 0x2000, %ecx
lgs 0x2000, %edx
lss 0x2000, %edx
addl $0x123, %eax
add $0x123, %ebx
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)
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
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
call *%eax
call *0x1000
call func1
.global L5,L6
L5:
L6:
lcall $0x100, $0x1000
jmp 0x1000
jmp *%eax
jmp *0x1000
ljmp $0x100, $0x1000
ret
retl
ret $10
retl $10
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
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
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
int $3
int $0x10
pusha
popa
clc
cld
cli
clts
cmc
lahf
sahf
pushfl
popfl
pushf
popf
stc
std
sti
aaa
aas
daa
das
aad
aam
cbw
cwd
cwde
cdq
cbtw
cwtd
cwtl
cltd
leave
int3
into
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
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
boundl %edx, 0x10000
boundw %bx, 0x1000
arpl %bx, 0x1000
lar 0x1000, %eax
lgdt 0x1000
lidt 0x1000
lldt 0x1000
lmsw 0x1000
lsl 0x1000, %ecx
ltr 0x1000
sgdt 0x1000
sidt 0x1000
sldt 0x1000
smsw 0x1000
str 0x1000
verr 0x1000
verw 0x1000
push %ds
pushw %ds
pushl %ds
pop %ds
popw %ds
popl %ds
fxsave 1(%ebx)
fxrstor 1(%ecx)
pushl $1
pushw $1
push $1
#ifdef __ASSEMBLER__ // should be defined, for S files
inc %eax
#endif
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"
pause
@@ -0,0 +1,285 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define NB_ITS 1000000
//#define NB_ITS 1
#define TAB_SIZE 100
int tab[TAB_SIZE];
int ret_sum;
char tab3[256];
int test1(void)
{
int i, sum = 0;
for(i=0;i<TAB_SIZE;i++) {
sum += tab[i];
}
return sum;
}
/* error */
int test2(void)
{
int i, sum = 0;
for(i=0;i<TAB_SIZE + 1;i++) {
sum += tab[i];
}
return sum;
}
/* actually, profiling test */
int test3(void)
{
int sum;
int i, it;
sum = 0;
for(it=0;it<NB_ITS;it++) {
for(i=0;i<TAB_SIZE;i++) {
sum += tab[i];
}
}
return sum;
}
/* ok */
int test4(void)
{
int i, sum = 0;
int *tab4;
fprintf(stderr, "%s start\n", __FUNCTION__);
tab4 = malloc(20 * sizeof(int));
for(i=0;i<20;i++) {
sum += tab4[i];
}
free(tab4);
fprintf(stderr, "%s end\n", __FUNCTION__);
return sum;
}
/* error */
int test5(void)
{
int i, sum = 0;
int *tab4;
fprintf(stderr, "%s start\n", __FUNCTION__);
tab4 = malloc(20 * sizeof(int));
for(i=0;i<21;i++) {
sum += tab4[i];
}
free(tab4);
fprintf(stderr, "%s end\n", __FUNCTION__);
return sum;
}
/* error */
/* XXX: currently: bug */
int test6(void)
{
int i, sum = 0;
int *tab4;
tab4 = malloc(20 * sizeof(int));
free(tab4);
for(i=0;i<21;i++) {
sum += tab4[i];
}
return sum;
}
/* error */
int test7(void)
{
int i, sum = 0;
int *p;
for(i=0;i<TAB_SIZE + 1;i++) {
p = &tab[i];
if (i == TAB_SIZE)
printf("i=%d %x\n", i, p);
sum += *p;
}
return sum;
}
/* ok */
int test8(void)
{
int i, sum = 0;
int tab[10];
for(i=0;i<10;i++) {
sum += tab[i];
}
return sum;
}
/* error */
int test9(void)
{
int i, sum = 0;
char tab[10];
for(i=0;i<11;i++) {
sum += tab[i];
}
return sum;
}
/* ok */
int test10(void)
{
char tab[10];
char tab1[10];
memset(tab, 0, 10);
memcpy(tab, tab1, 10);
memmove(tab, tab1, 10);
return 0;
}
/* error */
int test11(void)
{
char tab[10];
memset(tab, 0, 11);
return 0;
}
/* error */
int test12(void)
{
void *ptr;
ptr = malloc(10);
free(ptr);
free(ptr);
return 0;
}
/* error */
int test13(void)
{
char pad1 = 0;
char tab[10];
char pad2 = 0;
memset(tab, 'a', sizeof(tab));
return strlen(tab);
}
int test14(void)
{
char *p = alloca(TAB_SIZE);
memset(p, 'a', TAB_SIZE);
p[TAB_SIZE-1] = 0;
return strlen(p);
}
/* error */
int test15(void)
{
char *p = alloca(TAB_SIZE-1);
memset(p, 'a', TAB_SIZE);
p[TAB_SIZE-1] = 0;
return strlen(p);
}
/* ok */
int test16()
{
char *demo = "This is only a test.";
char *p;
fprintf(stderr, "%s start\n", __FUNCTION__);
p = alloca(16);
strcpy(p,"12345678901234");
printf("alloca: p is %s\n", p);
/* Test alloca embedded in a larger expression */
printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
fprintf(stderr, "%s end\n", __FUNCTION__);
}
/* error */
int test17()
{
char *demo = "This is only a test.";
char *p;
fprintf(stderr, "%s start\n", __FUNCTION__);
p = alloca(16);
strcpy(p,"12345678901234");
printf("alloca: p is %s\n", p);
/* Test alloca embedded in a larger expression */
printf("alloca: %s\n", strcpy(alloca(strlen(demo)),demo) );
fprintf(stderr, "%s end\n", __FUNCTION__);
}
int (*table_test[])(void) = {
test1,
test2,
test3,
test4,
test5,
test6,
test7,
test8,
test9,
test10,
test11,
test12,
test13,
test14,
test15,
test16,
test17,
};
int main(int argc, char **argv)
{
int index;
int (*ftest)(void);
int index_max = sizeof(table_test)/sizeof(table_test[0]);
if (argc < 2) {
printf(
"test TCC bound checking system\n"
"usage: boundtest N\n"
" 1 <= N <= %d\n", index_max);
exit(1);
}
index = 0;
if (argc >= 2)
index = atoi(argv[1]) - 1;
if ((index < 0) || (index >= index_max)) {
printf("N is outside of the valid range (%d)\n", index);
exit(2);
}
/* well, we also use bounds on this ! */
ftest = table_test[index];
ftest();
return 0;
}
/*
* without bound 0.77 s
* with bounds 4.73
*/
@@ -0,0 +1,33 @@
#!/bin/sh
TESTSUITE_PATH=$HOME/gcc/gcc-3.2/gcc/testsuite/gcc.c-torture
TCC="./tcc -B. -I. -DNO_TRAMPOLINES"
rm -f tcc.sum tcc.log
nb_failed="0"
for src in $TESTSUITE_PATH/compile/*.c ; do
echo $TCC -o /tmp/test.o -c $src
$TCC -o /tmp/test.o -c $src >> tcc.log 2>&1
if [ "$?" = "0" ] ; then
result="PASS"
else
result="FAIL"
nb_failed=$(( $nb_failed + 1 ))
fi
echo "$result: $src" >> tcc.sum
done
for src in $TESTSUITE_PATH/execute/*.c ; do
echo $TCC $src
$TCC $src >> tcc.log 2>&1
if [ "$?" = "0" ] ; then
result="PASS"
else
result="FAIL"
nb_failed=$(( $nb_failed + 1 ))
fi
echo "$result: $src" >> tcc.sum
done
echo "$nb_failed test(s) failed." >> tcc.sum
echo "$nb_failed test(s) failed."
@@ -0,0 +1,88 @@
/*
* Simple Test program for libtcc
*
* libtcc can be useful to use tcc as a "backend" for a code generator.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libtcc.h"
/* this function is called by the generated code */
int add(int a, int b)
{
return a + b;
}
char my_program[] =
"#include <tcclib.h>\n" /* include the "Simple libc header for TCC" */
"extern int add(int a, int b);\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(\"Hello World!\\n\");\n"
" printf(\"fib(%d) = %d\\n\", n, fib(n));\n"
" printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n"
" return 0;\n"
"}\n";
int main(int argc, char **argv)
{
TCCState *s;
int i;
int (*func)(int);
s = tcc_new();
if (!s) {
fprintf(stderr, "Could not create tcc state\n");
exit(1);
}
/* if tcclib.h and libtcc1.a are not installed, where can we find them */
for (i = 1; i < argc; ++i) {
char *a = argv[i];
if (a[0] == '-') {
if (a[1] == 'B')
tcc_set_lib_path(s, a+2);
else if (a[1] == 'I')
tcc_add_include_path(s, a+2);
else if (a[1] == 'L')
tcc_add_library_path(s, a+2);
}
}
/* MUST BE CALLED before any compilation */
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
if (tcc_compile_string(s, my_program) == -1)
return 1;
/* as a test, we add a symbol 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);
/* 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;
}
@@ -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";
@@ -0,0 +1 @@
char p[] = "x ## y";
@@ -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
@@ -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);
@@ -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)
@@ -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"
@@ -0,0 +1,4 @@
#define foobar 1
#define C(x,y) x##y
#define D(x) (C(x,bar))
D(foo)
@@ -0,0 +1 @@
(1)
@@ -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)
@@ -0,0 +1,3 @@
int j[] = { 123, 45, 67, 89,
10, 11, 12, };
int j[] = { 123, 45, 67, 89, 10, 11, 12, };
@@ -0,0 +1,5 @@
#define X(a,b, \
c,d) \
foo
X(1,2,3,4)
@@ -0,0 +1 @@
foo
@@ -0,0 +1,4 @@
#define a() YES
#define b() a
b()
b()()
@@ -0,0 +1,2 @@
a
YES
@@ -0,0 +1,4 @@
// test macro expansion in arguments
#define s_pos s_s.s_pos
#define foo(x) (x)
foo(hej.s_pos)
@@ -0,0 +1 @@
(hej.s_s.s_pos)
@@ -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)
@@ -0,0 +1 @@
aaaaoooo
@@ -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))))
@@ -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))))
@@ -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() ())
@@ -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
@@ -0,0 +1,8 @@
#define SRC(y...) \
9999: y; \
.section __ex_table, "a"; \
.long 9999b, 6001f ; \
// .previous
SRC(1: movw (%esi), %bx)
6001:
@@ -0,0 +1,2 @@
9999: 1: movw (%esi), %bx; .section __ex_table, "a"; .long 9999b, 6001f ;
6001:
@@ -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:
@@ -0,0 +1,6 @@
# `modelist' label. Each video mode record looks like:
.text
endtext:
@@ -0,0 +1,45 @@
#
# credits: 01..13.c from the pcc cpp-tests suite
#
TCC = ../../tcc
TESTS = $(patsubst %.c,%.test,$(wildcard *.c))
TESTS += $(patsubst %.S,%.test,$(wildcard *.S))
all test : $(TESTS)
%.test: %.c %.expect
@echo PPTest $* ...
@$(TCC) -E -P $< >$*.output 2>&1 ; \
diff -Nu -b -B -I "^#" $(EXTRA_DIFF_OPTS) $*.expect $*.output \
&& rm -f $*.output
%.test: %.S %.expect
@echo PPTest $* ...
@$(TCC) -E -P $< >$*.output 2>&1 ; \
diff -Nu -b -B -I "^#" $(EXTRA_DIFF_OPTS) $*.expect $*.output \
&& rm -f $*.output
# automatically generate .expect files with gcc:
%.expect: %.c
gcc -E -P $*.c >$*.expect 2>&1
%.expect: %.S
gcc -E -P $*.S >$*.expect 2>&1
# tell make not to delete
.PRECIOUS: %.expect
clean:
rm -vf *.output
# 02.test : EXTRA_DIFF_OPTS = -w
# 03.test : EXTRA_DIFF_OPTS = -w
# 04.test : EXTRA_DIFF_OPTS = -w
# 10.test : EXTRA_DIFF_OPTS = -w
# diff options:
# -b ighore space changes
# -w ighore all whitespace
# -B ignore blank lines
# -I <RE> ignore lines matching RE
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,15 @@
import subprocess
import sys
import difflib
def main():
reference = subprocess.check_output([sys.argv[1]])
compare = subprocess.check_output(sys.argv[2:])
failed = False
for line in difflib.unified_diff(reference.split('\n'), compare.split('\n'), fromfile='cc', tofile='tcc', lineterm=''):
failed = True
print line
sys.exit(1 if failed else 0)
if __name__ == '__main__':
main()
@@ -0,0 +1,9 @@
#include<stdio.h>
int main() {
int t1 = 176401255;
float f = 0.25f;
int t2a = (int)(t1 * f); // must be 44100313
int t2b = (int)(t1 * (float)0.25f);
printf("t2a=%d t2b=%d \n",t2a,t2b);
return 0;
}
@@ -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 :
@@ -0,0 +1,3 @@
42
64
12, 34
@@ -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 :
@@ -0,0 +1,5 @@
Hello
Hello
Hello
Hello
Hello
@@ -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 :
@@ -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'
@@ -0,0 +1,31 @@
#include <stdio.h>
struct fred
{
int boris;
int natasha;
};
int main()
{
struct fred bloggs;
bloggs.boris = 12;
bloggs.natasha = 34;
printf("%d\n", bloggs.boris);
printf("%d\n", bloggs.natasha);
struct fred jones[2];
jones[0].boris = 12;
jones[0].natasha = 34;
jones[1].boris = 56;
jones[1].natasha = 78;
printf("%d\n", jones[0].boris);
printf("%d\n", jones[0].natasha);
printf("%d\n", jones[1].boris);
printf("%d\n", jones[1].natasha);
return 0;
}
@@ -0,0 +1,6 @@
12
34
12
34
56
78
@@ -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 :
@@ -0,0 +1,10 @@
1
2
3
4
5
6
7
8
9
10
@@ -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 :
@@ -0,0 +1,10 @@
1
4
9
16
25
36
49
64
81
100
@@ -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 :
@@ -0,0 +1,8 @@
0
0
1
1
2
2
3
0
@@ -0,0 +1,30 @@
#include <stdio.h>
int myfunc(int x)
{
return x * x;
}
void vfunc(int a)
{
printf("a=%d\n", a);
}
void qfunc()
{
printf("qfunc()\n");
}
int main()
{
printf("%d\n", myfunc(3));
printf("%d\n", myfunc(4));
vfunc(1234);
qfunc();
return 0;
}
// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
@@ -0,0 +1,4 @@
9
16
a=1234
qfunc()
@@ -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 :
@@ -0,0 +1,11 @@
1
1
2
3
5
8
13
21
34
55
89
@@ -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 :
@@ -0,0 +1,11 @@
1
1
2
3
5
8
13
21
34
55
89
@@ -0,0 +1,40 @@
#include <stdio.h>
struct ziggy
{
int a;
int b;
int c;
} bolshevic;
int main()
{
int a;
int *b;
int c;
a = 42;
b = &a;
printf("a = %d\n", *b);
bolshevic.a = 12;
bolshevic.b = 34;
bolshevic.c = 56;
printf("bolshevic.a = %d\n", bolshevic.a);
printf("bolshevic.b = %d\n", bolshevic.b);
printf("bolshevic.c = %d\n", bolshevic.c);
struct ziggy *tsar = &bolshevic;
printf("tsar->a = %d\n", tsar->a);
printf("tsar->b = %d\n", tsar->b);
printf("tsar->c = %d\n", tsar->c);
b = &(bolshevic.b);
printf("bolshevic.b = %d\n", *b);
return 0;
}
// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
@@ -0,0 +1,8 @@
a = 42
bolshevic.a = 12
bolshevic.b = 34
bolshevic.c = 56
tsar->a = 12
tsar->b = 34
tsar->c = 56
bolshevic.b = 34
@@ -0,0 +1,40 @@
#include <stdio.h>
int main()
{
int a;
int b;
int c;
int d;
int e;
int f;
int x;
int y;
a = 12;
b = 34;
c = 56;
d = 78;
e = 0;
f = 1;
printf("%d\n", c + d);
printf("%d\n", (y = c + d));
printf("%d\n", e || e && f);
printf("%d\n", e || f && f);
printf("%d\n", e && e || f);
printf("%d\n", e && f || f);
printf("%d\n", a && f | f);
printf("%d\n", a | b ^ c & d);
printf("%d, %d\n", a == a, a == b);
printf("%d, %d\n", a != a, a != b);
printf("%d\n", a != b && c != d);
printf("%d\n", a + b * c / f);
printf("%d\n", a + b * c / f);
printf("%d\n", (4 << 4));
printf("%d\n", (64 >> 4));
return 0;
}
// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
@@ -0,0 +1,15 @@
134
134
0
1
1
1
1
46
1, 0
0, 1
1
1916
1916
64
4
@@ -0,0 +1,14 @@
#include <stdio.h>
#define FRED 12
#define BLOGGS(x) (12*(x))
int main()
{
printf("%d\n", FRED);
printf("%d, %d, %d\n", BLOGGS(1), BLOGGS(2), BLOGGS(3));
return 0;
}
// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
@@ -0,0 +1,2 @@
12
12, 24, 36
@@ -0,0 +1,20 @@
#include <stdio.h>
int main()
{
int a = 24680;
int b = 01234567;
int c = 0x2468ac;
int d = 0x2468AC;
int e = 0b010101010101;
printf("%d\n", a);
printf("%d\n", b);
printf("%d\n", c);
printf("%d\n", d);
printf("%d\n", e);
return 0;
}
// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
@@ -0,0 +1,5 @@
24680
342391
2386092
2386092
1365
@@ -0,0 +1,21 @@
#include <stdio.h>
int main()
{
int a = 1;
if (a)
printf("a is true\n");
else
printf("a is false\n");
int b = 0;
if (b)
printf("b is true\n");
else
printf("b is false\n");
return 0;
}
// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
@@ -0,0 +1,2 @@
a is true
b is false
@@ -0,0 +1,21 @@
#include <stdio.h>
int factorial(int i)
{
if (i < 2)
return i;
else
return i * factorial(i - 1);
}
int main()
{
int Count;
for (Count = 1; Count <= 10; Count++)
printf("%d\n", factorial(Count));
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,10 @@
1
2
6
24
120
720
5040
40320
362880
3628800
@@ -0,0 +1,21 @@
#include <stdio.h>
int main()
{
int x, y, z;
for (x = 0; x < 2; x++)
{
for (y = 0; y < 3; y++)
{
for (z = 0; z < 3; z++)
{
printf("%d %d %d\n", x, y, z);
}
}
}
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,18 @@
0 0 0
0 0 1
0 0 2
0 1 0
0 1 1
0 1 2
0 2 0
0 2 1
0 2 2
1 0 0
1 0 1
1 0 2
1 1 0
1 1 1
1 1 2
1 2 0
1 2 1
1 2 2
@@ -0,0 +1,29 @@
#include <stdio.h>
enum fred
{
a,
b,
c,
d,
e = 54,
f = 73,
g,
h
};
int main()
{
enum fred frod;
printf("%d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h);
/* printf("%d\n", frod); */
frod = 12;
printf("%d\n", frod);
frod = e;
printf("%d\n", frod);
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,3 @@
0 1 2 3 54 73 74 75
12
54
@@ -0,0 +1,12 @@
#include <stdio.h>
int main()
{
printf("including\n");
#include "18_include.h"
printf("done\n");
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,3 @@
including
included
done
@@ -0,0 +1 @@
printf("included\n");
@@ -0,0 +1,28 @@
#include <stdio.h>
int main()
{
int a;
int *b;
int *c;
a = 42;
b = &a;
c = NULL;
printf("%d\n", *b);
if (b == NULL)
printf("b is NULL\n");
else
printf("b is not NULL\n");
if (c == NULL)
printf("c is NULL\n");
else
printf("c is not NULL\n");
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,3 @@
42
b is not NULL
c is NULL
@@ -0,0 +1,24 @@
#include <stdio.h>
int main()
{
int a;
int b;
int *d;
int *e;
d = &a;
e = &b;
a = 12;
b = 34;
printf("%d\n", *d);
printf("%d\n", *e);
printf("%d\n", d == e);
printf("%d\n", d != e);
d = e;
printf("%d\n", d == e);
printf("%d\n", d != e);
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,6 @@
12
34
0
1
1
0
@@ -0,0 +1,33 @@
#include <stdio.h>
int main()
{
int x = 'a';
char y = x;
char *a = "hello";
printf("%s\n", a);
int c;
c = *a;
char *b;
for (b = a; *b != 0; b++)
printf("%c: %d\n", *b, *b);
char destarray[10];
char *dest = &destarray[0];
char *src = a;
while (*src != 0)
*dest++ = *src++;
*dest = 0;
printf("copied string is %s\n", destarray);
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,7 @@
hello
h: 104
e: 101
l: 108
l: 108
o: 111
copied string is hello
@@ -0,0 +1,50 @@
#include <stdio.h>
#include <math.h>
int main()
{
// variables
float a = 12.34 + 56.78;
printf("%f\n", a);
// infix operators
printf("%f\n", 12.34 + 56.78);
printf("%f\n", 12.34 - 56.78);
printf("%f\n", 12.34 * 56.78);
printf("%f\n", 12.34 / 56.78);
// comparison operators
printf("%d %d %d %d %d %d\n", 12.34 < 56.78, 12.34 <= 56.78, 12.34 == 56.78, 12.34 >= 56.78, 12.34 > 56.78, 12.34 != 56.78);
printf("%d %d %d %d %d %d\n", 12.34 < 12.34, 12.34 <= 12.34, 12.34 == 12.34, 12.34 >= 12.34, 12.34 > 12.34, 12.34 != 12.34);
printf("%d %d %d %d %d %d\n", 56.78 < 12.34, 56.78 <= 12.34, 56.78 == 12.34, 56.78 >= 12.34, 56.78 > 12.34, 56.78 != 12.34);
// assignment operators
a = 12.34;
a += 56.78;
printf("%f\n", a);
a = 12.34;
a -= 56.78;
printf("%f\n", a);
a = 12.34;
a *= 56.78;
printf("%f\n", a);
a = 12.34;
a /= 56.78;
printf("%f\n", a);
// prefix operators
printf("%f\n", +12.34);
printf("%f\n", -12.34);
// type coercion
a = 2;
printf("%f\n", a);
printf("%f\n", sin(2));
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,16 @@
69.120003
69.120000
-44.440000
700.665200
0.217330
1 1 0 0 0 1
0 1 1 1 0 0
0 0 0 1 1 1
69.120003
-44.439999
700.665222
0.217330
12.340000
-12.340000
2.000000
0.909297
@@ -0,0 +1,54 @@
#include <stdio.h>
void charfunc(char a)
{
printf("char: %c\n", a);
}
void intfunc(int a)
{
printf("int: %d\n", a);
}
void floatfunc(float a)
{
printf("float: %f\n", a);
}
int main()
{
charfunc('a');
charfunc(98);
charfunc(99.0);
intfunc('a');
intfunc(98);
intfunc(99.0);
floatfunc('a');
floatfunc(98);
floatfunc(99.0);
/* printf("%c %d %f\n", 'a', 'b', 'c'); */
/* printf("%c %d %f\n", 97, 98, 99); */
/* printf("%c %d %f\n", 97.0, 98.0, 99.0); */
char b = 97;
char c = 97.0;
printf("%d %d\n", b, c);
int d = 'a';
int e = 97.0;
printf("%d %d\n", d, e);
float f = 'a';
float g = 97;
printf("%f %f\n", f, g);
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,12 @@
char: a
char: b
char: c
int: 97
int: 98
int: 99
float: 97.000000
float: 98.000000
float: 99.000000
97 97
97 97
97.000000 97.000000
@@ -0,0 +1,30 @@
#define _ISOC99_SOURCE 1
#include <stdio.h>
#include <math.h>
int main()
{
printf("%f\n", sin(0.12));
printf("%f\n", cos(0.12));
printf("%f\n", tan(0.12));
printf("%f\n", asin(0.12));
printf("%f\n", acos(0.12));
printf("%f\n", atan(0.12));
printf("%f\n", sinh(0.12));
printf("%f\n", cosh(0.12));
printf("%f\n", tanh(0.12));
printf("%f\n", exp(0.12));
printf("%f\n", fabs(-0.12));
printf("%f\n", log(0.12));
printf("%f\n", log10(0.12));
printf("%f\n", pow(0.12, 0.12));
printf("%f\n", sqrt(0.12));
printf("%f\n", round(12.34));
printf("%f\n", ceil(12.34));
printf("%f\n", floor(12.34));
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,18 @@
0.119712
0.992809
0.120579
0.120290
1.450506
0.119429
0.120288
1.007209
0.119427
1.127497
0.120000
-2.120264
-0.920819
0.775357
0.346410
12.000000
13.000000
12.000000
@@ -0,0 +1,83 @@
#include <stdio.h>
int array[16];
//Swap integer values by array indexes
void swap(int a, int b)
{
int tmp = array[a];
array[a] = array[b];
array[b] = tmp;
}
//Partition the array into two halves and return the
//index about which the array is partitioned
int partition(int left, int right)
{
int pivotIndex = left;
int pivotValue = array[pivotIndex];
int index = left;
int i;
swap(pivotIndex, right);
for(i = left; i < right; i++)
{
if(array[i] < pivotValue)
{
swap(i, index);
index += 1;
}
}
swap(right, index);
return index;
}
//Quicksort the array
void quicksort(int left, int right)
{
if(left >= right)
return;
int index = partition(left, right);
quicksort(left, index - 1);
quicksort(index + 1, right);
}
int main()
{
int i;
array[0] = 62;
array[1] = 83;
array[2] = 4;
array[3] = 89;
array[4] = 36;
array[5] = 21;
array[6] = 74;
array[7] = 37;
array[8] = 65;
array[9] = 33;
array[10] = 96;
array[11] = 38;
array[12] = 53;
array[13] = 16;
array[14] = 74;
array[15] = 55;
for (i = 0; i < 16; i++)
printf("%d ", array[i]);
printf("\n");
quicksort(0, 15);
for (i = 0; i < 16; i++)
printf("%d ", array[i]);
printf("\n");
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,2 @@
62 83 4 89 36 21 74 37 65 33 96 38 53 16 74 55
4 16 21 33 36 37 38 53 55 62 65 74 74 83 89 96
@@ -0,0 +1,17 @@
#include <stdio.h>
int main()
{
printf("%d\n", '\1');
printf("%d\n", '\10');
printf("%d\n", '\100');
printf("%d\n", '\x01');
printf("%d\n", '\x0e');
printf("%d\n", '\x10');
printf("%d\n", '\x40');
printf("test \x40\n");
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,8 @@
1
8
64
1
14
16
64
test @
@@ -0,0 +1,18 @@
#include <stdio.h>
int main()
{
char a;
int b;
double c;
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(b));
printf("%d\n", sizeof(c));
printf("%d\n", sizeof(!a));
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,4 @@
1
4
8
4
@@ -0,0 +1,48 @@
#include <stdio.h>
#include <string.h>
//#include <strings.h>
#define index(a,b) strchr(a,b)
#define rindex(a,b) strrchr(a,b)
int main()
{
char a[10];
strcpy(a, "hello");
printf("%s\n", a);
strncpy(a, "gosh", 2);
printf("%s\n", a);
printf("%d\n", strcmp(a, "apple") > 0);
printf("%d\n", strcmp(a, "goere") > 0);
printf("%d\n", strcmp(a, "zebra") < 0);
printf("%d\n", strlen(a));
strcat(a, "!");
printf("%s\n", a);
printf("%d\n", strncmp(a, "apple", 2) > 0);
printf("%d\n", strncmp(a, "goere", 2) == 0);
printf("%d\n", strncmp(a, "goerg", 2) == 0);
printf("%d\n", strncmp(a, "zebra", 2) < 0);
printf("%s\n", index(a, 'o'));
printf("%s\n", rindex(a, 'l'));
printf("%d\n", rindex(a, 'x') == NULL);
memset(&a[1], 'r', 4);
printf("%s\n", a);
memcpy(&a[2], a, 2);
printf("%s\n", a);
printf("%d\n", memcmp(a, "apple", 4) > 0);
printf("%d\n", memcmp(a, "grgr", 4) == 0);
printf("%d\n", memcmp(a, "zebra", 4) < 0);
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,19 @@
hello
gollo
1
1
1
5
gollo!
1
1
1
1
ollo!
lo!
1
grrrr!
grgrr!
1
1
1
@@ -0,0 +1,13 @@
#include <stdio.h>
#include <string.h>
int main()
{
char a[10];
strcpy(a, "abcdef");
printf("%s\n", &a[1]);
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,122 @@
/* example from http://barnyard.syr.edu/quickies/hanoi.c */
/* hanoi.c: solves the tower of hanoi problem. (Programming exercise.) */
/* By Terry R. McConnell (12/2/97) */
/* Compile: cc -o hanoi hanoi.c */
/* This program does no error checking. But then, if it's right,
it's right ... right ? */
/* The original towers of hanoi problem seems to have been originally posed
by one M. Claus in 1883. There is a popular legend that goes along with
it that has been often repeated and paraphrased. It goes something like this:
In the great temple at Benares there are 3 golden spikes. On one of them,
God placed 64 disks increasing in size from bottom to top, at the beginning
of time. Since then, and to this day, the priest on duty constantly transfers
disks, one at a time, in such a way that no larger disk is ever put on top
of a smaller one. When the disks have been transferred entirely to another
spike the Universe will come to an end in a large thunderclap.
This paraphrases the original legend due to DeParville, La Nature, Paris 1884,
Part I, 285-286. For this and further information see: Mathematical
Recreations & Essays, W.W. Rouse Ball, MacMillan, NewYork, 11th Ed. 1967,
303-305.
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
/* This is the number of "disks" on tower A initially. Taken to be 64 in the
* legend. The number of moves required, in general, is 2^N - 1. For N = 64,
* this is 18,446,744,073,709,551,615 */
#define N 4
/* These are the three towers. For example if the state of A is 0,1,3,4, that
* means that there are three discs on A of sizes 1, 3, and 4. (Think of right
* as being the "down" direction.) */
int A[N], B[N], C[N];
void Hanoi(int,int*,int*,int*);
/* Print the current configuration of A, B, and C to the screen */
void PrintAll()
{
int i;
printf("A: ");
for(i=0;i<N;i++)printf(" %d ",A[i]);
printf("\n");
printf("B: ");
for(i=0;i<N;i++)printf(" %d ",B[i]);
printf("\n");
printf("C: ");
for(i=0;i<N;i++)printf(" %d ",C[i]);
printf("\n");
printf("------------------------------------------\n");
return;
}
/* Move the leftmost nonzero element of source to dest, leave behind 0. */
/* Returns the value moved (not used.) */
int Move(int *source, int *dest)
{
int i = 0, j = 0;
while (i<N && (source[i])==0) i++;
while (j<N && (dest[j])==0) j++;
dest[j-1] = source[i];
source[i] = 0;
PrintAll(); /* Print configuration after each move. */
return dest[j-1];
}
/* Moves first n nonzero numbers from source to dest using the rules of Hanoi.
Calls itself recursively.
*/
void Hanoi(int n,int *source, int *dest, int *spare)
{
int i;
if(n==1){
Move(source,dest);
return;
}
Hanoi(n-1,source,spare,dest);
Move(source,dest);
Hanoi(n-1,spare,dest,source);
return;
}
int main()
{
int i;
/* initialize the towers */
for(i=0;i<N;i++)A[i]=i+1;
for(i=0;i<N;i++)B[i]=0;
for(i=0;i<N;i++)C[i]=0;
printf("Solution of Tower of Hanoi Problem with %d Disks\n\n",N);
/* Print the starting state */
printf("Starting state:\n");
PrintAll();
printf("\n\nSubsequent states:\n\n");
/* Do it! Use A = Source, B = Destination, C = Spare */
Hanoi(N,A,B,C);
return 0;
}
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
@@ -0,0 +1,71 @@
Solution of Tower of Hanoi Problem with 4 Disks
Starting state:
A: 1 2 3 4
B: 0 0 0 0
C: 0 0 0 0
------------------------------------------
Subsequent states:
A: 0 2 3 4
B: 0 0 0 0
C: 0 0 0 1
------------------------------------------
A: 0 0 3 4
B: 0 0 0 2
C: 0 0 0 1
------------------------------------------
A: 0 0 3 4
B: 0 0 1 2
C: 0 0 0 0
------------------------------------------
A: 0 0 0 4
B: 0 0 1 2
C: 0 0 0 3
------------------------------------------
A: 0 0 1 4
B: 0 0 0 2
C: 0 0 0 3
------------------------------------------
A: 0 0 1 4
B: 0 0 0 0
C: 0 0 2 3
------------------------------------------
A: 0 0 0 4
B: 0 0 0 0
C: 0 1 2 3
------------------------------------------
A: 0 0 0 0
B: 0 0 0 4
C: 0 1 2 3
------------------------------------------
A: 0 0 0 0
B: 0 0 1 4
C: 0 0 2 3
------------------------------------------
A: 0 0 0 2
B: 0 0 1 4
C: 0 0 0 3
------------------------------------------
A: 0 0 1 2
B: 0 0 0 4
C: 0 0 0 3
------------------------------------------
A: 0 0 1 2
B: 0 0 3 4
C: 0 0 0 0
------------------------------------------
A: 0 0 0 2
B: 0 0 3 4
C: 0 0 0 1
------------------------------------------
A: 0 0 0 0
B: 0 2 3 4
C: 0 0 0 1
------------------------------------------
A: 0 0 0 0
B: 1 2 3 4
C: 0 0 0 0
------------------------------------------

Some files were not shown because too many files have changed in this diff Show More