]> git.sesse.net Git - interpreter_trials/commitdiff
added computed goto
authorRune Holm <rune.holm@arm.com>
Thu, 17 Jun 2021 11:59:17 +0000 (13:59 +0200)
committerRune Holm <rune.holm@arm.com>
Thu, 17 Jun 2021 11:59:17 +0000 (13:59 +0200)
interpreter11.cpp [new file with mode: 0644]
interpreter_trials.cpp
meson.build

diff --git a/interpreter11.cpp b/interpreter11.cpp
new file mode 100644 (file)
index 0000000..f34bab8
--- /dev/null
@@ -0,0 +1,133 @@
+#include "bytecode.h"
+#include <utility>
+#include "interpreter.h"
+
+namespace interpreter11
+{
+
+    struct CpuState
+    {
+        int32_t regs[16] = {0};
+    };
+
+
+
+
+    std::pair<int32_t, uint32_t> interpreter_run(uint8_t *program, int32_t param)
+    {
+        CpuState local_state;
+        CpuState *state = &local_state;
+        uint8_t *pc = program;
+        state->regs[X0] = param;
+        uint32_t cycle_count = 0;
+        bool flags_zero = false;
+        bool flags_negative = false;
+        static void *dispatch_table[] =
+            {
+                &&op_return,
+                &&op_add,
+                &&op_sub,
+                &&op_mov,
+                &&op_movi,
+                &&op_b,
+                &&op_bnz
+            };
+
+        uint8_t opcode = *pc++;
+        goto *dispatch_table[opcode];
+
+    op_return:
+        {
+            cycle_count += 1;
+            return std::make_pair(state->regs[X0], cycle_count);
+        }
+
+    op_add:
+        {
+            uint8_t reg = *pc++;
+            uint8_t dest = reg>>4, src = reg & 0xf;
+
+            int32_t v = state->regs[dest];
+            v += state->regs[src];
+
+            flags_zero = (v == 0);
+            flags_negative = (v < 0);
+            state->regs[dest] = v;
+            cycle_count += 2;
+
+            uint8_t opcode = *pc++;
+            goto *dispatch_table[opcode];
+        }
+
+    op_sub:
+        {
+            uint8_t reg = *pc++;
+            uint8_t dest = reg>>4, src = reg & 0xf;
+
+            int32_t v = state->regs[dest];
+            v -= state->regs[src];
+
+            flags_zero = (v == 0);
+            flags_negative = (v < 0);
+            state->regs[dest] = v;
+            cycle_count += 2;
+
+            uint8_t opcode = *pc++;
+            goto *dispatch_table[opcode];
+        }
+
+    op_mov:
+        {
+            uint8_t reg = *pc++;
+            uint8_t dest = reg>>4, src = reg & 0xf;
+
+            state->regs[dest] = state->regs[src];
+            cycle_count += 2;
+
+            uint8_t opcode = *pc++;
+            goto *dispatch_table[opcode];
+        }
+
+    op_movi:
+        {
+            uint8_t reg = *pc++;
+            uint8_t dest = reg>>4;
+
+            int32_t imm = *(int32_t *)pc;
+            pc += 4;
+
+            state->regs[dest] = imm;
+            cycle_count += 6;
+
+            uint8_t opcode = *pc++;
+            goto *dispatch_table[opcode];
+        }
+
+    op_b:
+        {
+            int8_t rel = *pc++;
+            pc += rel;
+            cycle_count += 2;
+
+            uint8_t opcode = *pc++;
+            goto *dispatch_table[opcode];
+        }
+
+    op_bnz:
+        {
+            int8_t rel = *pc++;
+            if(!flags_zero)
+            {
+                pc += rel;
+            }
+            cycle_count += 2;
+
+            uint8_t opcode = *pc++;
+            goto *dispatch_table[opcode];
+        }
+
+
+    }
+
+
+}
index 1289100feed757bc557933c663ee5837ebba5442..ece0c0514094db835c0de4a28aa688138d9d06c3 100644 (file)
@@ -100,4 +100,12 @@ static void interpreter10_only_4_parameters(benchmark::State& state) {
 }
 BENCHMARK(interpreter10_only_4_parameters);
 
+static void interpreter11_computed_goto(benchmark::State& state) {
+    for (auto _ : state)
+    {
+        run(interpreter11::interpreter_run);
+    }
+}
+BENCHMARK(interpreter11_computed_goto);
+
 BENCHMARK_MAIN();
index a92c08e3c1e8505d490cf9cd9c40eff149357100..9c1155a10ab0853fe999c64bce2e6efd06a80a6d 100644 (file)
@@ -17,4 +17,5 @@ executable('interpreter_trials',
        'interpreter8.cpp',
        'interpreter9.cpp',
        'interpreter10.cpp',
+       'interpreter11.cpp',
                                        dependencies : benchmark_dep)