DEADSOFTWARE

b0887aee7c82587beed212c50e56cac179a32b72
[dsw-obn.git] / generator.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <ctype.h>
5 #include <string.h>
6 #include <assert.h>
7 #include <stdbool.h>
9 #include <gc.h>
11 #include "oberon.h"
12 #include "generator.h"
14 // =======================================================================
15 // INTERNAL FUNCTIONS
16 // =======================================================================
18 static void *
19 __OBERON_ALLOC__ (size_t bytes)
20 {
21 void * p = GC_MALLOC(bytes);
22 memset(p, 0, bytes);
23 printf("allocated %lu bytes\n", bytes);
24 return p;
25 }
27 // =======================================================================
28 // ALLOC
29 // =======================================================================
31 static void
32 oberon_generator_open_block(gen_context_t * gen_context, gcc_jit_block * gcc_block)
33 {
34 gen_block_t * block = malloc(sizeof *block);
35 memset(block, 0, sizeof *block);
37 block -> gcc_block = gcc_block;
38 block -> up = gen_context -> block;
40 gen_context -> block = block;
41 }
43 static void
44 oberon_generator_close_block(gen_context_t * gen_context)
45 {
46 gen_context -> block = gen_context -> block -> up;
47 }
49 void
50 oberon_generator_init_context(oberon_context_t * ctx)
51 {
52 gen_context_t * gen_context = malloc(sizeof *gen_context);
53 memset(gen_context, 0, sizeof *gen_context);
55 gcc_jit_context * gcc_context;
56 gcc_context = gcc_jit_context_acquire();
58 ctx -> gen_context = gen_context;
59 gen_context -> gcc_context = gcc_context;
61 gcc_jit_type * void_ptr_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_VOID_PTR);
62 gcc_jit_type * size_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_SIZE_T);
63 gcc_jit_type * alloc_ptr_type = gcc_jit_context_new_function_ptr_type(
64 gcc_context, NULL, void_ptr_type, 1, &size_type, 0
65 );
66 gen_context -> gcc_alloc = gcc_jit_context_new_global(
67 gcc_context, NULL, GCC_JIT_GLOBAL_EXPORTED, alloc_ptr_type, "__OBERON_ALLOC__"
68 );
69 }
71 void
72 oberon_generator_destroy_context(oberon_context_t * ctx)
73 {
74 gen_context_t * gen_context = ctx -> gen_context;
75 gcc_jit_context * gcc_context = gen_context -> gcc_context;
77 gcc_jit_context_release(gcc_context);
78 }
80 void
81 oberon_generator_init_type(oberon_context_t * ctx, oberon_type_t * type)
82 {
83 gen_type_t * gen_type = malloc(sizeof *gen_type);
84 memset(gen_type, 0, sizeof *gen_type);
85 type -> gen_type = gen_type;
87 gen_context_t * gen_context = ctx -> gen_context;
88 gcc_jit_context * gcc_context = gen_context -> gcc_context;
90 gcc_jit_type * gcc_type = NULL;
91 gcc_jit_struct * gcc_struct = NULL;
92 if(type -> class == OBERON_TYPE_VOID)
93 {
94 gcc_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_VOID);
95 }
96 else if(type -> class == OBERON_TYPE_INTEGER)
97 {
98 gcc_type = gcc_jit_context_get_int_type(gcc_context, type -> size, 1);
99 }
100 else if(type -> class == OBERON_TYPE_BOOLEAN)
102 if(type -> size == sizeof(bool))
104 gcc_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_BOOL);
106 else
108 oberon_error(ctx, "generator: unsupported boolean size");
111 else if(type -> class == OBERON_TYPE_REAL)
113 if(type -> size == sizeof(float))
115 gcc_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_FLOAT);
117 else if(type -> size == sizeof(double))
119 gcc_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_DOUBLE);
121 else if(type -> size == sizeof(long double))
123 gcc_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_LONG_DOUBLE);
125 else
127 oberon_error(ctx, "generator: unsupported real size");
130 else if(type -> class == OBERON_TYPE_ARRAY)
132 gen_type_t * gen_base = type -> base -> gen_type;
133 gcc_jit_type * gcc_base = gen_base -> gcc_type;
134 gcc_type = gcc_jit_context_new_array_type(gcc_context, NULL, gcc_base, type -> size);
136 else if(type -> class == OBERON_TYPE_RECORD)
138 char name[32];
139 snprintf(name, 32, "RECORD%u", gen_context -> record_count);
140 gen_context -> record_count += 1;
142 gcc_struct = gcc_jit_context_new_opaque_struct(gcc_context, NULL, name);
143 gcc_type = gcc_jit_struct_as_type(gcc_struct);
145 else if(type -> class == OBERON_TYPE_POINTER)
147 gen_type_t * gen_base = type -> base -> gen_type;
148 gcc_jit_type * gcc_base = gen_base -> gcc_type;
149 gcc_type = gcc_jit_type_get_pointer(gcc_base);
151 else if(type -> class == OBERON_TYPE_PROCEDURE)
153 int num_params = type -> num_decl;
154 gcc_jit_type * params[num_params];
155 oberon_object_t * o = type -> decl;
156 for(int i = 0; i < num_params; i++)
158 gen_type_t * gen_type = o -> type -> gen_type;
159 params[i] = gen_type -> gcc_type;
160 o = o -> next;
163 gen_type_t * base = type -> base -> gen_type;
164 gcc_jit_type * result_type = base -> gcc_type;
166 gcc_type = gcc_jit_context_new_function_ptr_type(
167 gcc_context, NULL, result_type, num_params, params, 0
168 );
170 else
172 oberon_error(ctx, "oberon_generator_init_type: invalid type class %i", type -> class);
175 assert(gcc_type);
176 gen_type -> gcc_type = gcc_type;
177 gen_type -> gcc_struct = gcc_struct;
180 void
181 oberon_generator_init_record(oberon_context_t * ctx, oberon_type_t * type)
183 assert(type -> class == OBERON_TYPE_RECORD);
185 gen_type_t * gen_type = type -> gen_type;
186 gcc_jit_struct * gcc_struct = gen_type -> gcc_struct;
188 // TODO type exstension
190 int num_fields = type -> num_decl;
191 gcc_jit_field * fields[num_fields];
192 oberon_object_t * o = type -> decl;
193 for(int i = 0; i < num_fields; i++)
195 assert(o -> class == OBERON_CLASS_FIELD);
196 gen_var_t * var = o -> gen_var;
197 fields[i] = var -> gcc_field;
198 o = o -> next;
201 gcc_jit_struct_set_fields (gcc_struct, NULL, num_fields, fields);
203 //gcc_struct = gcc_jit_context_new_struct_type(gcc_context, NULL, "", num_fields, fields);
206 static void
207 oberon_generator_get_full_name(char * name, int max_len, oberon_object_t * x)
209 if(!x)
211 name[0] = 0;
212 return;
215 int add_module_prefix;
216 switch(x -> class)
218 case OBERON_CLASS_FIELD:
219 case OBERON_CLASS_PARAM:
220 case OBERON_CLASS_VAR_PARAM:
221 /* В локальных областях префиксы излишни */
222 add_module_prefix = 0;
223 break;
224 default:
225 add_module_prefix = 1;
226 break;
229 char parent[256];
230 oberon_generator_get_full_name(parent, 256, x -> parent);
232 if(strlen(parent) > 0)
234 snprintf(name, max_len, "%s_%s", parent, x -> name);
236 else if(add_module_prefix)
238 snprintf(name, max_len, "%s_%s", x -> module -> name, x -> name);
240 else
242 snprintf(name, max_len, "%s", x -> name);
246 void
247 oberon_generator_init_var(oberon_context_t * ctx, oberon_object_t * var)
249 gen_context_t * gen_context = ctx -> gen_context;
250 gen_type_t * gen_type = var -> type -> gen_type;
252 gen_var_t * gen_var = malloc(sizeof *gen_var);
253 memset(gen_var, 0, sizeof *gen_var);
254 var -> gen_var = gen_var;
256 gcc_jit_context * gcc_context = gen_context -> gcc_context;
257 gcc_jit_type * gcc_type = gen_type -> gcc_type;
259 char name[256];
260 oberon_generator_get_full_name(name, 256, var);
262 gcc_jit_lvalue * gcc_lvalue = NULL;
263 gcc_jit_param * gcc_param = NULL;
264 gcc_jit_field * gcc_field = NULL;
265 if(var -> class == OBERON_CLASS_VAR)
267 if(var -> local)
269 gen_proc_t * gen_func = var -> parent -> gen_proc;
270 gcc_jit_function * func = gen_func -> gcc_func;
272 gcc_lvalue = gcc_jit_function_new_local(func, NULL, gcc_type, name);
274 else
276 gcc_lvalue = gcc_jit_context_new_global(
277 gcc_context, NULL, GCC_JIT_GLOBAL_EXPORTED, gcc_type, name
278 );
281 else if(var -> class == OBERON_CLASS_PARAM)
283 gcc_param = gcc_jit_context_new_param(gcc_context, NULL, gcc_type, name);
284 gcc_lvalue = gcc_jit_param_as_lvalue(gcc_param);
286 else if(var -> class == OBERON_CLASS_VAR_PARAM)
288 gcc_type = gcc_jit_type_get_pointer(gcc_type);
289 gcc_param = gcc_jit_context_new_param(gcc_context, NULL, gcc_type, name);
290 gcc_lvalue = gcc_jit_param_as_lvalue(gcc_param);
292 else if(var -> class == OBERON_CLASS_FIELD)
294 gcc_field = gcc_jit_context_new_field(gcc_context, NULL, gcc_type, name);
296 else
298 oberon_error(ctx, "oberon_generator_init_var: invalid class %i", var -> class);
301 gen_var -> gcc_lvalue = gcc_lvalue;
302 gen_var -> gcc_param = gcc_param;
303 gen_var -> gcc_field = gcc_field;
306 void
307 oberon_generator_init_proc(oberon_context_t * ctx, oberon_object_t * proc)
309 if(proc -> local)
311 oberon_error(ctx, "generator: local procedures not supported");
314 gen_context_t * gen_context = ctx -> gen_context;
315 gcc_jit_context * gcc_context = gen_context -> gcc_context;
317 gen_proc_t * gen_proc = malloc(sizeof *gen_proc);
318 memset(gen_proc, 0, sizeof *gen_proc);
319 proc -> gen_proc = gen_proc;
321 char name[256];
322 oberon_generator_get_full_name(name, 256, proc);
324 gen_type_t * gen_result_type = proc -> type -> base -> gen_type;
325 gcc_jit_type * result_type = gen_result_type -> gcc_type;
327 /* Строим список параметров */
328 int num_param = proc -> type -> num_decl;
329 oberon_object_t * o = proc -> type -> decl;
330 gcc_jit_param * params[num_param];
331 for(int i = 0; i < num_param; i++)
333 gen_var_t * param_var = o -> gen_var;
334 params[i] = param_var -> gcc_param;
335 o = o -> next;
338 gcc_jit_function * gcc_func;
339 gcc_func = gcc_jit_context_new_function(
340 gcc_context, NULL, GCC_JIT_FUNCTION_EXPORTED, result_type, name, num_param, params, 0
341 );
343 gen_proc -> gcc_func = gcc_func;
346 // =======================================================================
347 // GENERATOR
348 // =======================================================================
350 static gcc_jit_rvalue * rvalue_from_item(oberon_context_t * ctx, oberon_item_t * item);
351 static gcc_jit_rvalue * rvalue_from_expr(oberon_context_t * ctx, oberon_expr_t * expr);
353 static int
354 oberon_generator_get_type_size(oberon_context_t * ctx, oberon_type_t * type)
356 int size = 0;
357 switch(type -> class)
359 case OBERON_TYPE_INTEGER:
360 size = type -> size;
361 printf("int size: %i\n", size);
362 break;
363 case OBERON_TYPE_BOOLEAN:
364 size = sizeof(bool);
365 printf("bool size: %i\n", size);
366 break;
367 case OBERON_TYPE_PROCEDURE:
368 case OBERON_TYPE_POINTER:
369 size = sizeof(void*);
370 printf("ptr size: %i\n", size);
371 break;
372 case OBERON_TYPE_ARRAY:
373 size = type -> size;
374 type = type -> base;
375 size = (size == 0) ? (1) : (size);
376 size *= oberon_generator_get_type_size(ctx, type);
377 printf("array size: %i\n", size);
378 break;
379 case OBERON_TYPE_RECORD:
381 int num = type -> num_decl;
382 oberon_object_t * arg = type -> decl;
383 for(int i = 0; i < num; i++)
385 oberon_type_t * x;
386 x = arg -> type;
387 size += oberon_generator_get_type_size(ctx, x);
388 arg = arg -> next;
391 printf("struct size: %i\n", size);
392 break;
393 default:
394 oberon_error(ctx, "oberon_generator_get_type_size: wat");
395 break;
398 return size;
401 void
402 oberon_generate_begin_module(oberon_context_t * ctx)
404 gen_context_t * gen_context = ctx -> gen_context;
405 gcc_jit_context * gcc_context = gen_context -> gcc_context;
407 char name[256];
408 snprintf(name, 256, "%s_BEGIN", ctx -> mod -> name);
410 gcc_jit_type * void_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_VOID);
411 gcc_jit_function * func = gcc_jit_context_new_function(
412 gcc_context, NULL, GCC_JIT_FUNCTION_EXPORTED, void_type, name, 0, NULL, 0
413 );
414 gcc_jit_block * gcc_block = gcc_jit_function_new_block(func, NULL);
416 oberon_generator_open_block(gen_context, gcc_block);
419 void
420 oberon_generate_end_module(oberon_context_t * ctx)
422 gen_context_t * gen_context = ctx -> gen_context;
423 gcc_jit_block * gcc_block = gen_context -> block -> gcc_block;
425 gcc_jit_block_end_with_void_return(gcc_block, NULL);
427 oberon_generator_close_block(gen_context);
430 void
431 oberon_generate_begin_proc(oberon_context_t * ctx, oberon_object_t * proc)
433 gen_context_t * gen_context = ctx -> gen_context;
434 gen_proc_t * gen_proc = proc -> gen_proc;
436 gcc_jit_function * func = gen_proc -> gcc_func;
437 gcc_jit_block * gcc_block = gcc_jit_function_new_block(func, NULL);
439 oberon_generator_open_block(gen_context, gcc_block);
442 void
443 oberon_generate_call_proc(oberon_context_t * ctx, oberon_expr_t * desig)
445 gen_context_t * gen_context = ctx -> gen_context;
446 gen_block_t * gen_block = gen_context -> block;
447 gcc_jit_block * block = gen_block -> gcc_block;
449 gcc_jit_rvalue * return_value;
450 return_value = rvalue_from_expr(ctx, desig);
451 gcc_jit_block_add_eval(block, NULL, return_value);
454 void
455 oberon_generate_end_proc(oberon_context_t * ctx)
457 gen_context_t * gen_context = ctx -> gen_context;
458 oberon_generator_close_block(gen_context);
461 void
462 oberon_generate_return(oberon_context_t * ctx, oberon_expr_t * expr)
464 gen_context_t * gen_context = ctx -> gen_context;
465 gen_block_t * gen_block = gen_context -> block;
466 gcc_jit_block * gcc_block = gen_block -> gcc_block;
468 if(expr == NULL)
470 gcc_jit_block_end_with_void_return(gcc_block, NULL);
472 else
474 gcc_jit_rvalue * r = rvalue_from_expr(ctx, expr);
475 gcc_jit_block_end_with_return(gcc_block, NULL, r);
479 static gcc_jit_lvalue *
480 lvalue_from_item(oberon_context_t * ctx, oberon_item_t * item)
482 gen_context_t * gen_context = ctx -> gen_context;
483 gcc_jit_context * gcc_context = gen_context -> gcc_context;
485 gcc_jit_lvalue * left;
487 if(item -> mode == MODE_VAR)
489 if(item -> var -> class == OBERON_CLASS_PROC)
491 oberon_error(ctx, "casting static procedure to pointer not supported by generator");
494 gen_var_t * gen_var = item -> var -> gen_var;
495 left = gen_var -> gcc_lvalue;
496 if(item -> var -> class == OBERON_CLASS_VAR_PARAM)
498 gcc_jit_rvalue * r = gcc_jit_lvalue_as_rvalue(left);
499 left = gcc_jit_rvalue_dereference(r, NULL);
502 else if(item -> mode == MODE_INDEX)
504 assert(item -> num_args == 1);
505 gcc_jit_rvalue * parent = rvalue_from_item(ctx, item -> parent);
506 gcc_jit_rvalue * index = rvalue_from_expr(ctx, item -> args);
507 left = gcc_jit_context_new_array_access(gcc_context, NULL, parent, index);
509 else if(item -> mode == MODE_FIELD)
511 printf("lvalue_from_item: %s\n", item -> var -> name);
512 gen_var_t * gen_var = item -> var -> gen_var;
513 gcc_jit_field * gcc_field = gen_var -> gcc_field;
515 gcc_jit_lvalue * parent = lvalue_from_item(ctx, item -> parent);
516 left = gcc_jit_lvalue_access_field(parent, NULL, gcc_field);
518 else if(item -> mode == MODE_DEREF)
520 gcc_jit_rvalue * parent = rvalue_from_item(ctx, item -> parent);
521 left = gcc_jit_rvalue_dereference(parent, NULL);
523 else
525 oberon_error(ctx, "lvalue_from_item: invalid mode %i", item -> mode);
528 return left;
531 static gcc_jit_lvalue *
532 lvalue_from_expr(oberon_context_t *ctx, oberon_expr_t * expr)
534 gcc_jit_lvalue * left;
535 oberon_item_t * item;
537 if(expr -> is_item)
539 item = (oberon_item_t *) expr;
540 left = lvalue_from_item(ctx, item);
542 else
544 oberon_error(ctx, "invalid lvalue expression");
547 return left;
550 static gcc_jit_rvalue *
551 rvalue_from_item(oberon_context_t * ctx, oberon_item_t * item)
553 gen_context_t * gen_context = ctx -> gen_context;
554 gcc_jit_context * gcc_context = gen_context -> gcc_context;
556 gcc_jit_rvalue * right;
557 if(item -> mode == MODE_VAR)
559 gcc_jit_lvalue * left = lvalue_from_item(ctx, item);
560 right = gcc_jit_lvalue_as_rvalue(left);
562 else if(item -> mode == MODE_INTEGER)
564 gcc_jit_type * int_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_INT);
565 right = gcc_jit_context_new_rvalue_from_int(gcc_context, int_type, item -> integer);
567 else if(item -> mode == MODE_BOOLEAN)
569 gcc_jit_type * bool_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_BOOL);
570 if(item -> boolean)
572 right = gcc_jit_context_one(gcc_context, bool_type);
574 else
576 right = gcc_jit_context_zero(gcc_context, bool_type);
579 else if(item -> mode == MODE_CALL)
581 oberon_type_t * signature = item -> var -> type;
582 gen_proc_t * gen_proc = item -> var -> gen_proc;
584 int num_args = item -> num_args;
585 gcc_jit_rvalue *args[num_args];
587 oberon_expr_t * expr = item -> args;
588 oberon_object_t * arg_param = signature -> decl;
589 for(int i = 0; i < num_args; i++)
591 if(arg_param -> class == OBERON_CLASS_VAR_PARAM)
593 gcc_jit_lvalue * left = lvalue_from_expr(ctx, expr);
594 args[i] = gcc_jit_lvalue_get_address(left, NULL);
596 else
598 args[i] = rvalue_from_expr(ctx, expr);
600 expr = expr -> next;
601 arg_param = arg_param -> next;
604 gcc_jit_rvalue * fnptr;
605 gcc_jit_function * func;
606 switch(item -> var -> class)
608 case OBERON_CLASS_PROC:
609 func = gen_proc -> gcc_func;
610 right = gcc_jit_context_new_call(
611 gcc_context, NULL, func, num_args, args
612 );
613 break;
614 case OBERON_CLASS_VAR:
615 case OBERON_CLASS_VAR_PARAM:
616 case OBERON_CLASS_PARAM:
617 fnptr = gcc_jit_lvalue_as_rvalue(item -> var -> gen_var -> gcc_lvalue);
618 right = gcc_jit_context_new_call_through_ptr(
619 gcc_context, NULL, fnptr, num_args, args
620 );
621 break;
622 default:
623 assert(0);
624 break;
627 else if(item -> mode == MODE_INDEX)
629 gcc_jit_lvalue * left = lvalue_from_item(ctx, item);
630 right = gcc_jit_lvalue_as_rvalue(left);
632 else if(item -> mode == MODE_FIELD)
634 gen_var_t * gen_var = item -> var -> gen_var;
635 gcc_jit_field * gcc_field = gen_var -> gcc_field;
637 gcc_jit_rvalue * parent = rvalue_from_item(ctx, item -> parent);
638 right = gcc_jit_rvalue_access_field(parent, NULL, gcc_field);
640 else if(item -> mode == MODE_DEREF)
642 gcc_jit_lvalue * left = lvalue_from_item(ctx, item);
643 right = gcc_jit_lvalue_as_rvalue(left);
645 else if(item -> mode == MODE_NIL)
647 gcc_jit_type * type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_VOID_PTR);
648 right = gcc_jit_context_null(gcc_context, type);
650 else if(item -> mode == MODE_NEW)
652 assert(item -> result -> class == OBERON_TYPE_POINTER);
654 oberon_type_t * type = item -> result -> base;
655 int type_size = oberon_generator_get_type_size(ctx, type);
656 int array_size = type_size;
658 int num = item -> num_args;
659 oberon_expr_t * arg = item -> args;
660 for(int i = 0; i < num; i++)
662 array_size *= arg -> item.integer;
663 arg = arg -> next;
666 gcc_jit_type * size_type;
667 size_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_SIZE_T);
669 gcc_jit_rvalue * fnarg;
670 fnarg = gcc_jit_context_new_rvalue_from_int(gcc_context, size_type, array_size);
672 gcc_jit_type * result_type = item -> result -> gen_type -> gcc_type;
673 gcc_jit_rvalue * gcc_alloc = gcc_jit_lvalue_as_rvalue(gen_context -> gcc_alloc);
674 right = gcc_jit_context_new_call_through_ptr(gcc_context, NULL, gcc_alloc, 1, &fnarg);
675 right = gcc_jit_context_new_cast(gcc_context, NULL, right, result_type);
677 else if(item -> mode == MODE_REAL)
679 gcc_jit_type * int_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_FLOAT);
680 right = gcc_jit_context_new_rvalue_from_int(gcc_context, int_type, item -> real);
682 else
684 oberon_error(ctx, "rvalue_from_item: invalid mode %i", item -> mode);
687 return right;
690 struct {
691 int type; // 0 - unary, 1 - binary, 2 - comp
692 union {
693 enum gcc_jit_unary_op unary_op;
694 enum gcc_jit_binary_op binary_op;
695 enum gcc_jit_comparison comp_op;
696 };
697 } op_table[] = {
698 { 0, .unary_op = GCC_JIT_UNARY_OP_MINUS },
699 { 0, .unary_op = GCC_JIT_UNARY_OP_BITWISE_NEGATE },
700 { 0, .unary_op = GCC_JIT_UNARY_OP_LOGICAL_NEGATE },
701 { 0, .unary_op = GCC_JIT_UNARY_OP_ABS },
703 { 1, .binary_op = GCC_JIT_BINARY_OP_PLUS },
704 { 1, .binary_op = GCC_JIT_BINARY_OP_MINUS },
705 { 1, .binary_op = GCC_JIT_BINARY_OP_MULT },
706 { 1, .binary_op = GCC_JIT_BINARY_OP_DIVIDE },
707 { 1, .binary_op = GCC_JIT_BINARY_OP_MODULO },
708 { 1, .binary_op = GCC_JIT_BINARY_OP_BITWISE_AND },
709 { 1, .binary_op = GCC_JIT_BINARY_OP_BITWISE_XOR },
710 { 1, .binary_op = GCC_JIT_BINARY_OP_BITWISE_OR },
711 { 1, .binary_op = GCC_JIT_BINARY_OP_LOGICAL_AND },
712 { 1, .binary_op = GCC_JIT_BINARY_OP_LOGICAL_OR },
714 { 2, .comp_op = GCC_JIT_COMPARISON_EQ },
715 { 2, .comp_op = GCC_JIT_COMPARISON_NE },
716 { 2, .comp_op = GCC_JIT_COMPARISON_LT },
717 { 2, .comp_op = GCC_JIT_COMPARISON_LE },
718 { 2, .comp_op = GCC_JIT_COMPARISON_GT },
719 { 2, .comp_op = GCC_JIT_COMPARISON_GE }
720 };
722 static gcc_jit_rvalue *
723 rvalue_from_operator(oberon_context_t * ctx, oberon_oper_t * operator)
725 gcc_jit_rvalue * right;
727 gen_context_t * gen_context = ctx -> gen_context;
728 gen_type_t * gen_type = operator -> result -> gen_type;
729 gcc_jit_context * gcc_context = gen_context -> gcc_context;
730 gcc_jit_type * result_type = gen_type -> gcc_type;
732 int expr_type = op_table[operator -> op].type;
733 if(expr_type == 0)
735 enum gcc_jit_unary_op op = op_table[operator -> op].unary_op;
736 gcc_jit_rvalue * l = rvalue_from_expr(ctx, operator -> left);
737 right = gcc_jit_context_new_unary_op(gcc_context, NULL, op, result_type, l);
739 else if(expr_type == 1)
741 enum gcc_jit_unary_op op = op_table[operator -> op].binary_op;
742 gcc_jit_rvalue * l = rvalue_from_expr(ctx, operator -> left);
743 gcc_jit_rvalue * r = rvalue_from_expr(ctx, operator -> right);
744 right = gcc_jit_context_new_binary_op(gcc_context, NULL, op, result_type, l, r);
746 else if(expr_type == 2)
748 enum gcc_jit_comparison op = op_table[operator -> op].comp_op;
749 gcc_jit_rvalue * l = rvalue_from_expr(ctx, operator -> left);
750 gcc_jit_rvalue * r = rvalue_from_expr(ctx, operator -> right);
751 right = gcc_jit_context_new_comparison(gcc_context, NULL, op, l, r);
753 else
755 oberon_error(ctx, "rvalue_from_operator: wat");
758 return right;
761 static gcc_jit_rvalue *
762 rvalue_from_expr(oberon_context_t * ctx, oberon_expr_t * expr)
764 gcc_jit_rvalue * right;
766 if(expr -> is_item)
768 oberon_item_t * item = (oberon_item_t *) expr;
769 right = rvalue_from_item(ctx, item);
771 else
773 oberon_oper_t * operator = (oberon_oper_t *) expr;
774 right = rvalue_from_operator(ctx, operator);
777 return right;
780 void
781 oberon_generate_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst)
783 gcc_jit_lvalue * left;
784 left = lvalue_from_expr(ctx, dst);
786 gcc_jit_rvalue * right;
787 right = rvalue_from_expr(ctx, src);
789 if(src -> is_item)
791 if(src -> item.mode == MODE_NIL)
793 gen_context_t * gen_context = ctx -> gen_context;
794 gcc_jit_context * gcc_context = gen_context -> gcc_context;
795 gen_type_t * gen_type = dst -> result -> gen_type;
796 gcc_jit_type * cast_to_type = gen_type -> gcc_type;
797 right = gcc_jit_context_new_cast(gcc_context, NULL, right, cast_to_type);
801 printf("oberon_generate_assign: class %i := class %i\n", dst -> result -> class, src -> result -> class);
803 gen_context_t * gen_context = ctx -> gen_context;
804 gen_block_t * gen_block = gen_context -> block;
805 gcc_jit_block * gcc_block = gen_block -> gcc_block;
806 gcc_jit_block_add_assignment(gcc_block, NULL, left, right);
809 void
810 oberon_generate_code(oberon_context_t * ctx)
812 gen_context_t * gen_context = ctx -> gen_context;
813 gcc_jit_context * gcc_context = gen_context -> gcc_context;
815 gcc_jit_result * gcc_result;
816 gcc_result = gcc_jit_context_compile(gcc_context);
818 gen_context -> gcc_result = gcc_result;
820 typedef void * (*TOberonAlloc)(size_t);
821 TOberonAlloc * fn_alloc_ptr = gcc_jit_result_get_global(gcc_result, "__OBERON_ALLOC__");
822 *fn_alloc_ptr = __OBERON_ALLOC__;
824 // ctx -> mod -> begin = gcc_jit_result_get_code(gcc_result, "BEGIN");
827 void
828 oberon_generator_dump(oberon_context_t * ctx, char * path)
830 gen_context_t * gen_context = ctx -> gen_context;
831 gcc_jit_context * gcc_context = gen_context -> gcc_context;
832 gcc_jit_context_dump_to_file(gcc_context, path, 0);
835 void *
836 oberon_generator_get_procedure(oberon_context_t * ctx, const char * name)
838 gen_context_t * gen_context = ctx -> gen_context;
839 gcc_jit_result * gcc_result = gen_context -> gcc_result;
841 return gcc_jit_result_get_code(gcc_result, name);
844 void *
845 oberon_generator_get_var(oberon_context_t * ctx, const char * name)
847 gen_context_t * gen_context = ctx -> gen_context;
848 gcc_jit_result * gcc_result = gen_context -> gcc_result;
850 return gcc_jit_result_get_global(gcc_result, name);