12 #include "generator.h"
14 // =======================================================================
16 // =======================================================================
19 __OBERON_ALLOC__ (size_t bytes
)
21 void * p
= GC_MALLOC(bytes
);
23 printf("allocated %lu bytes\n", bytes
);
27 // =======================================================================
29 // =======================================================================
32 oberon_generator_open_block(gen_context_t
* gen_context
, gcc_jit_block
* gcc_block
)
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
;
44 oberon_generator_close_block(gen_context_t
* gen_context
)
46 gen_context
-> block
= gen_context
-> block
-> up
;
50 oberon_generator_init_context(oberon_context_t
* ctx
)
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
66 gen_context
-> gcc_alloc
= gcc_jit_context_new_global(
67 gcc_context
, NULL
, GCC_JIT_GLOBAL_EXPORTED
, alloc_ptr_type
, "__OBERON_ALLOC__"
72 oberon_generator_destroy_context(oberon_context_t
* ctx
)
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
);
81 oberon_generator_init_type(oberon_context_t
* ctx
, oberon_type_t
* type
)
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
)
94 gcc_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_VOID
);
96 else if(type
-> class == OBERON_TYPE_INTEGER
)
98 gcc_type
= gcc_jit_context_get_int_type(gcc_context
, type
-> size
, 1);
100 else if(type
-> class == OBERON_TYPE_BOOLEAN
)
102 gcc_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_BOOL
);
104 else if(type
-> class == OBERON_TYPE_ARRAY
)
106 gen_type_t
* gen_base
= type
-> base
-> gen_type
;
107 gcc_jit_type
* gcc_base
= gen_base
-> gcc_type
;
108 gcc_type
= gcc_jit_context_new_array_type(gcc_context
, NULL
, gcc_base
, type
-> size
);
110 else if(type
-> class == OBERON_TYPE_RECORD
)
113 snprintf(name
, 32, "RECORD%u", gen_context
-> record_count
);
114 gen_context
-> record_count
+= 1;
116 gcc_struct
= gcc_jit_context_new_opaque_struct(gcc_context
, NULL
, name
);
117 gcc_type
= gcc_jit_struct_as_type(gcc_struct
);
119 else if(type
-> class == OBERON_TYPE_POINTER
)
121 gen_type_t
* gen_base
= type
-> base
-> gen_type
;
122 gcc_jit_type
* gcc_base
= gen_base
-> gcc_type
;
123 gcc_type
= gcc_jit_type_get_pointer(gcc_base
);
125 else if(type
-> class == OBERON_TYPE_PROCEDURE
)
127 int num_params
= type
-> num_decl
;
128 gcc_jit_type
* params
[num_params
];
129 oberon_object_t
* o
= type
-> decl
;
130 for(int i
= 0; i
< num_params
; i
++)
132 gen_type_t
* gen_type
= o
-> type
-> gen_type
;
133 params
[i
] = gen_type
-> gcc_type
;
137 gen_type_t
* base
= type
-> base
-> gen_type
;
138 gcc_jit_type
* result_type
= base
-> gcc_type
;
140 gcc_type
= gcc_jit_context_new_function_ptr_type(
141 gcc_context
, NULL
, result_type
, num_params
, params
, 0
146 oberon_error(ctx
, "oberon_generator_init_type: invalid type class %i", type
-> class);
150 gen_type
-> gcc_type
= gcc_type
;
151 gen_type
-> gcc_struct
= gcc_struct
;
155 oberon_generator_init_record(oberon_context_t
* ctx
, oberon_type_t
* type
)
157 assert(type
-> class == OBERON_TYPE_RECORD
);
159 gen_type_t
* gen_type
= type
-> gen_type
;
160 gcc_jit_struct
* gcc_struct
= gen_type
-> gcc_struct
;
162 // TODO type exstension
164 int num_fields
= type
-> num_decl
;
165 gcc_jit_field
* fields
[num_fields
];
166 oberon_object_t
* o
= type
-> decl
;
167 for(int i
= 0; i
< num_fields
; i
++)
169 assert(o
-> class == OBERON_CLASS_FIELD
);
170 gen_var_t
* var
= o
-> gen_var
;
171 fields
[i
] = var
-> gcc_field
;
175 gcc_jit_struct_set_fields (gcc_struct
, NULL
, num_fields
, fields
);
177 //gcc_struct = gcc_jit_context_new_struct_type(gcc_context, NULL, "", num_fields, fields);
181 oberon_generator_get_full_name(char * name
, int max_len
, oberon_object_t
* x
)
189 int add_module_prefix
;
192 case OBERON_CLASS_FIELD
:
193 case OBERON_CLASS_PARAM
:
194 case OBERON_CLASS_VAR_PARAM
:
195 /* В локальных областях префиксы излишни */
196 add_module_prefix
= 0;
199 add_module_prefix
= 1;
204 oberon_generator_get_full_name(parent
, 256, x
-> parent
);
206 if(strlen(parent
) > 0)
208 snprintf(name
, max_len
, "%s_%s", parent
, x
-> name
);
210 else if(add_module_prefix
)
212 snprintf(name
, max_len
, "%s_%s", x
-> module
-> name
, x
-> name
);
216 snprintf(name
, max_len
, "%s", x
-> name
);
221 oberon_generator_init_var(oberon_context_t
* ctx
, oberon_object_t
* var
)
223 gen_context_t
* gen_context
= ctx
-> gen_context
;
224 gen_type_t
* gen_type
= var
-> type
-> gen_type
;
226 gen_var_t
* gen_var
= malloc(sizeof *gen_var
);
227 memset(gen_var
, 0, sizeof *gen_var
);
228 var
-> gen_var
= gen_var
;
230 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
231 gcc_jit_type
* gcc_type
= gen_type
-> gcc_type
;
234 oberon_generator_get_full_name(name
, 256, var
);
236 gcc_jit_lvalue
* gcc_lvalue
= NULL
;
237 gcc_jit_param
* gcc_param
= NULL
;
238 gcc_jit_field
* gcc_field
= NULL
;
239 if(var
-> class == OBERON_CLASS_VAR
)
243 gen_proc_t
* gen_func
= var
-> parent
-> gen_proc
;
244 gcc_jit_function
* func
= gen_func
-> gcc_func
;
246 gcc_lvalue
= gcc_jit_function_new_local(func
, NULL
, gcc_type
, name
);
250 gcc_lvalue
= gcc_jit_context_new_global(
251 gcc_context
, NULL
, GCC_JIT_GLOBAL_EXPORTED
, gcc_type
, name
255 else if(var
-> class == OBERON_CLASS_PARAM
)
257 gcc_param
= gcc_jit_context_new_param(gcc_context
, NULL
, gcc_type
, name
);
258 gcc_lvalue
= gcc_jit_param_as_lvalue(gcc_param
);
260 else if(var
-> class == OBERON_CLASS_VAR_PARAM
)
262 gcc_type
= gcc_jit_type_get_pointer(gcc_type
);
263 gcc_param
= gcc_jit_context_new_param(gcc_context
, NULL
, gcc_type
, name
);
264 gcc_lvalue
= gcc_jit_param_as_lvalue(gcc_param
);
266 else if(var
-> class == OBERON_CLASS_FIELD
)
268 gcc_field
= gcc_jit_context_new_field(gcc_context
, NULL
, gcc_type
, name
);
272 oberon_error(ctx
, "oberon_generator_init_var: invalid class %i", var
-> class);
275 gen_var
-> gcc_lvalue
= gcc_lvalue
;
276 gen_var
-> gcc_param
= gcc_param
;
277 gen_var
-> gcc_field
= gcc_field
;
281 oberon_generator_init_proc(oberon_context_t
* ctx
, oberon_object_t
* proc
)
285 oberon_error(ctx
, "generator: local procedures not supported");
288 gen_context_t
* gen_context
= ctx
-> gen_context
;
289 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
291 gen_proc_t
* gen_proc
= malloc(sizeof *gen_proc
);
292 memset(gen_proc
, 0, sizeof *gen_proc
);
293 proc
-> gen_proc
= gen_proc
;
296 oberon_generator_get_full_name(name
, 256, proc
);
298 gen_type_t
* gen_result_type
= proc
-> type
-> base
-> gen_type
;
299 gcc_jit_type
* result_type
= gen_result_type
-> gcc_type
;
301 /* Строим список параметров */
302 int num_param
= proc
-> type
-> num_decl
;
303 oberon_object_t
* o
= proc
-> type
-> decl
;
304 gcc_jit_param
* params
[num_param
];
305 for(int i
= 0; i
< num_param
; i
++)
307 gen_var_t
* param_var
= o
-> gen_var
;
308 params
[i
] = param_var
-> gcc_param
;
312 gcc_jit_function
* gcc_func
;
313 gcc_func
= gcc_jit_context_new_function(
314 gcc_context
, NULL
, GCC_JIT_FUNCTION_EXPORTED
, result_type
, name
, num_param
, params
, 0
317 gen_proc
-> gcc_func
= gcc_func
;
320 // =======================================================================
322 // =======================================================================
324 static gcc_jit_rvalue
* rvalue_from_item(oberon_context_t
* ctx
, oberon_item_t
* item
);
325 static gcc_jit_rvalue
* rvalue_from_expr(oberon_context_t
* ctx
, oberon_expr_t
* expr
);
328 oberon_generator_get_type_size(oberon_context_t
* ctx
, oberon_type_t
* type
)
331 switch(type
-> class)
333 case OBERON_TYPE_INTEGER
:
335 printf("int size: %i\n", size
);
337 case OBERON_TYPE_BOOLEAN
:
339 printf("bool size: %i\n", size
);
341 case OBERON_TYPE_PROCEDURE
:
342 case OBERON_TYPE_POINTER
:
343 size
= sizeof(void*);
344 printf("ptr size: %i\n", size
);
346 case OBERON_TYPE_ARRAY
:
349 size
*= oberon_generator_get_type_size(ctx
, type
);
350 printf("array size: %i\n", size
);
352 case OBERON_TYPE_RECORD
:
354 int num
= type
-> num_decl
;
355 oberon_object_t
* arg
= type
-> decl
;
356 for(int i
= 0; i
< num
; i
++)
360 size
+= oberon_generator_get_type_size(ctx
, x
);
364 printf("struct size: %i\n", size
);
367 oberon_error(ctx
, "oberon_generator_get_type_size: wat");
375 oberon_generate_begin_module(oberon_context_t
* ctx
)
377 gen_context_t
* gen_context
= ctx
-> gen_context
;
378 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
381 snprintf(name
, 256, "%s_BEGIN", ctx
-> mod
-> name
);
383 gcc_jit_type
* void_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_VOID
);
384 gcc_jit_function
* func
= gcc_jit_context_new_function(
385 gcc_context
, NULL
, GCC_JIT_FUNCTION_EXPORTED
, void_type
, name
, 0, NULL
, 0
387 gcc_jit_block
* gcc_block
= gcc_jit_function_new_block(func
, NULL
);
389 oberon_generator_open_block(gen_context
, gcc_block
);
393 oberon_generate_end_module(oberon_context_t
* ctx
)
395 gen_context_t
* gen_context
= ctx
-> gen_context
;
396 gcc_jit_block
* gcc_block
= gen_context
-> block
-> gcc_block
;
398 gcc_jit_block_end_with_void_return(gcc_block
, NULL
);
400 oberon_generator_close_block(gen_context
);
404 oberon_generate_begin_proc(oberon_context_t
* ctx
, oberon_object_t
* proc
)
406 gen_context_t
* gen_context
= ctx
-> gen_context
;
407 gen_proc_t
* gen_proc
= proc
-> gen_proc
;
409 gcc_jit_function
* func
= gen_proc
-> gcc_func
;
410 gcc_jit_block
* gcc_block
= gcc_jit_function_new_block(func
, NULL
);
412 oberon_generator_open_block(gen_context
, gcc_block
);
416 oberon_generate_call_proc(oberon_context_t
* ctx
, oberon_expr_t
* desig
)
418 gen_context_t
* gen_context
= ctx
-> gen_context
;
419 gen_block_t
* gen_block
= gen_context
-> block
;
420 gcc_jit_block
* block
= gen_block
-> gcc_block
;
422 gcc_jit_rvalue
* return_value
;
423 return_value
= rvalue_from_expr(ctx
, desig
);
424 gcc_jit_block_add_eval(block
, NULL
, return_value
);
428 oberon_generate_end_proc(oberon_context_t
* ctx
)
430 gen_context_t
* gen_context
= ctx
-> gen_context
;
431 oberon_generator_close_block(gen_context
);
435 oberon_generate_return(oberon_context_t
* ctx
, oberon_expr_t
* expr
)
437 gen_context_t
* gen_context
= ctx
-> gen_context
;
438 gen_block_t
* gen_block
= gen_context
-> block
;
439 gcc_jit_block
* gcc_block
= gen_block
-> gcc_block
;
443 gcc_jit_block_end_with_void_return(gcc_block
, NULL
);
447 gcc_jit_rvalue
* r
= rvalue_from_expr(ctx
, expr
);
448 gcc_jit_block_end_with_return(gcc_block
, NULL
, r
);
452 static gcc_jit_lvalue
*
453 lvalue_from_item(oberon_context_t
* ctx
, oberon_item_t
* item
)
455 gen_context_t
* gen_context
= ctx
-> gen_context
;
456 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
458 gcc_jit_lvalue
* left
;
460 if(item
-> mode
== MODE_VAR
)
462 if(item
-> var
-> class == OBERON_CLASS_PROC
)
464 oberon_error(ctx
, "casting static procedure to pointer not supported by generator");
467 gen_var_t
* gen_var
= item
-> var
-> gen_var
;
468 left
= gen_var
-> gcc_lvalue
;
469 if(item
-> var
-> class == OBERON_CLASS_VAR_PARAM
)
471 gcc_jit_rvalue
* r
= gcc_jit_lvalue_as_rvalue(left
);
472 left
= gcc_jit_rvalue_dereference(r
, NULL
);
475 else if(item
-> mode
== MODE_INDEX
)
477 assert(item
-> num_args
== 1);
478 gcc_jit_rvalue
* parent
= rvalue_from_item(ctx
, item
-> parent
);
479 gcc_jit_rvalue
* index
= rvalue_from_expr(ctx
, item
-> args
);
480 left
= gcc_jit_context_new_array_access(gcc_context
, NULL
, parent
, index
);
482 else if(item
-> mode
== MODE_FIELD
)
484 printf("lvalue_from_item: %s\n", item
-> var
-> name
);
485 gen_var_t
* gen_var
= item
-> var
-> gen_var
;
486 gcc_jit_field
* gcc_field
= gen_var
-> gcc_field
;
488 gcc_jit_lvalue
* parent
= lvalue_from_item(ctx
, item
-> parent
);
489 left
= gcc_jit_lvalue_access_field(parent
, NULL
, gcc_field
);
491 else if(item
-> mode
== MODE_DEREF
)
493 gcc_jit_rvalue
* parent
= rvalue_from_item(ctx
, item
-> parent
);
494 left
= gcc_jit_rvalue_dereference(parent
, NULL
);
498 oberon_error(ctx
, "lvalue_from_item: invalid mode %i", item
-> mode
);
504 static gcc_jit_lvalue
*
505 lvalue_from_expr(oberon_context_t
*ctx
, oberon_expr_t
* expr
)
507 gcc_jit_lvalue
* left
;
508 oberon_item_t
* item
;
512 item
= (oberon_item_t
*) expr
;
513 left
= lvalue_from_item(ctx
, item
);
517 oberon_error(ctx
, "invalid lvalue expression");
523 static gcc_jit_rvalue
*
524 rvalue_from_item(oberon_context_t
* ctx
, oberon_item_t
* item
)
526 gen_context_t
* gen_context
= ctx
-> gen_context
;
527 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
529 gcc_jit_rvalue
* right
;
530 if(item
-> mode
== MODE_VAR
)
532 gcc_jit_lvalue
* left
= lvalue_from_item(ctx
, item
);
533 right
= gcc_jit_lvalue_as_rvalue(left
);
535 else if(item
-> mode
== MODE_INTEGER
)
537 gcc_jit_type
* int_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_INT
);
538 right
= gcc_jit_context_new_rvalue_from_int(gcc_context
, int_type
, item
-> integer
);
540 else if(item
-> mode
== MODE_BOOLEAN
)
542 gcc_jit_type
* bool_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_BOOL
);
545 right
= gcc_jit_context_one(gcc_context
, bool_type
);
549 right
= gcc_jit_context_zero(gcc_context
, bool_type
);
552 else if(item
-> mode
== MODE_CALL
)
554 oberon_type_t
* signature
= item
-> var
-> type
;
555 gen_proc_t
* gen_proc
= item
-> var
-> gen_proc
;
557 int num_args
= item
-> num_args
;
558 gcc_jit_rvalue
*args
[num_args
];
560 oberon_expr_t
* expr
= item
-> args
;
561 oberon_object_t
* arg_param
= signature
-> decl
;
562 for(int i
= 0; i
< num_args
; i
++)
564 if(arg_param
-> class == OBERON_CLASS_VAR_PARAM
)
566 gcc_jit_lvalue
* left
= lvalue_from_expr(ctx
, expr
);
567 args
[i
] = gcc_jit_lvalue_get_address(left
, NULL
);
571 args
[i
] = rvalue_from_expr(ctx
, expr
);
574 arg_param
= arg_param
-> next
;
577 gcc_jit_rvalue
* fnptr
;
578 gcc_jit_function
* func
;
579 switch(item
-> var
-> class)
581 case OBERON_CLASS_PROC
:
582 func
= gen_proc
-> gcc_func
;
583 right
= gcc_jit_context_new_call(
584 gcc_context
, NULL
, func
, num_args
, args
587 case OBERON_CLASS_VAR
:
588 case OBERON_CLASS_VAR_PARAM
:
589 case OBERON_CLASS_PARAM
:
590 fnptr
= gcc_jit_lvalue_as_rvalue(item
-> var
-> gen_var
-> gcc_lvalue
);
591 right
= gcc_jit_context_new_call_through_ptr(
592 gcc_context
, NULL
, fnptr
, num_args
, args
600 else if(item
-> mode
== MODE_INDEX
)
602 gcc_jit_lvalue
* left
= lvalue_from_item(ctx
, item
);
603 right
= gcc_jit_lvalue_as_rvalue(left
);
605 else if(item
-> mode
== MODE_FIELD
)
607 gen_var_t
* gen_var
= item
-> var
-> gen_var
;
608 gcc_jit_field
* gcc_field
= gen_var
-> gcc_field
;
610 gcc_jit_rvalue
* parent
= rvalue_from_item(ctx
, item
-> parent
);
611 right
= gcc_jit_rvalue_access_field(parent
, NULL
, gcc_field
);
613 else if(item
-> mode
== MODE_DEREF
)
615 gcc_jit_lvalue
* left
= lvalue_from_item(ctx
, item
);
616 right
= gcc_jit_lvalue_as_rvalue(left
);
618 else if(item
-> mode
== MODE_NIL
)
620 gcc_jit_type
* type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_VOID_PTR
);
621 right
= gcc_jit_context_null(gcc_context
, type
);
623 else if(item
-> mode
== MODE_NEW
)
625 assert(item
-> result
-> class == OBERON_TYPE_POINTER
);
627 oberon_type_t
* type
= item
-> result
-> base
;
628 int type_size
= oberon_generator_get_type_size(ctx
, type
);
629 int array_size
= type_size
;
631 int num
= item
-> num_args
;
632 oberon_expr_t
* arg
= item
-> args
;
633 for(int i
= 0; i
< num
; i
++)
635 array_size
*= arg
-> item
.integer
;
639 gcc_jit_type
* size_type
;
640 size_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_SIZE_T
);
642 gcc_jit_rvalue
* fnarg
;
643 fnarg
= gcc_jit_context_new_rvalue_from_int(gcc_context
, size_type
, array_size
);
645 gcc_jit_type
* result_type
= item
-> result
-> gen_type
-> gcc_type
;
646 gcc_jit_rvalue
* gcc_alloc
= gcc_jit_lvalue_as_rvalue(gen_context
-> gcc_alloc
);
647 right
= gcc_jit_context_new_call_through_ptr(gcc_context
, NULL
, gcc_alloc
, 1, &fnarg
);
648 right
= gcc_jit_context_new_cast(gcc_context
, NULL
, right
, result_type
);
652 oberon_error(ctx
, "rvalue_from_item: invalid mode %i", item
-> mode
);
659 int type
; // 0 - unary, 1 - binary, 2 - comp
661 enum gcc_jit_unary_op unary_op
;
662 enum gcc_jit_binary_op binary_op
;
663 enum gcc_jit_comparison comp_op
;
666 { 0, .unary_op
= GCC_JIT_UNARY_OP_MINUS
},
667 { 0, .unary_op
= GCC_JIT_UNARY_OP_BITWISE_NEGATE
},
668 { 0, .unary_op
= GCC_JIT_UNARY_OP_LOGICAL_NEGATE
},
669 { 0, .unary_op
= GCC_JIT_UNARY_OP_ABS
},
671 { 1, .binary_op
= GCC_JIT_BINARY_OP_PLUS
},
672 { 1, .binary_op
= GCC_JIT_BINARY_OP_MINUS
},
673 { 1, .binary_op
= GCC_JIT_BINARY_OP_MULT
},
674 { 1, .binary_op
= GCC_JIT_BINARY_OP_DIVIDE
},
675 { 1, .binary_op
= GCC_JIT_BINARY_OP_MODULO
},
676 { 1, .binary_op
= GCC_JIT_BINARY_OP_BITWISE_AND
},
677 { 1, .binary_op
= GCC_JIT_BINARY_OP_BITWISE_XOR
},
678 { 1, .binary_op
= GCC_JIT_BINARY_OP_BITWISE_OR
},
679 { 1, .binary_op
= GCC_JIT_BINARY_OP_LOGICAL_AND
},
680 { 1, .binary_op
= GCC_JIT_BINARY_OP_LOGICAL_OR
},
682 { 2, .comp_op
= GCC_JIT_COMPARISON_EQ
},
683 { 2, .comp_op
= GCC_JIT_COMPARISON_NE
},
684 { 2, .comp_op
= GCC_JIT_COMPARISON_LT
},
685 { 2, .comp_op
= GCC_JIT_COMPARISON_LE
},
686 { 2, .comp_op
= GCC_JIT_COMPARISON_GT
},
687 { 2, .comp_op
= GCC_JIT_COMPARISON_GE
}
690 static gcc_jit_rvalue
*
691 rvalue_from_operator(oberon_context_t
* ctx
, oberon_oper_t
* operator)
693 gcc_jit_rvalue
* right
;
695 gen_context_t
* gen_context
= ctx
-> gen_context
;
696 gen_type_t
* gen_type
= operator -> result
-> gen_type
;
697 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
698 gcc_jit_type
* result_type
= gen_type
-> gcc_type
;
700 int expr_type
= op_table
[operator -> op
].type
;
703 enum gcc_jit_unary_op op
= op_table
[operator -> op
].unary_op
;
704 gcc_jit_rvalue
* l
= rvalue_from_expr(ctx
, operator -> left
);
705 right
= gcc_jit_context_new_unary_op(gcc_context
, NULL
, op
, result_type
, l
);
707 else if(expr_type
== 1)
709 enum gcc_jit_unary_op op
= op_table
[operator -> op
].binary_op
;
710 gcc_jit_rvalue
* l
= rvalue_from_expr(ctx
, operator -> left
);
711 gcc_jit_rvalue
* r
= rvalue_from_expr(ctx
, operator -> right
);
712 right
= gcc_jit_context_new_binary_op(gcc_context
, NULL
, op
, result_type
, l
, r
);
714 else if(expr_type
== 2)
716 enum gcc_jit_comparison op
= op_table
[operator -> op
].comp_op
;
717 gcc_jit_rvalue
* l
= rvalue_from_expr(ctx
, operator -> left
);
718 gcc_jit_rvalue
* r
= rvalue_from_expr(ctx
, operator -> right
);
719 right
= gcc_jit_context_new_comparison(gcc_context
, NULL
, op
, l
, r
);
723 oberon_error(ctx
, "rvalue_from_operator: wat");
729 static gcc_jit_rvalue
*
730 rvalue_from_expr(oberon_context_t
* ctx
, oberon_expr_t
* expr
)
732 gcc_jit_rvalue
* right
;
736 oberon_item_t
* item
= (oberon_item_t
*) expr
;
737 right
= rvalue_from_item(ctx
, item
);
741 oberon_oper_t
* operator = (oberon_oper_t
*) expr
;
742 right
= rvalue_from_operator(ctx
, operator);
749 oberon_generate_assign(oberon_context_t
* ctx
, oberon_expr_t
* src
, oberon_expr_t
* dst
)
751 gcc_jit_lvalue
* left
;
752 left
= lvalue_from_expr(ctx
, dst
);
754 gcc_jit_rvalue
* right
;
755 right
= rvalue_from_expr(ctx
, src
);
759 if(src
-> item
.mode
== MODE_NIL
)
761 gen_context_t
* gen_context
= ctx
-> gen_context
;
762 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
763 gen_type_t
* gen_type
= dst
-> result
-> gen_type
;
764 gcc_jit_type
* cast_to_type
= gen_type
-> gcc_type
;
765 right
= gcc_jit_context_new_cast(gcc_context
, NULL
, right
, cast_to_type
);
769 printf("oberon_generate_assign: class %i := class %i\n", dst
-> result
-> class, src
-> result
-> class);
771 gen_context_t
* gen_context
= ctx
-> gen_context
;
772 gen_block_t
* gen_block
= gen_context
-> block
;
773 gcc_jit_block
* gcc_block
= gen_block
-> gcc_block
;
774 gcc_jit_block_add_assignment(gcc_block
, NULL
, left
, right
);
778 oberon_generate_code(oberon_context_t
* ctx
)
780 gen_context_t
* gen_context
= ctx
-> gen_context
;
781 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
783 gcc_jit_result
* gcc_result
;
784 gcc_result
= gcc_jit_context_compile(gcc_context
);
786 gen_context
-> gcc_result
= gcc_result
;
788 typedef void * (*TOberonAlloc
)(size_t);
789 TOberonAlloc
* fn_alloc_ptr
= gcc_jit_result_get_global(gcc_result
, "__OBERON_ALLOC__");
790 *fn_alloc_ptr
= __OBERON_ALLOC__
;
792 // ctx -> mod -> begin = gcc_jit_result_get_code(gcc_result, "BEGIN");
796 oberon_generator_dump(oberon_context_t
* ctx
, char * path
)
798 gen_context_t
* gen_context
= ctx
-> gen_context
;
799 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
800 gcc_jit_context_dump_to_file(gcc_context
, path
, 0);
804 oberon_generator_get_procedure(oberon_context_t
* ctx
, const char * name
)
806 gen_context_t
* gen_context
= ctx
-> gen_context
;
807 gcc_jit_result
* gcc_result
= gen_context
-> gcc_result
;
809 return gcc_jit_result_get_code(gcc_result
, name
);
813 oberon_generator_get_var(oberon_context_t
* ctx
, const char * name
)
815 gen_context_t
* gen_context
= ctx
-> gen_context
;
816 gcc_jit_result
* gcc_result
= gen_context
-> gcc_result
;
818 return gcc_jit_result_get_global(gcc_result
, name
);