aboutsummaryrefslogtreecommitdiff
path: root/arch/dummy
diff options
context:
space:
mode:
Diffstat (limited to 'arch/dummy')
-rw-r--r--arch/dummy/arch.j2.c130
-rw-r--r--arch/dummy/arch_vars.py21
2 files changed, 151 insertions, 0 deletions
diff --git a/arch/dummy/arch.j2.c b/arch/dummy/arch.j2.c
new file mode 100644
index 0000000..d62d411
--- /dev/null
+++ b/arch/dummy/arch.j2.c
@@ -0,0 +1,130 @@
+// Author: Paul Oliver <contact@pauloliver.dev>
+// Project: salis-v3
+
+// Defines a minimal viable architecture for the Salis VM.
+// Useful for debugging and benchmarking. May be used as a template when
+// implementing a new architecture.
+
+{% if args.command in ["bench", "new"] and anc_bytes is defined %}
+void arch_anc_init(struct Core *core) {
+ assert(core);
+
+ {% if arch_vars.mvec_loop %}
+ uint64_t addr = {{ uint64_half }};
+ {% else %}
+ uint64_t addr = 0;
+ {% endif %}
+
+ for (uint64_t i = 0; i < {{ args.clones }}; ++i) {
+ uint64_t addr_clone = addr + (({{ mvec_size }} / {{ args.clones }})) * i;
+
+ struct Proc *panc = proc_fetch(core, i);
+
+ panc->mb0a = addr_clone;
+ panc->mb0s = {{ anc_bytes|length }};
+ panc->ip = addr_clone;
+ panc->sp = addr_clone;
+ }
+}
+{% endif %}
+
+uint64_t arch_proc_mb0_addr(const struct Core *core, uint64_t pix) {
+ assert(core);
+ assert(mvec_proc_is_live(core, pix));
+ return proc_get(core, pix)->mb0a;
+}
+
+uint64_t arch_proc_mb0_size(const struct Core *core, uint64_t pix) {
+ assert(core);
+ assert(mvec_proc_is_live(core, pix));
+ return proc_get(core, pix)->mb0s;
+}
+
+uint64_t arch_proc_mb1_addr(const struct Core *core, uint64_t pix) {
+ assert(core);
+ assert(mvec_proc_is_live(core, pix));
+ return proc_get(core, pix)->mb1a;
+}
+
+uint64_t arch_proc_mb1_size(const struct Core *core, uint64_t pix) {
+ assert(core);
+ assert(mvec_proc_is_live(core, pix));
+ return proc_get(core, pix)->mb1s;
+}
+
+uint64_t arch_proc_ip_addr(const struct Core *core, uint64_t pix) {
+ assert(core);
+ assert(mvec_proc_is_live(core, pix));
+ return proc_get(core, pix)->ip;
+}
+
+uint64_t arch_proc_sp_addr(const struct Core *core, uint64_t pix) {
+ assert(core);
+ assert(mvec_proc_is_live(core, pix));
+ return proc_get(core, pix)->sp;
+}
+
+uint64_t arch_proc_slice(const struct Core *core, uint64_t pix) {
+ assert(core);
+ assert(mvec_proc_is_live(core, pix));
+
+ (void)core;
+ (void)pix;
+
+ return 1;
+}
+
+void arch_on_proc_kill(struct Core *core) {
+ assert(core);
+ assert(core->pnum > 1);
+
+ (void)core;
+}
+
+void arch_proc_step(struct Core *core, uint64_t pix) {
+ assert(core);
+ assert(mvec_proc_is_live(core, pix));
+
+ (void)core;
+ (void)pix;
+
+ return;
+}
+
+{% if not args.optimized %}
+void arch_validate_proc(const struct Core *core, uint64_t pix) {
+ assert(core);
+ assert(mvec_proc_is_live(core, pix));
+
+ (void)core;
+ (void)pix;
+
+ assert(true);
+}
+{% endif %}
+
+wchar_t arch_symbol(uint8_t inst) {
+ switch (inst) {
+ {% for i in arch_vars.inst_set %}
+ case {{ loop.index0 }}: return L'{{ i[1] }}';
+ {% endfor %}
+ }
+}
+
+const char *arch_mnemonic(uint8_t inst) {
+ switch (inst) {
+ {% for i in arch_vars.inst_set %}
+ case {{ loop.index0 }}: return "{{ i[0]|join(' ') }}";
+ {% endfor %}
+ }
+}
+
+{% if data_push_path is defined %}
+void arch_push_data_header() {
+ assert(g_sim_data);
+}
+
+void arch_push_data_line() {
+ assert(g_sim_data);
+}
+{% endif %}
diff --git a/arch/dummy/arch_vars.py b/arch/dummy/arch_vars.py
new file mode 100644
index 0000000..3a18200
--- /dev/null
+++ b/arch/dummy/arch_vars.py
@@ -0,0 +1,21 @@
+core_fields = []
+mvec_loop = True
+
+proc_fields = [
+ ("uint64_t", "ip"),
+ ("uint64_t", "sp"),
+ ("uint64_t", "mb0a"),
+ ("uint64_t", "mb0s"),
+ ("uint64_t", "mb1a"),
+ ("uint64_t", "mb1s"),
+]
+
+inst_set = [
+ (["dummy", f"{i:02x}"], symbol)
+ for i, symbol in enumerate(
+ "⠀⠁⠂⠃⠄⠅⠆⠇⡀⡁⡂⡃⡄⡅⡆⡇⠈⠉⠊⠋⠌⠍⠎⠏⡈⡉⡊⡋⡌⡍⡎⡏⠐⠑⠒⠓⠔⠕⠖⠗⡐⡑⡒⡓⡔⡕⡖⡗⠘⠙⠚⠛⠜⠝⠞⠟⡘⡙⡚⡛⡜⡝⡞⡟"
+ "⠠⠡⠢⠣⠤⠥⠦⠧⡠⡡⡢⡣⡤⡥⡦⡧⠨⠩⠪⠫⠬⠭⠮⠯⡨⡩⡪⡫⡬⡭⡮⡯⠰⠱⠲⠳⠴⠵⠶⠷⡰⡱⡲⡳⡴⡵⡶⡷⠸⠹⠺⠻⠼⠽⠾⠿⡸⡹⡺⡻⡼⡽⡾⡿"
+ "⢀⢁⢂⢃⢄⢅⢆⢇⣀⣁⣂⣃⣄⣅⣆⣇⢈⢉⢊⢋⢌⢍⢎⢏⣈⣉⣊⣋⣌⣍⣎⣏⢐⢑⢒⢓⢔⢕⢖⢗⣐⣑⣒⣓⣔⣕⣖⣗⢘⢙⢚⢛⢜⢝⢞⢟⣘⣙⣚⣛⣜⣝⣞⣟"
+ "⢠⢡⢢⢣⢤⢥⢦⢧⣠⣡⣢⣣⣤⣥⣦⣧⢨⢩⢪⢫⢬⢭⢮⢯⣨⣩⣪⣫⣬⣭⣮⣯⢰⢱⢲⢳⢴⢵⢶⢷⣰⣱⣲⣳⣴⣵⣶⣷⢸⢹⢺⢻⢼⢽⢾⢿⣸⣹⣺⣻⣼⣽⣾⣿"
+ )
+]