diff options
Diffstat (limited to 'test')
44 files changed, 1811 insertions, 0 deletions
diff --git a/test/anc/v1/1rops.asm b/test/anc/v1/1rops.asm new file mode 100644 index 0000000..6ab33a9 --- /dev/null +++ b/test/anc/v1/1rops.asm @@ -0,0 +1,109 @@ +; file : test/anc/v1/1rops.asm +; project : Salis-VM +; author : Paul Oliver <contact@pauloliver.dev> + +incn +incn +nop0 +incn +nop1 +nop2 +incn +nop2 +nop3 +nop0 +incn +nop3 + +noop + +decn +decn +nop0 +decn +nop1 +nop2 +decn +nop2 +nop3 +nop0 +decn +nop3 + +noop + +incn +incn +incn +notn +notn +nop0 +notn +nop1 +nop2 +notn +nop2 +nop3 +nop0 +notn +nop3 + +noop + +shfl +shfl +nop0 +shfl +nop1 +nop2 +shfl +nop2 +nop3 +nop0 +shfl +nop3 + +noop + +shfr +shfr +nop0 +shfr +nop1 +nop2 +shfr +nop2 +nop3 +nop0 +shfr +nop3 + +noop + +zero +zero +nop0 +zero +nop1 +nop2 +zero +nop2 +nop3 +nop0 +zero +nop3 + +noop + +unit +unit +nop0 +unit +nop1 +nop2 +unit +nop2 +nop3 +nop0 +unit +nop3 diff --git a/test/anc/v1/2rops.asm b/test/anc/v1/2rops.asm new file mode 100644 index 0000000..c1021d9 --- /dev/null +++ b/test/anc/v1/2rops.asm @@ -0,0 +1,26 @@ +; file : test/anc/v1/2rops.asm +; project : Salis-VM +; author : Paul Oliver <contact@pauloliver.dev> + +incn +incn +incn + +noop + +rdup +nop0 +nop1 +rdup +nop2 +rdup +nop1 +nop3 + +noop + +rswp +nop1 +rswp +nop3 +nop2 diff --git a/test/anc/v1/3rops.asm b/test/anc/v1/3rops.asm new file mode 100644 index 0000000..84c6596 --- /dev/null +++ b/test/anc/v1/3rops.asm @@ -0,0 +1,70 @@ +; file : test/anc/v1/3rops.asm +; project : Salis-VM +; author : Paul Oliver <contact@pauloliver.dev> + +incn +addn +addn +nop0 +addn +nop1 +nop0 +addn +nop2 +nop1 +nop0 +addn +nop3 +nop2 +nop1 + +noop + +subn +nop3 +nop2 +nop1 +subn +nop3 +nop2 +subn +nop3 +subn +nop1 +nop2 +subn + +noop + +incn +incn +muln +muln +nop0 +muln +nop1 +nop0 +muln +nop2 +nop1 +nop0 +muln +nop3 +nop2 +nop1 + +noop + +divn +nop3 +nop2 +nop1 +divn +nop3 +nop2 +divn +nop3 +divn +nop1 +nop2 +divn diff --git a/test/anc/v1/addrs.asm b/test/anc/v1/addrs.asm new file mode 100644 index 0000000..b67532e --- /dev/null +++ b/test/anc/v1/addrs.asm @@ -0,0 +1,75 @@ +; file : test/anc/v1/addrs.asm +; project : Salis-VM +; author : Paul Oliver <contact@pauloliver.dev> + +lokb +lokd +lokf +lokh +lokj +lokl +lokn +lokp + +noop +noop + +adrf +keya +adrb +keyb +nop1 +adrf +keyc +nop2 +adrb +keyd +nop3 +adrf +keye +nop0 +adrb +keyf +nop1 +adrf +keyg +nop2 +adrb +keyh +nop3 +adrf +keyi +nop0 +adrb +keyj +nop1 +adrf +keyk +nop2 +adrb +keyl +nop3 +adrf +keym +nop0 +adrb +keyn +nop1 +adrf +keyo +nop2 +adrb +keyp +nop3 + +noop +noop + +loka +lokc +loke +lokg +loki +lokk +lokm +loko diff --git a/test/anc/v1/allos.asm b/test/anc/v1/allos.asm new file mode 100644 index 0000000..37f8540 --- /dev/null +++ b/test/anc/v1/allos.asm @@ -0,0 +1,33 @@ +; file : test/anc/v1/allos.asm +; project : Salis-VM +; author : Paul Oliver <contact@pauloliver.dev> + +incn +shfl +shfl + +malf +nop0 +nop1 +malf +malb +bspl +bspl +bspl + +malf +nop0 +nop1 +malb +malf +bswp +bclr + +noop +noop +noop + +malb +nop0 +nop1 +bspl diff --git a/test/anc/v1/ifnzs.asm b/test/anc/v1/ifnzs.asm new file mode 100644 index 0000000..86899b0 --- /dev/null +++ b/test/anc/v1/ifnzs.asm @@ -0,0 +1,50 @@ +; file : test/anc/v1/ifnzs.asm +; project : Salis-VM +; author : Paul Oliver <contact@pauloliver.dev> + +ifnz +incn +incn +ifnz +nop0 +incn +nop0 + +noop + +ifnz +nop1 +incn +nop1 +incn +nop1 +ifnz +nop1 +incn +nop1 + +noop + +ifnz +nop2 +incn +nop2 +incn +nop2 +ifnz +nop2 +incn +nop2 + +noop + +ifnz +nop3 +incn +nop3 +incn +nop3 +ifnz +nop3 +incn +nop3 diff --git a/test/anc/v1/ioops.asm b/test/anc/v1/ioops.asm new file mode 100644 index 0000000..ca02d57 --- /dev/null +++ b/test/anc/v1/ioops.asm @@ -0,0 +1,104 @@ +; file : test/anc/v1/ioops.asm +; project : Salis-VM +; author : Paul Oliver <contact@pauloliver.dev> + +keya +lokb +keyc +lokd +keye +lokf +keyg +lokh + +noop + +incn +nop1 +incn +nop2 +incn +nop2 +incn +nop3 +incn +nop3 +incn +nop3 +rpsh +rpsh +nop1 +rpsh +nop2 +rpsh +nop3 + +noop + +rloa +rloa +nop1 +nop1 +rloa +nop2 +nop2 +rloa +nop3 +nop3 + +rpop +nop3 +rpop +nop2 +rpop +nop1 +rpop +rpsh +rpsh +nop1 +rpsh +nop2 +rpsh +nop3 + +noop + +rloa +nop2 +nop3 +rloa +nop1 +nop2 +rloa +nop0 +nop1 +rloa + +noop + +muln +nop0 +nop1 +nop2 +muln +nop1 +nop2 +nop3 +muln +nop2 +nop3 +zero +nop3 + +rwrt +nop3 +incn +nop3 +rwrt +nop3 +nop1 +incn +nop3 +rwrt +nop3 +nop2 diff --git a/test/anc/v1/jumps.asm b/test/anc/v1/jumps.asm new file mode 100644 index 0000000..6cde582 --- /dev/null +++ b/test/anc/v1/jumps.asm @@ -0,0 +1,56 @@ +; file : test/anc/v1/jumps.asm +; project : Salis-VM +; author : Paul Oliver <contact@pauloliver.dev> + +jmpf +keya +lokb +jmpf +keyc +lokd +jmpf +keye +lokf +jmpf +keyg +lokh +jmpf +keyi +lokj +jmpf +keyk +lokl +jmpf +keym +lokn +jmpf +keyo +lokp + +noop +noop + +loka +jmpb +keyb +lokc +jmpb +keyd +loke +jmpb +keyf +lokg +jmpb +keyh +loki +jmpb +keyj +lokk +jmpb +keyl +lokm +jmpb +keyn +loko +jmpb +keyp diff --git a/test/anc/v1/mbops.asm b/test/anc/v1/mbops.asm new file mode 100644 index 0000000..b57e88b --- /dev/null +++ b/test/anc/v1/mbops.asm @@ -0,0 +1,17 @@ +; file : test/anc/v1/mbops.asm +; project : Salis-VM +; author : Paul Oliver <contact@pauloliver.dev> + +incn +shfl +shfl +malf + +bswp +bswp +bswp + +bclr + +bswp +bclr diff --git a/test/anc/v1/noops.asm b/test/anc/v1/noops.asm new file mode 100644 index 0000000..e4547c2 --- /dev/null +++ b/test/anc/v1/noops.asm @@ -0,0 +1,42 @@ +; file : test/anc/v1/noops.asm +; project : Salis-VM +; author : Paul Oliver <contact@pauloliver.dev> + +noop +nop0 +nop1 +nop2 +nop3 + +keya +keyb +keyc +keyd +keye +keyf +keyg +keyh +keyi +keyj +keyk +keyl +keym +keyn +keyo +keyp +loka +lokb +lokc +lokd +loke +lokf +lokg +lokh +loki +lokj +lokk +lokl +lokm +lokn +loko +lokp diff --git a/test/anc/v1/stack.asm b/test/anc/v1/stack.asm new file mode 100644 index 0000000..bce1a25 --- /dev/null +++ b/test/anc/v1/stack.asm @@ -0,0 +1,51 @@ +; file : test/anc/v1/stack.asm +; project : Salis-VM +; author : Paul Oliver <contact@pauloliver.dev> + +incn +incn +nop1 +shfl +nop1 +incn +nop2 +shfl +nop2 +shfl +nop2 + +noop + +rpsh +rpsh +nop1 +rpsh +nop2 +rpsh +nop3 +rpsh +nop0 +rpsh +nop1 +rpsh +nop2 +rpsh +nop3 + +noop + +rpop +rpop +nop1 +rpop +nop2 +rpop +nop3 +rpop +nop0 +rpop +nop1 +rpop +nop2 +rpop +nop3 diff --git a/test/test_build.py b/test/test_build.py new file mode 100644 index 0000000..e13669a --- /dev/null +++ b/test/test_build.py @@ -0,0 +1,114 @@ +# file : test/test_build.py +# project : Salis-VM +# author : Paul Oliver <contact@pauloliver.dev> + +# index: +# [section] command lists +# [section] tests null +# [section] tests v1 +# [section] tests server & client + +import signal + +from test_general import SalisTest + +class TestBuild(SalisTest): + SIM_NAME = "test-build.sim" + + # -------------------------------------------------------------------------- + # [section] command lists + # -------------------------------------------------------------------------- + def commands_new(self, anc, arch): + return [ + f"./salis.py new -a{anc} -b -f -g{compiler} -H{self.tempdir.name} -n{self.SIM_NAME} {log_trace} {optimized} -s{seed} -u{ui} -v{arch}" + for compiler in ["clang", "gcc", "tcc"] + for log_trace in ["", "-l"] + for optimized in ["", "-o"] + for seed in [-1, 0, 1234] + for ui in ["curses", "daemon"] + ] + + def commands_load(self): + return [ + f"./salis.py load -b -g{compiler} -H{self.tempdir.name} -n{self.SIM_NAME} {log_trace} {optimized} -u{ui}" + for compiler in ["clang", "gcc", "tcc"] + for log_trace in ["", "-l"] + for optimized in ["", "-o"] + for ui in ["curses", "daemon"] + ] + + def cmds_server(self): + return [ + f"./salis.py server -b -g{compiler} -H{self.tempdir.name} -n{self.SIM_NAME} {optimized}" + for compiler in ["clang", "gcc"] + for optimized in ["", "-o"] + ] + + def cmds_client(self): + return [ + f"./salis.py client -b -g{c_compiler} -G{cpp_compiler} {optimized}" + for c_compiler, cpp_compiler in [("clang", "clang++"), ("gcc", "g++")] + for optimized in ["", "-o"] + ] + + # -------------------------------------------------------------------------- + # [section] tests null + # -------------------------------------------------------------------------- + def test_null_new(self): + for command in self.commands_new("0123", "null"): + self.run_subprocess(command) + self.assert_files_exist([f"{self.tempdir.name}/{self.SIM_NAME}/opts.json"]) + + def test_null_load(self): + self.run_subprocess(self.commands_new("0123", "null")[0]) + self.assert_files_exist([f"{self.tempdir.name}/{self.SIM_NAME}/opts.json"]) + + for command in self.commands_load(): + self.run_subprocess(command) + self.assert_files_exist([f"{self.tempdir.name}/{self.SIM_NAME}/opts.json"]) + + # -------------------------------------------------------------------------- + # [section] tests v1 + # -------------------------------------------------------------------------- + def test_v1_new(self): + for command in self.commands_new("55a", "v1"): + self.run_subprocess(command) + self.assert_files_exist([f"{self.tempdir.name}/{self.SIM_NAME}/opts.json"]) + + def test_v1_load(self): + self.run_subprocess(self.commands_new("55a", "v1")[0]) + self.assert_files_exist([f"{self.tempdir.name}/{self.SIM_NAME}/opts.json"]) + + for command in self.commands_load(): + self.run_subprocess(command) + self.assert_files_exist([f"{self.tempdir.name}/{self.SIM_NAME}/opts.json"]) + + # -------------------------------------------------------------------------- + # [section] tests server & client + # -------------------------------------------------------------------------- + def client_test(self): + with self.run_pipe(f"./salis.py server -H{self.tempdir.name}") as server_proc: + for line in server_proc.stdout: + if "Listening..." in line: + break + + for cmd in self.cmds_client(): + self.run_subprocess(cmd) + + server_proc.send_signal(signal.SIGINT) + + def test_server(self): + self.run_subprocess(self.commands_new("0123", "null")[0]) + self.assert_files_exist([f"{self.tempdir.name}/{self.SIM_NAME}/opts.json"]) + + for cmd in self.cmds_server(): + self.run_subprocess(cmd) + self.assert_files_exist([f"{self.tempdir.name}/{self.SIM_NAME}/opts.json"]) + + def test_client_null(self): + self.run_ui_test("0123", "anc", "null", "test/ui", "null") + self.client_test() + + def test_client_v1(self): + self.run_ui_test("55a", "anc", "null", "test/ui", "v1") + self.client_test() diff --git a/test/test_determinism.py b/test/test_determinism.py new file mode 100644 index 0000000..0d40fcb --- /dev/null +++ b/test/test_determinism.py @@ -0,0 +1,50 @@ +# file : test/test_determinism.py +# project : Salis-VM +# author : Paul Oliver <contact@pauloliver.dev> +# +# This test ensures simulator produces deterministic results. +# Resulting save, eva and DB files must be exactly the same for all simulations, +# whenever the same seed value is used. + +import hashlib +import os + +from test_general import SalisTest + +class TestDeterminism(SalisTest): + SIM_OPTS = { + "anc": "55a", + "anc_path": "anc", + "name": "determinism.sim", + "ui_path": "test/ui", + "vm_arch": "v1", + } + + SIM_OPTS_ASA4 = SIM_OPTS | {"ui": "asa4"} + SIM_OPTS_PUSH = SIM_OPTS | {"ui": "push"} + + def get_asa4_sums(self): + self.run_ui_test(**self.SIM_OPTS_ASA4, clones=2, cores=2, mvec_pow=16, seed=8765432, data_push_pow=20, sync_pow=16, auto_save_pow=20) + sim_path = f"{self.tempdir.name}/{self.SIM_OPTS["name"]}" + auto_saves = sorted(f"{sim_path}/{f}" for f in os.listdir(sim_path)) + auto_saves = filter(lambda f: f.startswith(f"{sim_path}/{self.SIM_OPTS["name"]}-"), auto_saves) + auto_saves = list(auto_saves)[:4] + evas = sorted(f"{sim_path}/evas/{f}" for f in os.listdir(f"{sim_path}/evas")) + evas = list(evas)[:4] + return {f: hashlib.md5(open(f, "rb").read()).hexdigest() for f in auto_saves + evas} + + def get_db_sums(self): + self.run_ui_test(**self.SIM_OPTS_PUSH, clones=2, cores=2, mvec_pow=16, seed=8765432, data_push_pow=20, sync_pow=16, auto_save_pow=20) + sim_path = f"{self.tempdir.name}/{self.SIM_OPTS["name"]}" + db_path = f"{sim_path}/{self.SIM_OPTS["name"]}.sqlite3" + return hashlib.md5(open(db_path, "rb").read()).hexdigest() + + def test_deterministic_saves_and_evas(self): + sums_1 = self.get_asa4_sums() + sums_2 = self.get_asa4_sums() + self.assertEqual(sums_1, sums_2) + + def test_deterministic_db(self): + sum_1 = self.get_db_sums() + sum_2 = self.get_db_sums() + self.assertEqual(sum_1, sum_2) diff --git a/test/test_general.py b/test/test_general.py new file mode 100644 index 0000000..2286b4f --- /dev/null +++ b/test/test_general.py @@ -0,0 +1,58 @@ +# file : test/test_general.py +# project : Salis-VM +# author : Paul Oliver <contact@pauloliver.dev> + +# index: +# [section] setup/teardown +# [section] file lists +# [section] assertions +# [section] subprocess + +import os +import subprocess +import unittest + +from tempfile import TemporaryDirectory + +class SalisTest(unittest.TestCase): + # -------------------------------------------------------------------------- + # [section] setup/teardown + # -------------------------------------------------------------------------- + def setUp(self): + self.tempdir = TemporaryDirectory(prefix="salis_test_") + + def tearDown(self): + self.tempdir.cleanup() + + # -------------------------------------------------------------------------- + # [section] file lists + # -------------------------------------------------------------------------- + def files_on_new(self, name): + return [ + f"{self.tempdir.name}/{name}/evas/evas-{0:016x}", + f"{self.tempdir.name}/{name}/opts.json", + f"{self.tempdir.name}/{name}/{name}", + f"{self.tempdir.name}/{name}/{name}-{0:016x}", + f"{self.tempdir.name}/{name}/{name}.sqlite3", + ] + + # -------------------------------------------------------------------------- + # [section] assertions + # -------------------------------------------------------------------------- + def assert_files_exist(self, files): + for file in files: + assert os.path.isfile(file), f"{file} does not exist" + + # -------------------------------------------------------------------------- + # [section] subprocess + # -------------------------------------------------------------------------- + def run_subprocess(self, command): + subprocess.run(command.split(), check=True, stdout=subprocess.DEVNULL) + + def run_pipe(self, command): + return subprocess.Popen(command.split(), stdout=subprocess.PIPE, text=True) + + def run_ui_test(self, anc, anc_path, ui, ui_path, vm_arch, clones=1, cores=1, mvec_pow=20, name="def.sim", seed=0, data_push_pow=28, sync_pow=20, auto_save_pow=36, **kwargs): + command = f"./salis.py new -a{anc} -A{anc_path} -C{clones} -c{cores} -d{data_push_pow} -f -H{self.tempdir.name} -m{mvec_pow} -n{name} -s{seed} -u{ui} -U{ui_path} -v{vm_arch} -y{sync_pow} -z{auto_save_pow}" + self.run_subprocess(command) + self.assert_files_exist(self.files_on_new(name)) diff --git a/test/test_run.py b/test/test_run.py new file mode 100644 index 0000000..c86b42b --- /dev/null +++ b/test/test_run.py @@ -0,0 +1,59 @@ +# file : test/test_run.py +# project : Salis-VM +# author : Paul Oliver <contact@pauloliver.dev> + +# index: +# [section] command lists +# [section] file lists +# [section] tests null +# [section] tests v1 + +from test_general import SalisTest + +class TestRun(SalisTest): + SIM_NAME = "test-run.sim" + PUSH_POW = 8 + + # -------------------------------------------------------------------------- + # [section] command lists + # -------------------------------------------------------------------------- + def commands(self, anc, arch): + return [ + ( + f"./salis.py new -a{anc} -d{self.PUSH_POW} -f -g{compiler} -H{self.tempdir.name} {log_trace} -n{self.SIM_NAME} {optimized} -s{seed} -upush -Utest/ui/ -v{arch} -y{self.PUSH_POW}", + f"./salis.py load -g{compiler} -H{self.tempdir.name} {log_trace} -n{self.SIM_NAME} {optimized} -upush -Utest/ui/", + ) + for compiler in ["clang", "gcc", "tcc"] + for log_trace in ["", "-l"] + for optimized in ["", "-o"] + for seed in [-1, 0, 1234] + ] + + # -------------------------------------------------------------------------- + # [section] file lists + # -------------------------------------------------------------------------- + def files_on_first_push(self): + return [*self.files_on_new(self.SIM_NAME), f"{self.tempdir.name}/{self.SIM_NAME}/evas/evas-{2 ** self.PUSH_POW:016x}"] + + def files_on_second_push(self): + return [*self.files_on_first_push(), f"{self.tempdir.name}/{self.SIM_NAME}/evas/evas-{2 * (2 ** self.PUSH_POW):016x}"] + + # -------------------------------------------------------------------------- + # [section] tests null + # -------------------------------------------------------------------------- + def test_null(self): + for command in self.commands("0123", "null"): + self.run_subprocess(command[0]) + self.assert_files_exist(self.files_on_first_push()) + self.run_subprocess(command[1]) + self.assert_files_exist(self.files_on_second_push()) + + # -------------------------------------------------------------------------- + # [section] tests v1 + # -------------------------------------------------------------------------- + def test_v1(self): + for command in self.commands("55a", "v1"): + self.run_subprocess(command[0]) + self.assert_files_exist(self.files_on_first_push()) + self.run_subprocess(command[1]) + self.assert_files_exist(self.files_on_second_push()) diff --git a/test/test_v1.py b/test/test_v1.py new file mode 100644 index 0000000..b84feb2 --- /dev/null +++ b/test/test_v1.py @@ -0,0 +1,51 @@ +# file : test/test_v1.py +# project : Salis-VM +# author : Paul Oliver <contact@pauloliver.dev> + +# index: +# [section] tests + +from test_general import SalisTest + +class TestV1(SalisTest): + SIM_OPTS = { + "anc_path": "test/anc", + "ui_path": "test/ui/v1", + "vm_arch": "v1", + } + + # -------------------------------------------------------------------------- + # [section] tests + # -------------------------------------------------------------------------- + def test_noops(self): + self.run_ui_test(**self.SIM_OPTS, anc="noops", ui="noops") + + def test_jumps(self): + self.run_ui_test(**self.SIM_OPTS, anc="jumps", ui="jumps") + + def test_addrs(self): + self.run_ui_test(**self.SIM_OPTS, anc="addrs", ui="addrs") + + def test_ifnzs(self): + self.run_ui_test(**self.SIM_OPTS, anc="ifnzs", ui="ifnzs") + + def test_allos(self): + self.run_ui_test(**self.SIM_OPTS, anc="allos", ui="allos") + + def test_mbops(self): + self.run_ui_test(**self.SIM_OPTS, anc="mbops", ui="mbops") + + def test_3rops(self): + self.run_ui_test(**self.SIM_OPTS, anc="3rops", ui="3rops") + + def test_1rops(self): + self.run_ui_test(**self.SIM_OPTS, anc="1rops", ui="1rops") + + def test_stack(self): + self.run_ui_test(**self.SIM_OPTS, anc="stack", ui="stack") + + def test_ioops(self): + self.run_ui_test(**self.SIM_OPTS, anc="ioops", ui="ioops") + + def test_2rops(self): + self.run_ui_test(**self.SIM_OPTS, anc="2rops", ui="2rops") diff --git a/test/ui/asa4/links.json b/test/ui/asa4/links.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/test/ui/asa4/links.json @@ -0,0 +1 @@ +[] diff --git a/test/ui/asa4/ui.c b/test/ui/asa4/ui.c new file mode 100644 index 0000000..5a96e3f --- /dev/null +++ b/test/ui/asa4/ui.c @@ -0,0 +1,29 @@ +// file : test/ui/asa4/ui.c +// project : Salis-VM +// author : Paul Oliver <contact@pauloliver.dev> + +#include <stdbool.h> +#include <stdint.h> +#include <threads.h> +#include <zlib.h> + +#include "arch_spec.h" +#include "arch_inst.h" +#include "compress.h" +#include "logger.h" +#include "salis.h" + +int main(void) { + salis_init(); + + // Run threads until 4 autosaves are made + while (g_step < AUTOSAVE_INTERVAL * 4) { + salis_start(); + sleep(1); + salis_signal_stop(); + salis_wait(); + } + + salis_save_and_free(); + return 0; +} diff --git a/test/ui/null/links.json b/test/ui/null/links.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/test/ui/null/links.json @@ -0,0 +1 @@ +[] diff --git a/test/ui/null/ui.c b/test/ui/null/ui.c new file mode 100644 index 0000000..7366e53 --- /dev/null +++ b/test/ui/null/ui.c @@ -0,0 +1,24 @@ +// file : test/ui/null/ui.c +// project : Salis-VM +// author : Paul Oliver <contact@pauloliver.dev> + +#include <stdbool.h> +#include <stdint.h> +#include <threads.h> +#include <zlib.h> + +#include "arch_spec.h" +#include "arch_inst.h" +#include "compress.h" +#include "logger.h" +#include "salis.h" + +int main(void) { +#if defined(COMMAND_NEW) + salis_init(); +#elif defined(COMMAND_LOAD) + salis_load(); +#endif + salis_save_and_free(); + return 0; +} diff --git a/test/ui/push/links.json b/test/ui/push/links.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/test/ui/push/links.json @@ -0,0 +1 @@ +[] diff --git a/test/ui/push/ui.c b/test/ui/push/ui.c new file mode 100644 index 0000000..cc5922f --- /dev/null +++ b/test/ui/push/ui.c @@ -0,0 +1,26 @@ +// file : test/ui/push/ui.c +// project : Salis-VM +// author : Paul Oliver <contact@pauloliver.dev> + +#include <stdbool.h> +#include <stdint.h> +#include <threads.h> +#include <zlib.h> + +#include "arch_spec.h" +#include "arch_inst.h" +#include "compress.h" +#include "logger.h" +#include "salis.h" + +int main(void) { +#if defined(COMMAND_NEW) + salis_init(); +#elif defined(COMMAND_LOAD) + salis_load(); +#endif + + salis_step(DATA_PUSH_INTERVAL); + salis_save_and_free(); + return 0; +} diff --git a/test/ui/v1/1rops/links.json b/test/ui/v1/1rops/links.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/test/ui/v1/1rops/links.json @@ -0,0 +1 @@ +[] diff --git a/test/ui/v1/1rops/ui.c b/test/ui/v1/1rops/ui.c new file mode 100644 index 0000000..637e3f5 --- /dev/null +++ b/test/ui/v1/1rops/ui.c @@ -0,0 +1,74 @@ +// file : test/ui/v1/1rops/ui.c +// project : Salis-VM +// author : Paul Oliver <contact@pauloliver.dev> + +#include <assert.h> +#include <stdint.h> +#include <threads.h> +#include <zlib.h> + +#include "arch_spec.h" +#include "arch_inst.h" +#include "compress.h" +#include "salis.h" + +int main(void) { + salis_init(); + + while (mvec_is_proc_owner(g_cores, g_cores->pvec->ip, g_cores->pcur)) { + uint8_t inst = mvec_get_inst(g_cores, g_cores->pvec->ip); + + if (inst != incn && inst != decn && inst != notn && inst != shfl && inst != shfr && inst != zero && inst != unit) { + salis_step(1); + continue; + } + + uint64_t *reg = &g_cores->pvec->r0x; + + switch (mvec_get_inst(g_cores, g_cores->pvec->ip + 1)) { + case nop0: + reg = &g_cores->pvec->r0x; + break; + case nop1: + reg = &g_cores->pvec->r1x; + break; + case nop2: + reg = &g_cores->pvec->r2x; + break; + case nop3: + reg = &g_cores->pvec->r3x; + break; + } + + uint64_t reg_val = *reg; + + salis_step(1); + + switch (inst) { + case incn: + assert(*reg == reg_val + 1); + break; + case decn: + assert(*reg == reg_val - 1); + break; + case notn: + assert(*reg == !reg_val); + break; + case shfl: + assert(*reg == reg_val << 1); + break; + case shfr: + assert(*reg == reg_val >> 1); + break; + case zero: + assert(*reg == 0); + break; + case unit: + assert(*reg == 1); + break; + } + } + + salis_save_and_free(); + return 0; +} diff --git a/test/ui/v1/2rops/links.json b/test/ui/v1/2rops/links.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/test/ui/v1/2rops/links.json @@ -0,0 +1 @@ +[] diff --git a/test/ui/v1/2rops/ui.c b/test/ui/v1/2rops/ui.c new file mode 100644 index 0000000..e74172b --- /dev/null +++ b/test/ui/v1/2rops/ui.c @@ -0,0 +1,56 @@ +// file : test/ui/v1/2rops/ui.c +// project : Salis-VM +// author : Paul Oliver <contact@pauloliver.dev> + +#include <assert.h> +#include <stdint.h> +#include <threads.h> +#include <zlib.h> + +#include "arch_spec.h" +#include "arch_inst.h" +#include "compress.h" +#include "salis.h" + +int main(void) { + salis_init(); + + while (mvec_is_proc_owner(g_cores, g_cores->pvec->ip, g_cores->pcur)) { + uint8_t inst = mvec_get_inst(g_cores, g_cores->pvec->ip); + + if (inst != rdup && inst != rswp) { + salis_step(1); + continue; + } + + uint64_t *regs[2] = { + &g_cores->pvec->r0x, + &g_cores->pvec->r0x, + }; + + for (uint64_t i = 0; i < 2; i++) { + uint8_t rmod = mvec_get_inst(g_cores, g_cores->pvec->ip + 1 + i); + if (rmod == nop0) regs[i] = &g_cores->pvec->r0x; + else if (rmod == nop1) regs[i] = &g_cores->pvec->r1x; + else if (rmod == nop2) regs[i] = &g_cores->pvec->r2x; + else if (rmod == nop3) regs[i] = &g_cores->pvec->r3x; + else break; + } + + uint64_t reg_vals[2] = {*regs[0], *regs[1]}; + salis_step(1); + + switch (inst) { + case rdup: + assert(*regs[1] == reg_vals[0]); + break; + case rswp: + assert(*regs[0] == reg_vals[1]); + assert(*regs[1] == reg_vals[0]); + break; + } + } + + salis_save_and_free(); + return 0; +} diff --git a/test/ui/v1/3rops/links.json b/test/ui/v1/3rops/links.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/test/ui/v1/3rops/links.json @@ -0,0 +1 @@ +[] diff --git a/test/ui/v1/3rops/ui.c b/test/ui/v1/3rops/ui.c new file mode 100644 index 0000000..2a53197 --- /dev/null +++ b/test/ui/v1/3rops/ui.c @@ -0,0 +1,65 @@ +// file : test/ui/v1/3rops/ui.c +// project : Salis-VM +// author : Paul Oliver <contact@pauloliver.dev> + +#include <assert.h> +#include <stdint.h> +#include <threads.h> +#include <zlib.h> + +#include "arch_spec.h" +#include "arch_inst.h" +#include "compress.h" +#include "salis.h" + +int main(void) { + salis_init(); + + while (mvec_is_proc_owner(g_cores, g_cores->pvec->ip, g_cores->pcur)) { + uint8_t inst = mvec_get_inst(g_cores, g_cores->pvec->ip); + + if (inst != addn && inst != subn && inst != muln && inst != divn) { + salis_step(1); + continue; + } + + uint64_t *regs[3] = { + &g_cores->pvec->r0x, + &g_cores->pvec->r0x, + &g_cores->pvec->r0x, + }; + + for (uint64_t i = 0; i < 3; i++) { + uint8_t rmod = mvec_get_inst(g_cores, g_cores->pvec->ip + 1 + i); + + if (rmod == nop0) regs[i] = &g_cores->pvec->r0x; + else if (rmod == nop1) regs[i] = &g_cores->pvec->r1x; + else if (rmod == nop2) regs[i] = &g_cores->pvec->r2x; + else if (rmod == nop3) regs[i] = &g_cores->pvec->r3x; + else break; + } + + uint64_t reg_vals[3] = {*regs[0], *regs[1], *regs[2]}; + salis_step(1); + uint64_t result = *regs[0]; + + switch (inst) { + case addn: + assert(result == reg_vals[1] + reg_vals[2]); + break; + case subn: + assert(result == reg_vals[1] - reg_vals[2]); + break; + case muln: + assert(result == reg_vals[1] * reg_vals[2]); + break; + case divn: + assert(reg_vals[2] != 0); + assert(result == reg_vals[1] / reg_vals[2]); + break; + } + } + + salis_save_and_free(); + return 0; +} diff --git a/test/ui/v1/addrs/links.json b/test/ui/v1/addrs/links.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/test/ui/v1/addrs/links.json @@ -0,0 +1 @@ +[] diff --git a/test/ui/v1/addrs/ui.c b/test/ui/v1/addrs/ui.c new file mode 100644 index 0000000..eb4361c --- /dev/null +++ b/test/ui/v1/addrs/ui.c @@ -0,0 +1,58 @@ +// file : test/ui/v1/addrs/ui.c +// project : Salis-VM +// author : Paul Oliver <contact@pauloliver.dev> + +#include <assert.h> +#include <stdint.h> +#include <threads.h> +#include <zlib.h> + +#include "arch_spec.h" +#include "arch_inst.h" +#include "compress.h" +#include "salis.h" + +static void check_found(uint64_t addr, uint64_t lok, uint64_t regi) { + assert(mvec_get_inst(g_cores, addr - 1) == (regi % 2 == 0 ? adrf : adrb)); + assert(mvec_get_inst(g_cores, (&g_cores->pvec->r0x)[regi]) == lok); +} + +int main(void) { + uint64_t regi = 0; + + salis_init(); + + while (mvec_is_proc_owner(g_cores, g_cores->pvec->ip, g_cores->pcur)) { + uint8_t inst = mvec_get_inst(g_cores, g_cores->pvec->ip); + + switch (inst) { +#define CASE(id) \ + case key##id: \ + check_found(g_cores->pvec->ip, lok##id, regi); \ + regi = (regi + 1) % 4; \ + break; + CASE(a) + CASE(b) + CASE(c) + CASE(d) + CASE(e) + CASE(f) + CASE(g) + CASE(h) + CASE(i) + CASE(j) + CASE(k) + CASE(l) + CASE(m) + CASE(n) + CASE(o) + CASE(p) +#undef CASE + } + + salis_step(1); + } + + salis_save_and_free(); + return 0; +} diff --git a/test/ui/v1/allos/links.json b/test/ui/v1/allos/links.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/test/ui/v1/allos/links.json @@ -0,0 +1 @@ +[] diff --git a/test/ui/v1/allos/ui.c b/test/ui/v1/allos/ui.c new file mode 100644 index 0000000..5b0da79 --- /dev/null +++ b/test/ui/v1/allos/ui.c @@ -0,0 +1,80 @@ +// file : test/ui/v1/allos/ui.c +// project : Salis-VM +// author : Paul Oliver <contact@pauloliver.dev> + +#include <assert.h> +#include <stdint.h> +#include <threads.h> +#include <zlib.h> + +#include "arch_spec.h" +#include "arch_inst.h" +#include "compress.h" +#include "salis.h" + +#define CHILD_SIZE 4 + +static const struct Proc *first_proc(void) { + return proc_fetch(g_cores, g_cores->pfst); +} + +static void check_new_proc(void) { + const struct Proc *proc = proc_get(g_cores, g_cores->plst); + + assert(proc->mb0s == CHILD_SIZE); + assert(proc->mb1a == 0); + assert(proc->mb1s == 0); + assert(proc->r0x == 0); + assert(proc->r1x == 0); + assert(proc->r2x == 0); + assert(proc->r3x == 0); + assert(proc->s0 == 0); + assert(proc->s1 == 0); + assert(proc->s2 == 0); + assert(proc->s3 == 0); + assert(proc->s4 == 0); + assert(proc->s5 == 0); + assert(proc->s6 == 0); + assert(proc->s7 == 0); + + uint64_t birth_addr = (uint64_t)-1; + + switch (g_cores->plst) { + case 1: + birth_addr = ANC_SIZE; + break; + case 2: + birth_addr = ANC_SIZE - 7; + break; + default: + assert(false); + } + + assert(proc->ip == birth_addr); + assert(proc->sp == birth_addr); + assert(proc->mb0a == birth_addr); +} + +int main(void) { + salis_init(); + + while (first_proc()->ip < (ANC_SIZE + (CHILD_SIZE * 2))) { + bool will_split = g_cores->pcur == g_cores->pfst && mvec_get_inst(g_cores, first_proc()->ip) == bspl && first_proc()->mb1s; + uint64_t pnum = g_cores->pnum; + + salis_step(1); + + if (will_split) { + assert(g_cores->pnum == pnum + 1); + assert(g_cores->plst == pnum); + check_new_proc(); + } else { + assert(g_cores->pnum == pnum); + } + } + + assert(g_cores->pnum == 3); + + salis_save_and_free(); + return 0; +} diff --git a/test/ui/v1/ifnzs/links.json b/test/ui/v1/ifnzs/links.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/test/ui/v1/ifnzs/links.json @@ -0,0 +1 @@ +[] diff --git a/test/ui/v1/ifnzs/ui.c b/test/ui/v1/ifnzs/ui.c new file mode 100644 index 0000000..0c3921e --- /dev/null +++ b/test/ui/v1/ifnzs/ui.c @@ -0,0 +1,56 @@ +// file : test/ui/v1/ifnzs/ui.c +// project : Salis-VM +// author : Paul Oliver <contact@pauloliver.dev> + +#include <assert.h> +#include <stdint.h> +#include <threads.h> +#include <zlib.h> + +#include "arch_spec.h" +#include "arch_inst.h" +#include "compress.h" +#include "salis.h" + +int main(void) { + uint64_t next_addr = 0; + + salis_init(); + + while (mvec_is_proc_owner(g_cores, g_cores->pvec->ip, g_cores->pcur)) { + assert(g_cores->pvec->ip == next_addr); + + if (mvec_get_inst(g_cores, g_cores->pvec->ip) == ifnz) { + switch (mvec_get_inst(g_cores, g_cores->pvec->ip + 1)) { + case nop0: + next_addr += g_cores->pvec->r0x ? 1 : 2; + break; + case nop1: + next_addr += g_cores->pvec->r1x ? 1 : 2; + break; + case nop2: + next_addr += g_cores->pvec->r2x ? 1 : 2; + break; + case nop3: + next_addr += g_cores->pvec->r3x ? 1 : 2; + break; + default: + next_addr += g_cores->pvec->r0x ? 0 : 1; + } + } + + salis_step(1); + next_addr++; + + assert(g_cores->pvec->ip == next_addr); + } + + assert(g_cores->pvec->ip == ANC_SIZE); + assert(g_cores->pvec->r0x == 2); + assert(g_cores->pvec->r1x == 2); + assert(g_cores->pvec->r2x == 2); + assert(g_cores->pvec->r3x == 2); + + salis_save_and_free(); + return 0; +} diff --git a/test/ui/v1/ioops/links.json b/test/ui/v1/ioops/links.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/test/ui/v1/ioops/links.json @@ -0,0 +1 @@ +[] diff --git a/test/ui/v1/ioops/ui.c b/test/ui/v1/ioops/ui.c new file mode 100644 index 0000000..8ec21b2 --- /dev/null +++ b/test/ui/v1/ioops/ui.c @@ -0,0 +1,66 @@ +// file : test/ui/v1/ioops/ui.c +// project : Salis-VM +// author : Paul Oliver <contact@pauloliver.dev> + +#include <assert.h> +#include <stdint.h> +#include <threads.h> +#include <zlib.h> + +#include "arch_spec.h" +#include "arch_inst.h" +#include "compress.h" +#include "salis.h" + +int main(void) { + salis_init(); + + while (mvec_is_proc_owner(g_cores, g_cores->pvec->ip, g_cores->pcur)) { + uint8_t inst = mvec_get_inst(g_cores, g_cores->pvec->ip); + + if (inst != rloa && inst != rwrt) { + salis_step(1); + continue; + } + + uint64_t *regs[2] = { + &g_cores->pvec->r0x, + &g_cores->pvec->r0x, + }; + + for (uint64_t i = 0; i < 2; i++) { + uint8_t rmod = mvec_get_inst(g_cores, g_cores->pvec->ip + 1 + i); + + if (rmod == nop0) regs[i] = &g_cores->pvec->r0x; + else if (rmod == nop1) regs[i] = &g_cores->pvec->r1x; + else if (rmod == nop2) regs[i] = &g_cores->pvec->r2x; + else if (rmod == nop3) regs[i] = &g_cores->pvec->r3x; + else break; + } + + if (g_cores->pvec->sp != *regs[0]) { + salis_step(1); + continue; + } + + uint64_t reg_vals[2] = {*regs[0], *regs[1]}; + + assert(g_cores->pvec->sp == *regs[0]); + salis_step(1); + assert(g_cores->pvec->sp == g_cores->pvec->ip); + + switch (inst) { + case rloa: + assert(*regs[1] == (uint64_t)mvec_get_inst(g_cores, reg_vals[0])); + break; + case rwrt: + assert(*regs[0] == reg_vals[0]); + assert(*regs[1] == reg_vals[1]); + assert(mvec_get_inst(g_cores, *regs[0]) == (*regs[1] & ARCH_INST_MASK)); + break; + } + } + + salis_save_and_free(); + return 0; +} diff --git a/test/ui/v1/jumps/links.json b/test/ui/v1/jumps/links.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/test/ui/v1/jumps/links.json @@ -0,0 +1 @@ +[] diff --git a/test/ui/v1/jumps/ui.c b/test/ui/v1/jumps/ui.c new file mode 100644 index 0000000..2ef5caa --- /dev/null +++ b/test/ui/v1/jumps/ui.c @@ -0,0 +1,31 @@ +// file : test/ui/v1/jumps/ui.c +// project : Salis-VM +// author : Paul Oliver <contact@pauloliver.dev> + +#include <assert.h> +#include <stdint.h> +#include <threads.h> +#include <zlib.h> + +#include "arch_spec.h" +#include "arch_inst.h" +#include "compress.h" +#include "salis.h" + +int main(void) { + uint8_t lok = loka; + + salis_init(); + + while (lok != lokp) { + if (mvec_get_inst(g_cores, g_cores->pvec->ip) == lok) { + lok = lok + 1; + } + + salis_step(1); + assert(g_cores->pvec->ip < ANC_SIZE); + } + + salis_save_and_free(); + return 0; +} diff --git a/test/ui/v1/mbops/links.json b/test/ui/v1/mbops/links.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/test/ui/v1/mbops/links.json @@ -0,0 +1 @@ +[] diff --git a/test/ui/v1/mbops/ui.c b/test/ui/v1/mbops/ui.c new file mode 100644 index 0000000..ea417d6 --- /dev/null +++ b/test/ui/v1/mbops/ui.c @@ -0,0 +1,46 @@ +// file : test/ui/v1/mbops/ui.c +// project : Salis-VM +// author : Paul Oliver <contact@pauloliver.dev> + +#include <assert.h> +#include <stdint.h> +#include <threads.h> +#include <zlib.h> + +#include "arch_spec.h" +#include "arch_inst.h" +#include "compress.h" +#include "salis.h" + +int main(void) { + salis_init(); + + while (g_cores->pvec->ip < ANC_SIZE) { + bool on_swap = mvec_get_inst(g_cores, g_cores->pvec->ip) == bswp; + bool on_clear = mvec_get_inst(g_cores, g_cores->pvec->ip) == bclr; + + uint64_t mb0a = g_cores->pvec->mb0a; + uint64_t mb0s = g_cores->pvec->mb0s; + uint64_t mb1a = g_cores->pvec->mb1a; + uint64_t mb1s = g_cores->pvec->mb1s; + + salis_step(1); + + if (on_swap) { + if (mb1s) { + assert(g_cores->pvec->mb0a == mb1a); + assert(g_cores->pvec->mb0s == mb1s); + assert(g_cores->pvec->mb1a == mb0a); + assert(g_cores->pvec->mb1s == mb0s); + } + } + + if (on_clear) { + assert(g_cores->pvec->mb1a == 0); + assert(g_cores->pvec->mb1s == 0); + } + } + + salis_save_and_free(); + return 0; +} diff --git a/test/ui/v1/noops/links.json b/test/ui/v1/noops/links.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/test/ui/v1/noops/links.json @@ -0,0 +1 @@ +[] diff --git a/test/ui/v1/noops/ui.c b/test/ui/v1/noops/ui.c new file mode 100644 index 0000000..b0ad004 --- /dev/null +++ b/test/ui/v1/noops/ui.c @@ -0,0 +1,136 @@ +// file : test/ui/v1/noops/ui.c +// project : Salis-VM +// author : Paul Oliver <contact@pauloliver.dev> + +#include <assert.h> +#include <stdint.h> +#include <threads.h> +#include <zlib.h> + +#include "arch_spec.h" +#include "arch_inst.h" +#include "compress.h" +#include "salis.h" + +static uint8_t g_anc_bytes[] = ANC_BYTES; + +static void check_invariants(void) { + assert(g_cores->mall == ANC_SIZE); + assert(g_cores->muta[0] == 0); + assert(g_cores->muta[1] == 0); + assert(g_cores->muta[2] == 0); + assert(g_cores->muta[3] == 0); + assert(g_cores->pnum == 1); + assert(g_cores->pcap == 1); + assert(g_cores->pfst == 0); + assert(g_cores->plst == 0); + assert(g_cores->pcur == 0); + assert(g_cores->psli == 1); + + for (uint64_t i = 0; i < SYNC_INTERVAL; i++) { + assert(g_cores->ivav[i] == 0); + assert(g_cores->iviv[i] == 0); + } + + for (uint64_t i = 0; i < MVEC_SIZE; i++) { + if (i < ANC_SIZE) { + assert(mvec_get_inst(g_cores, i) == g_anc_bytes[i]); + } else { + assert(mvec_get_inst(g_cores, i) == 0); + } + } + + assert(g_cores->pvec->mb0a == 0); + assert(g_cores->pvec->mb0s == ANC_SIZE); + assert(g_cores->pvec->mb1a == 0); + assert(g_cores->pvec->mb1s == 0); + assert(g_cores->pvec->r0x == 0); + assert(g_cores->pvec->r1x == 0); + assert(g_cores->pvec->r2x == 0); + assert(g_cores->pvec->r3x == 0); + assert(g_cores->pvec->s0 == 0); + assert(g_cores->pvec->s1 == 0); + assert(g_cores->pvec->s2 == 0); + assert(g_cores->pvec->s3 == 0); + assert(g_cores->pvec->s4 == 0); + assert(g_cores->pvec->s5 == 0); + assert(g_cores->pvec->s6 == 0); + assert(g_cores->pvec->s7 == 0); + + assert(g_cores->amb0 == 0.); + assert(g_cores->amb1 == 0.); + + assert(g_cores->emb1 == 0); + assert(g_cores->eliv == 0); + assert(g_cores->edea == 0); + + for (uint64_t i = 0; i < MVEC_SIZE; i++) { + assert(g_cores->aeva.data[i] == 0); + assert(g_cores->beva.data[i] == 0); + } + + // V1 arch specific + for (uint64_t i = 0; i < ARCH_INST_COUNT; i++) { + assert(g_cores->ipop[i] == 0); + assert(g_cores->iwrt[i] == 0); + } + + assert(g_cores->wmb0 == 0); + assert(g_cores->wmb1 == 0); + assert(g_cores->wdea == 0); + assert(g_cores->hlts == 0); + + for (uint64_t i = 0; i < MVEC_SIZE; i++) { + assert(g_cores->weva.data[i] == 0); + assert(g_cores->xeva.data[i] == 0); + } +} + +static void check_variants(void) { + assert(g_cores->step == g_step); + assert(g_cores->cycl == g_step); + assert(g_cores->ivpt == g_step); + + assert(g_cores->pvec->ip == g_step); + assert(g_cores->pvec->sp == g_step); + + assert(g_cores->emb0 == g_step); + + for (uint64_t i = 0; i < MVEC_SIZE; i++) { + assert(g_cores->eeva.data[i] == (i < g_step ? 1 : 0)); + } + + // V1 arch specific + for (uint64_t i = 0; i < ARCH_INST_COUNT; i++) { + uint64_t exed = 0; + + for (uint64_t j = 0; j < g_step; j++) { + if (mvec_get_inst(g_cores, j) == i) { + exed++; + } + } + + assert(g_cores->iexe[i] == exed); + } +} + +static void check_final(void) { + assert(g_cores->pvec->ip == ANC_SIZE); + assert(g_cores->pvec->sp == ANC_SIZE); +} + +int main(void) { + salis_init(); + check_invariants(); + check_variants(); + + while (mvec_is_proc_owner(g_cores, g_cores->pvec->ip, g_cores->pcur)) { + salis_step(1); + check_invariants(); + check_variants(); + } + + check_final(); + salis_save_and_free(); + return 0; +} diff --git a/test/ui/v1/stack/links.json b/test/ui/v1/stack/links.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/test/ui/v1/stack/links.json @@ -0,0 +1 @@ +[] diff --git a/test/ui/v1/stack/ui.c b/test/ui/v1/stack/ui.c new file mode 100644 index 0000000..f74b629 --- /dev/null +++ b/test/ui/v1/stack/ui.c @@ -0,0 +1,85 @@ +// file : test/ui/v1/stack/ui.c +// project : Salis-VM +// author : Paul Oliver <contact@pauloliver.dev> + +#include <assert.h> +#include <stdint.h> +#include <threads.h> +#include <zlib.h> + +#include "arch_spec.h" +#include "arch_inst.h" +#include "compress.h" +#include "salis.h" + +int main(void) { + salis_init(); + + while (mvec_is_proc_owner(g_cores, g_cores->pvec->ip, g_cores->pcur)) { + uint8_t inst = mvec_get_inst(g_cores, g_cores->pvec->ip); + + if (inst != rpsh && inst != rpop) { + salis_step(1); + continue; + } + + uint64_t *reg = &g_cores->pvec->r0x; + + switch (mvec_get_inst(g_cores, g_cores->pvec->ip + 1)) { + case nop0: + reg = &g_cores->pvec->r0x; + break; + case nop1: + reg = &g_cores->pvec->r1x; + break; + case nop2: + reg = &g_cores->pvec->r2x; + break; + case nop3: + reg = &g_cores->pvec->r3x; + break; + } + + uint64_t reg_val = *reg; + uint64_t stack_val[8] = { + g_cores->pvec->s0, + g_cores->pvec->s1, + g_cores->pvec->s2, + g_cores->pvec->s3, + g_cores->pvec->s4, + g_cores->pvec->s5, + g_cores->pvec->s6, + g_cores->pvec->s7, + }; + + salis_step(1); + + switch (inst) { + case rpsh: + assert(*reg == reg_val); + assert(g_cores->pvec->s0 == *reg); + assert(g_cores->pvec->s1 == stack_val[0]); + assert(g_cores->pvec->s2 == stack_val[1]); + assert(g_cores->pvec->s3 == stack_val[2]); + assert(g_cores->pvec->s4 == stack_val[3]); + assert(g_cores->pvec->s5 == stack_val[4]); + assert(g_cores->pvec->s6 == stack_val[5]); + assert(g_cores->pvec->s7 == stack_val[6]); + break; + case rpop: + assert(*reg == stack_val[0]); + assert(g_cores->pvec->s0 == stack_val[1]); + assert(g_cores->pvec->s1 == stack_val[2]); + assert(g_cores->pvec->s2 == stack_val[3]); + assert(g_cores->pvec->s3 == stack_val[4]); + assert(g_cores->pvec->s4 == stack_val[5]); + assert(g_cores->pvec->s5 == stack_val[6]); + assert(g_cores->pvec->s6 == stack_val[7]); + assert(g_cores->pvec->s7 == 0); + break; + } + } + + salis_save_and_free(); + return 0; +} |
