c633e542131722832c5d586e732e18d7f04d85f2
11 #include <libgccjit.h>
14 * oberon_var_t -> gvar == gcc_jit_lvalue;
15 * oberon_type_t -> gtype == gcc_jit_type;
16 * oberon_context_t -> gctx == gen_context_t;
21 gcc_jit_context
* gcc_context
;
22 gcc_jit_block
* gcc_block
;
23 gcc_jit_result
* gcc_result
;
26 static void printcontext(oberon_context_t
* ctx
, char * s
)
29 gen_context_t * gen_context = ctx -> gen_context;
30 gcc_jit_context * gcc_context = gen_context -> gcc_context;
31 gcc_jit_block * gcc_block = gen_context -> gcc_block;
34 printf(" ctx = %p:\n", ctx);
35 printf(" gctx = %p:\n", gctx);
36 printf(" context = %p:\n", context);
37 printf(" block = %p:\n", block);
41 // =======================================================================
43 // =======================================================================
46 oberon_generator_init_context(oberon_context_t
* ctx
)
48 gen_context_t
* gen_context
= malloc(sizeof *gen_context
);
49 memset(gen_context
, 0, sizeof *gen_context
);
51 gcc_jit_context
* gcc_context
;
52 gcc_context
= gcc_jit_context_acquire();
54 ctx
-> gen_context
= gen_context
;
55 gen_context
-> gcc_context
= gcc_context
;
57 printcontext(ctx
, "oberon_generator_init_context");
61 oberon_generator_destroy_context(oberon_context_t
* ctx
)
63 printcontext(ctx
, "oberon_generator_destroy_context");
65 gen_context_t
* gen_context
= ctx
-> gen_context
;
66 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
68 gcc_jit_context_release(gcc_context
);
72 oberon_generator_init_type(oberon_context_t
* ctx
, oberon_type_t
* type
)
74 printcontext(ctx
, "oberon_generator_init_type");
76 gen_context_t
* gen_context
= ctx
-> gen_context
;
77 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
79 gcc_jit_type
* gen_type
;
80 if(type
-> class == OBERON_TYPE_INTEGER
)
82 gen_type
= gcc_jit_context_get_int_type(gcc_context
, type
-> size
, 1);
84 else if(type
-> class == OBERON_TYPE_BOOLEAN
)
86 gen_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_BOOL
);
90 oberon_error(ctx
, "oberon_generator_init_type: invalid type class %i", type
-> class);
93 type
-> gen_type
= gen_type
;
97 oberon_generator_init_var(oberon_context_t
* ctx
, oberon_var_t
* var
)
99 printcontext(ctx
, "oberon_generator_init_var");
101 gen_context_t
* gen_context
= ctx
-> gen_context
;
102 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
103 gcc_jit_type
* gen_type
= var
-> type
-> gen_type
;
104 const char * name
= var
-> name
;
106 gcc_jit_lvalue
* gen_var
;
107 gen_var
= gcc_jit_context_new_global(gcc_context
, NULL
, GCC_JIT_GLOBAL_INTERNAL
, gen_type
, name
);
109 var
-> gen_var
= gen_var
;
112 // =======================================================================
114 // =======================================================================
116 static gcc_jit_rvalue
*
117 oberon_generate_rvalue_from_item(oberon_context_t
* ctx
, oberon_item_t
* item
)
119 printcontext(ctx
, "oberon_generate_rvalue_from_item");
121 gen_context_t
* gen_context
= ctx
-> gen_context
;
122 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
124 gcc_jit_rvalue
* right
;
125 if(item
-> mode
== MODE_VAR
)
127 gcc_jit_lvalue
* gen_var
= item
-> var
-> gen_var
;
128 right
= gcc_jit_lvalue_as_rvalue(gen_var
);
129 printf("PUSH (var) %s\n", item
-> var
-> name
);
131 else if(item
-> mode
== MODE_INTEGER
)
133 gcc_jit_type
* int_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_INT
);
134 right
= gcc_jit_context_new_rvalue_from_int(gcc_context
, int_type
, item
-> integer
);
135 printf("PUSH (int) %i\n", item
-> integer
);
137 else if(item
-> mode
== MODE_BOOLEAN
)
139 gcc_jit_type
* bool_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_BOOL
);
142 right
= gcc_jit_context_one(gcc_context
, bool_type
);
146 right
= gcc_jit_context_zero(gcc_context
, bool_type
);
148 printf("PUSH (bool) %i\n", item
-> boolean
);
152 oberon_error(ctx
, "oberon_generate_push: invalid mode %i", item
-> mode
);
159 oberon_generate_begin_module(oberon_context_t
* ctx
)
161 printcontext(ctx
, "oberon_generate_begin_module");
163 gen_context_t
* gen_context
= ctx
-> gen_context
;
164 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
166 gcc_jit_type
* void_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_VOID
);
167 gcc_jit_function
* func
= gcc_jit_context_new_function(
168 gcc_context
, NULL
, GCC_JIT_FUNCTION_EXPORTED
, void_type
, "BEGIN", 0, NULL
, 0
170 gcc_jit_block
* gcc_block
= gcc_jit_function_new_block(func
, NULL
);
172 gen_context
-> gcc_block
= gcc_block
;
176 oberon_generate_end_module(oberon_context_t
* ctx
)
178 printcontext(ctx
, "oberon_generate_end_module");
180 gen_context_t
* gen_context
= ctx
-> gen_context
;
181 gcc_jit_block
* gcc_block
= gen_context
-> gcc_block
;
183 gcc_jit_block_end_with_void_return(gcc_block
, NULL
);
185 gen_context
-> gcc_block
= NULL
;
189 oberon_generate_assign(oberon_context_t
* ctx
, oberon_item_t
* src
, oberon_item_t
* dst
)
191 printcontext(ctx
, "oberon_generate_assign");
193 gen_context_t
* gen_context
= ctx
-> gen_context
;
194 gcc_jit_block
* gcc_block
= gen_context
-> gcc_block
;
196 gcc_jit_lvalue
* left
;
197 gcc_jit_rvalue
* right
;
199 right
= oberon_generate_rvalue_from_item(ctx
, src
);
201 if(dst
-> mode
== MODE_VAR
)
203 printf("STORE %s\n", dst
-> var
-> name
);
204 left
= dst
-> var
-> gen_var
;
208 oberon_error(ctx
, "oberon_generate_assign: invalid assignment");
211 gcc_jit_block_add_assignment(gcc_block
, NULL
, left
, right
);
215 oberon_generate_code(oberon_context_t
* ctx
)
217 gen_context_t
* gen_context
= ctx
-> gen_context
;
218 gcc_jit_context
* gcc_context
= gen_context
-> gcc_context
;
220 gcc_jit_result
* gcc_result
;
221 gcc_result
= gcc_jit_context_compile(gcc_context
);
223 gen_context
-> gcc_result
= gcc_result
;
224 ctx
-> mod
-> begin
= gcc_jit_result_get_code(gcc_result
, "BEGIN");