+ irfun->code_function_def = vec_size(code_functions);
+ fun.entry = vec_size(code_statements);
+ }
+
+ vec_push(code_functions, fun);
+ return true;
+}
+
+static void ir_gen_extparam(ir_builder *ir)
+{
+ prog_section_def def;
+ ir_value *global;
+ char name[128];
+
+ snprintf(name, sizeof(name), "EXTPARM#%i", (int)(vec_size(ir->extparams)+8));
+ global = ir_value_var(name, store_global, TYPE_VECTOR);
+
+ def.name = code_genstring(name);
+ def.type = TYPE_VECTOR;
+ def.offset = vec_size(code_globals);
+
+ vec_push(code_defs, def);
+ ir_value_code_setaddr(global, def.offset);
+ vec_push(code_globals, 0);
+ vec_push(code_globals, 0);
+ vec_push(code_globals, 0);
+
+ vec_push(ir->extparams, global);
+}
+
+static bool gen_function_extparam_copy(ir_function *self)
+{
+ size_t i, ext, numparams;
+
+ ir_builder *ir = self->owner;
+ ir_value *ep;
+ prog_section_statement stmt;
+
+ numparams = vec_size(self->params);
+ if (!numparams)
+ return true;
+
+ stmt.opcode = INSTR_STORE_F;
+ stmt.o3.s1 = 0;
+ for (i = 8; i < numparams; ++i) {
+ ext = i - 8;
+ if (ext >= vec_size(ir->extparams))
+ ir_gen_extparam(ir);
+
+ ep = ir->extparams[ext];
+
+ stmt.opcode = type_store_instr[self->locals[i]->vtype];
+ if (self->locals[i]->vtype == TYPE_FIELD &&
+ self->locals[i]->fieldtype == TYPE_VECTOR)
+ {
+ stmt.opcode = INSTR_STORE_V;
+ }
+ stmt.o1.u1 = ir_value_code_addr(ep);
+ stmt.o2.u1 = ir_value_code_addr(self->locals[i]);
+ code_push_statement(&stmt, self->context.line);
+ }
+
+ return true;
+}
+
+static bool gen_global_function_code(ir_builder *ir, ir_value *global)
+{
+ prog_section_function *fundef;
+ ir_function *irfun;
+
+ (void)ir;
+
+ irfun = global->constval.vfunc;
+ if (!irfun) {
+ if (global->cvq == CV_NONE) {
+ irwarning(global->context, WARN_IMPLICIT_FUNCTION_POINTER,
+ "function `%s` has no body and in QC implicitly becomes a function-pointer", global->name);