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
--- /dev/null
+#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);
+ }
+
+ }
+
+
+}
}
}
-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();
'interpreter3.cpp',
'interpreter4.cpp',
'interpreter5.cpp',
+ 'interpreter6.cpp',
dependencies : benchmark_dep)