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