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