From bc1e43ea95b9455cdccee442db77bc5fafd3dcc6 Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Tue, 26 May 2020 22:11:32 +0200 Subject: tests for kvx --- test/kvx/.gitignore | 20 ++ test/kvx/builtins/clzll.c | 7 + test/kvx/builtins/stsud.c | 7 + test/kvx/coverage.sh | 24 ++ test/kvx/coverage_helper.py | 45 +++ test/kvx/delout.sh | 6 + test/kvx/do_test.sh | 50 ++++ test/kvx/general/clzd.c | 7 + test/kvx/general/clzw.c | 7 + test/kvx/general/ctzd.c | 7 + test/kvx/general/ctzw.c | 7 + test/kvx/general/satd.c | 7 + test/kvx/general/sbmm8.c | 7 + test/kvx/general/sbmmt8.c | 7 + test/kvx/hardcheck.sh | 6 + test/kvx/hardtest.sh | 6 + test/kvx/instr/.gitignore | 1 + test/kvx/instr/Makefile | 176 ++++++++++++ test/kvx/instr/builtin32.c | 12 + test/kvx/instr/builtin64.c | 17 ++ test/kvx/instr/div32.c | 5 + test/kvx/instr/divf32.c | 5 + test/kvx/instr/divf64.c | 5 + test/kvx/instr/divu32.c | 7 + test/kvx/instr/f32.c | 8 + test/kvx/instr/f64.c | 8 + test/kvx/instr/floatcmp.py | 93 +++++++ test/kvx/instr/framework.h | 66 +++++ test/kvx/instr/i32.c | 149 ++++++++++ test/kvx/instr/i64.c | 169 ++++++++++++ test/kvx/instr/individual/andw.c | 5 + test/kvx/instr/individual/branch.c | 10 + test/kvx/instr/individual/branchz.c | 10 + test/kvx/instr/individual/branchzu.c | 11 + test/kvx/instr/individual/call.c | 16 ++ test/kvx/instr/individual/cast_S32_S64.c | 7 + test/kvx/instr/individual/cast_S64_U32.c | 7 + test/kvx/instr/individual/cb.deqz.c | 10 + test/kvx/instr/individual/cb.dgez.c | 10 + test/kvx/instr/individual/cb.dgtz.c | 10 + test/kvx/instr/individual/cb.dlez.c | 10 + test/kvx/instr/individual/cb.dltz.c | 10 + test/kvx/instr/individual/cb.dnez.c | 10 + test/kvx/instr/individual/cb.wgez.c | 10 + test/kvx/instr/individual/cb.wgtz.c | 10 + test/kvx/instr/individual/cb.wlez.c | 10 + test/kvx/instr/individual/cb.wltz.c | 10 + test/kvx/instr/individual/compd.eq.c | 7 + test/kvx/instr/individual/compd.geu.c | 7 + test/kvx/instr/individual/compd.gt.c | 7 + test/kvx/instr/individual/compd.le.c | 7 + test/kvx/instr/individual/compd.leu.c | 7 + test/kvx/instr/individual/compd.lt.c | 7 + test/kvx/instr/individual/compd.ltu.c | 7 + test/kvx/instr/individual/compd.ne.c | 7 + test/kvx/instr/individual/compw.eq.c | 7 + test/kvx/instr/individual/compw.geu.c | 7 + test/kvx/instr/individual/compw.gt.c | 7 + test/kvx/instr/individual/compw.gtu.c | 7 + test/kvx/instr/individual/compw.le.c | 7 + test/kvx/instr/individual/compw.leu.c | 7 + test/kvx/instr/individual/compw.lt.c | 7 + test/kvx/instr/individual/compw.ltu.c | 7 + test/kvx/instr/individual/compw.ne.c | 7 + test/kvx/instr/individual/div2.c | 7 + test/kvx/instr/individual/doubleconv.c | 9 + test/kvx/instr/individual/floatconv.c | 9 + test/kvx/instr/individual/fmuld.c | 7 + test/kvx/instr/individual/fmulw.c | 7 + test/kvx/instr/individual/fnegd.c | 7 + test/kvx/instr/individual/fnegw.c | 7 + test/kvx/instr/individual/for.c | 9 + test/kvx/instr/individual/forvar.c | 9 + test/kvx/instr/individual/forvarl.c | 10 + test/kvx/instr/individual/fsbfd.c | 7 + test/kvx/instr/individual/fsbfw.c | 7 + test/kvx/instr/individual/indirect_call.c | 33 +++ test/kvx/instr/individual/indirect_tailcall.c | 33 +++ test/kvx/instr/individual/lbs.c | 9 + test/kvx/instr/individual/lbz.c | 9 + test/kvx/instr/individual/muld.c | 7 + test/kvx/instr/individual/mulw.c | 7 + test/kvx/instr/individual/negd.c | 7 + test/kvx/instr/individual/ord.c | 7 + test/kvx/instr/individual/sbfd.c | 7 + test/kvx/instr/individual/sbfw.c | 7 + test/kvx/instr/individual/simple.c | 7 + test/kvx/instr/individual/sllw.c | 7 + test/kvx/instr/individual/srad.c | 7 + test/kvx/instr/individual/srld.c | 7 + test/kvx/instr/individual/tailcall.c | 16 ++ test/kvx/instr/individual/udivd.c | 7 + test/kvx/instr/individual/umodd.c | 7 + test/kvx/instr/individual/xord.c | 7 + test/kvx/instr/modi32.c | 5 + test/kvx/instr/modui32.c | 7 + test/kvx/instr/ui32.c | 12 + test/kvx/instr/ui64.c | 10 + test/kvx/interop/.gitignore | 1 + test/kvx/interop/Makefile | 365 ++++++++++++++++++++++++ test/kvx/interop/common.c | 257 +++++++++++++++++ test/kvx/interop/common.h | 28 ++ test/kvx/interop/framework.h | 66 +++++ test/kvx/interop/i32.c | 13 + test/kvx/interop/i64.c | 14 + test/kvx/interop/individual/i_multiiargs.c | 6 + test/kvx/interop/individual/i_oneiarg.c | 6 + test/kvx/interop/individual/ll_multillargs.c | 7 + test/kvx/interop/individual/ll_onellarg.c | 7 + test/kvx/interop/individual/ll_void.c | 7 + test/kvx/interop/individual/void_void.c | 7 + test/kvx/interop/stackhell.c | 9 + test/kvx/interop/vaarg_common.c | 383 ++++++++++++++++++++++++++ test/kvx/lib/Makefile | 133 +++++++++ test/kvx/lib/printf-test.c | 9 + test/kvx/lib/printf.c | 9 + test/kvx/mmult/.gitignore | 4 + test/kvx/mmult/Makefile | 67 +++++ test/kvx/mmult/README.md | 17 ++ test/kvx/mmult/mmult.c | 146 ++++++++++ test/kvx/mmult/mmult.h | 10 + test/kvx/prng/.gitignore | 3 + test/kvx/prng/Makefile | 69 +++++ test/kvx/prng/README.md | 17 ++ test/kvx/prng/prng.c | 41 +++ test/kvx/prng/prng.h | 10 + test/kvx/prng/types.h | 7 + test/kvx/simucheck.sh | 8 + test/kvx/simutest.sh | 8 + test/kvx/sort/.gitignore | 9 + test/kvx/sort/Makefile | 91 ++++++ test/kvx/sort/README.md | 17 ++ test/kvx/sort/insertion.c | 59 ++++ test/kvx/sort/insertion.h | 6 + test/kvx/sort/main.c | 34 +++ test/kvx/sort/merge.c | 92 +++++++ test/kvx/sort/merge.h | 7 + test/kvx/sort/selection.c | 62 +++++ test/kvx/sort/selection.h | 6 + test/kvx/sort/test.h | 6 + 140 files changed, 3669 insertions(+) create mode 100644 test/kvx/.gitignore create mode 100644 test/kvx/builtins/clzll.c create mode 100644 test/kvx/builtins/stsud.c create mode 100755 test/kvx/coverage.sh create mode 100644 test/kvx/coverage_helper.py create mode 100755 test/kvx/delout.sh create mode 100644 test/kvx/do_test.sh create mode 100644 test/kvx/general/clzd.c create mode 100644 test/kvx/general/clzw.c create mode 100644 test/kvx/general/ctzd.c create mode 100644 test/kvx/general/ctzw.c create mode 100644 test/kvx/general/satd.c create mode 100644 test/kvx/general/sbmm8.c create mode 100644 test/kvx/general/sbmmt8.c create mode 100755 test/kvx/hardcheck.sh create mode 100755 test/kvx/hardtest.sh create mode 100644 test/kvx/instr/.gitignore create mode 100644 test/kvx/instr/Makefile create mode 100644 test/kvx/instr/builtin32.c create mode 100644 test/kvx/instr/builtin64.c create mode 100644 test/kvx/instr/div32.c create mode 100644 test/kvx/instr/divf32.c create mode 100644 test/kvx/instr/divf64.c create mode 100644 test/kvx/instr/divu32.c create mode 100644 test/kvx/instr/f32.c create mode 100644 test/kvx/instr/f64.c create mode 100755 test/kvx/instr/floatcmp.py create mode 100644 test/kvx/instr/framework.h create mode 100644 test/kvx/instr/i32.c create mode 100644 test/kvx/instr/i64.c create mode 100644 test/kvx/instr/individual/andw.c create mode 100644 test/kvx/instr/individual/branch.c create mode 100644 test/kvx/instr/individual/branchz.c create mode 100644 test/kvx/instr/individual/branchzu.c create mode 100644 test/kvx/instr/individual/call.c create mode 100644 test/kvx/instr/individual/cast_S32_S64.c create mode 100644 test/kvx/instr/individual/cast_S64_U32.c create mode 100644 test/kvx/instr/individual/cb.deqz.c create mode 100644 test/kvx/instr/individual/cb.dgez.c create mode 100644 test/kvx/instr/individual/cb.dgtz.c create mode 100644 test/kvx/instr/individual/cb.dlez.c create mode 100644 test/kvx/instr/individual/cb.dltz.c create mode 100644 test/kvx/instr/individual/cb.dnez.c create mode 100644 test/kvx/instr/individual/cb.wgez.c create mode 100644 test/kvx/instr/individual/cb.wgtz.c create mode 100644 test/kvx/instr/individual/cb.wlez.c create mode 100644 test/kvx/instr/individual/cb.wltz.c create mode 100644 test/kvx/instr/individual/compd.eq.c create mode 100644 test/kvx/instr/individual/compd.geu.c create mode 100644 test/kvx/instr/individual/compd.gt.c create mode 100644 test/kvx/instr/individual/compd.le.c create mode 100644 test/kvx/instr/individual/compd.leu.c create mode 100644 test/kvx/instr/individual/compd.lt.c create mode 100644 test/kvx/instr/individual/compd.ltu.c create mode 100644 test/kvx/instr/individual/compd.ne.c create mode 100644 test/kvx/instr/individual/compw.eq.c create mode 100644 test/kvx/instr/individual/compw.geu.c create mode 100644 test/kvx/instr/individual/compw.gt.c create mode 100644 test/kvx/instr/individual/compw.gtu.c create mode 100644 test/kvx/instr/individual/compw.le.c create mode 100644 test/kvx/instr/individual/compw.leu.c create mode 100644 test/kvx/instr/individual/compw.lt.c create mode 100644 test/kvx/instr/individual/compw.ltu.c create mode 100644 test/kvx/instr/individual/compw.ne.c create mode 100644 test/kvx/instr/individual/div2.c create mode 100644 test/kvx/instr/individual/doubleconv.c create mode 100644 test/kvx/instr/individual/floatconv.c create mode 100644 test/kvx/instr/individual/fmuld.c create mode 100644 test/kvx/instr/individual/fmulw.c create mode 100644 test/kvx/instr/individual/fnegd.c create mode 100644 test/kvx/instr/individual/fnegw.c create mode 100644 test/kvx/instr/individual/for.c create mode 100644 test/kvx/instr/individual/forvar.c create mode 100644 test/kvx/instr/individual/forvarl.c create mode 100644 test/kvx/instr/individual/fsbfd.c create mode 100644 test/kvx/instr/individual/fsbfw.c create mode 100644 test/kvx/instr/individual/indirect_call.c create mode 100644 test/kvx/instr/individual/indirect_tailcall.c create mode 100644 test/kvx/instr/individual/lbs.c create mode 100644 test/kvx/instr/individual/lbz.c create mode 100644 test/kvx/instr/individual/muld.c create mode 100644 test/kvx/instr/individual/mulw.c create mode 100644 test/kvx/instr/individual/negd.c create mode 100644 test/kvx/instr/individual/ord.c create mode 100644 test/kvx/instr/individual/sbfd.c create mode 100644 test/kvx/instr/individual/sbfw.c create mode 100644 test/kvx/instr/individual/simple.c create mode 100644 test/kvx/instr/individual/sllw.c create mode 100644 test/kvx/instr/individual/srad.c create mode 100644 test/kvx/instr/individual/srld.c create mode 100644 test/kvx/instr/individual/tailcall.c create mode 100644 test/kvx/instr/individual/udivd.c create mode 100644 test/kvx/instr/individual/umodd.c create mode 100644 test/kvx/instr/individual/xord.c create mode 100644 test/kvx/instr/modi32.c create mode 100644 test/kvx/instr/modui32.c create mode 100644 test/kvx/instr/ui32.c create mode 100644 test/kvx/instr/ui64.c create mode 100644 test/kvx/interop/.gitignore create mode 100644 test/kvx/interop/Makefile create mode 100644 test/kvx/interop/common.c create mode 100644 test/kvx/interop/common.h create mode 100644 test/kvx/interop/framework.h create mode 100644 test/kvx/interop/i32.c create mode 100644 test/kvx/interop/i64.c create mode 100644 test/kvx/interop/individual/i_multiiargs.c create mode 100644 test/kvx/interop/individual/i_oneiarg.c create mode 100644 test/kvx/interop/individual/ll_multillargs.c create mode 100644 test/kvx/interop/individual/ll_onellarg.c create mode 100644 test/kvx/interop/individual/ll_void.c create mode 100644 test/kvx/interop/individual/void_void.c create mode 100644 test/kvx/interop/stackhell.c create mode 100644 test/kvx/interop/vaarg_common.c create mode 100644 test/kvx/lib/Makefile create mode 100644 test/kvx/lib/printf-test.c create mode 100644 test/kvx/lib/printf.c create mode 100644 test/kvx/mmult/.gitignore create mode 100644 test/kvx/mmult/Makefile create mode 100644 test/kvx/mmult/README.md create mode 100644 test/kvx/mmult/mmult.c create mode 100644 test/kvx/mmult/mmult.h create mode 100644 test/kvx/prng/.gitignore create mode 100644 test/kvx/prng/Makefile create mode 100644 test/kvx/prng/README.md create mode 100644 test/kvx/prng/prng.c create mode 100644 test/kvx/prng/prng.h create mode 100644 test/kvx/prng/types.h create mode 100755 test/kvx/simucheck.sh create mode 100755 test/kvx/simutest.sh create mode 100644 test/kvx/sort/.gitignore create mode 100644 test/kvx/sort/Makefile create mode 100644 test/kvx/sort/README.md create mode 100644 test/kvx/sort/insertion.c create mode 100644 test/kvx/sort/insertion.h create mode 100644 test/kvx/sort/main.c create mode 100644 test/kvx/sort/merge.c create mode 100644 test/kvx/sort/merge.h create mode 100644 test/kvx/sort/selection.c create mode 100644 test/kvx/sort/selection.h create mode 100644 test/kvx/sort/test.h (limited to 'test/kvx') 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 +#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 +#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 + +#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 +#include + +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 -- cgit