aboutsummaryrefslogtreecommitdiffstats
path: root/test/kvx
diff options
context:
space:
mode:
authorDavid Monniaux <david.monniaux@univ-grenoble-alpes.fr>2020-05-26 22:11:32 +0200
committerDavid Monniaux <david.monniaux@univ-grenoble-alpes.fr>2020-05-26 22:11:32 +0200
commitbc1e43ea95b9455cdccee442db77bc5fafd3dcc6 (patch)
tree4e82b5f50870603f42ec46d57e543c3e10fb1f4f /test/kvx
parentb4a08d0815342b6238d307864f0823d0f07bb691 (diff)
downloadcompcert-kvx-bc1e43ea95b9455cdccee442db77bc5fafd3dcc6.tar.gz
compcert-kvx-bc1e43ea95b9455cdccee442db77bc5fafd3dcc6.zip
tests for kvx
Diffstat (limited to 'test/kvx')
-rw-r--r--test/kvx/.gitignore20
-rw-r--r--test/kvx/builtins/clzll.c7
-rw-r--r--test/kvx/builtins/stsud.c7
-rwxr-xr-xtest/kvx/coverage.sh24
-rw-r--r--test/kvx/coverage_helper.py45
-rwxr-xr-xtest/kvx/delout.sh6
-rw-r--r--test/kvx/do_test.sh50
-rw-r--r--test/kvx/general/clzd.c7
-rw-r--r--test/kvx/general/clzw.c7
-rw-r--r--test/kvx/general/ctzd.c7
-rw-r--r--test/kvx/general/ctzw.c7
-rw-r--r--test/kvx/general/satd.c7
-rw-r--r--test/kvx/general/sbmm8.c7
-rw-r--r--test/kvx/general/sbmmt8.c7
-rwxr-xr-xtest/kvx/hardcheck.sh6
-rwxr-xr-xtest/kvx/hardtest.sh6
-rw-r--r--test/kvx/instr/.gitignore1
-rw-r--r--test/kvx/instr/Makefile176
-rw-r--r--test/kvx/instr/builtin32.c12
-rw-r--r--test/kvx/instr/builtin64.c17
-rw-r--r--test/kvx/instr/div32.c5
-rw-r--r--test/kvx/instr/divf32.c5
-rw-r--r--test/kvx/instr/divf64.c5
-rw-r--r--test/kvx/instr/divu32.c7
-rw-r--r--test/kvx/instr/f32.c8
-rw-r--r--test/kvx/instr/f64.c8
-rwxr-xr-xtest/kvx/instr/floatcmp.py93
-rw-r--r--test/kvx/instr/framework.h66
-rw-r--r--test/kvx/instr/i32.c149
-rw-r--r--test/kvx/instr/i64.c169
-rw-r--r--test/kvx/instr/individual/andw.c5
-rw-r--r--test/kvx/instr/individual/branch.c10
-rw-r--r--test/kvx/instr/individual/branchz.c10
-rw-r--r--test/kvx/instr/individual/branchzu.c11
-rw-r--r--test/kvx/instr/individual/call.c16
-rw-r--r--test/kvx/instr/individual/cast_S32_S64.c7
-rw-r--r--test/kvx/instr/individual/cast_S64_U32.c7
-rw-r--r--test/kvx/instr/individual/cb.deqz.c10
-rw-r--r--test/kvx/instr/individual/cb.dgez.c10
-rw-r--r--test/kvx/instr/individual/cb.dgtz.c10
-rw-r--r--test/kvx/instr/individual/cb.dlez.c10
-rw-r--r--test/kvx/instr/individual/cb.dltz.c10
-rw-r--r--test/kvx/instr/individual/cb.dnez.c10
-rw-r--r--test/kvx/instr/individual/cb.wgez.c10
-rw-r--r--test/kvx/instr/individual/cb.wgtz.c10
-rw-r--r--test/kvx/instr/individual/cb.wlez.c10
-rw-r--r--test/kvx/instr/individual/cb.wltz.c10
-rw-r--r--test/kvx/instr/individual/compd.eq.c7
-rw-r--r--test/kvx/instr/individual/compd.geu.c7
-rw-r--r--test/kvx/instr/individual/compd.gt.c7
-rw-r--r--test/kvx/instr/individual/compd.le.c7
-rw-r--r--test/kvx/instr/individual/compd.leu.c7
-rw-r--r--test/kvx/instr/individual/compd.lt.c7
-rw-r--r--test/kvx/instr/individual/compd.ltu.c7
-rw-r--r--test/kvx/instr/individual/compd.ne.c7
-rw-r--r--test/kvx/instr/individual/compw.eq.c7
-rw-r--r--test/kvx/instr/individual/compw.geu.c7
-rw-r--r--test/kvx/instr/individual/compw.gt.c7
-rw-r--r--test/kvx/instr/individual/compw.gtu.c7
-rw-r--r--test/kvx/instr/individual/compw.le.c7
-rw-r--r--test/kvx/instr/individual/compw.leu.c7
-rw-r--r--test/kvx/instr/individual/compw.lt.c7
-rw-r--r--test/kvx/instr/individual/compw.ltu.c7
-rw-r--r--test/kvx/instr/individual/compw.ne.c7
-rw-r--r--test/kvx/instr/individual/div2.c7
-rw-r--r--test/kvx/instr/individual/doubleconv.c9
-rw-r--r--test/kvx/instr/individual/floatconv.c9
-rw-r--r--test/kvx/instr/individual/fmuld.c7
-rw-r--r--test/kvx/instr/individual/fmulw.c7
-rw-r--r--test/kvx/instr/individual/fnegd.c7
-rw-r--r--test/kvx/instr/individual/fnegw.c7
-rw-r--r--test/kvx/instr/individual/for.c9
-rw-r--r--test/kvx/instr/individual/forvar.c9
-rw-r--r--test/kvx/instr/individual/forvarl.c10
-rw-r--r--test/kvx/instr/individual/fsbfd.c7
-rw-r--r--test/kvx/instr/individual/fsbfw.c7
-rw-r--r--test/kvx/instr/individual/indirect_call.c33
-rw-r--r--test/kvx/instr/individual/indirect_tailcall.c33
-rw-r--r--test/kvx/instr/individual/lbs.c9
-rw-r--r--test/kvx/instr/individual/lbz.c9
-rw-r--r--test/kvx/instr/individual/muld.c7
-rw-r--r--test/kvx/instr/individual/mulw.c7
-rw-r--r--test/kvx/instr/individual/negd.c7
-rw-r--r--test/kvx/instr/individual/ord.c7
-rw-r--r--test/kvx/instr/individual/sbfd.c7
-rw-r--r--test/kvx/instr/individual/sbfw.c7
-rw-r--r--test/kvx/instr/individual/simple.c7
-rw-r--r--test/kvx/instr/individual/sllw.c7
-rw-r--r--test/kvx/instr/individual/srad.c7
-rw-r--r--test/kvx/instr/individual/srld.c7
-rw-r--r--test/kvx/instr/individual/tailcall.c16
-rw-r--r--test/kvx/instr/individual/udivd.c7
-rw-r--r--test/kvx/instr/individual/umodd.c7
-rw-r--r--test/kvx/instr/individual/xord.c7
-rw-r--r--test/kvx/instr/modi32.c5
-rw-r--r--test/kvx/instr/modui32.c7
-rw-r--r--test/kvx/instr/ui32.c12
-rw-r--r--test/kvx/instr/ui64.c10
-rw-r--r--test/kvx/interop/.gitignore1
-rw-r--r--test/kvx/interop/Makefile365
-rw-r--r--test/kvx/interop/common.c257
-rw-r--r--test/kvx/interop/common.h28
-rw-r--r--test/kvx/interop/framework.h66
-rw-r--r--test/kvx/interop/i32.c13
-rw-r--r--test/kvx/interop/i64.c14
-rw-r--r--test/kvx/interop/individual/i_multiiargs.c6
-rw-r--r--test/kvx/interop/individual/i_oneiarg.c6
-rw-r--r--test/kvx/interop/individual/ll_multillargs.c7
-rw-r--r--test/kvx/interop/individual/ll_onellarg.c7
-rw-r--r--test/kvx/interop/individual/ll_void.c7
-rw-r--r--test/kvx/interop/individual/void_void.c7
-rw-r--r--test/kvx/interop/stackhell.c9
-rw-r--r--test/kvx/interop/vaarg_common.c383
-rw-r--r--test/kvx/lib/Makefile133
-rw-r--r--test/kvx/lib/printf-test.c9
-rw-r--r--test/kvx/lib/printf.c9
-rw-r--r--test/kvx/mmult/.gitignore4
-rw-r--r--test/kvx/mmult/Makefile67
-rw-r--r--test/kvx/mmult/README.md17
-rw-r--r--test/kvx/mmult/mmult.c146
-rw-r--r--test/kvx/mmult/mmult.h10
-rw-r--r--test/kvx/prng/.gitignore3
-rw-r--r--test/kvx/prng/Makefile69
-rw-r--r--test/kvx/prng/README.md17
-rw-r--r--test/kvx/prng/prng.c41
-rw-r--r--test/kvx/prng/prng.h10
-rw-r--r--test/kvx/prng/types.h7
-rwxr-xr-xtest/kvx/simucheck.sh8
-rwxr-xr-xtest/kvx/simutest.sh8
-rw-r--r--test/kvx/sort/.gitignore9
-rw-r--r--test/kvx/sort/Makefile91
-rw-r--r--test/kvx/sort/README.md17
-rw-r--r--test/kvx/sort/insertion.c59
-rw-r--r--test/kvx/sort/insertion.h6
-rw-r--r--test/kvx/sort/main.c34
-rw-r--r--test/kvx/sort/merge.c92
-rw-r--r--test/kvx/sort/merge.h7
-rw-r--r--test/kvx/sort/selection.c62
-rw-r--r--test/kvx/sort/selection.h6
-rw-r--r--test/kvx/sort/test.h6
140 files changed, 3669 insertions, 0 deletions
diff --git a/test/kvx/.gitignore b/test/kvx/.gitignore
new file mode 100644
index 00000000..b10c40c8
--- /dev/null
+++ b/test/kvx/.gitignore
@@ -0,0 +1,20 @@
+check
+asm_coverage
+instr/Makefile
+mmult/Makefile
+prng/Makefile
+sort/Makefile
+prng/.zero
+sort/.zero
+sort/insertion-ccomp-kvx
+sort/insertion-gcc-kvx
+sort/insertion-gcc-x86
+sort/main-ccomp-kvx
+sort/main-gcc-kvx
+sort/main-gcc-x86
+sort/merge-ccomp-kvx
+sort/merge-gcc-kvx
+sort/merge-gcc-x86
+sort/selection-ccomp-kvx
+sort/selection-gcc-kvx
+sort/selection-gcc-x86
diff --git a/test/kvx/builtins/clzll.c b/test/kvx/builtins/clzll.c
new file mode 100644
index 00000000..13905cba
--- /dev/null
+++ b/test/kvx/builtins/clzll.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ c = __builtin_clzll(a);
+}
+END_TEST()
diff --git a/test/kvx/builtins/stsud.c b/test/kvx/builtins/stsud.c
new file mode 100644
index 00000000..fa42b001
--- /dev/null
+++ b/test/kvx/builtins/stsud.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST_N(unsigned long long, 2)
+{
+ c = __builtin_kvx_stsud(t[0], t[1]);
+}
+END_TEST()
diff --git a/test/kvx/coverage.sh b/test/kvx/coverage.sh
new file mode 100755
index 00000000..96f6bc04
--- /dev/null
+++ b/test/kvx/coverage.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+printer=../../kvx/TargetPrinter.ml
+asmdir=instr/asm/
+to_cover_raw=/tmp/to_cover_raw
+to_cover=/tmp/to_cover
+covered_raw=/tmp/covered_raw
+covered=/tmp/covered
+
+# Stop at any error
+set -e
+# Pipes do not mask errors
+set -o pipefail
+
+sed -n "s/^.*fprintf\s\+oc\s*\"\s*\([a-z][^[:space:]]*\)\s.*/\1/p" $printer > $to_cover_raw
+python2.7 coverage_helper.py $to_cover_raw | sort -u > $to_cover
+
+rm -f $covered_raw
+for asm in $(ls $asmdir/*.ccomp.s); do
+ grep -v ":" $asm | sed -n "s/^\s*\([a-z][a-z0-9.]*\).*/\1/p" | sort -u >> $covered_raw
+done
+python2.7 coverage_helper.py $covered_raw | sort -u > $covered
+
+vimdiff $to_cover $covered
diff --git a/test/kvx/coverage_helper.py b/test/kvx/coverage_helper.py
new file mode 100644
index 00000000..e5b1907c
--- /dev/null
+++ b/test/kvx/coverage_helper.py
@@ -0,0 +1,45 @@
+import fileinput
+import sys
+
+all_loads_stores = "lbs lbz lhz lo lq ld lhs lws sb sd sh so sq sw".split(" ")
+
+all_bconds = "wnez weqz wltz wgez wlez wgtz dnez deqz dltz dgez dlez dgtz".split(" ")
+
+all_iconds = "ne eq lt ge le gt ltu geu leu gtu".split(" ")
+
+all_fconds = "one ueq oeq une olt uge oge ult".split(" ")
+
+replaces_a = [(["cb.", "cmoved."], all_bconds),
+ (["compd.", "compw."], all_iconds),
+ (["fcompd.", "fcompw."], all_fconds),
+ (all_loads_stores, [".xs", ""])]
+
+replaces_dd = [(["addx", "sbfx"], ["2d", "4d", "8d", "16d"])]
+replaces_dw = [(["addx", "sbfx"], ["2w", "4w", "8w", "16w"])]
+
+macros_binds = {"%a": replaces_a, "%dd": replaces_dd, "%dw": replaces_dw}
+
+def expand_macro(fullinst, macro, replaceTable):
+ inst = fullinst.replace(macro, "")
+ for (searchlist, mods) in replaceTable:
+ if inst in searchlist:
+ return [fullinst.replace(macro, mod) for mod in mods]
+ raise NameError
+
+insts = []
+for line in fileinput.input():
+ fullinst = line[:-1]
+ try:
+ for macro in macros_binds:
+ if macro in fullinst:
+ insts.extend(expand_macro(fullinst, macro, macros_binds[macro]))
+ break
+ else:
+ insts.append(fullinst)
+ except NameError:
+ print >> sys.stderr, fullinst + " could not be found any match for macro " + macro
+ sys.exit(1)
+
+for inst in insts:
+ print inst
+occurs = {}
diff --git a/test/kvx/delout.sh b/test/kvx/delout.sh
new file mode 100755
index 00000000..e9c72e1c
--- /dev/null
+++ b/test/kvx/delout.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+for folder in prng mmult sort instr interop; do
+ rm -f $folder/*.out
+ rm -f $folder/out/*
+done
diff --git a/test/kvx/do_test.sh b/test/kvx/do_test.sh
new file mode 100644
index 00000000..5cc23dee
--- /dev/null
+++ b/test/kvx/do_test.sh
@@ -0,0 +1,50 @@
+do_test () {
+cat << EOF
+
+##
+# PRNG tests
+##
+EOF
+(cd prng && make $1 -j$2)
+
+cat << EOF
+
+##
+# Matrix Multiplication tests
+##
+EOF
+(cd mmult && make $1 -j$2)
+
+cat << EOF
+
+##
+# List sort tests
+##
+EOF
+(cd sort && make $1 -j$2)
+
+cat << EOF
+
+##
+# Instruction unit tests
+##
+EOF
+(cd instr && make $1 -j$2)
+
+cat << EOF
+
+##
+# Interoperability with GCC
+##
+EOF
+(cd interop && make $1 -j$2)
+
+cat << EOF
+
+##
+# printf wrapper test
+##
+(cd lib && make $1 -j$2)
+EOF
+
+}
diff --git a/test/kvx/general/clzd.c b/test/kvx/general/clzd.c
new file mode 100644
index 00000000..d3e8a8ec
--- /dev/null
+++ b/test/kvx/general/clzd.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST_N(unsigned long long, 1)
+{
+ c = __builtin_kvx_clzd(t[0]);
+}
+END_TEST()
diff --git a/test/kvx/general/clzw.c b/test/kvx/general/clzw.c
new file mode 100644
index 00000000..7b5478fd
--- /dev/null
+++ b/test/kvx/general/clzw.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST_N(unsigned long long, 1)
+{
+ c = __builtin_kvx_clzw(t[0]);
+}
+END_TEST()
diff --git a/test/kvx/general/ctzd.c b/test/kvx/general/ctzd.c
new file mode 100644
index 00000000..bba869e1
--- /dev/null
+++ b/test/kvx/general/ctzd.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST_N(unsigned long long, 1)
+{
+ c = __builtin_kvx_ctzd(t[0]);
+}
+END_TEST()
diff --git a/test/kvx/general/ctzw.c b/test/kvx/general/ctzw.c
new file mode 100644
index 00000000..a7128b04
--- /dev/null
+++ b/test/kvx/general/ctzw.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST_N(unsigned long long, 1)
+{
+ c = __builtin_kvx_ctzw(t[0]);
+}
+END_TEST()
diff --git a/test/kvx/general/satd.c b/test/kvx/general/satd.c
new file mode 100644
index 00000000..9d0d1cf9
--- /dev/null
+++ b/test/kvx/general/satd.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST_N(unsigned long long, 2)
+{
+ c = __builtin_kvx_satd(t[0], t[1]);
+}
+END_TEST()
diff --git a/test/kvx/general/sbmm8.c b/test/kvx/general/sbmm8.c
new file mode 100644
index 00000000..91f13425
--- /dev/null
+++ b/test/kvx/general/sbmm8.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST_N(unsigned long long, 2)
+{
+ c = __builtin_kvx_sbmm8(t[0], t[1]);
+}
+END_TEST()
diff --git a/test/kvx/general/sbmmt8.c b/test/kvx/general/sbmmt8.c
new file mode 100644
index 00000000..7b120dfa
--- /dev/null
+++ b/test/kvx/general/sbmmt8.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST_N(unsigned long long, 2)
+{
+ c = __builtin_kvx_sbmmt8(t[0], t[1]);
+}
+END_TEST()
diff --git a/test/kvx/hardcheck.sh b/test/kvx/hardcheck.sh
new file mode 100755
index 00000000..b6538f0e
--- /dev/null
+++ b/test/kvx/hardcheck.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# Tests the execution of the binaries produced by CompCert, in hardware
+
+source do_test.sh
+
+do_test hardcheck 1
diff --git a/test/kvx/hardtest.sh b/test/kvx/hardtest.sh
new file mode 100755
index 00000000..6321bc7d
--- /dev/null
+++ b/test/kvx/hardtest.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# Tests the validity of the tests, in hardware
+
+source do_test.sh
+
+do_test hardtest 1
diff --git a/test/kvx/instr/.gitignore b/test/kvx/instr/.gitignore
new file mode 100644
index 00000000..ea1472ec
--- /dev/null
+++ b/test/kvx/instr/.gitignore
@@ -0,0 +1 @@
+output/
diff --git a/test/kvx/instr/Makefile b/test/kvx/instr/Makefile
new file mode 100644
index 00000000..e4f964b3
--- /dev/null
+++ b/test/kvx/instr/Makefile
@@ -0,0 +1,176 @@
+SHELL := /bin/bash
+
+KVXC ?= k1-cos-gcc
+CC ?= gcc
+CCOMP ?= ccomp
+OPTIM ?= -O2
+CFLAGS ?= $(OPTIM)
+CCOMPFLAGS ?= $(CFLAGS)
+SIMU ?= k1-mppa
+TIMEOUT ?= --signal=SIGTERM 120s
+DIFF ?= python2.7 floatcmp.py -reltol .00001
+HARDRUN ?= k1-jtag-runner
+
+DIR=./
+SRCDIR=$(DIR)
+OUTDIR=$(DIR)/out
+BINDIR=$(DIR)/bin
+ASMDIR=$(DIR)/asm
+LIB=../lib/system.x86-gcc.a
+K1LIB=../lib/system.gcc.a
+
+##
+# Intended flow : .c -> .gcc.s -> .gcc.bin -> .gcc.out
+# -> .ccomp.s -> .ccomp.bin -> .ccomp.out
+##
+
+KVXCPATH=$(shell which $(KVXC))
+CCPATH=$(shell which $(CC))
+CCOMPPATH=$(shell which $(CCOMP))
+SIMUPATH=$(shell which $(SIMU))
+
+TESTNAMES?=$(notdir $(subst .c,,$(wildcard $(DIR)/*.c)))
+X86_GCC_OUT=$(addprefix $(OUTDIR)/,$(addsuffix .x86-gcc.out,$(TESTNAMES)))
+GCC_SIMUOUT=$(addprefix $(OUTDIR)/,$(addsuffix .gcc.simu.out,$(TESTNAMES)))
+CCOMP_SIMUOUT=$(addprefix $(OUTDIR)/,$(addsuffix .ccomp.simu.out,$(TESTNAMES)))
+GCC_HARDOUT=$(addprefix $(OUTDIR)/,$(addsuffix .gcc.hard.out,$(TESTNAMES)))
+CCOMP_HARDOUT=$(addprefix $(OUTDIR)/,$(addsuffix .ccomp.hard.out,$(TESTNAMES)))
+
+BIN=$(addprefix $(BINDIR)/,$(addsuffix .x86-gcc.bin,$(TESTNAMES)))\
+ $(addprefix $(BINDIR)/,$(addsuffix .gcc.bin,$(TESTNAMES)))\
+ $(addprefix $(BINDIR)/,$(addsuffix .ccomp.bin,$(TESTNAMES)))
+
+##
+# Targets
+##
+
+all: $(BIN)
+
+GREEN=\033[0;32m
+RED=\033[0;31m
+YELLOW=\033[0;33m
+NC=\033[0m
+
+.PHONY:
+test: simutest
+
+.PHONY:
+check: simucheck
+
+.PHONY:
+simutest: $(X86_GCC_OUT) $(GCC_SIMUOUT)
+ @echo "Comparing x86 gcc output to k1 gcc.."
+ for test in $(TESTNAMES); do\
+ x86out=$(OUTDIR)/$$test.x86-gcc.out;\
+ gccout=$(OUTDIR)/$$test.gcc.simu.out;\
+ if grep "__KVX__" -q $$test.c; then\
+ printf "$(YELLOW)UNTESTED: $$test.c contains an \`#ifdef __KVX__\`\n";\
+ elif $(DIFF) $$x86out $$gccout > /dev/null; test $${PIPESTATUS[0]} -ne 0; then\
+ >&2 printf "$(RED)ERROR: $$x86out and $$gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$x86out and $$gccout concur$(NC)\n";\
+ fi;\
+ done
+
+.PHONY:
+simucheck: $(GCC_SIMUOUT) $(CCOMP_SIMUOUT)
+ @echo "Comparing k1 gcc output to ccomp.."
+ @for test in $(TESTNAMES); do\
+ gccout=$(OUTDIR)/$$test.gcc.simu.out;\
+ ccompout=$(OUTDIR)/$$test.ccomp.simu.out;\
+ if $(DIFF) $$ccompout $$gccout > /dev/null; test $${PIPESTATUS[0]} -ne 0; then\
+ >&2 printf "$(RED)ERROR: $$ccompout and $$gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$ccompout and $$gccout concur$(NC)\n";\
+ fi;\
+ done
+
+.PHONY:
+hardtest: $(X86_GCC_OUT) $(GCC_HARDOUT)
+ @echo "Comparing x86 gcc output to k1 gcc.."
+ for test in $(TESTNAMES); do\
+ x86out=$(OUTDIR)/$$test.x86-gcc.out;\
+ gccout=$(OUTDIR)/$$test.gcc.hard.out;\
+ if grep "__KVX__" -q $$test.c; then\
+ printf "$(YELLOW)UNTESTED: $$test.c contains an \`#ifdef __KVX__\`\n";\
+ elif $(DIFF) $$x86out $$gccout > /dev/null; test $${PIPESTATUS[0]} -ne 0; then\
+ >&2 printf "$(RED)ERROR: $$x86out and $$gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$x86out and $$gccout concur$(NC)\n";\
+ fi;\
+ done
+
+.PHONY:
+hardcheck: $(GCC_HARDOUT) $(CCOMP_HARDOUT)
+ @echo "Comparing k1 gcc output to ccomp.."
+ @for test in $(TESTNAMES); do\
+ gccout=$(OUTDIR)/$$test.gcc.hard.out;\
+ ccompout=$(OUTDIR)/$$test.ccomp.hard.out;\
+ if $(DIFF) $$ccompout $$gccout > /dev/null; test $${PIPESTATUS[0]} -ne 0; then\
+ >&2 printf "$(RED)ERROR: $$ccompout and $$gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$ccompout and $$gccout concur$(NC)\n";\
+ fi;\
+ done
+
+##
+# Rules
+##
+
+.SECONDARY:
+$(LIB):
+ (cd $(dir $(LIB)) && make)
+
+$(K1LIB):
+ (cd $(dir $(LIB)) && make)
+
+# Generating output
+
+## Version avec timeout
+$(OUTDIR)/%.x86-gcc.out: $(BINDIR)/%.x86-gcc.bin
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) ./$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.gcc.simu.out: $(BINDIR)/%.gcc.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(SIMU) -- $< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.ccomp.simu.out: $(BINDIR)/%.ccomp.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(SIMU) -- $< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.gcc.hard.out: $(BINDIR)/%.gcc.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(HARDRUN) --exec-file=Cluster0:$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.ccomp.hard.out: $(BINDIR)/%.ccomp.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(HARDRUN) --exec-file=Cluster0:$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+# Assembly to binary
+
+$(BINDIR)/%.x86-gcc.bin: $(ASMDIR)/%.x86-gcc.s $(LIB) $(CCPATH)
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) $(filter-out $(CCPATH),$^) -o $@
+
+$(BINDIR)/%.gcc.bin: $(ASMDIR)/%.gcc.s $(K1LIB) $(KVXCPATH)
+ @mkdir -p $(@D)
+ $(KVXC) $(CFLAGS) $(filter-out $(KVXCPATH),$^) -o $@
+
+$(BINDIR)/%.ccomp.bin: $(ASMDIR)/%.ccomp.s $(K1LIB) $(CCOMPPATH)
+ @mkdir -p $(@D)
+ $(CCOMP) $(CCOMPFLAGS) $(filter-out $(CCOMPPATH),$^) -o $@
+
+# Source to assembly
+
+$(ASMDIR)/%.x86-gcc.s: $(SRCDIR)/%.c $(CCPATH)
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) -S $< -o $@
+
+$(ASMDIR)/%.gcc.s: $(SRCDIR)/%.c $(KVXCPATH)
+ @mkdir -p $(@D)
+ $(KVXC) $(CFLAGS) -S $< -o $@
+
+$(ASMDIR)/%.ccomp.s: $(SRCDIR)/%.c $(CCOMPPATH)
+ @mkdir -p $(@D)
+ $(CCOMP) $(CCOMPFLAGS) -S $< -o $@
diff --git a/test/kvx/instr/builtin32.c b/test/kvx/instr/builtin32.c
new file mode 100644
index 00000000..9efb33cd
--- /dev/null
+++ b/test/kvx/instr/builtin32.c
@@ -0,0 +1,12 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+ int *ptr = &c;
+#ifdef __KVX__
+ int d = c;
+ a = __builtin_kvx_alclrw(ptr);
+ c = d;
+
+#endif
+END_TEST32()
+
diff --git a/test/kvx/instr/builtin64.c b/test/kvx/instr/builtin64.c
new file mode 100644
index 00000000..252eb2c6
--- /dev/null
+++ b/test/kvx/instr/builtin64.c
@@ -0,0 +1,17 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+ long long *ptr = &c;
+#ifdef __KVX__
+ long long d = c;
+ a = __builtin_kvx_alclrd(ptr);
+ c = d;
+ c += a;
+
+ c += __builtin_clzll(a);
+
+ /* Removed the AFADDD builtin who was incorrect in CompCert, see #157 */
+ // a = __builtin_kvx_afaddd(ptr, a);
+ // a = __builtin_kvx_afaddd(ptr, a);
+#endif
+END_TEST64()
diff --git a/test/kvx/instr/div32.c b/test/kvx/instr/div32.c
new file mode 100644
index 00000000..83c3a0e3
--- /dev/null
+++ b/test/kvx/instr/div32.c
@@ -0,0 +1,5 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+ c = a/b;
+END_TEST32()
diff --git a/test/kvx/instr/divf32.c b/test/kvx/instr/divf32.c
new file mode 100644
index 00000000..513a3293
--- /dev/null
+++ b/test/kvx/instr/divf32.c
@@ -0,0 +1,5 @@
+#include "framework.h"
+
+BEGIN_TEST(float)
+ c = a / b;
+END_TESTF32()
diff --git a/test/kvx/instr/divf64.c b/test/kvx/instr/divf64.c
new file mode 100644
index 00000000..0dd23826
--- /dev/null
+++ b/test/kvx/instr/divf64.c
@@ -0,0 +1,5 @@
+#include "framework.h"
+
+BEGIN_TEST(double)
+ c = a / b;
+END_TESTF64()
diff --git a/test/kvx/instr/divu32.c b/test/kvx/instr/divu32.c
new file mode 100644
index 00000000..1fe196c4
--- /dev/null
+++ b/test/kvx/instr/divu32.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned int)
+{
+ c = a/b;
+}
+END_TEST32()
diff --git a/test/kvx/instr/f32.c b/test/kvx/instr/f32.c
new file mode 100644
index 00000000..7e304aeb
--- /dev/null
+++ b/test/kvx/instr/f32.c
@@ -0,0 +1,8 @@
+#include "framework.h"
+
+BEGIN_TEST(float)
+ c = ((float)a + (float)b);
+ c += ((float)a * (float)b);
+ c += (-(float)a);
+ c += ((float)a - (float)b);
+END_TESTF32()
diff --git a/test/kvx/instr/f64.c b/test/kvx/instr/f64.c
new file mode 100644
index 00000000..be8094c9
--- /dev/null
+++ b/test/kvx/instr/f64.c
@@ -0,0 +1,8 @@
+#include "framework.h"
+
+BEGIN_TEST(double)
+ c = ((double)a + (double)b);
+ c += ((double)a * (double)b);
+ c += (-(double)a);
+ c += ((double)a - (double)b);
+END_TESTF64()
diff --git a/test/kvx/instr/floatcmp.py b/test/kvx/instr/floatcmp.py
new file mode 100755
index 00000000..49f1bc13
--- /dev/null
+++ b/test/kvx/instr/floatcmp.py
@@ -0,0 +1,93 @@
+#!/usr/bin/python2.7
+
+import argparse as ap
+import sys
+
+parser = ap.ArgumentParser()
+parser.add_argument("file1", help="First file to compare")
+parser.add_argument("file2", help="Second file to compare")
+parser.add_argument("-reltol", help="Relative error")
+parser.add_argument("-abstol", help="Absolute error")
+parser.add_argument("-s", help="Silent output", action="store_true")
+args = parser.parse_args()
+
+reltol = float(args.reltol) if args.reltol else None
+abstol = float(args.abstol) if args.abstol else None
+silent = args.s
+
+if silent:
+ sys.stdout = open("/dev/null", "w")
+
+import re
+from math import fabs
+
+def floatcmp(f1, f2):
+ if abstol:
+ if fabs(f1 - f2) > abstol:
+ return False
+ if reltol:
+ if f2 != 0. and fabs((f1 - f2) / f2) > reltol:
+ return False
+ return True
+
+class Parsed(list):
+ def __eq__(self, other):
+ if len(self) != len(other):
+ return False
+ comps = zip(self, other)
+ for comp in comps:
+ if all(isinstance(compElt, str) for compElt in comp):
+ if comp[0] != comp[1]:
+ return False
+ elif all (isinstance(compElt, float) for compElt in comp):
+ if not floatcmp(comp[0], comp[1]):
+ return False
+ else:
+ return False
+ return True
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+parseLine = re.compile(r"\s*(\S+)")
+def readline(line):
+ words = parseLine.findall(line)
+ parsed = Parsed([])
+ for word in words:
+ try:
+ parse = float(word)
+ parsed.append(parse)
+ except ValueError:
+ parsed.append(word)
+ return parsed
+
+def readfile(filename):
+ L = []
+ try:
+ with open(filename) as f:
+ for line in f:
+ L.append(readline(line))
+ except IOError:
+ print "Unable to read {}".format(filename)
+ sys.exit(2)
+ return L
+
+L1 = readfile(args.file1)
+L2 = readfile(args.file2)
+
+if len(L1) != len(L2):
+ print "The files have different amount of lines"
+ print "\t{}: {} lines".format(args.file1, len(L1))
+ print "\t{}: {} lines".format(args.file2, len(L2))
+ sys.exit(1)
+
+cmpL = zip(L1, L2)
+for i, cmpElt in enumerate(cmpL):
+ if cmpElt[0] != cmpElt[1]:
+ print "The files differ at line {}".format(i)
+ print "\t{}: {}".format(args.file1, cmpElt[0])
+ print "\t{}: {}".format(args.file2, cmpElt[1])
+ sys.exit(1)
+
+print "Comparison succeeded"
+sys.exit(0)
diff --git a/test/kvx/instr/framework.h b/test/kvx/instr/framework.h
new file mode 100644
index 00000000..3bbfa271
--- /dev/null
+++ b/test/kvx/instr/framework.h
@@ -0,0 +1,66 @@
+#ifndef __FRAMEWORK_H__
+#define __FRAMEWORK_H__
+
+#include <stdio.h>
+#include "../prng/prng.c"
+
+#define BEGIN_TEST_N(type, N)\
+ int main(void){\
+ type t[N], c, i, j, S;\
+ srand(0);\
+ S = 0;\
+ for (i = 0 ; i < 100 ; i++){\
+ c = randlong();\
+ for (j = 0 ; j < N ; j++)\
+ t[j] = randlong();\
+ /* END BEGIN_TEST_N */
+
+#define BEGIN_TEST(type)\
+ int main(void){\
+ type a, b, c, S;\
+ int i;\
+ srand(0);\
+ S = 0;\
+ for (i = 0 ; i < 100 ; i++){\
+ c = randlong();\
+ a = randlong();\
+ b = randlong();
+ /* END BEGIN_TEST */
+
+/* In between BEGIN_TEST and END_TEST : definition of c */
+
+#define END_TEST64()\
+ printf("%llu\t%llu\t%llu\n", a, b, c);\
+ S += c;\
+ }\
+ return S;\
+ }
+ /* END END_TEST64 */
+
+#define END_TEST32()\
+ printf("%u\t%u\t%u\n", a, b, c);\
+ S += c;\
+ }\
+ return S;\
+ }
+ /* END END_TEST32 */
+
+#define END_TESTF32()\
+ printf("%e\t%e\t%e\n", a, b, c);\
+ S += c;\
+ }\
+ return 0;\
+ }
+ /* END END_TESTF32 */
+
+#define END_TESTF64()\
+ printf("%e\t%e\t%e\n", a, b, c);\
+ S += c;\
+ }\
+ return 0;\
+ }
+ /* END END_TESTF64 */
+
+#endif
+
+
diff --git a/test/kvx/instr/i32.c b/test/kvx/instr/i32.c
new file mode 100644
index 00000000..e350931c
--- /dev/null
+++ b/test/kvx/instr/i32.c
@@ -0,0 +1,149 @@
+#include "framework.h"
+
+int sum(int a, int b){
+ return a+b;
+}
+
+int make(int a){
+ return a;
+}
+
+int tailsum(int a, int b){
+ return make(a+b);
+}
+
+int fact(int a){
+ int r = 1;
+ int i;
+ for (i = 1; i < a; i++)
+ r *= i;
+ return r;
+}
+
+float int2float(int v){
+ return v;
+}
+
+BEGIN_TEST(int)
+ c = a+b;
+ c += a&b;
+
+ /* testing if, cb version */
+ if ((a & 0x1) == 1)
+ c += fact(1);
+ else
+ c += fact(2);
+
+ if (a & 0x1 == 0)
+ c += fact(4);
+ else
+ c += fact(8);
+
+ if (a & 0x1 == 0)
+ c += fact(4);
+ else
+ c += fact(8);
+
+ b = !(a & 0x01);
+ if (!b)
+ c += fact(16);
+ else
+ c += fact(32);
+
+ c += sum(make(a), make(b));
+ c += (long long) a;
+
+ if (0 > (a & 0x1) - 1)
+ c += fact(64);
+ else
+ c += fact(128);
+
+ if (0 >= (a & 0x1))
+ c += fact(256);
+ else
+ c += fact(512);
+
+ if ((a & 0x1) > 0)
+ c += fact(1024);
+ else
+ c += fact(2048);
+
+ if ((a & 0x1) - 1 >= 0)
+ c += fact(4096);
+ else
+ c += fact(8192);
+
+ /* cmoved version */
+ if ((a & 0x1) == 1)
+ c += 1;
+ else
+ c += 2;
+
+ if (a & 0x1 == 0)
+ c += 4;
+ else
+ c += 8;
+
+ if (a & 0x1 == 0)
+ c += 4;
+ else
+ c += 8;
+
+ b = !(a & 0x01);
+ if (!b)
+ c += 16;
+ else
+ c += 32;
+
+ if (0 > (a & 0x1) - 1)
+ c += 64;
+ else
+ c += 128;
+
+ if (0 >= (a & 0x1))
+ c += 256;
+ else
+ c += 512;
+
+ if ((a & 0x1) > 0)
+ c += 1024;
+ else
+ c += 2048;
+
+ if ((a & 0x1) - 1 >= 0)
+ c += 4096;
+ else
+ c += 8192;
+
+ c += ((a & 0x1) == (b & 0x1));
+ c += (a > b);
+ c += (a <= b);
+ c += (a < b);
+ c += (a + b) / 2;
+ c += (int) int2float(a) + (int) int2float(b) + (int) int2float(42.3);
+ c += (a << 4); // addx16w
+ c += (a << 3); // addx8w
+ c += (a << 2); // addx4w
+ c += (a << 1); // addx2w
+
+ c += ~a & b; // andnw
+
+ int j;
+ for (j = 0 ; j < 10 ; j++)
+ c += a;
+ int k;
+ for (k = 0 ; k < (b & 0x8) ; k++)
+ c += a;
+
+ char s[] = "Tome and Cherry at the playa\n";
+ c += s[(a & (sizeof(s)-1))];
+
+ unsigned char s2[] = "Tim is sorry at the playa\n";
+ c += s2[a & (sizeof(s) - 1)];
+
+ c += a*b;
+ c += a-b;
+ c += a << (b & 0x8);
+
+ c += sum(a, b);
+END_TEST32()
diff --git a/test/kvx/instr/i64.c b/test/kvx/instr/i64.c
new file mode 100644
index 00000000..e869d93c
--- /dev/null
+++ b/test/kvx/instr/i64.c
@@ -0,0 +1,169 @@
+#include "framework.h"
+
+long long sum(long long a, long long b){
+ return a+b;
+}
+
+long long diff(long long a, long long b){
+ return a-b;
+}
+
+long long mul(long long a, long long b){
+ return a*b;
+}
+
+long long make(long long a){
+ return a;
+}
+
+long long random_op(long long a, long long b){
+ long long d = 3;
+ long long (*op)(long long, long long);
+
+ if (a % d == 0)
+ op = sum;
+ else if (a % d == 1)
+ op = diff;
+ else
+ op = mul;
+
+ return op(a, b);
+}
+
+long fact(long a){
+ long r = 1;
+ long i;
+ for (i = 1; i < a; i++)
+ r *= i;
+ return r;
+}
+
+double long2double(long v){
+ return v;
+}
+
+BEGIN_TEST(long long)
+ c = a&b;
+ c += a*b;
+ c += -a;
+ c += a | b;
+ c += a-b;
+ c += a >> (b & 0x8LL);
+ c += a >> (b & 0x8ULL);
+ c += a % b;
+ c += (a << 4); // addx16d
+ c += (a << 3); // addx8d
+ c += (a << 2); // addx4d
+ c += (a << 1); // addx2d
+
+ c += ~a & b; // andnd
+
+ long long d = 3;
+ long long (*op)(long long, long long);
+
+ if (a % d == 0)
+ op = sum;
+ else if (a % d == 1)
+ op = diff;
+ else
+ op = mul;
+
+ c += op(make(a), make(b));
+ c += random_op(a, b);
+ c += a/b;
+ c += a^b;
+ c += (unsigned int) a;
+
+ /* Testing if, cb */
+ if (0 != (a & 0x1LL))
+ c += fact(1);
+ else
+ c += fact(2);
+
+ if (0 > (a & 0x1LL))
+ c += fact(4);
+ else
+ c += fact(8);
+
+ if (0 >= (a & 0x1LL) - 1)
+ c += fact(16);
+ else
+ c += fact(32);
+
+ if ((unsigned long long)(a & 0x1LL) >= 1)
+ c += fact(18);
+ else
+ c += fact(31);
+
+
+ if (a-41414141 > 0)
+ c += fact(13);
+ else
+ c += fact(31);
+
+ if (a & 0x1LL > 0)
+ c += fact(64);
+ else
+ c += fact(128);
+
+ if ((a & 0x1LL) - 1 >= 0)
+ c += fact(256);
+ else
+ c += fact(512);
+
+ if (0 == (a & 0x1LL))
+ c += fact(1024);
+ else
+ c += fact(2048);
+
+ /* Testing if, cmoved */
+ if (0 != (a & 0x1LL))
+ c += 1;
+ else
+ c += 2;
+
+ if (0 > (a & 0x1LL))
+ c += 4;
+ else
+ c += 8;
+
+ if (0 >= (a & 0x1LL) - 1)
+ c += 16;
+ else
+ c += 32;
+
+ if (a-41414141 > 0)
+ c += 13;
+ else
+ c += 31;
+
+ if (a & 0x1LL > 0)
+ c += 64;
+ else
+ c += 128;
+
+ if ((a & 0x1LL) - 1 >= 0)
+ c += 256;
+ else
+ c += 512;
+
+ if (0 == (a & 0x1LL))
+ c += 1024;
+ else
+ c += 2048;
+
+ c += ((a & 0x1LL) == (b & 0x1LL));
+ c += (a >= b);
+ c += (a > b);
+ c += (a <= b);
+ c += (a < b);
+ c += (long) long2double(a) + (long) long2double(b) + (long) long2double(42.3);
+
+ int j;
+
+ for (j = 0 ; j < (b & 0x8LL) ; j++)
+ c += a;
+
+ c += ((a & 0x1LL) == (b & 0x1LL));
+
+END_TEST64()
diff --git a/test/kvx/instr/individual/andw.c b/test/kvx/instr/individual/andw.c
new file mode 100644
index 00000000..799dc7fb
--- /dev/null
+++ b/test/kvx/instr/individual/andw.c
@@ -0,0 +1,5 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+ c = a&b;
+END_TEST32()
diff --git a/test/kvx/instr/individual/branch.c b/test/kvx/instr/individual/branch.c
new file mode 100644
index 00000000..c9937e31
--- /dev/null
+++ b/test/kvx/instr/individual/branch.c
@@ -0,0 +1,10 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ if ((a & 0x1) == 1)
+ c = 0;
+ else
+ c = 1;
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/branchz.c b/test/kvx/instr/individual/branchz.c
new file mode 100644
index 00000000..d3e021b5
--- /dev/null
+++ b/test/kvx/instr/individual/branchz.c
@@ -0,0 +1,10 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ if (a & 0x1 == 0)
+ c = 0;
+ else
+ c = 1;
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/branchzu.c b/test/kvx/instr/individual/branchzu.c
new file mode 100644
index 00000000..d0169174
--- /dev/null
+++ b/test/kvx/instr/individual/branchzu.c
@@ -0,0 +1,11 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ b = !(a & 0x01);
+ if (!b)
+ c = 0;
+ else
+ c = 1;
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/call.c b/test/kvx/instr/individual/call.c
new file mode 100644
index 00000000..ba2ec323
--- /dev/null
+++ b/test/kvx/instr/individual/call.c
@@ -0,0 +1,16 @@
+#include "framework.h"
+
+int sum(int a, int b){
+ return a+b;
+}
+
+int make(int a){
+ return a;
+}
+
+BEGIN_TEST(int)
+{
+ c = sum(make(a), make(b));
+}
+END_TEST32()
+/* RETURN VALUE: 60 */
diff --git a/test/kvx/instr/individual/cast_S32_S64.c b/test/kvx/instr/individual/cast_S32_S64.c
new file mode 100644
index 00000000..09c97e00
--- /dev/null
+++ b/test/kvx/instr/individual/cast_S32_S64.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ c = (long long) a;
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/cast_S64_U32.c b/test/kvx/instr/individual/cast_S64_U32.c
new file mode 100644
index 00000000..2d9dc723
--- /dev/null
+++ b/test/kvx/instr/individual/cast_S64_U32.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ c = (unsigned int) a;
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/cb.deqz.c b/test/kvx/instr/individual/cb.deqz.c
new file mode 100644
index 00000000..6da2ab07
--- /dev/null
+++ b/test/kvx/instr/individual/cb.deqz.c
@@ -0,0 +1,10 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ if (0 != (a & 0x1LL))
+ c = 1;
+ else
+ c = 0;
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/cb.dgez.c b/test/kvx/instr/individual/cb.dgez.c
new file mode 100644
index 00000000..7bef25ad
--- /dev/null
+++ b/test/kvx/instr/individual/cb.dgez.c
@@ -0,0 +1,10 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ if (0 > (a & 0x1LL))
+ c = 1;
+ else
+ c = 0;
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/cb.dgtz.c b/test/kvx/instr/individual/cb.dgtz.c
new file mode 100644
index 00000000..1a43fb1f
--- /dev/null
+++ b/test/kvx/instr/individual/cb.dgtz.c
@@ -0,0 +1,10 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ if (0 >= (a & 0x1LL) - 1)
+ c = 1;
+ else
+ c = 0;
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/cb.dlez.c b/test/kvx/instr/individual/cb.dlez.c
new file mode 100644
index 00000000..2fb97939
--- /dev/null
+++ b/test/kvx/instr/individual/cb.dlez.c
@@ -0,0 +1,10 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ if (a & 0x1LL > 0)
+ c = 1;
+ else
+ c = 0;
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/cb.dltz.c b/test/kvx/instr/individual/cb.dltz.c
new file mode 100644
index 00000000..a431d5d0
--- /dev/null
+++ b/test/kvx/instr/individual/cb.dltz.c
@@ -0,0 +1,10 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ if ((a & 0x1LL) - 1 >= 0)
+ c = 1;
+ else
+ c = 0;
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/cb.dnez.c b/test/kvx/instr/individual/cb.dnez.c
new file mode 100644
index 00000000..44516cbe
--- /dev/null
+++ b/test/kvx/instr/individual/cb.dnez.c
@@ -0,0 +1,10 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ if (0 == (a & 0x1LL))
+ c = 1;
+ else
+ c = 0;
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/cb.wgez.c b/test/kvx/instr/individual/cb.wgez.c
new file mode 100644
index 00000000..5779ad92
--- /dev/null
+++ b/test/kvx/instr/individual/cb.wgez.c
@@ -0,0 +1,10 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ if (0 > (a & 0x1) - 1)
+ c = 1;
+ else
+ c = 0;
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/cb.wgtz.c b/test/kvx/instr/individual/cb.wgtz.c
new file mode 100644
index 00000000..abb695bd
--- /dev/null
+++ b/test/kvx/instr/individual/cb.wgtz.c
@@ -0,0 +1,10 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ if (0 >= (a & 0x1))
+ c = 1;
+ else
+ c = 0;
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/cb.wlez.c b/test/kvx/instr/individual/cb.wlez.c
new file mode 100644
index 00000000..3a2e08c1
--- /dev/null
+++ b/test/kvx/instr/individual/cb.wlez.c
@@ -0,0 +1,10 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ if ((a & 0x1) > 0)
+ c = 1;
+ else
+ c = 0;
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/cb.wltz.c b/test/kvx/instr/individual/cb.wltz.c
new file mode 100644
index 00000000..5d52c72a
--- /dev/null
+++ b/test/kvx/instr/individual/cb.wltz.c
@@ -0,0 +1,10 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ if ((a & 0x1) - 1 >= 0)
+ c = 1;
+ else
+ c = 0;
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/compd.eq.c b/test/kvx/instr/individual/compd.eq.c
new file mode 100644
index 00000000..4fe8de2a
--- /dev/null
+++ b/test/kvx/instr/individual/compd.eq.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ c = ((a & 0x1LL) == (b & 0x1LL));
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/compd.geu.c b/test/kvx/instr/individual/compd.geu.c
new file mode 100644
index 00000000..fccf0804
--- /dev/null
+++ b/test/kvx/instr/individual/compd.geu.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned long long)
+{
+ c = (a >= b);
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/compd.gt.c b/test/kvx/instr/individual/compd.gt.c
new file mode 100644
index 00000000..b9901436
--- /dev/null
+++ b/test/kvx/instr/individual/compd.gt.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ c = (a > b);
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/compd.le.c b/test/kvx/instr/individual/compd.le.c
new file mode 100644
index 00000000..6fa0f103
--- /dev/null
+++ b/test/kvx/instr/individual/compd.le.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ c = (a <= b);
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/compd.leu.c b/test/kvx/instr/individual/compd.leu.c
new file mode 100644
index 00000000..1ad18281
--- /dev/null
+++ b/test/kvx/instr/individual/compd.leu.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned long long)
+{
+ c = (a <= b);
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/compd.lt.c b/test/kvx/instr/individual/compd.lt.c
new file mode 100644
index 00000000..c42cda56
--- /dev/null
+++ b/test/kvx/instr/individual/compd.lt.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ c = (a < b);
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/compd.ltu.c b/test/kvx/instr/individual/compd.ltu.c
new file mode 100644
index 00000000..b03d4d53
--- /dev/null
+++ b/test/kvx/instr/individual/compd.ltu.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned long long)
+{
+ c = (a < b);
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/compd.ne.c b/test/kvx/instr/individual/compd.ne.c
new file mode 100644
index 00000000..fd9d0b28
--- /dev/null
+++ b/test/kvx/instr/individual/compd.ne.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned long long)
+{
+ c = ((a & 0x1ULL) != (b & 0x1ULL));
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/compw.eq.c b/test/kvx/instr/individual/compw.eq.c
new file mode 100644
index 00000000..cd93f365
--- /dev/null
+++ b/test/kvx/instr/individual/compw.eq.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ c = ((a & 0x1) == (b & 0x1));
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/compw.geu.c b/test/kvx/instr/individual/compw.geu.c
new file mode 100644
index 00000000..b8fb1adf
--- /dev/null
+++ b/test/kvx/instr/individual/compw.geu.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned int)
+{
+ c = (a >= b);
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/compw.gt.c b/test/kvx/instr/individual/compw.gt.c
new file mode 100644
index 00000000..5f6bc907
--- /dev/null
+++ b/test/kvx/instr/individual/compw.gt.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ c = (a > b);
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/compw.gtu.c b/test/kvx/instr/individual/compw.gtu.c
new file mode 100644
index 00000000..947f6a14
--- /dev/null
+++ b/test/kvx/instr/individual/compw.gtu.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned int)
+{
+ c = (a > b);
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/compw.le.c b/test/kvx/instr/individual/compw.le.c
new file mode 100644
index 00000000..35ec6b7d
--- /dev/null
+++ b/test/kvx/instr/individual/compw.le.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ c = (a <= b);
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/compw.leu.c b/test/kvx/instr/individual/compw.leu.c
new file mode 100644
index 00000000..74ebfb42
--- /dev/null
+++ b/test/kvx/instr/individual/compw.leu.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned int)
+{
+ c = (a <= b);
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/compw.lt.c b/test/kvx/instr/individual/compw.lt.c
new file mode 100644
index 00000000..cb1f30bd
--- /dev/null
+++ b/test/kvx/instr/individual/compw.lt.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ c = (a < b);
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/compw.ltu.c b/test/kvx/instr/individual/compw.ltu.c
new file mode 100644
index 00000000..6a0c5af1
--- /dev/null
+++ b/test/kvx/instr/individual/compw.ltu.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned int)
+{
+ c = (a < b);
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/compw.ne.c b/test/kvx/instr/individual/compw.ne.c
new file mode 100644
index 00000000..7035e2c7
--- /dev/null
+++ b/test/kvx/instr/individual/compw.ne.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned int)
+{
+ c = ((a & 0x1U) != (b & 0x1U));
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/div2.c b/test/kvx/instr/individual/div2.c
new file mode 100644
index 00000000..b5dfe63a
--- /dev/null
+++ b/test/kvx/instr/individual/div2.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ c = (a + b) / 2;
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/doubleconv.c b/test/kvx/instr/individual/doubleconv.c
new file mode 100644
index 00000000..55b1ddab
--- /dev/null
+++ b/test/kvx/instr/individual/doubleconv.c
@@ -0,0 +1,9 @@
+#include "framework.h"
+
+double long2double(long v){
+ return v;
+}
+
+BEGIN_TEST(long)
+ c = (long) long2double(a) + (long) long2double(b) + (long) long2double(42.3);
+END_TEST64()
diff --git a/test/kvx/instr/individual/floatconv.c b/test/kvx/instr/individual/floatconv.c
new file mode 100644
index 00000000..32b798e1
--- /dev/null
+++ b/test/kvx/instr/individual/floatconv.c
@@ -0,0 +1,9 @@
+#include "framework.h"
+
+float int2float(int v){
+ return v;
+}
+
+BEGIN_TEST(int)
+ c = (int) int2float(a) + (int) int2float(b) + (int) int2float(42.3);
+END_TEST32()
diff --git a/test/kvx/instr/individual/fmuld.c b/test/kvx/instr/individual/fmuld.c
new file mode 100644
index 00000000..03c990fa
--- /dev/null
+++ b/test/kvx/instr/individual/fmuld.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(double)
+{
+ c = ((double)a * (double)b);
+}
+END_TESTF64()
diff --git a/test/kvx/instr/individual/fmulw.c b/test/kvx/instr/individual/fmulw.c
new file mode 100644
index 00000000..f85eba64
--- /dev/null
+++ b/test/kvx/instr/individual/fmulw.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(float)
+{
+ c = ((float)a * (float)b);
+}
+END_TESTF32()
diff --git a/test/kvx/instr/individual/fnegd.c b/test/kvx/instr/individual/fnegd.c
new file mode 100644
index 00000000..974eb7e8
--- /dev/null
+++ b/test/kvx/instr/individual/fnegd.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(double)
+{
+ c = (-(double)a);
+}
+END_TESTF64()
diff --git a/test/kvx/instr/individual/fnegw.c b/test/kvx/instr/individual/fnegw.c
new file mode 100644
index 00000000..fbeaab8e
--- /dev/null
+++ b/test/kvx/instr/individual/fnegw.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(float)
+{
+ c = (-(float)a);
+}
+END_TESTF64()
diff --git a/test/kvx/instr/individual/for.c b/test/kvx/instr/individual/for.c
new file mode 100644
index 00000000..373ab6bd
--- /dev/null
+++ b/test/kvx/instr/individual/for.c
@@ -0,0 +1,9 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ int j;
+ for (j = 0 ; j < 10 ; j++)
+ c += a;
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/forvar.c b/test/kvx/instr/individual/forvar.c
new file mode 100644
index 00000000..9e43c198
--- /dev/null
+++ b/test/kvx/instr/individual/forvar.c
@@ -0,0 +1,9 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ int k;
+ for (k = 0 ; k < (b & 0x8) ; k++)
+ c += a;
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/forvarl.c b/test/kvx/instr/individual/forvarl.c
new file mode 100644
index 00000000..c1fe90fd
--- /dev/null
+++ b/test/kvx/instr/individual/forvarl.c
@@ -0,0 +1,10 @@
+#include "framework.h"
+
+BEGIN_TEST(long long int)
+{
+ int j;
+
+ for (j = 0 ; j < (b & 0x8LL) ; j++)
+ c += a;
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/fsbfd.c b/test/kvx/instr/individual/fsbfd.c
new file mode 100644
index 00000000..f80c1efe
--- /dev/null
+++ b/test/kvx/instr/individual/fsbfd.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(double)
+{
+ c = ((double)a - (double)b);
+}
+END_TESTF64()
diff --git a/test/kvx/instr/individual/fsbfw.c b/test/kvx/instr/individual/fsbfw.c
new file mode 100644
index 00000000..067c40b5
--- /dev/null
+++ b/test/kvx/instr/individual/fsbfw.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(float)
+{
+ c = ((float)a - (float)b);
+}
+END_TESTF64()
diff --git a/test/kvx/instr/individual/indirect_call.c b/test/kvx/instr/individual/indirect_call.c
new file mode 100644
index 00000000..f376c00a
--- /dev/null
+++ b/test/kvx/instr/individual/indirect_call.c
@@ -0,0 +1,33 @@
+#include "framework.h"
+
+long long sum(long long a, long long b){
+ return a+b;
+}
+
+long long diff(long long a, long long b){
+ return a-b;
+}
+
+long long mul(long long a, long long b){
+ return a*b;
+}
+
+long long make(long long a){
+ return a;
+}
+
+BEGIN_TEST(long long)
+{
+ long long d = 3;
+ long long (*op)(long long, long long);
+
+ if (a % d == 0)
+ op = sum;
+ else if (a % d == 1)
+ op = diff;
+ else
+ op = mul;
+
+ c += op(make(a), make(b));
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/indirect_tailcall.c b/test/kvx/instr/individual/indirect_tailcall.c
new file mode 100644
index 00000000..e6c16ea1
--- /dev/null
+++ b/test/kvx/instr/individual/indirect_tailcall.c
@@ -0,0 +1,33 @@
+#include "framework.h"
+
+long long sum(long long a, long long b){
+ return a+b;
+}
+
+long long diff(long long a, long long b){
+ return a-b;
+}
+
+long long mul(long long a, long long b){
+ return a*b;
+}
+
+long long random_op(long long a, long long b){
+ long long d = 3;
+ long long (*op)(long long, long long);
+
+ if (a % d == 0)
+ op = sum;
+ else if (a % d == 1)
+ op = diff;
+ else
+ op = mul;
+
+ return op(a, b);
+}
+
+BEGIN_TEST(long long)
+{
+ c += random_op(a, b);
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/lbs.c b/test/kvx/instr/individual/lbs.c
new file mode 100644
index 00000000..22a50632
--- /dev/null
+++ b/test/kvx/instr/individual/lbs.c
@@ -0,0 +1,9 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ char s[] = "Tome and Cherry at the playa\n";
+
+ c = s[(a & (sizeof(s)-1))];
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/lbz.c b/test/kvx/instr/individual/lbz.c
new file mode 100644
index 00000000..04ba098d
--- /dev/null
+++ b/test/kvx/instr/individual/lbz.c
@@ -0,0 +1,9 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ unsigned char s[] = "Tim is sorry at the playa\n";
+
+ c = s[a & (sizeof(s) - 1)];
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/muld.c b/test/kvx/instr/individual/muld.c
new file mode 100644
index 00000000..f7e23850
--- /dev/null
+++ b/test/kvx/instr/individual/muld.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ c = a*b;
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/mulw.c b/test/kvx/instr/individual/mulw.c
new file mode 100644
index 00000000..a91d966e
--- /dev/null
+++ b/test/kvx/instr/individual/mulw.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ c = a * b;
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/negd.c b/test/kvx/instr/individual/negd.c
new file mode 100644
index 00000000..837b9828
--- /dev/null
+++ b/test/kvx/instr/individual/negd.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ c = -a;
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/ord.c b/test/kvx/instr/individual/ord.c
new file mode 100644
index 00000000..cae1ae8b
--- /dev/null
+++ b/test/kvx/instr/individual/ord.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ c = a | b;
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/sbfd.c b/test/kvx/instr/individual/sbfd.c
new file mode 100644
index 00000000..77c28c77
--- /dev/null
+++ b/test/kvx/instr/individual/sbfd.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ c = a-b;
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/sbfw.c b/test/kvx/instr/individual/sbfw.c
new file mode 100644
index 00000000..e38a1fff
--- /dev/null
+++ b/test/kvx/instr/individual/sbfw.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ c = a-b;
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/simple.c b/test/kvx/instr/individual/simple.c
new file mode 100644
index 00000000..944f09c9
--- /dev/null
+++ b/test/kvx/instr/individual/simple.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ c = a+b;
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/sllw.c b/test/kvx/instr/individual/sllw.c
new file mode 100644
index 00000000..6dd41a6c
--- /dev/null
+++ b/test/kvx/instr/individual/sllw.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+{
+ c = a << (b & 0x8);
+}
+END_TEST32()
diff --git a/test/kvx/instr/individual/srad.c b/test/kvx/instr/individual/srad.c
new file mode 100644
index 00000000..00be9d0c
--- /dev/null
+++ b/test/kvx/instr/individual/srad.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ c = a >> (b & 0x8LL);
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/srld.c b/test/kvx/instr/individual/srld.c
new file mode 100644
index 00000000..14970efd
--- /dev/null
+++ b/test/kvx/instr/individual/srld.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned long long)
+{
+ c = a >> (b & 0x8ULL);
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/tailcall.c b/test/kvx/instr/individual/tailcall.c
new file mode 100644
index 00000000..6c659a01
--- /dev/null
+++ b/test/kvx/instr/individual/tailcall.c
@@ -0,0 +1,16 @@
+#include "framework.h"
+
+int make(int a){
+ return a;
+}
+
+int sum(int a, int b){
+ return make(a+b);
+}
+
+BEGIN_TEST(int)
+{
+ c = sum(a, b);
+}
+END_TEST32()
+/* RETURN VALUE: 60 */
diff --git a/test/kvx/instr/individual/udivd.c b/test/kvx/instr/individual/udivd.c
new file mode 100644
index 00000000..cfb31881
--- /dev/null
+++ b/test/kvx/instr/individual/udivd.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned long long)
+{
+ c = a/b;
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/umodd.c b/test/kvx/instr/individual/umodd.c
new file mode 100644
index 00000000..a7f25f1c
--- /dev/null
+++ b/test/kvx/instr/individual/umodd.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned long long)
+{
+ c = a%b;
+}
+END_TEST64()
diff --git a/test/kvx/instr/individual/xord.c b/test/kvx/instr/individual/xord.c
new file mode 100644
index 00000000..b6a90cb0
--- /dev/null
+++ b/test/kvx/instr/individual/xord.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(long long)
+{
+ c = a^b;
+}
+END_TEST64()
diff --git a/test/kvx/instr/modi32.c b/test/kvx/instr/modi32.c
new file mode 100644
index 00000000..958ae920
--- /dev/null
+++ b/test/kvx/instr/modi32.c
@@ -0,0 +1,5 @@
+#include "framework.h"
+
+BEGIN_TEST(int)
+ c = a%b;
+END_TEST32()
diff --git a/test/kvx/instr/modui32.c b/test/kvx/instr/modui32.c
new file mode 100644
index 00000000..a39034a8
--- /dev/null
+++ b/test/kvx/instr/modui32.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned int)
+{
+ c = a%b;
+}
+END_TEST32()
diff --git a/test/kvx/instr/ui32.c b/test/kvx/instr/ui32.c
new file mode 100644
index 00000000..f56a9b95
--- /dev/null
+++ b/test/kvx/instr/ui32.c
@@ -0,0 +1,12 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned int)
+{
+ c = (long long) a;
+ c += (a >= b);
+ c += (a > b);
+ c += (a <= b);
+ c += (a < b);
+ c += ((a & 0x1U) != (b & 0x1U));
+}
+END_TEST32()
diff --git a/test/kvx/instr/ui64.c b/test/kvx/instr/ui64.c
new file mode 100644
index 00000000..908dec3c
--- /dev/null
+++ b/test/kvx/instr/ui64.c
@@ -0,0 +1,10 @@
+#include "framework.h"
+
+BEGIN_TEST(unsigned long long)
+{
+ c = (a > b);
+ c += (a <= b);
+ c += (a < b);
+ c += ((a & 0x1ULL) != (b & 0x1ULL));
+}
+END_TEST64()
diff --git a/test/kvx/interop/.gitignore b/test/kvx/interop/.gitignore
new file mode 100644
index 00000000..ea1472ec
--- /dev/null
+++ b/test/kvx/interop/.gitignore
@@ -0,0 +1 @@
+output/
diff --git a/test/kvx/interop/Makefile b/test/kvx/interop/Makefile
new file mode 100644
index 00000000..a0d4d7da
--- /dev/null
+++ b/test/kvx/interop/Makefile
@@ -0,0 +1,365 @@
+SHELL := /bin/bash
+
+KVXC ?= k1-cos-gcc
+CC ?= gcc
+CCOMP ?= ccomp
+CFLAGS ?= -O2 -Wno-varargs
+SIMU ?= k1-mppa
+TIMEOUT ?= --signal=SIGTERM 120s
+HARDRUN ?= k1-jtag-runner
+
+DIR=./
+SRCDIR=$(DIR)
+OUTDIR=$(DIR)/out
+BINDIR=$(DIR)/bin
+ASMDIR=$(DIR)/asm
+OBJDIR=$(DIR)/obj
+COMMON=common
+VAARG_COMMON=vaarg_common
+
+##
+# Intended flow : .c -> .gcc.s -> .gcc.o -> .gcc.bin -> .gcc.out
+# -> .ccomp.s -> .ccomp.o -> .ccomp.bin -> .ccomp.out
+# -> .x86-gcc.s -> .x86-gcc.o -> .x86-gcc.bin -> .x86-gcc.out
+#
+# The .o -> .bin part uses $(COMMON).gcc.o or $(COMMON).x86-gcc.o depending on the architecture
+# There is also a $(VAARG_COMMON) that is the same than $(COMMON) but with va_arg
+##
+
+KVXCPATH=$(shell which $(KVXC))
+CCPATH=$(shell which $(CC))
+CCOMPPATH=$(shell which $(CCOMP))
+SIMUPATH=$(shell which $(SIMU))
+
+TESTNAMES ?= $(filter-out $(VAARG_COMMON),$(filter-out $(COMMON),$(notdir $(subst .c,,$(wildcard $(DIR)/*.c)))))
+
+X86_GCC_OUT=$(addprefix $(OUTDIR)/,$(addsuffix .x86-gcc.out,$(TESTNAMES)))
+GCC_SIMUOUT=$(addprefix $(OUTDIR)/,$(addsuffix .gcc.simu.out,$(TESTNAMES)))
+GCC_REV_SIMUOUT=$(addprefix $(OUTDIR)/,$(addsuffix .gcc.rev.simu.out,$(TESTNAMES)))
+CCOMP_SIMUOUT=$(addprefix $(OUTDIR)/,$(addsuffix .ccomp.simu.out,$(TESTNAMES)))
+
+GCC_HARDOUT=$(addprefix $(OUTDIR)/,$(addsuffix .gcc.hard.out,$(TESTNAMES)))
+GCC_REV_HARDOUT=$(addprefix $(OUTDIR)/,$(addsuffix .gcc.rev.hard.out,$(TESTNAMES)))
+CCOMP_HARDOUT=$(addprefix $(OUTDIR)/,$(addsuffix .ccomp.hard.out,$(TESTNAMES)))
+
+VAARG_X86_GCC_OUT=$(addprefix $(OUTDIR)/,$(addsuffix .x86-gcc.vaarg.out,$(TESTNAMES)))
+VAARG_GCC_SIMUOUT=$(addprefix $(OUTDIR)/,$(addsuffix .gcc.vaarg.simu.out,$(TESTNAMES)))
+VAARG_GCC_REV_SIMUOUT=$(addprefix $(OUTDIR)/,$(addsuffix .gcc.rev.vaarg.simu.out,$(TESTNAMES)))
+VAARG_CCOMP_SIMUOUT=$(addprefix $(OUTDIR)/,$(addsuffix .ccomp.vaarg.simu.out,$(TESTNAMES)))
+
+VAARG_GCC_HARDOUT=$(addprefix $(OUTDIR)/,$(addsuffix .gcc.vaarg.hard.out,$(TESTNAMES)))
+VAARG_GCC_REV_HARDOUT=$(addprefix $(OUTDIR)/,$(addsuffix .gcc.rev.vaarg.hard.out,$(TESTNAMES)))
+VAARG_CCOMP_HARDOUT=$(addprefix $(OUTDIR)/,$(addsuffix .ccomp.vaarg.hard.out,$(TESTNAMES)))
+
+BIN=$(addprefix $(BINDIR)/,$(addsuffix .x86-gcc.bin,$(TESTNAMES)))\
+ $(addprefix $(BINDIR)/,$(addsuffix .gcc.bin,$(TESTNAMES)))\
+ $(addprefix $(BINDIR)/,$(addsuffix .ccomp.bin,$(TESTNAMES)))\
+ $(addprefix $(BINDIR)/,$(addsuffix .gcc.rev.bin,$(TESTNAMES)))\
+ $(addprefix $(BINDIR)/,$(addsuffix .x86-gcc.vaarg.bin,$(TESTNAMES)))\
+ $(addprefix $(BINDIR)/,$(addsuffix .gcc.vaarg.bin,$(TESTNAMES)))\
+ $(addprefix $(BINDIR)/,$(addsuffix .ccomp.vaarg.bin,$(TESTNAMES)))\
+ $(addprefix $(BINDIR)/,$(addsuffix .gcc.rev.vaarg.bin,$(TESTNAMES)))
+
+##
+# Targets
+##
+
+all: $(BIN)
+
+GREEN=\033[0;32m
+RED=\033[0;31m
+NC=\033[0m
+
+.PHONY:
+test: simutest
+
+.PHONY:
+simutest: $(X86_GCC_OUT) $(GCC_SIMUOUT) $(VAARG_X86_GCC_OUT) $(VAARG_GCC_SIMUOUT)
+ @echo "Comparing x86 gcc output to k1 gcc.."
+ @for test in $(TESTNAMES); do\
+ x86out=$(OUTDIR)/$$test.x86-gcc.out;\
+ gccout=$(OUTDIR)/$$test.gcc.simu.out;\
+ vaarg_x86out=$(OUTDIR)/$$test.x86-gcc.vaarg.out;\
+ vaarg_gccout=$(OUTDIR)/$$test.gcc.vaarg.simu.out;\
+ if ! diff $$x86out $$gccout > /dev/null; then\
+ >&2 printf "$(RED)ERROR: $$x86out and $$gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$x86out and $$gccout concur$(NC)\n";\
+ fi;\
+ if ! diff $$vaarg_x86out $$vaarg_gccout > /dev/null; then\
+ >&2 printf "$(RED)ERROR: $$vaarg_x86out and $$vaarg_gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$vaarg_x86out and $$vaarg_gccout concur$(NC)\n";\
+ fi;\
+ done
+
+.PHONY:
+check: simucheck
+
+.PHONY:
+simucheck: $(GCC_SIMUOUT) $(CCOMP_SIMUOUT) $(GCC_REV_SIMUOUT) $(VAARG_GCC_SIMUOUT) $(VAARG_CCOMP_SIMUOUT) $(VAARG_GCC_REV_SIMUOUT)
+ @echo "Comparing k1 gcc output to ccomp.."
+ @for test in $(TESTNAMES); do\
+ gccout=$(OUTDIR)/$$test.gcc.simu.out;\
+ ccompout=$(OUTDIR)/$$test.ccomp.simu.out;\
+ gccrevout=$(OUTDIR)/$$test.gcc.rev.simu.out;\
+ vaarg_gccout=$(OUTDIR)/$$test.gcc.vaarg.simu.out;\
+ vaarg_ccompout=$(OUTDIR)/$$test.ccomp.vaarg.simu.out;\
+ vaarg_gccrevout=$(OUTDIR)/$$test.gcc.rev.vaarg.simu.out;\
+ if ! diff $$ccompout $$gccout > /dev/null; then\
+ >&2 printf "$(RED)ERROR: $$ccompout and $$gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$ccompout and $$gccout concur$(NC)\n";\
+ fi;\
+ if ! diff $$gccrevout $$gccout > /dev/null; then\
+ >&2 printf "$(RED)ERROR: $$gccrevout and $$gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$gccrevout and $$gccout concur$(NC)\n";\
+ fi;\
+ if ! diff $$vaarg_ccompout $$vaarg_gccout > /dev/null; then\
+ >&2 printf "$(RED)ERROR: $$vaarg_ccompout and $$vaarg_gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$vaarg_ccompout and $$vaarg_gccout concur$(NC)\n";\
+ fi;\
+ if ! diff $$vaarg_gccrevout $$vaarg_gccout > /dev/null; then\
+ >&2 printf "$(RED)ERROR: $$vaarg_gccrevout and $$vaarg_gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$vaarg_gccrevout and $$vaarg_gccout concur$(NC)\n";\
+ fi;\
+ done
+
+.PHONY:
+hardtest: $(X86_GCC_OUT) $(GCC_HARDOUT) $(VAARG_X86_GCC_OUT) $(VAARG_GCC_HARDOUT)
+ @echo "Comparing x86 gcc output to k1 gcc.."
+ @for test in $(TESTNAMES); do\
+ x86out=$(OUTDIR)/$$test.x86-gcc.out;\
+ gccout=$(OUTDIR)/$$test.gcc.hard.out;\
+ vaarg_x86out=$(OUTDIR)/$$test.x86-gcc.vaarg.out;\
+ vaarg_gccout=$(OUTDIR)/$$test.gcc.vaarg.hard.out;\
+ if ! diff $$x86out $$gccout > /dev/null; then\
+ >&2 printf "$(RED)ERROR: $$x86out and $$gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$x86out and $$gccout concur$(NC)\n";\
+ fi;\
+ if ! diff $$vaarg_x86out $$vaarg_gccout > /dev/null; then\
+ >&2 printf "$(RED)ERROR: $$vaarg_x86out and $$vaarg_gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$vaarg_x86out and $$vaarg_gccout concur$(NC)\n";\
+ fi;\
+ done
+
+.PHONY:
+hardcheck: $(GCC_HARDOUT) $(CCOMP_HARDOUT) $(GCC_REV_HARDOUT) $(VAARG_GCC_HARDOUT) $(VAARG_CCOMP_HARDOUT) $(VAARG_GCC_REV_HARDOUT)
+ @echo "Comparing k1 gcc output to ccomp.."
+ @for test in $(TESTNAMES); do\
+ gccout=$(OUTDIR)/$$test.gcc.hard.out;\
+ ccompout=$(OUTDIR)/$$test.ccomp.hard.out;\
+ gccrevout=$(OUTDIR)/$$test.gcc.rev.hard.out;\
+ vaarg_gccout=$(OUTDIR)/$$test.gcc.vaarg.hard.out;\
+ vaarg_ccompout=$(OUTDIR)/$$test.ccomp.vaarg.hard.out;\
+ vaarg_gccrevout=$(OUTDIR)/$$test.gcc.rev.vaarg.hard.out;\
+ if ! diff $$ccompout $$gccout > /dev/null; then\
+ >&2 printf "$(RED)ERROR: $$ccompout and $$gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$ccompout and $$gccout concur$(NC)\n";\
+ fi;\
+ if ! diff $$gccrevout $$gccout > /dev/null; then\
+ >&2 printf "$(RED)ERROR: $$gccrevout and $$gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$gccrevout and $$gccout concur$(NC)\n";\
+ fi;\
+ if ! diff $$vaarg_ccompout $$vaarg_gccout > /dev/null; then\
+ >&2 printf "$(RED)ERROR: $$vaarg_ccompout and $$vaarg_gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$vaarg_ccompout and $$vaarg_gccout concur$(NC)\n";\
+ fi;\
+ if ! diff $$vaarg_gccrevout $$vaarg_gccout > /dev/null; then\
+ >&2 printf "$(RED)ERROR: $$vaarg_gccrevout and $$vaarg_gccout differ$(NC)\n";\
+ else\
+ printf "$(GREEN)GOOD: $$vaarg_gccrevout and $$vaarg_gccout concur$(NC)\n";\
+ fi;\
+ done
+
+##
+# Rules
+##
+
+.SECONDARY:
+
+##
+# Generating output
+##
+
+## Version sans les timeout
+#$(OUTDIR)/%.x86-gcc.out: $(BINDIR)/%.x86-gcc.bin
+# @mkdir -p $(@D)
+# ./$< > $@; echo $$? >> $@
+#
+#$(OUTDIR)/%.gcc.out: $(BINDIR)/%.gcc.bin $(SIMUPATH)
+# @mkdir -p $(@D)
+# $(SIMU) -- $< > $@ ; echo $$? >> $@
+#
+#$(OUTDIR)/%.ccomp.out: $(BINDIR)/%.ccomp.bin $(SIMUPATH)
+# @mkdir -p $(@D)
+# $(SIMU) -- $< > $@ ; echo $$? >> $@
+
+## No vaarg
+
+$(OUTDIR)/%.x86-gcc.out: $(BINDIR)/%.x86-gcc.bin
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) ./$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.gcc.simu.out: $(BINDIR)/%.gcc.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(SIMU) -- $< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.gcc.rev.simu.out: $(BINDIR)/%.gcc.rev.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(SIMU) -- $< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.ccomp.simu.out: $(BINDIR)/%.ccomp.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(SIMU) -- $< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.gcc.hard.out: $(BINDIR)/%.gcc.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(HARDRUN) --exec-file=Cluster0:$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.gcc.rev.hard.out: $(BINDIR)/%.gcc.rev.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(HARDRUN) --exec-file=Cluster0:$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.ccomp.hard.out: $(BINDIR)/%.ccomp.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(HARDRUN) --exec-file=Cluster0:$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+## With vaarg
+
+$(OUTDIR)/%.x86-gcc.vaarg.out: $(BINDIR)/%.x86-gcc.vaarg.bin
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) ./$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.gcc.vaarg.simu.out: $(BINDIR)/%.gcc.vaarg.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(SIMU) -- $< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.gcc.rev.vaarg.simu.out: $(BINDIR)/%.gcc.rev.vaarg.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(SIMU) -- $< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.ccomp.vaarg.simu.out: $(BINDIR)/%.ccomp.vaarg.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(SIMU) -- $< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.gcc.vaarg.hard.out: $(BINDIR)/%.gcc.vaarg.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(HARDRUN) --exec-file=Cluster0:$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.gcc.rev.vaarg.hard.out: $(BINDIR)/%.gcc.rev.vaarg.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(HARDRUN) --exec-file=Cluster0:$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.ccomp.vaarg.hard.out: $(BINDIR)/%.ccomp.vaarg.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(HARDRUN) --exec-file=Cluster0:$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+##
+# Object to binary
+##
+
+## common
+
+$(BINDIR)/$(COMMON).x86-gcc.bin: $(OBJDIR)/$(COMMON).x86-gcc.o $(CCPATH)
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) $< -o $@
+
+$(BINDIR)/$(COMMON).gcc.bin: $(OBJDIR)/$(COMMON).gcc.o $(KVXCPATH)
+ @mkdir -p $(@D)
+ $(KVXC) $(CFLAGS) $< -o $@
+
+$(BINDIR)/$(COMMON).ccomp.bin: $(OBJDIR)/$(COMMON).ccomp.o $(CCOMPPATH)
+ @mkdir -p $(@D)
+ $(CCOMP) $(CFLAGS) $< -o $@
+
+## vaarg_common
+
+$(BINDIR)/$(VAARG_COMMON).x86-gcc.bin: $(OBJDIR)/$(VAARG_COMMON).x86-gcc.o $(CCPATH)
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) $< -o $@
+
+$(BINDIR)/$(VAARG_COMMON).gcc.bin: $(OBJDIR)/$(VAARG_COMMON).gcc.o $(KVXCPATH)
+ @mkdir -p $(@D)
+ $(KVXC) $(CFLAGS) $< -o $@
+
+$(BINDIR)/$(VAARG_COMMON).ccomp.bin: $(OBJDIR)/$(VAARG_COMMON).ccomp.o $(CCOMPPATH)
+ @mkdir -p $(@D)
+ $(CCOMP) $(CFLAGS) $< -o $@
+
+## no vaarg
+
+$(BINDIR)/%.x86-gcc.bin: $(OBJDIR)/%.x86-gcc.o $(OBJDIR)/$(COMMON).x86-gcc.o $(CCPATH)
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) $(wordlist 1,2,$^) -o $@
+
+$(BINDIR)/%.gcc.bin: $(OBJDIR)/%.gcc.o $(OBJDIR)/$(COMMON).gcc.o $(KVXCPATH)
+ @mkdir -p $(@D)
+ $(KVXC) $(CFLAGS) $(wordlist 1,2,$^) -o $@
+
+$(BINDIR)/%.gcc.rev.bin: $(OBJDIR)/%.gcc.o $(OBJDIR)/$(COMMON).ccomp.o $(KVXCPATH)
+ @mkdir -p $(@D)
+ $(CCOMP) $(CFLAGS) $(wordlist 1,2,$^) -o $@
+
+$(BINDIR)/%.ccomp.bin: $(OBJDIR)/%.ccomp.o $(OBJDIR)/$(COMMON).gcc.o $(CCOMPPATH)
+ @mkdir -p $(@D)
+ $(CCOMP) $(CFLAGS) $(wordlist 1,2,$^) -o $@
+
+## with vaarg
+
+$(BINDIR)/%.x86-gcc.vaarg.bin: $(OBJDIR)/%.x86-gcc.o $(OBJDIR)/$(VAARG_COMMON).x86-gcc.o $(CCPATH)
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) $(wordlist 1,2,$^) -o $@
+
+$(BINDIR)/%.gcc.vaarg.bin: $(OBJDIR)/%.gcc.o $(OBJDIR)/$(VAARG_COMMON).gcc.o $(KVXCPATH)
+ @mkdir -p $(@D)
+ $(KVXC) $(CFLAGS) $(wordlist 1,2,$^) -o $@
+
+$(BINDIR)/%.gcc.rev.vaarg.bin: $(OBJDIR)/%.gcc.o $(OBJDIR)/$(VAARG_COMMON).ccomp.o $(KVXCPATH)
+ @mkdir -p $(@D)
+ $(CCOMP) $(CFLAGS) $(wordlist 1,2,$^) -o $@
+
+$(BINDIR)/%.ccomp.vaarg.bin: $(OBJDIR)/%.ccomp.o $(OBJDIR)/$(VAARG_COMMON).gcc.o $(CCOMPPATH)
+ @mkdir -p $(@D)
+ $(CCOMP) $(CFLAGS) $(wordlist 1,2,$^) -o $@
+
+##
+# Assembly to object
+##
+
+$(OBJDIR)/%.x86-gcc.o: $(ASMDIR)/%.x86-gcc.s $(CCPATH)
+ @mkdir -p $(@D)
+ $(CC) -c $(CFLAGS) $< -o $@
+
+$(OBJDIR)/%.gcc.o: $(ASMDIR)/%.gcc.s $(KVXCPATH)
+ @mkdir -p $(@D)
+ $(KVXC) -c $(CFLAGS) $< -o $@
+
+$(OBJDIR)/%.ccomp.o: $(ASMDIR)/%.ccomp.s $(CCOMPPATH)
+ @mkdir -p $(@D)
+ $(CCOMP) -c $(CFLAGS) $< -o $@
+
+
+##
+# Source to assembly
+##
+
+$(ASMDIR)/%.x86-gcc.s: $(SRCDIR)/%.c $(CCPATH)
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) -S $< -o $@
+
+$(ASMDIR)/%.gcc.s: $(SRCDIR)/%.c $(KVXCPATH)
+ @mkdir -p $(@D)
+ $(KVXC) $(CFLAGS) -S $< -o $@
+
+$(ASMDIR)/%.ccomp.s: $(SRCDIR)/%.c $(CCOMPPATH)
+ @mkdir -p $(@D)
+ $(CCOMP) $(CFLAGS) -S $< -o $@
diff --git a/test/kvx/interop/common.c b/test/kvx/interop/common.c
new file mode 100644
index 00000000..05b49187
--- /dev/null
+++ b/test/kvx/interop/common.c
@@ -0,0 +1,257 @@
+#define STACK int a[100];\
+ a[42] = 42;
+
+#define ONEARG_OP(arg) (3*magic(arg)+2)
+
+#define MULTIARG_OP(arg1, arg2, arg3, arg4) (arg1 ^ magic(arg2) << arg3 - arg4)
+
+#define MANYARG_OP(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,\
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19,\
+ a20, a21, a22, a23, a24, a25, a26, a27, a28, a29)\
+ (a0 * a1 * a2 * magic(a3) * a4 * a5 * a6 * a7 * a8 * a9 *\
+ a10 * a11 * a12 * a13 * a14 * a15 * a16 * a17 * a18 * a19 *\
+ a20 * a21 * a22 * a23 * a24 * a25 * a26 * a27 * a28 * a29)
+
+int magic(long a){
+ return a*42 + 26;
+}
+
+void void_void(){
+ STACK;
+}
+
+long long ll_void(){
+ STACK;
+ return 0xdeadbeefdeadbeefULL;
+}
+
+int i_oneiarg(int arg){
+ STACK;
+ return ONEARG_OP(arg);
+}
+
+int i_multiiargs(int arg1, char arg2, char arg3, int arg4){
+ STACK;
+ return MULTIARG_OP(arg1, arg2, arg3, arg4);
+}
+
+int i_manyiargs(char a0, int a1, char a2, int a3, char a4, char a5, int a6, int a7, char a8, int a9,
+ char a10, int a11, char a12, int a13, char a14, char a15, int a16, int a17, char a18, int a19,
+ char a20, int a21, char a22, int a23, char a24, char a25, int a26, int a27, char a28, int a29)
+{
+ STACK;
+ return MANYARG_OP(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19,
+ a20, a21, a22, a23, a24, a25, a26, a27, a28, a29);
+}
+
+int ll_onellarg(long long arg){
+ STACK;
+ return ONEARG_OP(arg);
+}
+
+long long ll_multillargs(long long arg1, char arg2, char arg3, long long arg4){
+ STACK;
+ return MULTIARG_OP(arg1, arg2, arg3, arg4);
+}
+
+long long ll_manyllargs(char a0, int a1, char a2, long long a3, char a4, char a5, long long a6, long long a7, char a8, long long a9,
+ char a10, long long a11, char a12, int a13, char a14, char a15, long long a16, long long a17, char a18, long long a19,
+ char a20, int a21, char a22, long long a23, char a24, char a25, long long a26, int a27, char a28, long long a29)
+{
+ STACK;
+ return MANYARG_OP(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19,
+ a20, a21, a22, a23, a24, a25, a26, a27, a28, a29);
+}
+
+double stackhell(char a0, int a1, float a2, long long a3, double a4, char a5, long long a6, long long a7, float a8, long long a9,
+ double a10, long long a11, char a12, int a13, float a14, double a15, long long a16, long long a17, float a18, long long a19,
+ char a20, int a21, char a22, long long a23, float a24, char a25, long long a26, int a27, double a28, long long a29)
+{
+ long long b0 = a0;
+ long long b1 = a1 * b0;
+ long long b2 = a2 * b1;
+ float b3 = a3 * b2;
+ int b4 = a4 * b3;
+ double b5 = a5 * b4;
+ int b6 = a6 * b5;
+ float b7 = a7 * b6;
+ char b8 = a8 * b7;
+ double b9 = a9 * b8;
+ char b10 = a10 * b9;
+ float b11 = a11 * b10;
+ char b12 = a12 * b11;
+ int b13 = a13 * b12;
+ long long b14 = a14 * b13;
+ long long b15 = a15 * b14;
+ long long b16 = a16 * b15;
+ long long b17 = a17 * b16;
+ long long b18 = a18 * b17;
+ long long b19 = a19 * b18;
+ long long b20 = a20 * b19;
+ long long b21 = a21 * b20;
+ long long b22 = a22 * b21;
+ long long b23 = a23 * b22;
+ long long b24 = a24 * b23;
+ long long b25 = a25 * b24;
+ long long b26 = a26 * b25;
+ long long b27 = a27 * b26;
+ int b28 = a28 * b27;
+ double b29 = a29 * b28;
+ float b30 = b0 * b29;
+ double b31 = b1 * b30;
+ int b32 = b2 * b31;
+ char b33 = b3 * b32;
+ float b34 = b4 * b33;
+ char b35 = b5 * b34;
+ double b36 = b6 * b35;
+ float b37 = b7 * b36;
+ int b38 = b8 * b37;
+ double b39 = b9 * b38;
+ float b40 = b0 * b39;
+ int b41 = b1 * b40;
+ double b42 = b2 * b41;
+ float b43 = b3 * b42;
+ int b44 = b4 * b43;
+ double b45 = b5 * b44;
+ int b46 = b6 * b45;
+ double b47 = b7 * b46;
+ int b48 = b8 * b47;
+ long long b49 = b9 * b48;
+ long long b50 = b0 * b49;
+ long long b51 = b1 * b50;
+ long long b52 = b2 * b51;
+ long long b53 = b3 * b52;
+ long long b54 = b4 * b53;
+ long long b55 = b5 * b54;
+ long long b56 = b6 * b55;
+ long long b57 = b7 * b56;
+ int b58 = b8 * b57;
+ float b59 = b9 * b58;
+ int b60 = b0 * b59;
+ float b61 = b1 * b60;
+ float b62 = b2 * b61;
+ int b63 = b3 * b62;
+ double b64 = b4 * b63;
+ int b65 = b5 * b64;
+ int b66 = b6 * b65;
+ double b67 = b7 * b66;
+ double b68 = b8 * b67;
+ int b69 = b9 * b68;
+ char b70 = b0 * b69;
+ char b71 = b1 * b70;
+ double b72 = b2 * b71;
+ double b73 = b3 * b72;
+ char b74 = b4 * b73;
+ float b75 = b5 * b74;
+ float b76 = b6 * b75;
+ double b77 = b7 * b76;
+ char b78 = b8 * b77;
+ float b79 = b9 * b78;
+ float b80 = b0 * b79;
+ char b81 = b1 * b80;
+ char b82 = b2 * b81;
+ float b83 = b3 * b82;
+ char b84 = b4 * b83;
+ int b85 = b5 * b84;
+ int b86 = b6 * b85;
+ double b87 = b7 * b86;
+ float b88 = b8 * b87;
+ double b89 = b9 * b88;
+ int b90 = b0 * b89;
+ float b91 = b1 * b90;
+ double b92 = b2 * b91;
+ int b93 = b3 * b92;
+ int b94 = b4 * b93;
+ long long b95 = b5 * b94;
+ long long b96 = b6 * b95;
+ long long b97 = b7 * b96;
+ long long b98 = b8 * b97;
+ long long b99 = b9 * b98;
+ long long b100 = b0 * b99;
+ long long b101 = b1 * b100;
+ long long b102 = b2 * b101;
+ long long b103 = b3 * b102;
+ long long b104 = b4 * b103;
+ long long b105 = b5 * b104;
+ long long b106 = b6 * b105;
+ long long b107 = b7 * b106;
+ long long b108 = b8 * b107;
+ long long b109 = b9 * b108;
+ long long b110 = b0 * b109;
+ long long b111 = b1 * b110;
+ long long b112 = b2 * b111;
+ long long b113 = b3 * b112;
+ long long b114 = b4 * b113;
+ int b115 = b5 * b114;
+ int b116 = b6 * b115;
+ int b117 = b7 * b116;
+ float b118 = b8 * b117;
+ float b119 = b9 * b118;
+ int b120 = b0 * b119;
+ double b121 = b1 * b120;
+ float b122 = b2 * b121;
+ int b123 = b3 * b122;
+ double b124 = b4 * b123;
+ int b125 = b5 * b124;
+ char b126 = b6 * b125;
+ double b127 = b7 * b126;
+ char b128 = b8 * b127;
+ float b129 = b9 * b128;
+ char b130 = b0 * b129;
+ double b131 = b1 * b130;
+ char b132 = b2 * b131;
+ float b133 = b3 * b132;
+ char b134 = b4 * b133;
+ double b135 = b5 * b134;
+ char b136 = b6 * b135;
+ float b137 = b7 * b136;
+ char b138 = b8 * b137;
+ double b139 = b9 * b138;
+ char b140 = b0 * b139;
+ float b141 = b1 * b140;
+ char b142 = b2 * b141;
+ double b143 = b3 * b142;
+ char b144 = b4 * b143;
+ float b145 = b5 * b144;
+ char b146 = b6 * b145;
+ double b147 = b7 * b146;
+ int b148 = b8 * b147;
+ float b149 = b9 * b148;
+ int b150 = b0 * b149;
+ double b151 = b1 * b150;
+ int b152 = b2 * b151;
+ float b153 = b3 * b152;
+ int b154 = b4 * b153;
+ double b155 = b5 * b154;
+ int b156 = b6 * b155;
+ float b157 = b7 * b156;
+ int b158 = b8 * b157;
+ double b159 = b9 * b158;
+ int b160 = b0 * b159;
+ float b161 = b1 * b160;
+ int b162 = b2 * b161;
+ return MANYARG_OP(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19,
+ a20, a21, a22, a23, a24, a25, a26, a27, a28, a29)
+ * b0 * b1 * b2 * b3 * b4 * b5 * b6 * b7 * b8 * b9
+ * b10 * b11 * b12 * b13 * b14 * b15 * b16 * b17 * b18 * b19
+ * b20 * b21 * b22 * b23 * b24 * b25 * b26 * b27 * b28 * b29
+ * b30 * b31 * b32 * b33 * b34 * b35 * b36 * b37 * b38 * b39
+ * b40 * b41 * b42 * b43 * b44 * b45 * b46 * b47 * b48 * b49
+ * b50 * b51 * b52 * b53 * b54 * b55 * b56 * b57 * b58 * b59
+ * b60 * b61 * b62 * b63 * b64 * b65 * b66 * b67 * b68 * b69
+ * b70 * b71 * b72 * b73 * b74 * b75 * b76 * b77 * b78 * b79
+ * b80 * b81 * b82 * b83 * b84 * b85 * b86 * b87 * b88 * b89
+ * b90 * b91 * b92 * b93 * b94 * b95 * b96 * b97 * b98 * b99
+ * b100 * b101 * b102 * b103 * b104 * b105 * b106 * b107 * b108 * b109
+ * b110 * b111 * b112 * b113 * b114 * b115 * b116 * b117 * b118 * b119
+ * b120 * b121 * b122 * b123 * b124 * b125 * b126 * b127 * b128 * b129
+ * b130 * b131 * b132 * b133 * b134 * b135 * b136 * b137 * b138 * b139
+ * b140 * b141 * b142 * b143 * b144 * b145 * b146 * b147 * b148 * b149
+ * b150 * b151 * b152 * b153 * b154 * b155 * b156 * b157 * b158 * b159
+ * b160 * b161 * b162
+ ;
+}
+
diff --git a/test/kvx/interop/common.h b/test/kvx/interop/common.h
new file mode 100644
index 00000000..055ce7ea
--- /dev/null
+++ b/test/kvx/interop/common.h
@@ -0,0 +1,28 @@
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+void void_void(void);
+
+long long ll_void(void);
+
+int i_oneiarg(int arg);
+
+int i_multiiargs(int arg1, char arg2, char arg3, int arg4);
+
+int i_manyiargs(char a0, int a1, char a2, int a3, char a4, char a5, int a6, int a7, char a8, int a9,
+ char a10, int a11, char a12, int a13, char a14, char a15, int a16, int a17, char a18, int a19,
+ char a20, int a21, char a22, int a23, char a24, char a25, int a26, int a27, char a28, int a29);
+
+int ll_onellarg(long long arg);
+
+long long ll_multillargs(long long arg1, char arg2, char arg3, long long arg4);
+
+long long ll_manyllargs(char a0, long long a1, char a2, long long a3, char a4, char a5, long long a6, long long a7, char a8, long long a9,
+ char a10, long long a11, char a12, long long a13, char a14, char a15, long long a16, long long a17, char a18, long long a19,
+ char a20, long long a21, char a22, long long a23, char a24, char a25, long long a26, long long a27, char a28, long long a29);
+
+double stackhell(char a0, long long a1, char a2, long long a3, char a4, char a5, long long a6, long long a7, char a8, long long a9,
+ char a10, long long a11, char a12, long long a13, char a14, char a15, long long a16, long long a17, char a18, long long a19,
+ char a20, long long a21, char a22, long long a23, char a24, char a25, long long a26, long long a27, char a28, long long a29);
+
+#endif
diff --git a/test/kvx/interop/framework.h b/test/kvx/interop/framework.h
new file mode 100644
index 00000000..3bbfa271
--- /dev/null
+++ b/test/kvx/interop/framework.h
@@ -0,0 +1,66 @@
+#ifndef __FRAMEWORK_H__
+#define __FRAMEWORK_H__
+
+#include <stdio.h>
+#include "../prng/prng.c"
+
+#define BEGIN_TEST_N(type, N)\
+ int main(void){\
+ type t[N], c, i, j, S;\
+ srand(0);\
+ S = 0;\
+ for (i = 0 ; i < 100 ; i++){\
+ c = randlong();\
+ for (j = 0 ; j < N ; j++)\
+ t[j] = randlong();\
+ /* END BEGIN_TEST_N */
+
+#define BEGIN_TEST(type)\
+ int main(void){\
+ type a, b, c, S;\
+ int i;\
+ srand(0);\
+ S = 0;\
+ for (i = 0 ; i < 100 ; i++){\
+ c = randlong();\
+ a = randlong();\
+ b = randlong();
+ /* END BEGIN_TEST */
+
+/* In between BEGIN_TEST and END_TEST : definition of c */
+
+#define END_TEST64()\
+ printf("%llu\t%llu\t%llu\n", a, b, c);\
+ S += c;\
+ }\
+ return S;\
+ }
+ /* END END_TEST64 */
+
+#define END_TEST32()\
+ printf("%u\t%u\t%u\n", a, b, c);\
+ S += c;\
+ }\
+ return S;\
+ }
+ /* END END_TEST32 */
+
+#define END_TESTF32()\
+ printf("%e\t%e\t%e\n", a, b, c);\
+ S += c;\
+ }\
+ return 0;\
+ }
+ /* END END_TESTF32 */
+
+#define END_TESTF64()\
+ printf("%e\t%e\t%e\n", a, b, c);\
+ S += c;\
+ }\
+ return 0;\
+ }
+ /* END END_TESTF64 */
+
+#endif
+
+
diff --git a/test/kvx/interop/i32.c b/test/kvx/interop/i32.c
new file mode 100644
index 00000000..6bc2705c
--- /dev/null
+++ b/test/kvx/interop/i32.c
@@ -0,0 +1,13 @@
+#include "framework.h"
+#include "common.h"
+
+BEGIN_TEST(int)
+ c = i_manyiargs(a, b, a-b, a+b, a*2, b*2, a*2-b, a+b*2, (a-b)*2, (a+b)*2,
+ -2*a, -2*b, a-b, a+b, a*3, b*3, a*3-b, a+b*3, (a-b)*3, (a+b)*3,
+ -3*a, -3*b, a-b, a+b, a*4, b*4, a*4-b, a+b*4, (a-b)*4, (a+b)*4);
+ c += i_multiiargs(a, b, a-b, a+b);
+ c += i_oneiarg(a);
+ void_void();
+ c += a;
+END_TEST32()
+
diff --git a/test/kvx/interop/i64.c b/test/kvx/interop/i64.c
new file mode 100644
index 00000000..3e7240f7
--- /dev/null
+++ b/test/kvx/interop/i64.c
@@ -0,0 +1,14 @@
+#include "framework.h"
+#include "common.h"
+
+BEGIN_TEST(long long)
+ c = ll_manyllargs(a, b, a-b, a+b, a*2, b*2, a*2-b, a+b*2, (a-b)*2, (a+b)*2,
+ -2*a, -2*b, a-b, a+b, a*3, b*3, a*3-b, a+b*3, (a-b)*3, (a+b)*3,
+ -3*a, -3*b, a-b, a+b, a*4, b*4, a*4-b, a+b*4, (a-b)*4, (a+b)*4);
+ c += ll_multillargs(a, b, a-b, a+b);
+ c += ll_onellarg(a);
+ c = ll_void();
+ c += a;
+ void_void();
+ c += a;
+END_TEST64()
diff --git a/test/kvx/interop/individual/i_multiiargs.c b/test/kvx/interop/individual/i_multiiargs.c
new file mode 100644
index 00000000..888742b5
--- /dev/null
+++ b/test/kvx/interop/individual/i_multiiargs.c
@@ -0,0 +1,6 @@
+#include "framework.h"
+#include "common.h"
+
+BEGIN_TEST(int)
+ c = i_multiiargs(a, b, a-b, a+b);
+END_TEST32()
diff --git a/test/kvx/interop/individual/i_oneiarg.c b/test/kvx/interop/individual/i_oneiarg.c
new file mode 100644
index 00000000..9c969fb8
--- /dev/null
+++ b/test/kvx/interop/individual/i_oneiarg.c
@@ -0,0 +1,6 @@
+#include "framework.h"
+#include "common.h"
+
+BEGIN_TEST(int)
+ c = i_oneiarg(a);
+END_TEST32()
diff --git a/test/kvx/interop/individual/ll_multillargs.c b/test/kvx/interop/individual/ll_multillargs.c
new file mode 100644
index 00000000..34b422eb
--- /dev/null
+++ b/test/kvx/interop/individual/ll_multillargs.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+#include "common.h"
+
+BEGIN_TEST(long long)
+ c = ll_multillargs(a, b, a-b, a+b);
+END_TEST64()
+
diff --git a/test/kvx/interop/individual/ll_onellarg.c b/test/kvx/interop/individual/ll_onellarg.c
new file mode 100644
index 00000000..a2fbbbe9
--- /dev/null
+++ b/test/kvx/interop/individual/ll_onellarg.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+#include "common.h"
+
+BEGIN_TEST(long long)
+ c = ll_onellarg(a);
+END_TEST64()
+
diff --git a/test/kvx/interop/individual/ll_void.c b/test/kvx/interop/individual/ll_void.c
new file mode 100644
index 00000000..da128fdd
--- /dev/null
+++ b/test/kvx/interop/individual/ll_void.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+#include "common.h"
+
+BEGIN_TEST(long long)
+ c = ll_void();
+ c += a;
+END_TEST64()
diff --git a/test/kvx/interop/individual/void_void.c b/test/kvx/interop/individual/void_void.c
new file mode 100644
index 00000000..976a721b
--- /dev/null
+++ b/test/kvx/interop/individual/void_void.c
@@ -0,0 +1,7 @@
+#include "framework.h"
+#include "common.h"
+
+BEGIN_TEST(long long)
+ void_void();
+ c = a;
+END_TEST64()
diff --git a/test/kvx/interop/stackhell.c b/test/kvx/interop/stackhell.c
new file mode 100644
index 00000000..5abaa71d
--- /dev/null
+++ b/test/kvx/interop/stackhell.c
@@ -0,0 +1,9 @@
+#include "framework.h"
+#include "common.h"
+
+BEGIN_TEST(double)
+ c = stackhell(a, b, a*b, a*b, a*2, b*2, a*2*b, a*b*2, (a*b)*2, (a*b)*2,
+ 2*a, 2*b, a*b, a*b, a*3, b*3, a*3*b, a*b*3, (a*b)*3, (a*b)*3,
+ 3*a, 3*b, a*b, a*b, a*4, b*4, a*4*b, a*b*4, (a*b)*4, (a*b)*4);
+
+END_TESTF64()
diff --git a/test/kvx/interop/vaarg_common.c b/test/kvx/interop/vaarg_common.c
new file mode 100644
index 00000000..3314959f
--- /dev/null
+++ b/test/kvx/interop/vaarg_common.c
@@ -0,0 +1,383 @@
+#include <stdarg.h>
+
+#define STACK int a[100];\
+ a[42] = 42;
+
+#define ONEARG_OP(arg) (3*magic(arg)+2)
+
+#define MULTIARG_OP(arg1, arg2, arg3, arg4) (arg1 ^ magic(arg2) << arg3 - arg4)
+
+#define MANYARG_OP(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,\
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19,\
+ a20, a21, a22, a23, a24, a25, a26, a27, a28, a29)\
+ (a0 + a1 * a2 + magic(a3) * a4 + a5 + a6 + a7 - a8 + a9 +\
+ a10 + a11 - a12 ^ a13 + a14 - magic(a15) + a16 ^ a17 + a18 + a19 +\
+ a20 + a21 + a22 * a23 + a24 + a25 << a26 & a27 + a28 + a29)
+
+#define VA_START(vl, arg) va_list vl; va_start(vl, arg)
+#define VA_END(vl) va_end(vl)
+
+int magic(long a){
+ return a*2 + 42;
+}
+
+void void_void(void){
+ STACK;
+}
+
+long long ll_void(void){
+ STACK;
+ return 0xdeadbeefdeadbeefULL;
+}
+
+// int i_oneiarg(int arg){
+int i_oneiarg(int arg, ...){
+ STACK;
+ VA_START(vl, arg);
+ VA_END(vl);
+ return ONEARG_OP(arg);
+}
+
+//int i_multiiargs(int arg1, char arg2, char arg3, int arg4){
+int i_multiiargs(int arg1, ...){
+ STACK;
+ VA_START(vl, arg1);
+ char arg2 = va_arg(vl, int);
+ char arg3 = va_arg(vl, int);
+ int arg4 = va_arg(vl, int);
+ VA_END(vl);
+ return MULTIARG_OP(arg1, arg2, arg3, arg4);
+}
+
+//int i_manyiargs(char a0, int a1, char a2, int a3, char a4, char a5, int a6, int a7, char a8, int a9,
+// char a10, int a11, char a12, int a13, char a14, char a15, int a16, int a17, char a18, int a19,
+// char a20, int a21, char a22, int a23, char a24, char a25, int a26, int a27, char a28, int a29)
+int i_manyiargs(char a0, ...)
+{
+ STACK;
+ VA_START(vl, a0);
+ VA_START(vl2, a0);
+ int a1 = va_arg(vl, int);
+ char a2 = va_arg(vl, int);
+ int a3 = va_arg(vl, int);
+ char a4 = va_arg(vl, int);
+ char a5 = va_arg(vl, int);
+ char b1 = va_arg(vl2, int);
+ int a6 = va_arg(vl, int);
+ int a7 = va_arg(vl, int);
+ char a8 = va_arg(vl, int);
+ char b2 = va_arg(vl2, int);
+ int a9 = va_arg(vl, int);
+ char a10 = va_arg(vl, int);
+ int a11 = va_arg(vl, int);
+ char a12 = va_arg(vl, int);
+ char b3 = va_arg(vl2, int);
+ int a13 = va_arg(vl, int);
+ char a14 = va_arg(vl, int);
+ char a15 = va_arg(vl, int);
+ int a16 = va_arg(vl, int);
+ int a17 = va_arg(vl, int);
+ char a18 = va_arg(vl, int);
+ int a19 = va_arg(vl, int);
+ char a20 = va_arg(vl, int);
+ int a21 = va_arg(vl, int);
+ char a22 = va_arg(vl, int);
+ int a23 = va_arg(vl, int);
+ char a24 = va_arg(vl, int);
+ char a25 = va_arg(vl, int);
+ int a26 = va_arg(vl, int);
+ char b4 = va_arg(vl2, int);
+ int a27 = va_arg(vl, int);
+ char a28 = va_arg(vl, int);
+ int a29 = va_arg(vl, int);
+ VA_END(vl);
+ VA_END(vl);
+ return MANYARG_OP(a0, a1, a2, a3, a4, (a5*b2), a6, a7, a8, a9,
+ (a10*b3), a11, a12, a13, a14, a15, a16, a17, a18, a19,
+ a20, (a21*b1), a22, a23, (a24*b3), a25, a26, a27, a28, a29);
+}
+
+//int ll_onellarg(long long arg){
+int ll_onellarg(long long arg, ...){
+ STACK;
+ VA_START(vl, arg);
+ VA_END(vl);
+ return ONEARG_OP(arg);
+}
+
+//long long ll_multillargs(long long arg1, char arg2, char arg3, long long arg4){
+long long ll_multillargs(long long arg1, ...){
+ STACK;
+ VA_START(vl, arg1);
+ char arg2 = va_arg(vl, int);
+ char arg3 = va_arg(vl, int);
+ long long arg4 = va_arg(vl, long long);
+ VA_END(vl);
+ return MULTIARG_OP(arg1, arg2, arg3, arg4);
+}
+
+//long long ll_manyllargs(char a0, int a1, char a2, long long a3, char a4, char a5, long long a6, long long a7, char a8, long long a9,
+// char a10, long long a11, char a12, int a13, char a14, char a15, long long a16, long long a17, char a18, long long a19,
+// char a20, int a21, char a22, long long a23, char a24, char a25, long long a26, int a27, char a28, long long a29)
+long long ll_manyllargs(char a0, ...)
+{
+ STACK;
+ VA_START(vl, a0);
+ int a1 = va_arg(vl, int);
+ char a2 = va_arg(vl, int);
+ long long a3 = va_arg(vl, long long);
+ char a4 = va_arg(vl, int);
+ char a5 = va_arg(vl, int);
+ long long a6 = va_arg(vl, long long);
+ long long a7 = va_arg(vl, long long);
+ char a8 = va_arg(vl, int);
+ long long a9 = va_arg(vl, long long);
+ char a10 = va_arg(vl, int);
+ long long a11 = va_arg(vl, long long);
+ char a12 = va_arg(vl, int);
+ int a13 = va_arg(vl, int);
+ char a14 = va_arg(vl, int);
+ char a15 = va_arg(vl, int);
+ long long a16 = va_arg(vl, long long);
+ long long a17 = va_arg(vl, long long);
+ char a18 = va_arg(vl, int);
+ long long a19 = va_arg(vl, long long);
+ char a20 = va_arg(vl, int);
+ int a21 = va_arg(vl, int);
+ char a22 = va_arg(vl, int);
+ long long a23 = va_arg(vl, long long);
+ char a24 = va_arg(vl, int);
+ char a25 = va_arg(vl, int);
+ long long a26 = va_arg(vl, long long);
+ int a27 = va_arg(vl, int);
+ char a28 = va_arg(vl, int);
+ long long a29 = va_arg(vl, long long);
+ VA_END(vl);
+ return MANYARG_OP(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19,
+ a20, a21, a22, a23, a24, a25, a26, a27, a28, a29);
+}
+
+//long long stackhell(char a0, int a1, char a2, long long a3, char a4, char a5, long long a6, long long a7, char a8, long long a9,
+// char a10, long long a11, char a12, int a13, char a14, char a15, long long a16, long long a17, char a18, long long a19,
+// char a20, int a21, char a22, long long a23, char a24, char a25, long long a26, int a27, char a28, long long a29)
+long long stackhell(char a0, ...)
+{
+ VA_START(vl, a0);
+ int a1 = va_arg(vl, int);
+ char a2 = va_arg(vl, int);
+ long long a3 = va_arg(vl, long long);
+ char a4 = va_arg(vl, int);
+ char a5 = va_arg(vl, int);
+ long long a6 = va_arg(vl, long long);
+ long long a7 = va_arg(vl, long long);
+ char a8 = va_arg(vl, int);
+ long long a9 = va_arg(vl, long long);
+ char a10 = va_arg(vl, int);
+ long long a11 = va_arg(vl, long long);
+ char a12 = va_arg(vl, int);
+ int a13 = va_arg(vl, int);
+ char a14 = va_arg(vl, int);
+ char a15 = va_arg(vl, int);
+ long long a16 = va_arg(vl, long long);
+ long long a17 = va_arg(vl, long long);
+ char a18 = va_arg(vl, int);
+ long long a19 = va_arg(vl, long long);
+ char a20 = va_arg(vl, int);
+ int a21 = va_arg(vl, int);
+ char a22 = va_arg(vl, int);
+ long long a23 = va_arg(vl, long long);
+ char a24 = va_arg(vl, int);
+ char a25 = va_arg(vl, int);
+ long long a26 = va_arg(vl, long long);
+ int a27 = va_arg(vl, int);
+ char a28 = va_arg(vl, int);
+ long long a29 = va_arg(vl, long long);
+ VA_END(vl);
+
+ long long b0 = a0;
+ long long b1 = a1 + b0;
+ long long b2 = a2 + b1;
+ int b3 = a3 + b2;
+ int b4 = a4 + b3;
+ int b5 = a5 + b4;
+ int b6 = a6 + b5;
+ int b7 = a7 + b6;
+ char b8 = a8 + b7;
+ char b9 = a9 + b8;
+ char b10 = a10 + b9;
+ char b11 = a11 + b10;
+ char b12 = a12 + b11;
+ int b13 = a13 + b12;
+ long long b14 = a14 + b13;
+ long long b15 = a15 + b14;
+ long long b16 = a16 + b15;
+ long long b17 = a17 + b16;
+ long long b18 = a18 + b17;
+ long long b19 = a19 + b18;
+ long long b20 = a20 + b19;
+ long long b21 = a21 + b20;
+ long long b22 = a22 + b21;
+ long long b23 = a23 + b22;
+ long long b24 = a24 + b23;
+ long long b25 = a25 + b24;
+ long long b26 = a26 + b25;
+ long long b27 = a27 + b26;
+ int b28 = a28 + b27;
+ int b29 = a29 + b28;
+ int b30 = b0 + b29;
+ int b31 = b1 + b30;
+ int b32 = b2 + b31;
+ char b33 = b3 + b32;
+ char b34 = b4 + b33;
+ char b35 = b5 + b34;
+ char b36 = b6 + b35;
+ char b37 = b7 + b36;
+ int b38 = b8 + b37;
+ int b39 = b9 + b38;
+ int b40 = b0 + b39;
+ int b41 = b1 + b40;
+ int b42 = b2 + b41;
+ int b43 = b3 + b42;
+ int b44 = b4 + b43;
+ int b45 = b5 + b44;
+ int b46 = b6 + b45;
+ int b47 = b7 + b46;
+ int b48 = b8 + b47;
+ long long b49 = b9 + b48;
+ long long b50 = b0 + b49;
+ long long b51 = b1 + b50;
+ long long b52 = b2 + b51;
+ long long b53 = b3 + b52;
+ long long b54 = b4 + b53;
+ long long b55 = b5 + b54;
+ long long b56 = b6 + b55;
+ long long b57 = b7 + b56;
+ int b58 = b8 + b57;
+ int b59 = b9 + b58;
+ int b60 = b0 + b59;
+ int b61 = b1 + b60;
+ int b62 = b2 + b61;
+ int b63 = b3 + b62;
+ int b64 = b4 + b63;
+ int b65 = b5 + b64;
+ int b66 = b6 + b65;
+ int b67 = b7 + b66;
+ int b68 = b8 + b67;
+ int b69 = b9 + b68;
+ char b70 = b0 + b69;
+ char b71 = b1 + b70;
+ char b72 = b2 + b71;
+ char b73 = b3 + b72;
+ char b74 = b4 + b73;
+ char b75 = b5 + b74;
+ char b76 = b6 + b75;
+ char b77 = b7 + b76;
+ char b78 = b8 + b77;
+ char b79 = b9 + b78;
+ char b80 = b0 + b79;
+ char b81 = b1 + b80;
+ char b82 = b2 + b81;
+ char b83 = b3 + b82;
+ char b84 = b4 + b83;
+ int b85 = b5 + b84;
+ int b86 = b6 + b85;
+ int b87 = b7 + b86;
+ int b88 = b8 + b87;
+ int b89 = b9 + b88;
+ int b90 = b0 + b89;
+ int b91 = b1 + b90;
+ int b92 = b2 + b91;
+ int b93 = b3 + b92;
+ int b94 = b4 + b93;
+ long long b95 = b5 + b94;
+ long long b96 = b6 + b95;
+ long long b97 = b7 + b96;
+ long long b98 = b8 + b97;
+ long long b99 = b9 + b98;
+ long long b100 = b0 + b99;
+ long long b101 = b1 + b100;
+ long long b102 = b2 + b101;
+ long long b103 = b3 + b102;
+ long long b104 = b4 + b103;
+ long long b105 = b5 + b104;
+ long long b106 = b6 + b105;
+ long long b107 = b7 + b106;
+ long long b108 = b8 + b107;
+ long long b109 = b9 + b108;
+ long long b110 = b0 + b109;
+ long long b111 = b1 + b110;
+ long long b112 = b2 + b111;
+ long long b113 = b3 + b112;
+ long long b114 = b4 + b113;
+ int b115 = b5 + b114;
+ int b116 = b6 + b115;
+ int b117 = b7 + b116;
+ int b118 = b8 + b117;
+ int b119 = b9 + b118;
+ int b120 = b0 + b119;
+ int b121 = b1 + b120;
+ int b122 = b2 + b121;
+ int b123 = b3 + b122;
+ int b124 = b4 + b123;
+ int b125 = b5 + b124;
+ char b126 = b6 + b125;
+ char b127 = b7 + b126;
+ char b128 = b8 + b127;
+ char b129 = b9 + b128;
+ char b130 = b0 + b129;
+ char b131 = b1 + b130;
+ char b132 = b2 + b131;
+ char b133 = b3 + b132;
+ char b134 = b4 + b133;
+ char b135 = b5 + b134;
+ char b136 = b6 + b135;
+ char b137 = b7 + b136;
+ char b138 = b8 + b137;
+ char b139 = b9 + b138;
+ char b140 = b0 + b139;
+ char b141 = b1 + b140;
+ char b142 = b2 + b141;
+ char b143 = b3 + b142;
+ char b144 = b4 + b143;
+ char b145 = b5 + b144;
+ char b146 = b6 + b145;
+ char b147 = b7 + b146;
+ int b148 = b8 + b147;
+ int b149 = b9 + b148;
+ int b150 = b0 + b149;
+ int b151 = b1 + b150;
+ int b152 = b2 + b151;
+ int b153 = b3 + b152;
+ int b154 = b4 + b153;
+ int b155 = b5 + b154;
+ int b156 = b6 + b155;
+ int b157 = b7 + b156;
+ int b158 = b8 + b157;
+ int b159 = b9 + b158;
+ int b160 = b0 + b159;
+ int b161 = b1 + b160;
+ int b162 = b2 + b161;
+ return MANYARG_OP(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19,
+ a20, a21, a22, a23, a24, a25, a26, a27, a28, a29)
+ + b0 + b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8 + b9
+ + b10 + b11 + b12 + b13 + b14 + b15 + b16 + b17 + b18 + b19
+ + b20 + b21 + b22 + b23 + b24 + b25 + b26 + b27 + b28 + b29
+ + b30 + b31 + b32 + b33 + b34 + b35 + b36 + b37 + b38 + b39
+ + b40 + b41 + b42 + b43 + b44 + b45 + b46 + b47 + b48 + b49
+ + b50 + b51 + b52 + b53 + b54 + b55 + b56 + b57 + b58 + b59
+ + b60 + b61 + b62 + b63 + b64 + b65 + b66 + b67 + b68 + b69
+ + b70 + b71 + b72 + b73 + b74 + b75 + b76 + b77 + b78 + b79
+ + b80 + b81 + b82 + b83 + b84 + b85 + b86 + b87 + b88 + b89
+ + b90 + b91 + b92 + b93 + b94 + b95 + b96 + b97 + b98 + b99
+ + b100 + b101 + b102 + b103 + b104 + b105 + b106 + b107 + b108 + b109
+ + b110 + b111 + b112 + b113 + b114 + b115 + b116 + b117 + b118 + b119
+ + b120 + b121 + b122 + b123 + b124 + b125 + b126 + b127 + b128 + b129
+ + b130 + b131 + b132 + b133 + b134 + b135 + b136 + b137 + b138 + b139
+ + b140 + b141 + b142 + b143 + b144 + b145 + b146 + b147 + b148 + b149
+ + b150 + b151 + b152 + b153 + b154 + b155 + b156 + b157 + b158 + b159
+ + b160 + b161 + b162
+ ;
+}
+
diff --git a/test/kvx/lib/Makefile b/test/kvx/lib/Makefile
new file mode 100644
index 00000000..5a947bb3
--- /dev/null
+++ b/test/kvx/lib/Makefile
@@ -0,0 +1,133 @@
+KVXC ?= k1-cos-gcc
+K1AR ?= k1-cos-ar
+CC ?= gcc
+AR ?= gcc-ar
+CCOMP ?= ccomp
+CFLAGS ?= -O1 -Wl,--wrap=printf
+SIMU ?= k1-mppa
+TIMEOUT ?= --signal=SIGTERM 60s
+
+DIR=./
+SRCDIR=$(DIR)
+OUTDIR=$(DIR)/out
+BINDIR=$(DIR)/bin
+ASMDIR=$(DIR)/asm
+OBJDIR=$(DIR)/obj
+
+KVXCPATH=$(shell which $(KVXC))
+K1ARPATH=$(shell which $(K1AR))
+CCPATH=$(shell which $(CC))
+ARPATH=$(shell which $(AR))
+SIMUPATH=$(shell which $(SIMU))
+
+TESTNAMES=printf-test
+X86_GCC_OUT=$(addprefix $(OUTDIR)/,$(addsuffix .x86-gcc.out,$(TESTNAMES)))
+GCC_OUT=$(addprefix $(OUTDIR)/,$(addsuffix .gcc.out,$(TESTNAMES)))
+CCOMP_OUT=$(addprefix $(OUTDIR)/,$(addsuffix .ccomp.out,$(TESTNAMES)))
+
+OUT=$(X86_GCC_OUT) $(GCC_OUT) $(CCOMP_OUT)
+BIN=$(addprefix $(BINDIR)/,$(addsuffix .x86-gcc.bin,$(TESTNAMES)))\
+ $(addprefix $(BINDIR)/,$(addsuffix .gcc.bin,$(TESTNAMES)))\
+ $(addprefix $(BINDIR)/,$(addsuffix .ccomp.bin,$(TESTNAMES)))
+
+##
+# Targets
+##
+
+all: $(BIN) system.x86-gcc.a system.gcc.a
+
+.PHONY:
+test: $(X86_GCC_OUT) $(GCC_OUT)
+ @echo "Comparing x86 gcc output to k1 gcc.."
+ @for test in $(TESTNAMES); do\
+ x86out=$(OUTDIR)/$$test.x86-gcc.out;\
+ gccout=$(OUTDIR)/$$test.gcc.out;\
+ if ! diff $$x86out $$gccout; then\
+ >&2 echo "ERROR: $$x86out and $$gccout differ";\
+ else\
+ echo "GOOD: $$x86out and $$gccout concur";\
+ fi;\
+ done
+
+.PHONY:
+check: $(GCC_OUT) $(CCOMP_OUT)
+ @echo "Comparing k1 gcc output to ccomp.."
+ @for test in $(TESTNAMES); do\
+ gccout=$(OUTDIR)/$$test.gcc.out;\
+ ccompout=$(OUTDIR)/$$test.ccomp.out;\
+ if ! diff $$ccompout $$gccout; then\
+ >&2 echo "ERROR: $$ccompout and $$gccout differ";\
+ else\
+ echo "GOOD: $$ccompout and $$gccout concur";\
+ fi;\
+ done
+
+##
+# Rules
+##
+
+.SECONDARY:
+
+# Generating output
+
+## Version avec timeout
+$(OUTDIR)/%.x86-gcc.out: $(BINDIR)/%.x86-gcc.bin
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) ./$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.gcc.out: $(BINDIR)/%.gcc.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(SIMU) -- $< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+$(OUTDIR)/%.ccomp.out: $(BINDIR)/%.ccomp.bin $(SIMUPATH)
+ @mkdir -p $(@D)
+ ret=0; timeout $(TIMEOUT) $(SIMU) -- $< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+# Object to binary
+
+$(BINDIR)/%.x86-gcc.bin: $(OBJDIR)/%.x86-gcc.o system.x86-gcc.a $(CCPATH)
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) $(filter-out $(CCPATH),$^) -o $@
+
+$(BINDIR)/%.gcc.bin: $(OBJDIR)/%.gcc.o system.gcc.a $(KVXCPATH)
+ @mkdir -p $(@D)
+ $(KVXC) $(CFLAGS) $(filter-out $(KVXCPATH),$^) -o $@
+
+$(BINDIR)/%.ccomp.bin: $(OBJDIR)/%.ccomp.o system.gcc.a $(CCOMPPATH)
+ @mkdir -p $(@D)
+ $(CCOMP) $(CFLAGS) $(filter-out $(CCOMPPATH),$^) -o $@
+
+# Generating libraries
+system.x86-gcc.a: $(OBJDIR)/printf.x86-gcc.o $(ARPATH)
+ $(AR) rcs $@ $<
+
+system.gcc.a: $(OBJDIR)/printf.gcc.o $(K1ARPATH)
+ $(K1AR) rcs $@ $<
+
+# Assembly to object
+
+$(OBJDIR)/%.x86-gcc.o: $(ASMDIR)/%.x86-gcc.s $(CCPATH)
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(OBJDIR)/%.gcc.o: $(ASMDIR)/%.gcc.s $(KVXCPATH)
+ @mkdir -p $(@D)
+ $(KVXC) $(CFLAGS) -c $< -o $@
+
+$(OBJDIR)/%.ccomp.o: $(ASMDIR)/%.ccomp.s $(CCOMPPATH)
+ $(CCOMP) $(CFLAGS) -c $< -o $@
+
+# Source to assembly
+
+$(ASMDIR)/%.x86-gcc.s: $(SRCDIR)/%.c $(CCPATH)
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) -S $< -o $@
+
+$(ASMDIR)/%.gcc.s: $(SRCDIR)/%.c $(KVXCPATH)
+ @mkdir -p $(@D)
+ $(KVXC) $(CFLAGS) -S $< -o $@
+
+$(ASMDIR)/%.ccomp.s: $(SRCDIR)/%.c $(CCOMPPATH)
+ @mkdir -p $(@D)
+ $(CCOMP) $(CFLAGS) -S $< -o $@
+
diff --git a/test/kvx/lib/printf-test.c b/test/kvx/lib/printf-test.c
new file mode 100644
index 00000000..25afd436
--- /dev/null
+++ b/test/kvx/lib/printf-test.c
@@ -0,0 +1,9 @@
+int printf(const char *, ...);
+
+int main(void){
+ int a = 42;
+ char *str = "Hi there";
+ printf("%s, I am %u\n", str, a);
+
+ return 0;
+}
diff --git a/test/kvx/lib/printf.c b/test/kvx/lib/printf.c
new file mode 100644
index 00000000..79984ef6
--- /dev/null
+++ b/test/kvx/lib/printf.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int __wrap_printf(const char *format, ...){
+ va_list args;
+ va_start(args, format);
+ vprintf(format, args);
+ va_end(args);
+}
diff --git a/test/kvx/mmult/.gitignore b/test/kvx/mmult/.gitignore
new file mode 100644
index 00000000..b43ccc5f
--- /dev/null
+++ b/test/kvx/mmult/.gitignore
@@ -0,0 +1,4 @@
+mmult-test-ccomp-kvx
+mmult-test-gcc-kvx
+mmult-test-gcc-x86
+.zero
diff --git a/test/kvx/mmult/Makefile b/test/kvx/mmult/Makefile
new file mode 100644
index 00000000..e7cd890e
--- /dev/null
+++ b/test/kvx/mmult/Makefile
@@ -0,0 +1,67 @@
+KVXC ?= k1-cos-gcc
+CC ?= gcc
+CCOMP ?= ccomp
+CFLAGS ?= -O2
+SIMU ?= k1-mppa
+TIMEOUT ?= 10s
+
+KVXCPATH=$(shell which $(KVXC))
+CCPATH=$(shell which $(CC))
+CCOMPPATH=$(shell which $(CCOMP))
+SIMUPATH=$(shell which $(SIMU))
+
+PRNG=../prng/prng.c
+
+ALL= mmult-test-gcc-x86 mmult-test-gcc-kvx mmult-test-ccomp-kvx
+CCOMP_OUT= mmult-test-ccomp-kvx.out
+GCC_OUT= mmult-test-gcc-kvx.out
+X86_GCC_OUT= mmult-test-gcc-x86.out
+STUB_OUT=.zero
+
+all: $(ALL)
+
+mmult-test-gcc-x86: mmult.c $(PRNG) $(CCPATH)
+ $(CC) $(CFLAGS) $(filter-out $(CCPATH),$^) -o $@
+
+mmult-test-gcc-kvx: mmult.c $(PRNG) $(KVXCPATH)
+ $(KVXC) $(CFLAGS) $(filter-out $(KVXCPATH),$^) -o $@
+
+mmult-test-ccomp-kvx: mmult.c $(PRNG) $(CCOMPPATH)
+ $(CCOMP) $(CFLAGS) $(filter-out $(CCOMPPATH),$^) -o $@
+
+.SECONDARY:
+%kvx.out: %kvx $(SIMUPATH)
+ ret=0; timeout $(TIMEOUT) $(SIMU) -- $< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+%x86.out: %x86
+ ret=0; timeout $(TIMEOUT) ./$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+.zero:
+ @echo "0" > $@
+
+.PHONY:
+test: test-x86 test-kvx
+
+.PHONY:
+test-x86: $(X86_GCC_OUT) $(STUB_OUT)
+ @if ! diff $< $(STUB_OUT); then\
+ >&2 echo "ERROR x86: $< failed";\
+ else\
+ echo "GOOD x86: $< succeeded";\
+ fi
+
+.PHONY:
+test-kvx: $(GCC_OUT) $(STUB_OUT)
+ @if ! diff $< $(STUB_OUT); then\
+ >&2 echo "ERROR kvx: $< failed";\
+ else\
+ echo "GOOD kvx: $< succeeded";\
+ fi
+
+.PHONY:
+check: $(CCOMP_OUT) $(STUB_OUT)
+ @if ! diff $< $(STUB_OUT); then\
+ >&2 echo "ERROR kvx: $< failed";\
+ else\
+ echo "GOOD kvx: $< succeeded";\
+ fi
diff --git a/test/kvx/mmult/README.md b/test/kvx/mmult/README.md
new file mode 100644
index 00000000..780603f6
--- /dev/null
+++ b/test/kvx/mmult/README.md
@@ -0,0 +1,17 @@
+MMULT
+=====
+
+Examples of matrix multiplication using different methods.
+
+We compute matrix multiplication using column-based matrix multiplication, then row-based, and finally block based.
+
+The test verifies that the result is the same on the three methods. If it is the same, 0 will be returned.
+
+The following commands can be run inside the folder:
+
+- `make`: produces the unitary test binaries
+ - `mmult-test-gcc-x86` : binary from gcc on x86
+ - `mmult-test-kvx-x86` : binary from gcc on kvx
+ - `mmult-test-ccomp-x86` : binary from ccomp on kvx
+- `make test`: tests the return value of the binaries produced by gcc.
+- `make check`: tests the return value of the binary produced by CompCert.
diff --git a/test/kvx/mmult/mmult.c b/test/kvx/mmult/mmult.c
new file mode 100644
index 00000000..aeb91d48
--- /dev/null
+++ b/test/kvx/mmult/mmult.c
@@ -0,0 +1,146 @@
+#include "../prng/types.h"
+#include "../prng/prng.h"
+
+#define __UNIT_TEST_MMULT__
+
+#ifdef __UNIT_TEST_MMULT__
+#define SIZE 10
+#else
+#include "test.h"
+#endif
+
+void mmult_row(uint64_t C[][SIZE], uint64_t A[][SIZE], uint64_t B[][SIZE]){
+ int i, j, k;
+
+ for (i = 0 ; i < SIZE ; i++)
+ for (j = 0 ; j < SIZE ; j++)
+ C[i][j] = 0;
+
+ for (i = 0 ; i < SIZE ; i++)
+ for (j = 0 ; j < SIZE ; j++)
+ for (k = 0 ; k < SIZE ; k++)
+ C[i][j] += A[i][k] * B[k][j];
+}
+
+void mmult_col(uint64_t C[][SIZE], uint64_t A[][SIZE], uint64_t B[][SIZE]){
+ int i, j, k;
+
+ for (i = 0 ; i < SIZE ; i++)
+ for (j = 0 ; j < SIZE ; j++)
+ C[i][j] = 0;
+
+ for (k = 0 ; k < SIZE ; k++)
+ for (i = 0 ; i < SIZE ; i++)
+ for (j = 0 ; j < SIZE ; j++)
+ C[i][j] += A[i][k] * B[k][j];
+}
+
+typedef struct mblock {
+ int imin, imax, jmin, jmax;
+ uint64_t *mat;
+} mblock;
+
+#define MAT_XY(mat, x, y) (mat)[(x)*SIZE + (y)]
+#define MAT_IJ(block, i, j) MAT_XY((block)->mat, (block)->imin + (i), block->jmin + (j))
+
+void divac_mul(mblock *C, const mblock *A, const mblock *B){
+ const int size = C->imax - C->imin;
+ int i, j, k;
+
+ for (i = 0 ; i < size ; i++)
+ for (j = 0 ; j < size ; j++)
+ for (k = 0 ; k < size ; k++)
+ MAT_IJ(C, i, j) += MAT_IJ(A, i, k) * MAT_IJ(B, k, j);
+}
+
+#define BLOCK_X_MID(block) ((block)->imin + (block)->imax) / 2
+#define BLOCK_Y_MID(block) ((block)->jmin + (block)->jmax) / 2
+
+#define MAKE_MBLOCK(newb, block, I, J) \
+ mblock newb = {.mat=(block)->mat};\
+ if ((I) == 0){\
+ newb.imin = (block)->imin;\
+ newb.imax = BLOCK_X_MID((block));\
+ } else {\
+ newb.imin = BLOCK_X_MID((block));\
+ newb.imax = (block)->imax;\
+ } if ((J) == 0){\
+ newb.jmin = (block)->jmin;\
+ newb.jmax = BLOCK_Y_MID((block));\
+ } else {\
+ newb.jmin = BLOCK_Y_MID((block));\
+ newb.jmax = (block)->jmax;\
+ }
+
+void divac_part(mblock *C, const mblock *A, const mblock *B);
+
+void divac_wrap(mblock *C , char IC, char JC,
+ const mblock *A, char IA, char JA,
+ const mblock *B, char IB, char JB){
+ MAKE_MBLOCK(Cb, C, IC, JC);
+ MAKE_MBLOCK(Ab, A, IA, JA);
+ MAKE_MBLOCK(Bb, B, IB, JB);
+
+ divac_part(&Cb, &Ab, &Bb);
+}
+
+
+void divac_part(mblock *C, const mblock *A, const mblock *B){
+ const int size = C->imax - C->imin;
+
+ if (size % 2 == 1)
+ divac_mul(C, A, B);
+ else{
+ /* C_00 = A_00 B_00 + A_01 B_10 */
+ divac_wrap(C, 0, 0, A, 0, 0, B, 0, 0);
+ divac_wrap(C, 0, 0, A, 0, 1, B, 1, 0);
+
+ /* C_10 = A_10 B_00 + A_11 B_10 */
+ divac_wrap(C, 1, 0, A, 1, 0, B, 0, 0);
+ divac_wrap(C, 1, 0, A, 1, 1, B, 1, 0);
+
+ /* C_01 = A_00 B_01 + A_01 B_11 */
+ divac_wrap(C, 0, 1, A, 0, 0, B, 0, 1);
+ divac_wrap(C, 0, 1, A, 0, 1, B, 1, 1);
+
+ /* C_11 = A_10 B_01 + A_11 B_11 */
+ divac_wrap(C, 1, 1, A, 1, 0, B, 0, 1);
+ divac_wrap(C, 1, 1, A, 1, 1, B, 1, 1);
+ }
+
+}
+
+void mmult_divac(uint64_t C[][SIZE], uint64_t A[][SIZE], uint64_t B[][SIZE]){
+ mblock Cb = {.mat = (uint64_t *) C, .imin = 0, .imax = SIZE, .jmin = 0, .jmax = SIZE};
+ mblock Ab = {.mat = (uint64_t *) A , .imin = 0, .imax = SIZE, .jmin = 0, .jmax = SIZE};
+ mblock Bb = {.mat = (uint64_t *) B , .imin = 0, .imax = SIZE, .jmin = 0, .jmax = SIZE};
+
+ divac_part(&Cb, &Ab, &Bb);
+}
+
+#ifdef __UNIT_TEST_MMULT__
+static uint64_t C1[SIZE][SIZE], C2[SIZE][SIZE], C3[SIZE][SIZE];
+static uint64_t A[SIZE][SIZE], B[SIZE][SIZE];
+
+int main(void){
+ srand(42);
+ int i, j;
+
+ for (i = 0 ; i < SIZE ; i++)
+ for (j = 0 ; j < SIZE ; j++){
+ A[i][j] = randlong();
+ B[i][j] = randlong();
+ }
+
+ mmult_row(C1, A, B);
+ mmult_col(C2, A, B);
+ mmult_divac(C3, A, B);
+
+ for (i = 0 ; i < SIZE ; i++)
+ for (j = 0 ; j < SIZE ; j++)
+ if (!(C1[i][j] == C2[i][j] && C1[i][j] == C3[i][j]))
+ return -1;
+
+ return 0;
+}
+#endif /* __UNIT_TEST_MMULT__ */
diff --git a/test/kvx/mmult/mmult.h b/test/kvx/mmult/mmult.h
new file mode 100644
index 00000000..3721784a
--- /dev/null
+++ b/test/kvx/mmult/mmult.h
@@ -0,0 +1,10 @@
+#ifndef __MMULT_H__
+#define __MMULT_H__
+
+#include "../lib/types.h"
+
+void mmult_row(uint64_t *A, const uint64_t *B, const uint64_t *C);
+void mmult_column(uint64_t *A, const uint64_t *B, const uint64_t *C);
+void mmult_strassen(uint64_t *A, const uint64_t *B, const uint64_t *C);
+
+#endif /* __MMULT_H__ */
diff --git a/test/kvx/prng/.gitignore b/test/kvx/prng/.gitignore
new file mode 100644
index 00000000..08023900
--- /dev/null
+++ b/test/kvx/prng/.gitignore
@@ -0,0 +1,3 @@
+prng-test-ccomp-kvx
+prng-test-gcc-x86
+prng-test-gcc-kvx
diff --git a/test/kvx/prng/Makefile b/test/kvx/prng/Makefile
new file mode 100644
index 00000000..68e5ffc9
--- /dev/null
+++ b/test/kvx/prng/Makefile
@@ -0,0 +1,69 @@
+KVXC ?= k1-cos-gcc
+CC ?= gcc
+CCOMP ?= ccomp
+CFLAGS ?= -O2
+SIMU ?= k1-mppa
+TIMEOUT ?= 10s
+
+KVXCPATH=$(shell which $(KVXC))
+CCPATH=$(shell which $(CC))
+CCOMPPATH=$(shell which $(CCOMP))
+SIMUPATH=$(shell which $(SIMU))
+
+ALL= prng-test-gcc-x86 prng-test-gcc-kvx prng-test-ccomp-kvx
+CCOMP_OUT= prng-test-ccomp-kvx.out
+GCC_OUT= prng-test-gcc-kvx.out
+X86_GCC_OUT= prng-test-gcc-x86.out
+STUB_OUT=.zero
+
+all: $(ALL)
+
+prng-test-gcc-x86: prng.c $(CCPATH)
+ $(CC) -D__UNIT_TEST_PRNG__ $(CFLAGS) $< -o $@
+
+prng-test-gcc-kvx: prng.c $(KVXCPATH)
+ $(KVXC) -D__UNIT_TEST_PRNG__ $(CFLAGS) $< -o $@
+
+prng-test-ccomp-kvx: prng.c $(CCOMPPATH)
+ $(CCOMP) -D__UNIT_TEST_PRNG__ $(CFLAGS) $< -o $@
+
+.SECONDARY:
+%kvx.out: %kvx $(SIMUPATH)
+ ret=0; timeout $(TIMEOUT) $(SIMU) -- $< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+%x86.out: %x86
+ ret=0; timeout $(TIMEOUT) ./$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+.zero:
+ @echo "0" > $@
+
+.PHONY:
+test: test-x86 test-kvx
+
+.PHONY:
+test-x86: $(X86_GCC_OUT) $(STUB_OUT)
+ @if ! diff $< $(STUB_OUT); then\
+ >&2 echo "ERROR x86: $< failed";\
+ else\
+ echo "GOOD x86: $< succeeded";\
+ fi
+
+.PHONY:
+test-kvx: $(GCC_OUT) $(STUB_OUT)
+ @if ! diff $< $(STUB_OUT); then\
+ >&2 echo "ERROR kvx: $< failed";\
+ else\
+ echo "GOOD kvx: $< succeeded";\
+ fi
+
+.PHONY:
+check: $(CCOMP_OUT) $(STUB_OUT)
+ @if ! diff $< $(STUB_OUT); then\
+ >&2 echo "ERROR kvx: $< failed";\
+ else\
+ echo "GOOD kvx: $< succeeded";\
+ fi
+
+.PHONY:
+clean:
+ rm -f prng-test-gcc-x86 prng-test-gcc-kvx prng-test-ccomp-kvx
diff --git a/test/kvx/prng/README.md b/test/kvx/prng/README.md
new file mode 100644
index 00000000..98ed539d
--- /dev/null
+++ b/test/kvx/prng/README.md
@@ -0,0 +1,17 @@
+PRNG
+====
+
+This is a simple Pseudo Random Number Generator.
+
+`prng.c` contains a simple unitary test that compares the sum of the "bytewise sum"
+of 1000 generated numbers to a hardcoded result, that is the one obtained with
+`gcc -O2` on a x86 processor, and returns 0 if the result is correct.
+
+The following commands can be run inside that folder:
+
+- `make`: produces the unitary test binaries
+ - `prng-test-gcc-x86` : binary from gcc on x86
+ - `prng-test-kvx-x86` : binary from gcc on kvx
+ - `prng-test-ccomp-x86` : binary from ccomp on kvx
+- `make test`: tests the return value of the binaries produced by gcc.
+- `make check`: tests the return value of the binary produced by CompCert.
diff --git a/test/kvx/prng/prng.c b/test/kvx/prng/prng.c
new file mode 100644
index 00000000..71de1dc3
--- /dev/null
+++ b/test/kvx/prng/prng.c
@@ -0,0 +1,41 @@
+// https://en.wikipedia.org/wiki/Linear_congruential_generator -> MMIX Donald Knuth
+// modulo 2^64 = no need to do it explicitly
+
+#include "types.h"
+
+#define MULTIPLIER 6364136223846793005LL
+#define INCREMENT 1442695040888963407LL
+
+static uint64_t current;
+
+void srand(uint64_t seed){
+ current = seed;
+}
+
+uint64_t randlong(void){
+ return (current = MULTIPLIER * current + INCREMENT);
+}
+
+#ifdef __UNIT_TEST_PRNG__
+char bytewise_sum(uint64_t to_check){
+ char sum = 0;
+ int i;
+
+ for (i = 0 ; i < 8 ; i++)
+ sum += (to_check & (uint64_t)(0xFFULL << i*8)) >> i*8;
+
+ return sum;
+}
+
+int main(void){
+ srand(42);
+ int i;
+
+ for (i = 0 ; i < 1000 ; i++)
+ randlong();
+
+ uint64_t last = randlong();
+
+ return !((unsigned char)bytewise_sum(last) == 155);
+}
+#endif // __UNIT_TEST_PRNG__
diff --git a/test/kvx/prng/prng.h b/test/kvx/prng/prng.h
new file mode 100644
index 00000000..6abdb45a
--- /dev/null
+++ b/test/kvx/prng/prng.h
@@ -0,0 +1,10 @@
+#ifndef __PRNG_H__
+#define __PRNG_H__
+
+#include "types.h"
+
+void srand(uint64_t seed);
+
+uint64_t randlong(void);
+
+#endif // __PRNG_H__
diff --git a/test/kvx/prng/types.h b/test/kvx/prng/types.h
new file mode 100644
index 00000000..584023e3
--- /dev/null
+++ b/test/kvx/prng/types.h
@@ -0,0 +1,7 @@
+#ifndef __TYPES_H__
+#define __TYPES_H__
+
+#define uint64_t unsigned long long
+#define int64_t signed long long
+
+#endif // __TYPES_H__
diff --git a/test/kvx/simucheck.sh b/test/kvx/simucheck.sh
new file mode 100755
index 00000000..48698e35
--- /dev/null
+++ b/test/kvx/simucheck.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+# Tests the execution of the binaries produced by CompCert, by simulation
+
+cores=$(grep -c ^processor /proc/cpuinfo)
+
+source do_test.sh
+
+do_test check $cores
diff --git a/test/kvx/simutest.sh b/test/kvx/simutest.sh
new file mode 100755
index 00000000..729d1ba0
--- /dev/null
+++ b/test/kvx/simutest.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+# Tests the validity of the tests, in simulator
+
+cores=$(grep -c ^processor /proc/cpuinfo)
+
+source do_test.sh
+
+do_test test $cores
diff --git a/test/kvx/sort/.gitignore b/test/kvx/sort/.gitignore
new file mode 100644
index 00000000..070b87c4
--- /dev/null
+++ b/test/kvx/sort/.gitignore
@@ -0,0 +1,9 @@
+main-test-ccomp-kvx
+main-test-gcc-kvx
+main-test-gcc-x86
+merge-test-gcc-kvx
+merge-test-gcc-x86
+selection-test-gcc-kvx
+selection-test-gcc-x86
+insertion-test-gcc-kvx
+insertion-test-gcc-x86
diff --git a/test/kvx/sort/Makefile b/test/kvx/sort/Makefile
new file mode 100644
index 00000000..c4090352
--- /dev/null
+++ b/test/kvx/sort/Makefile
@@ -0,0 +1,91 @@
+KVXC ?= k1-cos-gcc
+CC ?= gcc
+CCOMP ?= ccomp
+CFLAGS ?= -O2
+SIMU ?= k1-mppa
+TIMEOUT ?= 10s
+
+KVXCPATH=$(shell which $(KVXC))
+CCPATH=$(shell which $(CC))
+CCOMPPATH=$(shell which $(CCOMP))
+SIMUPATH=$(shell which $(SIMU))
+
+PRNG=../prng/prng.c
+
+CFILES=insertion.c merge.c selection.c main.c
+
+ALL= insertion-gcc-x86 insertion-gcc-kvx insertion-ccomp-kvx\
+ selection-gcc-x86 selection-gcc-kvx selection-ccomp-kvx\
+ merge-gcc-x86 merge-gcc-kvx merge-ccomp-kvx\
+ main-gcc-x86 main-gcc-kvx main-ccomp-kvx
+
+CCOMP_OUT= insertion-ccomp-kvx.out selection-ccomp-kvx.out merge-ccomp-kvx.out\
+ main-ccomp-kvx.out
+GCC_OUT= insertion-gcc-kvx.out selection-gcc-kvx.out merge-gcc-kvx.out\
+ main-gcc-kvx.out
+X86_GCC_OUT= insertion-gcc-x86.out selection-gcc-x86.out merge-gcc-x86.out\
+ main-gcc-x86.out
+STUB_OUT= .zero
+
+all: $(ALL)
+
+main-gcc-x86: $(CFILES) $(PRNG) $(CCPATH)
+ $(CC) $(CFLAGS) $(filter-out $(CCPATH),$^) -o $@
+
+%-gcc-x86: %.c $(PRNG) $(CCPATH)
+ $(CC) -D__UNIT_TEST_$$(echo $(basename $<) | tr a-z A-Z)__ $(CFLAGS) $(filter-out $(CCPATH),$^) -o $@
+
+main-gcc-kvx: $(CFILES) $(PRNG) $(CCPATH)
+ $(KVXC) $(CFLAGS) $(filter-out $(CCPATH),$^) -o $@
+
+%-gcc-kvx: %.c $(PRNG) $(KVXCPATH)
+ $(KVXC) -D__UNIT_TEST_$$(echo $(basename $<) | tr a-z A-Z)__ $(CFLAGS) $(filter-out $(KVXCPATH),$^) -o $@
+
+main-ccomp-kvx: $(CFILES) $(PRNG) $(CCOMPPATH)
+ $(CCOMP) $(CFLAGS) $(filter-out $(CCOMPPATH),$^) -o $@
+
+%-ccomp-kvx: %.c $(PRNG) $(CCOMPPATH)
+ $(CCOMP) -D__UNIT_TEST_$$(echo $(basename $<) | tr a-z A-Z)__ $(CFLAGS) $(filter-out $(CCOMPPATH),$^) -o $@
+
+.SECONDARY:
+%x86.out: %x86
+ ret=0; timeout $(TIMEOUT) ./$< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+%kvx.out: %kvx $(SIMUPATH)
+ ret=0; timeout $(TIMEOUT) $(SIMU) -- $< > $@ || { ret=$$?; }; echo $$ret >> $@
+
+.zero:
+ @echo "0" > $@
+
+.PHONY:
+test-x86: $(STUB_OUT) $(X86_GCC_OUT)
+ @for test in $(wordlist 2,100,$^); do\
+ if ! diff $$test $(STUB_OUT); then\
+ >&2 echo "ERROR x86: $$test failed";\
+ else\
+ echo "GOOD x86: $$test succeeded";\
+ fi;\
+ done
+
+.PHONY:
+test-kvx: $(STUB_OUT) $(GCC_OUT)
+ @for test in $(wordlist 2,100,$^); do\
+ if ! diff $$test $(STUB_OUT); then\
+ >&2 echo "ERROR kvx: $$test failed";\
+ else\
+ echo "GOOD kvx: $$test succeeded";\
+ fi;\
+ done
+
+.PHONY:
+test: test-x86 test-kvx
+
+.PHONY:
+check: $(STUB_OUT) $(CCOMP_OUT)
+ @for test in $(wordlist 2,100,$^); do\
+ if ! diff $$test $(STUB_OUT); then\
+ >&2 echo "ERROR kvx: $$test failed";\
+ else\
+ echo "GOOD kvx: $$test succeeded";\
+ fi;\
+ done
diff --git a/test/kvx/sort/README.md b/test/kvx/sort/README.md
new file mode 100644
index 00000000..98ed539d
--- /dev/null
+++ b/test/kvx/sort/README.md
@@ -0,0 +1,17 @@
+PRNG
+====
+
+This is a simple Pseudo Random Number Generator.
+
+`prng.c` contains a simple unitary test that compares the sum of the "bytewise sum"
+of 1000 generated numbers to a hardcoded result, that is the one obtained with
+`gcc -O2` on a x86 processor, and returns 0 if the result is correct.
+
+The following commands can be run inside that folder:
+
+- `make`: produces the unitary test binaries
+ - `prng-test-gcc-x86` : binary from gcc on x86
+ - `prng-test-kvx-x86` : binary from gcc on kvx
+ - `prng-test-ccomp-x86` : binary from ccomp on kvx
+- `make test`: tests the return value of the binaries produced by gcc.
+- `make check`: tests the return value of the binary produced by CompCert.
diff --git a/test/kvx/sort/insertion.c b/test/kvx/sort/insertion.c
new file mode 100644
index 00000000..bca09599
--- /dev/null
+++ b/test/kvx/sort/insertion.c
@@ -0,0 +1,59 @@
+#include "../prng/prng.h"
+#include "../prng/types.h"
+
+#ifdef __UNIT_TEST_INSERTION__
+#define SIZE 100
+#else
+#include "test.h"
+#endif
+
+void swap_ins(uint64_t *a, uint64_t *b){
+ uint64_t tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+int insert_sort(uint64_t *res, const uint64_t *T){
+ int i, j;
+
+ if (SIZE <= 0)
+ return -1;
+
+ for (i = 0 ; i < SIZE ; i++)
+ res[i] = T[i];
+
+ for (i = 0 ; i < SIZE-1 ; i++){
+ if (res[i] > res[i+1]){
+ swap_ins(&res[i], &res[i+1]);
+ for (j = i ; j > 0 ; j--)
+ if (res[j-1] > res[j])
+ swap_ins(&res[j-1], &res[j]);
+ }
+ }
+
+ return 0;
+}
+
+#ifdef __UNIT_TEST_INSERTION__
+int main(void){
+ uint64_t T[SIZE];
+ uint64_t res[SIZE];
+ int i;
+ srand(42);
+
+ for (i = 0 ; i < SIZE ; i++)
+ T[i] = randlong();
+
+ /* Sorting the table */
+ if (insert_sort(res, T) < 0) return -1;
+
+ /* Computing max(T) */
+ uint64_t max = T[0];
+ for (i = 1 ; i < SIZE ; i++)
+ if (T[i] > max)
+ max = T[i];
+
+ /* We should have: max(T) == res[SIZE] */
+ return !(max == res[SIZE-1]);
+}
+#endif // __UNIT_TEST_INSERTION__
diff --git a/test/kvx/sort/insertion.h b/test/kvx/sort/insertion.h
new file mode 100644
index 00000000..6e37c5fe
--- /dev/null
+++ b/test/kvx/sort/insertion.h
@@ -0,0 +1,6 @@
+#ifndef __INSERTION_H__
+#define __INSERTION_H__
+
+int insert_sort(uint64_t *res, const uint64_t *T);
+
+#endif // __INSERTION_H__
diff --git a/test/kvx/sort/main.c b/test/kvx/sort/main.c
new file mode 100644
index 00000000..aef419aa
--- /dev/null
+++ b/test/kvx/sort/main.c
@@ -0,0 +1,34 @@
+#include "../prng/prng.h"
+#include "../prng/types.h"
+
+#include "test.h"
+#include "insertion.h"
+#include "selection.h"
+#include "merge.h"
+
+int main(void){
+ uint64_t T[SIZE];
+ uint64_t res1[SIZE], res2[SIZE], res3[SIZE];
+ int i;
+ srand(42);
+
+ for (i = 0 ; i < SIZE ; i++)
+ T[i] = randlong();
+
+ /* insertion sort */
+ if (insert_sort(res1, T) < 0) return -1;
+
+ /* selection sort */
+ if (select_sort(res2, T) < 0) return -2;
+
+ /* merge sort */
+ if (merge_sort(res3, T) < 0) return -3;
+
+ /* We should have: res1[i] == res2[i] == res3[i] */
+ for (i = 0 ; i < SIZE ; i++){
+ if (!(res1[i] == res2[i] && res2[i] == res3[i]))
+ return -4;
+ }
+
+ return 0;
+}
diff --git a/test/kvx/sort/merge.c b/test/kvx/sort/merge.c
new file mode 100644
index 00000000..99f8ba85
--- /dev/null
+++ b/test/kvx/sort/merge.c
@@ -0,0 +1,92 @@
+#include "../prng/prng.h"
+#include "../prng/types.h"
+
+//https://en.wikipedia.org/wiki/Merge_sort
+
+#ifdef __UNIT_TEST_MERGE__
+#define SIZE 100
+#else
+#include "test.h"
+#endif
+
+int min(int a, int b){
+ return (a < b)?a:b;
+}
+
+void BottomUpMerge(const uint64_t *A, int iLeft, int iRight, int iEnd, uint64_t *B)
+{
+ int i = iLeft, j = iRight, k;
+ for (k = iLeft; k < iEnd; k++) {
+ if (i < iRight && (j >= iEnd || A[i] <= A[j])) {
+ B[k] = A[i];
+ i = i + 1;
+ } else {
+ B[k] = A[j];
+ j = j + 1;
+ }
+ }
+}
+
+void CopyArray(uint64_t *to, const uint64_t *from)
+{
+ const int n = SIZE;
+ int i;
+
+ for(i = 0; i < n; i++)
+ to[i] = from[i];
+}
+
+void BottomUpMergeSort(uint64_t *A, uint64_t *B)
+{
+ const int n = SIZE;
+ int width, i;
+
+ for (width = 1; width < n; width = 2 * width)
+ {
+ for (i = 0; i < n; i = i + 2 * width)
+ {
+ BottomUpMerge(A, i, min(i+width, n), min(i+2*width, n), B);
+ }
+ CopyArray(A, B);
+ }
+}
+
+int merge_sort(uint64_t *res, const uint64_t *T){
+ int i;
+
+ if (SIZE <= 0)
+ return -1;
+
+ uint64_t B[SIZE];
+ uint64_t *A = res;
+ for (i = 0 ; i < SIZE ; i++)
+ A[i] = T[i];
+
+ BottomUpMergeSort(A, B);
+
+ return 0;
+}
+
+#ifdef __UNIT_TEST_MERGE__
+int main(void){
+ uint64_t T[SIZE];
+ uint64_t res[SIZE];
+ int i;
+ srand(42);
+
+ for (i = 0 ; i < SIZE ; i++)
+ T[i] = randlong();
+
+ /* Sorting the table */
+ if (merge_sort(res, T) < 0) return -1;
+
+ /* Computing max(T) */
+ uint64_t max = T[0];
+ for (i = 1 ; i < SIZE ; i++)
+ if (T[i] > max)
+ max = T[i];
+
+ /* We should have: max(T) == res[SIZE] */
+ return !(max == res[SIZE-1]);
+}
+#endif // __UNIT_TEST_MERGE__
diff --git a/test/kvx/sort/merge.h b/test/kvx/sort/merge.h
new file mode 100644
index 00000000..439ce64a
--- /dev/null
+++ b/test/kvx/sort/merge.h
@@ -0,0 +1,7 @@
+#ifndef __MERGE_H__
+#define __MERGE_H__
+
+int merge_sort(uint64_t *res, const uint64_t *T);
+
+#endif // __MERGE_H__
+
diff --git a/test/kvx/sort/selection.c b/test/kvx/sort/selection.c
new file mode 100644
index 00000000..df4be04f
--- /dev/null
+++ b/test/kvx/sort/selection.c
@@ -0,0 +1,62 @@
+#include "../prng/prng.h"
+#include "../prng/types.h"
+
+#ifdef __UNIT_TEST_SELECTION__
+#define SIZE 100
+#else
+#include "test.h"
+#endif
+
+void swap_sel(uint64_t *a, uint64_t *b){
+ uint64_t tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+int select_sort(uint64_t *res, const uint64_t *T){
+ int i, j, iMin;
+
+ if (SIZE <= 0)
+ return -1;
+
+ for (i = 0 ; i < SIZE ; i++)
+ res[i] = T[i];
+
+ for (j = 0 ; j < SIZE ; j++){
+ iMin = j;
+ for (i = j+1 ; i < SIZE ; i++)
+ if (res[i] < res[iMin])
+ iMin = i;
+
+ if (iMin != j)
+ swap_sel (&res[j], &res[iMin]);
+ }
+
+ return 0;
+}
+
+#ifdef __UNIT_TEST_SELECTION__
+int main(void){
+ uint64_t T[SIZE];
+ uint64_t res[SIZE];
+ uint64_t max;
+ int i;
+ srand(42);
+
+ for (i = 0 ; i < SIZE ; i++)
+ T[i] = randlong();
+
+ /* Sorting the table */
+ if (select_sort(res, T) < 0) return -1;
+
+ /* Computing max(T) */
+ max = T[0];
+ for (i = 1 ; i < SIZE ; i++)
+ if (T[i] > max)
+ max = T[i];
+
+ /* We should have: max(T) == res[SIZE] */
+ return !(max == res[SIZE-1]);
+}
+#endif // __UNIT_TEST_SELECTION__
+
diff --git a/test/kvx/sort/selection.h b/test/kvx/sort/selection.h
new file mode 100644
index 00000000..92a6b461
--- /dev/null
+++ b/test/kvx/sort/selection.h
@@ -0,0 +1,6 @@
+#ifndef __SELECTION_H__
+#define __SELECTION_H__
+
+int select_sort(uint64_t *res, const uint64_t *T);
+
+#endif // __SELECTION_H__
diff --git a/test/kvx/sort/test.h b/test/kvx/sort/test.h
new file mode 100644
index 00000000..4501ee38
--- /dev/null
+++ b/test/kvx/sort/test.h
@@ -0,0 +1,6 @@
+#ifndef __TEST_H__
+#define __TEST_H__
+
+#define SIZE 100
+
+#endif