MEM_VECTOR_INIT(self, values);
MEM_VECTOR_INIT(self, locals);
+ self->code_function_def = -1;
+
self->run_id = 0;
return self;
}
in = ir_instr_new(self, INSTR_CALL0);
if (!in)
return NULL;
- out = ir_value_out(self->owner, label, store_return, func->outtype);
+ out = ir_value_out(self->owner, label, (func->outtype == TYPE_VOID) ? store_return : store_value, func->outtype);
if (!out) {
ir_instr_delete(in);
return NULL;
function_allocator alloc;
- if (!self->locals_count)
+ if (!self->locals_count && !self->values_count)
return true;
MEM_VECTOR_INIT(&alloc, locals);
self->allocated_locals = pos + alloc.sizes[alloc.sizes_count-1];
/* Take over the actual slot positions */
- for (i = 0; i < self->values_count; ++i)
+ for (i = 0; i < self->values_count; ++i) {
self->values[i]->code.local = alloc.positions[self->values[i]->code.local];
+ }
goto cleanup;
*write = 0;
*read = 1;
break;
+ case INSTR_STOREP_F:
+ case INSTR_STOREP_V:
+ case INSTR_STOREP_S:
+ case INSTR_STOREP_ENT:
+ case INSTR_STOREP_FLD:
+ case INSTR_STOREP_FNC:
+ *write = 0;
+ *read = 7;
+ break;
default:
*write = 1;
*read = 6;
#endif
}
+ /* call params are read operands too */
+ for (p = 0; p < instr->params_count; ++p)
+ {
+ value = instr->params[p];
+#if ! defined(LIFE_RANGE_WITHOUT_LAST_READ)
+ if (!ir_block_living_find(self, value, NULL) &&
+ !ir_block_living_add(self, value))
+ {
+ goto on_error;
+ }
+#else
+ if (!new_reads_t_v_find(&new_reads, value, NULL))
+ {
+ if (!new_reads_t_v_add(&new_reads, value))
+ goto on_error;
+ }
+#endif
+ }
+
/* See which operands are read and write operands */
ir_op_read_write(instr->opcode, &read, &write);
fun.firstlocal = code_globals_elements;
fun.locals = irfun->allocated_locals + irfun->locals_count;
- local_var_end = 0;
+ local_var_end = fun.firstlocal;
for (i = 0; i < irfun->locals_count; ++i) {
if (!ir_builder_gen_global(ir, irfun->locals[i])) {
- irerror(irfun->locals[i]->context, "Failed to generate global %s\n", irfun->locals[i]->name);
+ irerror(irfun->locals[i]->context, "Failed to generate local %s", irfun->locals[i]->name);
return false;
}
}
ir_value *v = irfun->values[i];
ir_value_code_setaddr(v, local_var_end + v->code.local);
}
- for (i = 0; i < irfun->locals_count; ++i) {
+ for (i = 0; i < irfun->allocated_locals; ++i) {
/* fill the locals with zeros */
code_globals_add(0);
}
if (irfun->builtin)
fun.entry = irfun->builtin;
else {
+ irfun->code_function_def = code_functions_elements;
fun.entry = code_statements_elements;
+ /* done in second pass: gen_global_function_code!
if (!gen_function_code(irfun)) {
- irerror(irfun->context, "Failed to generate code for function %s\n", irfun->name);
+ irerror(irfun->context, "Failed to generate code for function %s", irfun->name);
return false;
}
+ */
}
return (code_functions_add(fun) >= 0);
}
+static bool gen_global_function_code(ir_builder *ir, ir_value *global)
+{
+ prog_section_function *fundef;
+ ir_function *irfun;
+
+ irfun = global->constval.vfunc;
+ if (irfun->builtin)
+ return true;
+
+ if (irfun->code_function_def < 0) {
+ irerror(irfun->context, "`%s`: IR global wasn't generated, failed to access function-def", irfun->name);
+ return false;
+ }
+ fundef = &code_functions_data[irfun->code_function_def];
+
+ fundef->entry = code_statements_elements;
+ if (!gen_function_code(irfun)) {
+ irerror(irfun->context, "Failed to generate code for function %s", irfun->name);
+ return false;
+ }
+ return true;
+}
+
static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
{
size_t i;
}
}
+ /* generate function code */
+ for (i = 0; i < self->globals_count; ++i)
+ {
+ if (self->globals[i]->vtype == TYPE_FUNCTION) {
+ if (!gen_global_function_code(self, self->globals[i])) {
+ return false;
+ }
+ }
+ }
+
printf("writing '%s'...\n", filename);
return code_write(filename);
}