namespace interpreter1
{
- std::pair<int32_t, uint32_t> interpreter1_run(uint8_t *program, int32_t param);
+ std::pair<int32_t, uint32_t> interpreter_run(uint8_t *program, int32_t param);
+}
+
+namespace interpreter2
+{
+ std::pair<int32_t, uint32_t> interpreter_run(uint8_t *program, int32_t param);
+}
+
+namespace interpreter3
+{
+ std::pair<int32_t, uint32_t> interpreter_run(uint8_t *program, int32_t param);
+}
+
+namespace interpreter4
+{
+ std::pair<int32_t, uint32_t> interpreter_run(uint8_t *program, int32_t param);
+}
+
+namespace interpreter5
+{
+ std::pair<int32_t, uint32_t> interpreter_run(uint8_t *program, int32_t param);
}
#endif
--- /dev/null
+#include "bytecode.h"
+#include <utility>
+#include "interpreter.h"
+
+namespace interpreter2
+{
+
+ struct CpuState
+ {
+ int32_t regs[16] = {0};
+ bool zero_flag = false;
+ bool negative_flag = false;
+ uint8_t *pc = nullptr;
+ uint32_t cycle_count = 0;
+ };
+
+
+ struct ReturnException
+ {
+ };
+
+ void op_return(CpuState *state)
+ {
+ throw ReturnException();
+ }
+
+ void op_add(CpuState *state)
+ {
+ uint8_t reg = *state->pc++;
+ uint8_t dest = reg>>4, src = reg & 0xf;
+
+ int32_t v = state->regs[dest];
+ v += state->regs[src];
+
+ state->zero_flag = (v == 0);
+ state->negative_flag = (v < 0);
+ state->regs[dest] = v;
+
+ }
+
+ void op_sub(CpuState *state)
+ {
+ uint8_t reg = *state->pc++;
+ uint8_t dest = reg>>4, src = reg & 0xf;
+
+ int32_t v = state->regs[dest];
+ v -= state->regs[src];
+
+ state->zero_flag = (v == 0);
+ state->negative_flag = (v < 0);
+ state->regs[dest] = v;
+ }
+
+ void op_mov(CpuState *state)
+ {
+ uint8_t reg = *state->pc++;
+ uint8_t dest = reg>>4, src = reg & 0xf;
+
+ state->regs[dest] = state->regs[src];
+
+ }
+
+ void op_movi(CpuState *state)
+ {
+ uint8_t reg = *state->pc++;
+ uint8_t dest = reg>>4;
+
+ int32_t imm = *(int32_t *)state->pc;
+ state->pc += 4;
+
+ state->regs[dest] = imm;
+
+ }
+
+ void op_b(CpuState *state)
+ {
+ int8_t rel = *state->pc++;
+ state->pc += rel;
+ }
+
+ void op_bnz(CpuState *state)
+ {
+ int8_t rel = *state->pc++;
+ if(!state->zero_flag)
+ {
+ state->pc += rel;
+ }
+ }
+
+ void (*dispatch_table[])(CpuState *) =
+ {
+ 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;
+ state->pc = program;
+ state->regs[X0] = param;
+ state->cycle_count = 0;
+ try
+ {
+ while(true)
+ {
+ uint8_t opcode = *state->pc++;
+ dispatch_table[opcode](state);
+ state->cycle_count += cycle_table[opcode];
+
+
+ }
+
+
+ } catch(ReturnException ex)
+ {
+ return std::make_pair(state->regs[X0], state->cycle_count);
+ }
+
+ }
+
+
+}
}
}
-// Define another benchmark
static void interpreter1_fibonacci(benchmark::State& state) {
for (auto _ : state)
{
- run(interpreter1::interpreter1_run);
+ run(interpreter1::interpreter_run);
}
}
BENCHMARK(interpreter1_fibonacci);
+static void interpreter2_fibonacci(benchmark::State& state) {
+ for (auto _ : state)
+ {
+ run(interpreter2::interpreter_run);
+ }
+}
+BENCHMARK(interpreter2_fibonacci);
+
BENCHMARK_MAIN();