aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-28 17:18:19 +0200
committerBad Diode <bd@badd10de.dev>2024-06-28 17:18:19 +0200
commitef1f5f9478195059828d0edeb52fa15f610f5a04 (patch)
tree5f20d045994b952050a1e5c10f80a3c4e5422f2b /src
parent2bf7cd7633d0040546c28462d61a1f181dd7e858 (diff)
downloadbdl-ef1f5f9478195059828d0edeb52fa15f610f5a04.tar.gz
bdl-ef1f5f9478195059828d0edeb52fa15f610f5a04.zip
Add bitwise operations
Diffstat (limited to 'src')
-rw-r--r--src/compiler.c53
-rw-r--r--src/vm.c23
2 files changed, 74 insertions, 2 deletions
diff --git a/src/compiler.c b/src/compiler.c
index a251a90..e303cee 100644
--- a/src/compiler.c
+++ b/src/compiler.c
@@ -114,6 +114,17 @@ typedef enum OpCode {
114 OP_AND, // and rx, ra, rb 114 OP_AND, // and rx, ra, rb
115 OP_OR, // or rx, ra, rb 115 OP_OR, // or rx, ra, rb
116 OP_NOT, // not rx, ra 116 OP_NOT, // not rx, ra
117 // Bitwise operations.
118 OP_BITLSHIFTI, // shli rx, ra, cb
119 OP_BITRSHIFTI, // shri rx, ra, cb
120 OP_BITANDI, // bandi rx, ra, cb
121 OP_BITORI, // bori rx, ra, cb
122 OP_BITNOTI, // bnoti rx, ca
123 OP_BITLSHIFT, // shl rx, ra, rb
124 OP_BITRSHIFT, // shr rx, ra, rb
125 OP_BITAND, // band rx, ra, rb
126 OP_BITOR, // bor rx, ra, rb
127 OP_BITNOT, // bnot rx, ra
117} OpCode; 128} OpCode;
118 129
119Str op_str[] = { 130Str op_str[] = {
@@ -185,6 +196,17 @@ Str op_str[] = {
185 [OP_AND] = cstr("AND "), 196 [OP_AND] = cstr("AND "),
186 [OP_OR] = cstr("OR "), 197 [OP_OR] = cstr("OR "),
187 [OP_NOT] = cstr("NOT "), 198 [OP_NOT] = cstr("NOT "),
199 // Bitwise operations.
200 [OP_BITLSHIFTI] = cstr("LSHI "),
201 [OP_BITRSHIFTI] = cstr("RSHI "),
202 [OP_BITANDI] = cstr("BANDI "),
203 [OP_BITORI] = cstr("BORI "),
204 [OP_BITNOTI] = cstr("BNOTI "),
205 [OP_BITLSHIFT] = cstr("LSH "),
206 [OP_BITRSHIFT] = cstr("RSH "),
207 [OP_BITAND] = cstr("BAND "),
208 [OP_BITOR] = cstr("BOR "),
209 [OP_BITNOT] = cstr("BNOT "),
188}; 210};
189 211
190typedef enum { 212typedef enum {
@@ -218,6 +240,7 @@ compile_binary(Chunk *chunk, Node *node) {
218 OpCode opi = OP_HALT; 240 OpCode opi = OP_HALT;
219 OpCode ldop = OP_LD64K; 241 OpCode ldop = OP_LD64K;
220 switch (node->kind) { 242 switch (node->kind) {
243 // Arithmetic.
221 case NODE_ADD: { 244 case NODE_ADD: {
222 if (str_eq(node->type, cstr("int"))) { 245 if (str_eq(node->type, cstr("int"))) {
223 op = OP_ADD; 246 op = OP_ADD;
@@ -263,6 +286,7 @@ compile_binary(Chunk *chunk, Node *node) {
263 opi = OP_MODFI; 286 opi = OP_MODFI;
264 } 287 }
265 } break; 288 } break;
289 // Logic.
266 case NODE_EQ: { 290 case NODE_EQ: {
267 op = OP_EQ; 291 op = OP_EQ;
268 opi = OP_EQI; 292 opi = OP_EQI;
@@ -295,6 +319,23 @@ compile_binary(Chunk *chunk, Node *node) {
295 op = OP_OR; 319 op = OP_OR;
296 opi = OP_ORI; 320 opi = OP_ORI;
297 } break; 321 } break;
322 // Bitwise.
323 case NODE_BITOR: {
324 op = OP_BITOR;
325 opi = OP_BITORI;
326 } break;
327 case NODE_BITAND: {
328 op = OP_BITAND;
329 opi = OP_BITANDI;
330 } break;
331 case NODE_BITLSHIFT: {
332 op = OP_BITLSHIFT;
333 opi = OP_BITLSHIFTI;
334 } break;
335 case NODE_BITRSHIFT: {
336 op = OP_BITRSHIFT;
337 opi = OP_BITRSHIFTI;
338 } break;
298 default: break; 339 default: break;
299 } 340 }
300 CompResult comp_a = compile_expr(chunk, node->left); 341 CompResult comp_a = compile_expr(chunk, node->left);
@@ -334,12 +375,15 @@ CompResult
334compile_unary(Chunk *chunk, Node *node) { 375compile_unary(Chunk *chunk, Node *node) {
335 OpCode op = OP_HALT; 376 OpCode op = OP_HALT;
336 OpCode opi = OP_HALT; 377 OpCode opi = OP_HALT;
337 OpCode ldop = OP_LD64K;
338 switch (node->kind) { 378 switch (node->kind) {
339 case NODE_NOT: { 379 case NODE_NOT: {
340 op = OP_NOT; 380 op = OP_NOT;
341 opi = OP_NOTI; 381 opi = OP_NOTI;
342 } break; 382 } break;
383 case NODE_BITNOT: {
384 op = OP_BITNOT;
385 opi = OP_BITNOTI;
386 } break;
343 default: break; 387 default: break;
344 } 388 }
345 CompResult comp_a = compile_expr(chunk, node->left); 389 CompResult comp_a = compile_expr(chunk, node->left);
@@ -366,6 +410,7 @@ compile_expr(Chunk *chunk, Node *node) {
366 switch (node->kind) { 410 switch (node->kind) {
367 // Logic. 411 // Logic.
368 // case NODE_XOR: 412 // case NODE_XOR:
413 case NODE_BITNOT:
369 case NODE_NOT: return compile_unary(chunk, node); break; 414 case NODE_NOT: return compile_unary(chunk, node); break;
370 case NODE_AND: 415 case NODE_AND:
371 case NODE_OR: 416 case NODE_OR:
@@ -374,6 +419,11 @@ compile_expr(Chunk *chunk, Node *node) {
374 case NODE_LT: 419 case NODE_LT:
375 case NODE_GT: 420 case NODE_GT:
376 case NODE_LE: 421 case NODE_LE:
422 // Bitwise ops.
423 case NODE_BITAND:
424 case NODE_BITOR:
425 case NODE_BITLSHIFT:
426 case NODE_BITRSHIFT:
377 // Arithmetic. 427 // Arithmetic.
378 case NODE_GE: 428 case NODE_GE:
379 case NODE_ADD: 429 case NODE_ADD:
@@ -384,6 +434,7 @@ compile_expr(Chunk *chunk, Node *node) {
384 case NODE_TRUE: 434 case NODE_TRUE:
385 case NODE_FALSE: 435 case NODE_FALSE:
386 case NODE_NUM_FLOAT: 436 case NODE_NUM_FLOAT:
437 case NODE_NUM_UINT:
387 case NODE_NUM_INT: { 438 case NODE_NUM_INT: {
388 sz value = node->value.i; 439 sz value = node->value.i;
389 // Make sure we don't have duplicated constants. 440 // Make sure we don't have duplicated constants.
diff --git a/src/vm.c b/src/vm.c
index 644a682..2771d07 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -47,6 +47,10 @@ disassemble_instruction(Instruction instruction) {
47 case OP_GEI: 47 case OP_GEI:
48 case OP_ANDI: 48 case OP_ANDI:
49 case OP_ORI: 49 case OP_ORI:
50 case OP_BITLSHIFTI:
51 case OP_BITRSHIFTI:
52 case OP_BITANDI:
53 case OP_BITORI:
50 println("%s r%d, r%d, c%d", op_str[instruction.op], instruction.dst, 54 println("%s r%d, r%d, c%d", op_str[instruction.op], instruction.dst,
51 instruction.a, instruction.b); 55 instruction.a, instruction.b);
52 break; 56 break;
@@ -76,13 +80,19 @@ disassemble_instruction(Instruction instruction) {
76 case OP_GE: 80 case OP_GE:
77 case OP_AND: 81 case OP_AND:
78 case OP_OR: 82 case OP_OR:
83 case OP_BITLSHIFT:
84 case OP_BITRSHIFT:
85 case OP_BITAND:
86 case OP_BITOR:
79 println("%s r%d, r%d, r%d", op_str[instruction.op], instruction.dst, 87 println("%s r%d, r%d, r%d", op_str[instruction.op], instruction.dst,
80 instruction.a, instruction.b); 88 instruction.a, instruction.b);
81 break; 89 break;
90 case OP_BITNOTI:
82 case OP_NOTI: 91 case OP_NOTI:
83 println("%s r%d, c%d", op_str[instruction.op], instruction.dst, 92 println("%s r%d, c%d", op_str[instruction.op], instruction.dst,
84 instruction.a, instruction.b); 93 instruction.a, instruction.b);
85 break; 94 break;
95 case OP_BITNOT:
86 case OP_NOT: 96 case OP_NOT:
87 println("%s r%d, r%d", op_str[instruction.op], instruction.dst, 97 println("%s r%d, r%d", op_str[instruction.op], instruction.dst,
88 instruction.a, instruction.b); 98 instruction.a, instruction.b);
@@ -183,6 +193,11 @@ vm_run(VM *vm) {
183 vm->regs[dst].i = vm->chunk->constants[src_a].i; 193 vm->regs[dst].i = vm->chunk->constants[src_a].i;
184 } break; 194 } break;
185 case OP_NOT: OP_UNARY(!, i) break; 195 case OP_NOT: OP_UNARY(!, i) break;
196 case OP_BITNOT: OP_UNARY(~, i) break;
197 case OP_BITOR: OP_BINARY(|, i) break;
198 case OP_BITAND: OP_BINARY(&, i) break;
199 case OP_BITLSHIFT: OP_BINARY(<<, i) break;
200 case OP_BITRSHIFT: OP_BINARY(>>, i) break;
186 case OP_EQ: OP_BINARY(==, i) break; 201 case OP_EQ: OP_BINARY(==, i) break;
187 case OP_NEQ: OP_BINARY(!=, i) break; 202 case OP_NEQ: OP_BINARY(!=, i) break;
188 case OP_LT: OP_BINARY(<, i) break; 203 case OP_LT: OP_BINARY(<, i) break;
@@ -208,6 +223,11 @@ vm_run(VM *vm) {
208 fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f); 223 fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f);
209 } break; 224 } break;
210 case OP_NOTI: OP_UNARY_CONST(!, i) break; 225 case OP_NOTI: OP_UNARY_CONST(!, i) break;
226 case OP_BITNOTI: OP_UNARY_CONST(~, i) break;
227 case OP_BITORI: OP_BINARY_CONST(|, i) break;
228 case OP_BITANDI: OP_BINARY_CONST(&, i) break;
229 case OP_BITLSHIFTI: OP_BINARY_CONST(<<, i) break;
230 case OP_BITRSHIFTI: OP_BINARY_CONST(>>, i) break;
211 case OP_EQI: OP_BINARY_CONST(==, i) break; 231 case OP_EQI: OP_BINARY_CONST(==, i) break;
212 case OP_NEQI: OP_BINARY_CONST(!=, i) break; 232 case OP_NEQI: OP_BINARY_CONST(!=, i) break;
213 case OP_LTI: OP_BINARY_CONST(<, i) break; 233 case OP_LTI: OP_BINARY_CONST(<, i) break;
@@ -233,8 +253,9 @@ vm_run(VM *vm) {
233 fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f); 253 fmod(vm->regs[src_a].f, vm->chunk->constants[src_b].f);
234 } break; 254 } break;
235 case OP_HALT: { 255 case OP_HALT: {
236 println("VM HALT (int) -> %d", vm->regs[instruction.dst]); 256 println("VM HALT (int) -> %d", vm->regs[instruction.dst]);
237 println("VM HALT (float) -> %f", vm->regs[instruction.dst]); 257 println("VM HALT (float) -> %f", vm->regs[instruction.dst]);
258 println("VM HALT (hex) -> %x", vm->regs[instruction.dst]);
238 return; 259 return;
239 } 260 }
240 default: { 261 default: {