11 #include "../../../include/oberon.h"
12 #include "../../oberon-internals.h"
13 #include "generator-libgccjit.h"
15 // =======================================================================
17 // =======================================================================
20 __OBERON_ALLOC__ (size_t bytes
)
22 void * p
= GC_MALLOC(bytes
);
24 printf("allocated %lu bytes\n", bytes
);
28 // =======================================================================
30 // =======================================================================
33 oberon_generator_open_block(gen_context_t
* gen_context
, gcc_jit_block
* gcc_block
)
35 gen_block_t
* block
= malloc(sizeof *block
);
36 memset(block
, 0, sizeof *block
);
38 block
-> gcc_block
= gcc_block
;
39 block
-> up
= gen_context
-> block
;
41 gen_context
-> block
= block
;
45 oberon_generator_close_block(gen_context_t
* gen_context
)
47 gen_context
-> block
= gen_context
-> block
-> up
;
51 oberon_generator_init_context(oberon_context_t
* ctx
)
53 gen_context_t
* gen_context
= malloc(sizeof *gen_context
);
54 memset(gen_context
, 0, sizeof *gen_context
);
56 gcc_jit_context
* gcc_context
;
57 gcc_context
= gcc_jit_context_acquire();
59 ctx
-> gen_context
= gen_context
;
60 gen_context
-> gcc_context
= gcc_context
;
62 gcc_jit_type
* void_ptr_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_VOID_PTR
);
63 gcc_jit_type
* size_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_SIZE_T
);
64 gcc_jit_type
* alloc_ptr_type
= gcc_jit_context_new_function_ptr_type(
65 gcc_context
, NULL
, void_ptr_type
, 1, &size_type
, 0
67 gen_context
-> gcc_alloc
= gcc_jit_context_new_global(
68 gcc_context
, NULL
, GCC_JIT_GLOBAL_EXPORTED
, alloc_ptr_type
, "__OBERON_ALLOC__"
73 oberon_generator_destroy_context(oberon_context_t
* ctx
)
75 gen_context_t
* gen_context
= ctx
-> gen_context
;
76 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
78 gcc_jit_context_release(gcc_context
);
82 oberon_generator_init_type(oberon_context_t
* ctx
, oberon_type_t
* type
)
84 gen_type_t
* gen_type
= malloc(sizeof *gen_type
);
85 memset(gen_type
, 0, sizeof *gen_type
);
86 type
-> gen_type
= gen_type
;
88 gen_context_t
* gen_context
= ctx
-> gen_context
;
89 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
91 gcc_jit_type
* gcc_type
= NULL
;
92 gcc_jit_struct
* gcc_struct
= NULL
;
93 if(type
-> class == OBERON_TYPE_VOID
)
95 gcc_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_VOID
);
97 else if(type
-> class == OBERON_TYPE_INTEGER
)
99 gcc_type
= gcc_jit_context_get_int_type(gcc_context
, type
-> size
, 1);
101 else if(type
-> class == OBERON_TYPE_BOOLEAN
)
103 if(type
-> size
== sizeof(bool))
105 gcc_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_BOOL
);
109 oberon_error(ctx
, "generator: unsupported boolean size");
112 else if(type
-> class == OBERON_TYPE_REAL
)
114 if(type
-> size
== sizeof(float))
116 gcc_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_FLOAT
);
118 else if(type
-> size
== sizeof(double))
120 gcc_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_DOUBLE
);
122 else if(type
-> size
== sizeof(long double))
124 gcc_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_LONG_DOUBLE
);
128 oberon_error(ctx
, "generator: unsupported real size");
131 else if(type
-> class == OBERON_TYPE_ARRAY
)
133 gen_type_t
* gen_base
= type
-> base
-> gen_type
;
134 gcc_jit_type
* gcc_base
= gen_base
-> gcc_type
;
135 gcc_type
= gcc_jit_context_new_array_type(gcc_context
, NULL
, gcc_base
, type
-> size
);
137 else if(type
-> class == OBERON_TYPE_RECORD
)
140 snprintf(name
, 32, "RECORD%u", gen_context
-> record_count
);
141 gen_context
-> record_count
+= 1;
143 gcc_struct
= gcc_jit_context_new_opaque_struct(gcc_context
, NULL
, name
);
144 gcc_type
= gcc_jit_struct_as_type(gcc_struct
);
146 else if(type
-> class == OBERON_TYPE_POINTER
)
148 gen_type_t
* gen_base
= type
-> base
-> gen_type
;
149 gcc_jit_type
* gcc_base
= gen_base
-> gcc_type
;
150 gcc_type
= gcc_jit_type_get_pointer(gcc_base
);
152 else if(type
-> class == OBERON_TYPE_PROCEDURE
)
154 int num_params
= type
-> num_decl
;
155 gcc_jit_type
* params
[num_params
];
156 oberon_object_t
* o
= type
-> decl
;
157 for(int i
= 0; i
< num_params
; i
++)
159 gen_type_t
* gen_type
= o
-> type
-> gen_type
;
160 params
[i
] = gen_type
-> gcc_type
;
164 gen_type_t
* base
= type
-> base
-> gen_type
;
165 gcc_jit_type
* result_type
= base
-> gcc_type
;
167 gcc_type
= gcc_jit_context_new_function_ptr_type(
168 gcc_context
, NULL
, result_type
, num_params
, params
, 0
173 oberon_error(ctx
, "oberon_generator_init_type: invalid type class %i", type
-> class);
177 gen_type
-> gcc_type
= gcc_type
;
178 gen_type
-> gcc_struct
= gcc_struct
;
182 oberon_generator_init_record(oberon_context_t
* ctx
, oberon_type_t
* type
)
184 assert(type
-> class == OBERON_TYPE_RECORD
);
186 gen_type_t
* gen_type
= type
-> gen_type
;
187 gcc_jit_struct
* gcc_struct
= gen_type
-> gcc_struct
;
189 // TODO type exstension
191 int num_fields
= type
-> num_decl
;
192 gcc_jit_field
* fields
[num_fields
];
193 oberon_object_t
* o
= type
-> decl
;
194 for(int i
= 0; i
< num_fields
; i
++)
196 assert(o
-> class == OBERON_CLASS_FIELD
);
197 gen_var_t
* var
= o
-> gen_var
;
198 fields
[i
] = var
-> gcc_field
;
202 gcc_jit_struct_set_fields (gcc_struct
, NULL
, num_fields
, fields
);
204 //gcc_struct = gcc_jit_context_new_struct_type(gcc_context, NULL, "", num_fields, fields);
208 oberon_generator_get_full_name(char * name
, int max_len
, oberon_object_t
* x
)
216 int add_module_prefix
;
219 case OBERON_CLASS_FIELD
:
220 case OBERON_CLASS_PARAM
:
221 case OBERON_CLASS_VAR_PARAM
:
222 /* В локальных областях префиксы излишни */
223 add_module_prefix
= 0;
226 add_module_prefix
= 1;
231 oberon_generator_get_full_name(parent
, 256, x
-> parent
);
233 if(strlen(parent
) > 0)
235 snprintf(name
, max_len
, "%s_%s", parent
, x
-> name
);
237 else if(add_module_prefix
)
239 snprintf(name
, max_len
, "%s_%s", x
-> module
-> name
, x
-> name
);
243 snprintf(name
, max_len
, "%s", x
-> name
);
248 oberon_generator_init_var(oberon_context_t
* ctx
, oberon_object_t
* var
)
250 gen_context_t
* gen_context
= ctx
-> gen_context
;
251 gen_type_t
* gen_type
= var
-> type
-> gen_type
;
253 gen_var_t
* gen_var
= malloc(sizeof *gen_var
);
254 memset(gen_var
, 0, sizeof *gen_var
);
255 var
-> gen_var
= gen_var
;
257 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
258 gcc_jit_type
* gcc_type
= gen_type
-> gcc_type
;
261 oberon_generator_get_full_name(name
, 256, var
);
263 gcc_jit_lvalue
* gcc_lvalue
= NULL
;
264 gcc_jit_param
* gcc_param
= NULL
;
265 gcc_jit_field
* gcc_field
= NULL
;
266 if(var
-> class == OBERON_CLASS_VAR
)
270 gen_proc_t
* gen_func
= var
-> parent
-> gen_proc
;
271 gcc_jit_function
* func
= gen_func
-> gcc_func
;
273 gcc_lvalue
= gcc_jit_function_new_local(func
, NULL
, gcc_type
, name
);
277 gcc_lvalue
= gcc_jit_context_new_global(
278 gcc_context
, NULL
, GCC_JIT_GLOBAL_EXPORTED
, gcc_type
, name
282 else if(var
-> class == OBERON_CLASS_PARAM
)
284 gcc_param
= gcc_jit_context_new_param(gcc_context
, NULL
, gcc_type
, name
);
285 gcc_lvalue
= gcc_jit_param_as_lvalue(gcc_param
);
287 else if(var
-> class == OBERON_CLASS_VAR_PARAM
)
289 gcc_type
= gcc_jit_type_get_pointer(gcc_type
);
290 gcc_param
= gcc_jit_context_new_param(gcc_context
, NULL
, gcc_type
, name
);
291 gcc_lvalue
= gcc_jit_param_as_lvalue(gcc_param
);
293 else if(var
-> class == OBERON_CLASS_FIELD
)
295 gcc_field
= gcc_jit_context_new_field(gcc_context
, NULL
, gcc_type
, name
);
299 oberon_error(ctx
, "oberon_generator_init_var: invalid class %i", var
-> class);
302 gen_var
-> gcc_lvalue
= gcc_lvalue
;
303 gen_var
-> gcc_param
= gcc_param
;
304 gen_var
-> gcc_field
= gcc_field
;
308 oberon_generator_init_proc(oberon_context_t
* ctx
, oberon_object_t
* proc
)
312 oberon_error(ctx
, "generator: local procedures not supported");
315 gen_context_t
* gen_context
= ctx
-> gen_context
;
316 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
318 gen_proc_t
* gen_proc
= malloc(sizeof *gen_proc
);
319 memset(gen_proc
, 0, sizeof *gen_proc
);
320 proc
-> gen_proc
= gen_proc
;
323 oberon_generator_get_full_name(name
, 256, proc
);
325 gen_type_t
* gen_result_type
= proc
-> type
-> base
-> gen_type
;
326 gcc_jit_type
* result_type
= gen_result_type
-> gcc_type
;
328 /* Строим список параметров */
329 int num_param
= proc
-> type
-> num_decl
;
330 oberon_object_t
* o
= proc
-> type
-> decl
;
331 gcc_jit_param
* params
[num_param
];
332 for(int i
= 0; i
< num_param
; i
++)
334 gen_var_t
* param_var
= o
-> gen_var
;
335 params
[i
] = param_var
-> gcc_param
;
339 gcc_jit_function
* gcc_func
;
340 gcc_func
= gcc_jit_context_new_function(
341 gcc_context
, NULL
, GCC_JIT_FUNCTION_EXPORTED
, result_type
, name
, num_param
, params
, 0
344 gen_proc
-> gcc_func
= gcc_func
;
347 // =======================================================================
349 // =======================================================================
351 static gcc_jit_rvalue
* rvalue_from_item(oberon_context_t
* ctx
, oberon_item_t
* item
);
352 static gcc_jit_rvalue
* rvalue_from_expr(oberon_context_t
* ctx
, oberon_expr_t
* expr
);
355 oberon_generator_get_type_size(oberon_context_t
* ctx
, oberon_type_t
* type
)
358 switch(type
-> class)
360 case OBERON_TYPE_INTEGER
:
362 printf("int size: %i\n", size
);
364 case OBERON_TYPE_BOOLEAN
:
366 printf("bool size: %i\n", size
);
368 case OBERON_TYPE_PROCEDURE
:
369 case OBERON_TYPE_POINTER
:
370 size
= sizeof(void*);
371 printf("ptr size: %i\n", size
);
373 case OBERON_TYPE_ARRAY
:
376 size
= (size
== 0) ? (1) : (size
);
377 size
*= oberon_generator_get_type_size(ctx
, type
);
378 printf("array size: %i\n", size
);
380 case OBERON_TYPE_RECORD
:
382 int num
= type
-> num_decl
;
383 oberon_object_t
* arg
= type
-> decl
;
384 for(int i
= 0; i
< num
; i
++)
388 size
+= oberon_generator_get_type_size(ctx
, x
);
392 printf("struct size: %i\n", size
);
395 oberon_error(ctx
, "oberon_generator_get_type_size: wat");
403 oberon_generate_begin_module(oberon_context_t
* ctx
)
405 gen_context_t
* gen_context
= ctx
-> gen_context
;
406 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
409 snprintf(name
, 256, "%s_BEGIN", ctx
-> mod
-> name
);
411 gcc_jit_type
* void_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_VOID
);
412 gcc_jit_function
* func
= gcc_jit_context_new_function(
413 gcc_context
, NULL
, GCC_JIT_FUNCTION_EXPORTED
, void_type
, name
, 0, NULL
, 0
415 gcc_jit_block
* gcc_block
= gcc_jit_function_new_block(func
, NULL
);
417 oberon_generator_open_block(gen_context
, gcc_block
);
421 oberon_generate_end_module(oberon_context_t
* ctx
)
423 gen_context_t
* gen_context
= ctx
-> gen_context
;
424 gcc_jit_block
* gcc_block
= gen_context
-> block
-> gcc_block
;
426 gcc_jit_block_end_with_void_return(gcc_block
, NULL
);
428 oberon_generator_close_block(gen_context
);
432 oberon_generate_begin_proc(oberon_context_t
* ctx
, oberon_object_t
* proc
)
434 gen_context_t
* gen_context
= ctx
-> gen_context
;
435 gen_proc_t
* gen_proc
= proc
-> gen_proc
;
437 gcc_jit_function
* func
= gen_proc
-> gcc_func
;
438 gcc_jit_block
* gcc_block
= gcc_jit_function_new_block(func
, NULL
);
440 oberon_generator_open_block(gen_context
, gcc_block
);
444 oberon_generate_call_proc(oberon_context_t
* ctx
, oberon_expr_t
* desig
)
446 gen_context_t
* gen_context
= ctx
-> gen_context
;
447 gen_block_t
* gen_block
= gen_context
-> block
;
448 gcc_jit_block
* block
= gen_block
-> gcc_block
;
450 gcc_jit_rvalue
* return_value
;
451 return_value
= rvalue_from_expr(ctx
, desig
);
452 gcc_jit_block_add_eval(block
, NULL
, return_value
);
456 oberon_generate_end_proc(oberon_context_t
* ctx
)
458 gen_context_t
* gen_context
= ctx
-> gen_context
;
459 oberon_generator_close_block(gen_context
);
463 oberon_generate_return(oberon_context_t
* ctx
, oberon_expr_t
* expr
)
465 gen_context_t
* gen_context
= ctx
-> gen_context
;
466 gen_block_t
* gen_block
= gen_context
-> block
;
467 gcc_jit_block
* gcc_block
= gen_block
-> gcc_block
;
471 gcc_jit_block_end_with_void_return(gcc_block
, NULL
);
475 gcc_jit_rvalue
* r
= rvalue_from_expr(ctx
, expr
);
476 gcc_jit_block_end_with_return(gcc_block
, NULL
, r
);
480 static gcc_jit_lvalue
*
481 lvalue_from_item(oberon_context_t
* ctx
, oberon_item_t
* item
)
483 gen_context_t
* gen_context
= ctx
-> gen_context
;
484 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
486 gcc_jit_lvalue
* left
;
488 if(item
-> mode
== MODE_VAR
)
490 if(item
-> var
-> class == OBERON_CLASS_PROC
)
492 oberon_error(ctx
, "casting static procedure to pointer not supported by generator");
495 gen_var_t
* gen_var
= item
-> var
-> gen_var
;
496 left
= gen_var
-> gcc_lvalue
;
497 if(item
-> var
-> class == OBERON_CLASS_VAR_PARAM
)
499 gcc_jit_rvalue
* r
= gcc_jit_lvalue_as_rvalue(left
);
500 left
= gcc_jit_rvalue_dereference(r
, NULL
);
503 else if(item
-> mode
== MODE_INDEX
)
505 assert(item
-> num_args
== 1);
506 gcc_jit_rvalue
* parent
= rvalue_from_item(ctx
, item
-> parent
);
507 gcc_jit_rvalue
* index
= rvalue_from_expr(ctx
, item
-> args
);
508 left
= gcc_jit_context_new_array_access(gcc_context
, NULL
, parent
, index
);
510 else if(item
-> mode
== MODE_FIELD
)
512 printf("lvalue_from_item: %s\n", item
-> var
-> name
);
513 gen_var_t
* gen_var
= item
-> var
-> gen_var
;
514 gcc_jit_field
* gcc_field
= gen_var
-> gcc_field
;
516 gcc_jit_lvalue
* parent
= lvalue_from_item(ctx
, item
-> parent
);
517 left
= gcc_jit_lvalue_access_field(parent
, NULL
, gcc_field
);
519 else if(item
-> mode
== MODE_DEREF
)
521 gcc_jit_rvalue
* parent
= rvalue_from_item(ctx
, item
-> parent
);
522 left
= gcc_jit_rvalue_dereference(parent
, NULL
);
526 oberon_error(ctx
, "lvalue_from_item: invalid mode %i", item
-> mode
);
532 static gcc_jit_lvalue
*
533 lvalue_from_expr(oberon_context_t
*ctx
, oberon_expr_t
* expr
)
535 gcc_jit_lvalue
* left
;
536 oberon_item_t
* item
;
540 item
= (oberon_item_t
*) expr
;
541 left
= lvalue_from_item(ctx
, item
);
545 oberon_error(ctx
, "invalid lvalue expression");
551 static gcc_jit_rvalue
*
552 rvalue_from_item(oberon_context_t
* ctx
, oberon_item_t
* item
)
554 gen_context_t
* gen_context
= ctx
-> gen_context
;
555 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
557 gcc_jit_rvalue
* right
;
558 if(item
-> mode
== MODE_VAR
)
560 gcc_jit_lvalue
* left
= lvalue_from_item(ctx
, item
);
561 right
= gcc_jit_lvalue_as_rvalue(left
);
563 else if(item
-> mode
== MODE_INTEGER
)
565 gcc_jit_type
* int_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_INT
);
566 right
= gcc_jit_context_new_rvalue_from_int(gcc_context
, int_type
, item
-> integer
);
568 else if(item
-> mode
== MODE_BOOLEAN
)
570 gcc_jit_type
* bool_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_BOOL
);
573 right
= gcc_jit_context_one(gcc_context
, bool_type
);
577 right
= gcc_jit_context_zero(gcc_context
, bool_type
);
580 else if(item
-> mode
== MODE_CALL
)
582 oberon_type_t
* signature
= item
-> var
-> type
;
583 gen_proc_t
* gen_proc
= item
-> var
-> gen_proc
;
585 int num_args
= item
-> num_args
;
586 gcc_jit_rvalue
*args
[num_args
];
588 oberon_expr_t
* expr
= item
-> args
;
589 oberon_object_t
* arg_param
= signature
-> decl
;
590 for(int i
= 0; i
< num_args
; i
++)
592 if(arg_param
-> class == OBERON_CLASS_VAR_PARAM
)
594 gcc_jit_lvalue
* left
= lvalue_from_expr(ctx
, expr
);
595 args
[i
] = gcc_jit_lvalue_get_address(left
, NULL
);
599 args
[i
] = rvalue_from_expr(ctx
, expr
);
602 arg_param
= arg_param
-> next
;
605 gcc_jit_rvalue
* fnptr
;
606 gcc_jit_function
* func
;
607 switch(item
-> var
-> class)
609 case OBERON_CLASS_PROC
:
610 func
= gen_proc
-> gcc_func
;
611 right
= gcc_jit_context_new_call(
612 gcc_context
, NULL
, func
, num_args
, args
615 case OBERON_CLASS_VAR
:
616 case OBERON_CLASS_VAR_PARAM
:
617 case OBERON_CLASS_PARAM
:
618 fnptr
= gcc_jit_lvalue_as_rvalue(item
-> var
-> gen_var
-> gcc_lvalue
);
619 right
= gcc_jit_context_new_call_through_ptr(
620 gcc_context
, NULL
, fnptr
, num_args
, args
628 else if(item
-> mode
== MODE_INDEX
)
630 gcc_jit_lvalue
* left
= lvalue_from_item(ctx
, item
);
631 right
= gcc_jit_lvalue_as_rvalue(left
);
633 else if(item
-> mode
== MODE_FIELD
)
635 gen_var_t
* gen_var
= item
-> var
-> gen_var
;
636 gcc_jit_field
* gcc_field
= gen_var
-> gcc_field
;
638 gcc_jit_rvalue
* parent
= rvalue_from_item(ctx
, item
-> parent
);
639 right
= gcc_jit_rvalue_access_field(parent
, NULL
, gcc_field
);
641 else if(item
-> mode
== MODE_DEREF
)
643 gcc_jit_lvalue
* left
= lvalue_from_item(ctx
, item
);
644 right
= gcc_jit_lvalue_as_rvalue(left
);
646 else if(item
-> mode
== MODE_NIL
)
648 gcc_jit_type
* type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_VOID_PTR
);
649 right
= gcc_jit_context_null(gcc_context
, type
);
651 else if(item
-> mode
== MODE_NEW
)
653 assert(item
-> result
-> class == OBERON_TYPE_POINTER
);
655 oberon_type_t
* type
= item
-> result
-> base
;
656 int type_size
= oberon_generator_get_type_size(ctx
, type
);
657 int array_size
= type_size
;
659 int num
= item
-> num_args
;
660 oberon_expr_t
* arg
= item
-> args
;
661 for(int i
= 0; i
< num
; i
++)
663 array_size
*= arg
-> item
.integer
;
667 gcc_jit_type
* size_type
;
668 size_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_SIZE_T
);
670 gcc_jit_rvalue
* fnarg
;
671 fnarg
= gcc_jit_context_new_rvalue_from_int(gcc_context
, size_type
, array_size
);
673 gcc_jit_type
* result_type
= item
-> result
-> gen_type
-> gcc_type
;
674 gcc_jit_rvalue
* gcc_alloc
= gcc_jit_lvalue_as_rvalue(gen_context
-> gcc_alloc
);
675 right
= gcc_jit_context_new_call_through_ptr(gcc_context
, NULL
, gcc_alloc
, 1, &fnarg
);
676 right
= gcc_jit_context_new_cast(gcc_context
, NULL
, right
, result_type
);
678 else if(item
-> mode
== MODE_REAL
)
680 gcc_jit_type
* int_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_FLOAT
);
681 right
= gcc_jit_context_new_rvalue_from_int(gcc_context
, int_type
, item
-> real
);
685 oberon_error(ctx
, "rvalue_from_item: invalid mode %i", item
-> mode
);
692 int type
; // 0 - unary, 1 - binary, 2 - comp
694 enum gcc_jit_unary_op unary_op
;
695 enum gcc_jit_binary_op binary_op
;
696 enum gcc_jit_comparison comp_op
;
699 { 0, .unary_op
= GCC_JIT_UNARY_OP_MINUS
},
700 { 0, .unary_op
= GCC_JIT_UNARY_OP_BITWISE_NEGATE
},
701 { 0, .unary_op
= GCC_JIT_UNARY_OP_LOGICAL_NEGATE
},
702 { 0, .unary_op
= GCC_JIT_UNARY_OP_ABS
},
704 { 1, .binary_op
= GCC_JIT_BINARY_OP_PLUS
},
705 { 1, .binary_op
= GCC_JIT_BINARY_OP_MINUS
},
706 { 1, .binary_op
= GCC_JIT_BINARY_OP_MULT
},
707 { 1, .binary_op
= GCC_JIT_BINARY_OP_DIVIDE
},
708 { 1, .binary_op
= GCC_JIT_BINARY_OP_MODULO
},
709 { 1, .binary_op
= GCC_JIT_BINARY_OP_BITWISE_AND
},
710 { 1, .binary_op
= GCC_JIT_BINARY_OP_BITWISE_XOR
},
711 { 1, .binary_op
= GCC_JIT_BINARY_OP_BITWISE_OR
},
712 { 1, .binary_op
= GCC_JIT_BINARY_OP_LOGICAL_AND
},
713 { 1, .binary_op
= GCC_JIT_BINARY_OP_LOGICAL_OR
},
715 { 2, .comp_op
= GCC_JIT_COMPARISON_EQ
},
716 { 2, .comp_op
= GCC_JIT_COMPARISON_NE
},
717 { 2, .comp_op
= GCC_JIT_COMPARISON_LT
},
718 { 2, .comp_op
= GCC_JIT_COMPARISON_LE
},
719 { 2, .comp_op
= GCC_JIT_COMPARISON_GT
},
720 { 2, .comp_op
= GCC_JIT_COMPARISON_GE
}
723 static gcc_jit_rvalue
*
724 rvalue_from_operator(oberon_context_t
* ctx
, oberon_oper_t
* operator)
726 gcc_jit_rvalue
* right
;
728 gen_context_t
* gen_context
= ctx
-> gen_context
;
729 gen_type_t
* gen_type
= operator -> result
-> gen_type
;
730 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
731 gcc_jit_type
* result_type
= gen_type
-> gcc_type
;
733 int expr_type
= op_table
[operator -> op
].type
;
736 enum gcc_jit_unary_op op
= op_table
[operator -> op
].unary_op
;
737 gcc_jit_rvalue
* l
= rvalue_from_expr(ctx
, operator -> left
);
738 right
= gcc_jit_context_new_unary_op(gcc_context
, NULL
, op
, result_type
, l
);
740 else if(expr_type
== 1)
742 enum gcc_jit_unary_op op
= op_table
[operator -> op
].binary_op
;
743 gcc_jit_rvalue
* l
= rvalue_from_expr(ctx
, operator -> left
);
744 gcc_jit_rvalue
* r
= rvalue_from_expr(ctx
, operator -> right
);
745 right
= gcc_jit_context_new_binary_op(gcc_context
, NULL
, op
, result_type
, l
, r
);
747 else if(expr_type
== 2)
749 enum gcc_jit_comparison op
= op_table
[operator -> op
].comp_op
;
750 gcc_jit_rvalue
* l
= rvalue_from_expr(ctx
, operator -> left
);
751 gcc_jit_rvalue
* r
= rvalue_from_expr(ctx
, operator -> right
);
752 right
= gcc_jit_context_new_comparison(gcc_context
, NULL
, op
, l
, r
);
756 oberon_error(ctx
, "rvalue_from_operator: wat");
762 static gcc_jit_rvalue
*
763 rvalue_from_expr(oberon_context_t
* ctx
, oberon_expr_t
* expr
)
765 gcc_jit_rvalue
* right
;
769 oberon_item_t
* item
= (oberon_item_t
*) expr
;
770 right
= rvalue_from_item(ctx
, item
);
774 oberon_oper_t
* operator = (oberon_oper_t
*) expr
;
775 right
= rvalue_from_operator(ctx
, operator);
782 oberon_generate_assign(oberon_context_t
* ctx
, oberon_expr_t
* src
, oberon_expr_t
* dst
)
784 gcc_jit_lvalue
* left
;
785 left
= lvalue_from_expr(ctx
, dst
);
787 gcc_jit_rvalue
* right
;
788 right
= rvalue_from_expr(ctx
, src
);
792 if(src
-> item
.mode
== MODE_NIL
)
794 gen_context_t
* gen_context
= ctx
-> gen_context
;
795 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
796 gen_type_t
* gen_type
= dst
-> result
-> gen_type
;
797 gcc_jit_type
* cast_to_type
= gen_type
-> gcc_type
;
798 right
= gcc_jit_context_new_cast(gcc_context
, NULL
, right
, cast_to_type
);
802 printf("oberon_generate_assign: class %i := class %i\n", dst
-> result
-> class, src
-> result
-> class);
804 gen_context_t
* gen_context
= ctx
-> gen_context
;
805 gen_block_t
* gen_block
= gen_context
-> block
;
806 gcc_jit_block
* gcc_block
= gen_block
-> gcc_block
;
807 gcc_jit_block_add_assignment(gcc_block
, NULL
, left
, right
);
811 oberon_generate_code(oberon_context_t
* ctx
)
813 gen_context_t
* gen_context
= ctx
-> gen_context
;
814 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
816 gcc_jit_result
* gcc_result
;
817 gcc_result
= gcc_jit_context_compile(gcc_context
);
819 gen_context
-> gcc_result
= gcc_result
;
821 typedef void * (*TOberonAlloc
)(size_t);
822 TOberonAlloc
* fn_alloc_ptr
= gcc_jit_result_get_global(gcc_result
, "__OBERON_ALLOC__");
823 *fn_alloc_ptr
= __OBERON_ALLOC__
;
825 // ctx -> mod -> begin = gcc_jit_result_get_code(gcc_result, "BEGIN");
829 oberon_generator_dump(oberon_context_t
* ctx
, char * path
)
831 gen_context_t
* gen_context
= ctx
-> gen_context
;
832 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
833 gcc_jit_context_dump_to_file(gcc_context
, path
, 0);
837 oberon_generator_get_procedure(oberon_context_t
* ctx
, const char * name
)
839 gen_context_t
* gen_context
= ctx
-> gen_context
;
840 gcc_jit_result
* gcc_result
= gen_context
-> gcc_result
;
842 return gcc_jit_result_get_code(gcc_result
, name
);
846 oberon_generator_get_var(oberon_context_t
* ctx
, const char * name
)
848 gen_context_t
* gen_context
= ctx
-> gen_context
;
849 gcc_jit_result
* gcc_result
= gen_context
-> gcc_result
;
851 return gcc_jit_result_get_global(gcc_result
, name
);