diff options
Diffstat (limited to 'src/vm.c')
-rw-r--r-- | src/vm.c | 136 |
1 files changed, 16 insertions, 120 deletions
@@ -4,130 +4,12 @@ | |||
4 | #include "badlib.h" | 4 | #include "badlib.h" |
5 | #include "compiler.c" | 5 | #include "compiler.c" |
6 | 6 | ||
7 | void | ||
8 | disassemble_instruction(Instruction instruction) { | ||
9 | switch (instruction.op) { | ||
10 | case OP_MOV8: | ||
11 | case OP_MOV16: | ||
12 | case OP_MOV32: | ||
13 | case OP_MOV64: | ||
14 | println("%s r%d, r%d", op_str[instruction.op], instruction.dst, | ||
15 | instruction.a, instruction.b); | ||
16 | break; | ||
17 | case OP_LD8K: | ||
18 | case OP_LD16K: | ||
19 | case OP_LD32K: | ||
20 | case OP_LD64K: | ||
21 | println("%s r%d, c%d", op_str[instruction.op], instruction.dst, | ||
22 | instruction.a, instruction.b); | ||
23 | break; | ||
24 | case OP_LD8I: | ||
25 | case OP_LD16I: | ||
26 | case OP_LD32I: | ||
27 | case OP_LD64I: | ||
28 | case OP_ST8I: | ||
29 | case OP_ST16I: | ||
30 | case OP_ST32I: | ||
31 | case OP_ST64I: | ||
32 | case OP_ADDI: | ||
33 | case OP_SUBI: | ||
34 | case OP_MULI: | ||
35 | case OP_DIVI: | ||
36 | case OP_MODI: | ||
37 | case OP_ADDFI: | ||
38 | case OP_SUBFI: | ||
39 | case OP_MULFI: | ||
40 | case OP_DIVFI: | ||
41 | case OP_MODFI: | ||
42 | case OP_EQI: | ||
43 | case OP_NEQI: | ||
44 | case OP_LTI: | ||
45 | case OP_GTI: | ||
46 | case OP_LEI: | ||
47 | case OP_GEI: | ||
48 | case OP_ANDI: | ||
49 | case OP_ORI: | ||
50 | case OP_BITLSHIFTI: | ||
51 | case OP_BITRSHIFTI: | ||
52 | case OP_BITANDI: | ||
53 | case OP_BITORI: | ||
54 | println("%s r%d, r%d, c%d", op_str[instruction.op], instruction.dst, | ||
55 | instruction.a, instruction.b); | ||
56 | break; | ||
57 | case OP_LD8: | ||
58 | case OP_LD16: | ||
59 | case OP_LD32: | ||
60 | case OP_LD64: | ||
61 | case OP_ST8: | ||
62 | case OP_ST16: | ||
63 | case OP_ST32: | ||
64 | case OP_ST64: | ||
65 | case OP_ADD: | ||
66 | case OP_SUB: | ||
67 | case OP_MUL: | ||
68 | case OP_DIV: | ||
69 | case OP_MOD: | ||
70 | case OP_ADDF: | ||
71 | case OP_SUBF: | ||
72 | case OP_MULF: | ||
73 | case OP_DIVF: | ||
74 | case OP_MODF: | ||
75 | case OP_EQ: | ||
76 | case OP_NEQ: | ||
77 | case OP_LT: | ||
78 | case OP_GT: | ||
79 | case OP_LE: | ||
80 | case OP_GE: | ||
81 | case OP_AND: | ||
82 | case OP_OR: | ||
83 | case OP_BITLSHIFT: | ||
84 | case OP_BITRSHIFT: | ||
85 | case OP_BITAND: | ||
86 | case OP_BITOR: | ||
87 | println("%s r%d, r%d, r%d", op_str[instruction.op], instruction.dst, | ||
88 | instruction.a, instruction.b); | ||
89 | break; | ||
90 | case OP_BITNOTI: | ||
91 | case OP_NOTI: | ||
92 | println("%s r%d, c%d", op_str[instruction.op], instruction.dst, | ||
93 | instruction.a, instruction.b); | ||
94 | break; | ||
95 | case OP_BITNOT: | ||
96 | case OP_NOT: | ||
97 | println("%s r%d, r%d", op_str[instruction.op], instruction.dst, | ||
98 | instruction.a, instruction.b); | ||
99 | break; | ||
100 | case OP_HALT: println("%s", op_str[instruction.op]); break; | ||
101 | default: println("Unknown opcode %d", instruction.op); break; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | void | ||
106 | disassemble_chunk(Chunk chunk) { | ||
107 | println("%s: =========== code ===========", chunk.file_name); | ||
108 | for (sz i = 0; i < array_size(chunk.code); i++) { | ||
109 | print("%s: %x{4}: ", chunk.file_name, i); | ||
110 | disassemble_instruction(chunk.code[i]); | ||
111 | } | ||
112 | if (array_size(chunk.constants) > 0) { | ||
113 | println("%s: ========= constants ========", chunk.file_name); | ||
114 | for (sz i = 0; i < array_size(chunk.constants); i++) { | ||
115 | println("%s: %x{2}: %x{8}", chunk.file_name, i, | ||
116 | chunk.constants[i]); | ||
117 | } | ||
118 | } | ||
119 | if (array_size(chunk.strings) > 0) { | ||
120 | println("%s: ========== strings =========", chunk.file_name); | ||
121 | for (sz i = 0; i < array_size(chunk.strings); i++) { | ||
122 | println("%s: %x{2}: %s", chunk.file_name, i, chunk.strings[i]); | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | |||
127 | #define N_CONST 256 | 7 | #define N_CONST 256 |
8 | #define STACK_SIZE KB(64) | ||
128 | typedef struct VM { | 9 | typedef struct VM { |
129 | Chunk *chunk; | 10 | Chunk *chunk; |
130 | Constant regs[N_CONST]; | 11 | Constant regs[N_CONST]; |
12 | u8 stack[STACK_SIZE]; | ||
131 | Instruction *ip; | 13 | Instruction *ip; |
132 | } VM; | 14 | } VM; |
133 | 15 | ||
@@ -252,6 +134,20 @@ vm_run(VM *vm) { | |||
252 | vm->regs[dst].f = | 134 | vm->regs[dst].f = |
253 | fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f); | 135 | fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f); |
254 | } break; | 136 | } break; |
137 | case OP_STVAR: { | ||
138 | u8 dst = instruction.dst; | ||
139 | u8 src = instruction.a; | ||
140 | Variable var = vm->chunk->vars[dst]; | ||
141 | s64 *stack = (s64*)&vm->stack[var.offset]; | ||
142 | *stack = vm->regs[src].i; | ||
143 | } break; | ||
144 | case OP_STVARI: { | ||
145 | u8 dst = instruction.dst; | ||
146 | u8 src = instruction.a; | ||
147 | Variable var = vm->chunk->vars[dst]; | ||
148 | s64 *stack = (s64*)&vm->stack[var.offset]; | ||
149 | *stack = vm->chunk->constants[src].i; | ||
150 | } break; | ||
255 | case OP_HALT: { | 151 | case OP_HALT: { |
256 | println("VM HALT (int) -> %d", vm->regs[instruction.dst]); | 152 | println("VM HALT (int) -> %d", vm->regs[instruction.dst]); |
257 | println("VM HALT (float) -> %f", vm->regs[instruction.dst]); | 153 | println("VM HALT (float) -> %f", vm->regs[instruction.dst]); |