]> git.sesse.net Git - interpreter_trials/blob - interpreter3.cpp
interpreter 9: flags in separate registers
[interpreter_trials] / interpreter3.cpp
1 #include "bytecode.h"
2 #include <utility>
3 #include "interpreter.h"
4
5 namespace interpreter3
6 {
7
8     struct CpuState
9     {
10         int32_t regs[16] = {0};
11         bool zero_flag = false;
12         bool negative_flag = false;
13         uint8_t *pc = nullptr;
14         uint32_t cycle_count = 0;
15     };
16
17
18     struct ReturnException
19     {
20     };
21
22     void op_return(CpuState *state)
23     {
24         state->cycle_count += 1;
25         throw ReturnException();
26     }
27
28     void op_add(CpuState *state)
29     {
30         uint8_t reg = *state->pc++;
31         uint8_t dest = reg>>4, src = reg & 0xf;
32
33         int32_t v = state->regs[dest];
34         v += state->regs[src];
35
36         state->zero_flag = (v == 0);
37         state->negative_flag = (v < 0);
38         state->regs[dest] = v;
39         state->cycle_count += 2;
40
41     }
42
43     void op_sub(CpuState *state)
44     {
45         uint8_t reg = *state->pc++;
46         uint8_t dest = reg>>4, src = reg & 0xf;
47
48         int32_t v = state->regs[dest];
49         v -= state->regs[src];
50
51         state->zero_flag = (v == 0);
52         state->negative_flag = (v < 0);
53         state->regs[dest] = v;
54         state->cycle_count += 2;
55     }
56
57     void op_mov(CpuState *state)
58     {
59         uint8_t reg = *state->pc++;
60         uint8_t dest = reg>>4, src = reg & 0xf;
61
62         state->regs[dest] = state->regs[src];
63         state->cycle_count += 2;
64
65     }
66
67     void op_movi(CpuState *state)
68     {
69         uint8_t reg = *state->pc++;
70         uint8_t dest = reg>>4;
71
72         int32_t imm = *(int32_t *)state->pc;
73         state->pc += 4;
74
75         state->regs[dest] = imm;
76         state->cycle_count += 6;
77
78     }
79
80     void op_b(CpuState *state)
81     {
82         int8_t rel = *state->pc++;
83         state->pc += rel;
84         state->cycle_count += 2;
85     }
86
87     void op_bnz(CpuState *state)
88     {
89         int8_t rel = *state->pc++;
90         if(!state->zero_flag)
91         {
92             state->pc += rel;
93         }
94         state->cycle_count += 2;
95     }
96
97     void (*dispatch_table[])(CpuState *) =
98     {
99         op_return,
100         op_add,
101         op_sub,
102         op_mov,
103         op_movi,
104         op_b,
105         op_bnz
106     };
107
108     std::pair<int32_t, uint32_t> interpreter_run(uint8_t *program, int32_t param)
109     {
110         CpuState local_state;
111         CpuState *state = &local_state;
112         state->pc = program;
113         state->regs[X0] = param;
114         state->cycle_count = 0;
115         try
116         {
117             while(true)
118             {
119                 uint8_t opcode = *state->pc++;
120                 dispatch_table[opcode](state);
121
122
123             }
124
125
126         } catch(ReturnException ex)
127         {
128             return std::make_pair(state->regs[X0], state->cycle_count);
129         }
130
131     }
132
133
134 }