]> git.sesse.net Git - interpreter_trials/commitdiff
cycle count in registers
authorRune Holm <rune.holm@arm.com>
Wed, 16 Jun 2021 22:17:55 +0000 (00:17 +0200)
committerRune Holm <rune.holm@arm.com>
Wed, 16 Jun 2021 22:17:55 +0000 (00:17 +0200)
interpreter.h
interpreter6.cpp [new file with mode: 0644]
interpreter_trials.cpp
meson.build

index 91c1fcd3f7c8d556bbde277e50df7d9f37387602..dbe1ba1c9f03e028e2a190c10dbc1d38bd204ad9 100644 (file)
@@ -29,4 +29,34 @@ namespace interpreter5
     std::pair<int32_t, uint32_t> interpreter_run(uint8_t *program, int32_t param);
 }
 
+namespace interpreter6
+{
+    std::pair<int32_t, uint32_t> interpreter_run(uint8_t *program, int32_t param);
+}
+
+namespace interpreter7
+{
+    std::pair<int32_t, uint32_t> interpreter_run(uint8_t *program, int32_t param);
+}
+
+namespace interpreter8
+{
+    std::pair<int32_t, uint32_t> interpreter_run(uint8_t *program, int32_t param);
+}
+
+namespace interpreter9
+{
+    std::pair<int32_t, uint32_t> interpreter_run(uint8_t *program, int32_t param);
+}
+
+namespace interpreter10
+{
+    std::pair<int32_t, uint32_t> interpreter_run(uint8_t *program, int32_t param);
+}
+
+namespace interpreter11
+{
+    std::pair<int32_t, uint32_t> interpreter_run(uint8_t *program, int32_t param);
+}
+
 #endif
diff --git a/interpreter6.cpp b/interpreter6.cpp
new file mode 100644 (file)
index 0000000..e71cfb9
--- /dev/null
@@ -0,0 +1,158 @@
+#include "bytecode.h"
+#include <utility>
+#include "interpreter.h"
+
+namespace interpreter6
+{
+
+    struct Flags
+    {
+        unsigned int zero:16;
+        unsigned int negative:16;
+    };
+
+    struct CpuState
+    {
+        int32_t regs[16] = {0};
+        uint32_t final_cycle_count = 0;
+    };
+
+
+    struct ReturnException
+    {
+    };
+
+
+    struct ReturnVal
+    {
+        uint8_t *pc;
+        Flags flags;
+        uint32_t cycle_count;
+    };
+
+
+#define PARAMS CpuState *state, uint8_t *pc, Flags flags, uint32_t cycle_count
+#define ARGS state, pc, flags, cycle_count
+#define RETURN_VAL {pc, flags, cycle_count}
+
+    ReturnVal op_return(PARAMS)
+    {
+        cycle_count += 1;
+        state->final_cycle_count = cycle_count;
+        throw ReturnException();
+    }
+
+    ReturnVal op_add(PARAMS)
+    {
+        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;
+        return RETURN_VAL;
+    }
+
+    ReturnVal op_sub(PARAMS)
+    {
+        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;
+        return RETURN_VAL;
+    }
+
+    ReturnVal op_mov(PARAMS)
+    {
+        uint8_t reg = *pc++;
+        uint8_t dest = reg>>4, src = reg & 0xf;
+
+        state->regs[dest] = state->regs[src];
+        cycle_count += 2;
+        return RETURN_VAL;
+
+    }
+
+    ReturnVal op_movi(PARAMS)
+    {
+        uint8_t reg = *pc++;
+        uint8_t dest = reg>>4;
+
+        int32_t imm = *(int32_t *)pc;
+        pc += 4;
+
+        state->regs[dest] = imm;
+        cycle_count += 6;
+        return RETURN_VAL;
+
+    }
+
+    ReturnVal op_b(PARAMS)
+    {
+        int8_t rel = *pc++;
+        pc += rel;
+        cycle_count += 2;
+        return RETURN_VAL;
+    }
+
+    ReturnVal op_bnz(PARAMS)
+    {
+        int8_t rel = *pc++;
+        if(!flags.zero)
+        {
+            pc += rel;
+        }
+        cycle_count += 2;
+        return RETURN_VAL;
+    }
+
+    ReturnVal (*dispatch_table[])(PARAMS) =
+    {
+        op_return,
+        op_add,
+        op_sub,
+        op_mov,
+        op_movi,
+        op_b,
+        op_bnz
+    };
+
+    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;
+        Flags flags = {0, 0};
+        try
+        {
+            while(true)
+            {
+                uint8_t opcode = *pc++;
+                ReturnVal ret = dispatch_table[opcode](ARGS);
+                pc = ret.pc;
+                flags = ret.flags;
+                cycle_count = ret.cycle_count;
+            }
+
+
+        } catch(ReturnException ex)
+        {
+            return std::make_pair(state->regs[X0], state->final_cycle_count);
+        }
+
+    }
+
+
+}
index c09bdf0d4427cb17f2c522cc279038a16cbfcd10..31ed90628dd089622c9b8166d4e614315765609e 100644 (file)
@@ -20,44 +20,52 @@ void run(RunLoop run_loop)
     }
 }
 
-static void interpreter1_fibonacci(benchmark::State& state) {
+static void interpreter1_baseline(benchmark::State& state) {
     for (auto _ : state)
     {
         run(interpreter1::interpreter_run);
     }
 }
-BENCHMARK(interpreter1_fibonacci);
+BENCHMARK(interpreter1_baseline);
 
-static void interpreter2_fibonacci(benchmark::State& state) {
+static void interpreter2_state_as_parameters(benchmark::State& state) {
     for (auto _ : state)
     {
         run(interpreter2::interpreter_run);
     }
 }
-BENCHMARK(interpreter2_fibonacci);
+BENCHMARK(interpreter2_state_as_parameters);
 
-static void interpreter3_fibonacci(benchmark::State& state) {
+static void interpreter3_cycle_count_in_op_funs(benchmark::State& state) {
     for (auto _ : state)
     {
         run(interpreter3::interpreter_run);
     }
 }
-BENCHMARK(interpreter3_fibonacci);
+BENCHMARK(interpreter3_cycle_count_in_op_funs);
 
-static void interpreter4_fibonacci(benchmark::State& state) {
+static void interpreter4_pc_in_registers(benchmark::State& state) {
     for (auto _ : state)
     {
         run(interpreter4::interpreter_run);
     }
 }
-BENCHMARK(interpreter4_fibonacci);
+BENCHMARK(interpreter4_pc_in_registers);
 
-static void interpreter5_fibonacci(benchmark::State& state) {
+static void interpreter5_pc_flags_in_registers(benchmark::State& state) {
     for (auto _ : state)
     {
         run(interpreter5::interpreter_run);
     }
 }
-BENCHMARK(interpreter5_fibonacci);
+BENCHMARK(interpreter5_pc_flags_in_registers);
+
+static void interpreter6_pc_flags_cycle_count_in_registers(benchmark::State& state) {
+    for (auto _ : state)
+    {
+        run(interpreter6::interpreter_run);
+    }
+}
+BENCHMARK(interpreter6_pc_flags_cycle_count_in_registers);
 
 BENCHMARK_MAIN();
index 5440d8c70914b76366f39f0320a3a1956fddd749..f53cca78d4f534f6cfbdc416736c5148a7c3587d 100644 (file)
@@ -12,4 +12,5 @@ executable('interpreter_trials',
        'interpreter3.cpp',
        'interpreter4.cpp',
        'interpreter5.cpp',
+       'interpreter6.cpp',
                                        dependencies : benchmark_dep)