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