From: Wolfgang (Blub) Bumiller Date: Sun, 18 Nov 2012 19:06:28 +0000 (+0100) Subject: Make functions copy their extparams X-Git-Tag: 0.1.9~404^2~6 X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=commitdiff_plain;h=f023004a677b75d939ab18eda239f0474ae2176e Make functions copy their extparams --- diff --git a/ast.c b/ast.c index 9e59ca9..3fc7353 100644 --- a/ast.c +++ b/ast.c @@ -1247,6 +1247,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) /* fill the parameter list */ ec = &self->vtype->expression; + irf->max_parameters = vec_size(ec->params); for (i = 0; i < vec_size(ec->params); ++i) { vec_push(irf->params, ec->params[i]->expression.vtype); diff --git a/ir.c b/ir.c index f652f6a..1fd94a0 100644 --- a/ir.c +++ b/ir.c @@ -259,6 +259,7 @@ ir_builder* ir_builder_new(const char *modulename) self->functions = NULL; self->globals = NULL; self->fields = NULL; + self->extparams = NULL; self->filenames = NULL; self->filestrings = NULL; @@ -280,6 +281,10 @@ void ir_builder_delete(ir_builder* self) ir_function_delete_quick(self->functions[i]); } vec_free(self->functions); + for (i = 0; i != vec_size(self->extparams); ++i) { + ir_value_delete(self->extparams[i]); + } + vec_free(self->extparams); for (i = 0; i != vec_size(self->globals); ++i) { ir_value_delete(self->globals[i]); } @@ -427,6 +432,8 @@ ir_function* ir_function_new(ir_builder* owner, int outtype) self->values = NULL; self->locals = NULL; + self->max_parameters = 0; + self->code_function_def = -1; self->allocated_locals = 0; @@ -2698,6 +2705,62 @@ static bool gen_global_function(ir_builder *ir, ir_value *global) 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; + + ir_builder *ir = self->owner; + ir_value *ep; + prog_section_statement stmt; + + if (!self->max_parameters) + return true; + + stmt.opcode = INSTR_STORE_F; + stmt.o3.s1 = 0; + for (i = 8; i < self->max_parameters; ++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]); + vec_push(code_statements, stmt); + } + + return true; +} + static bool gen_global_function_code(ir_builder *ir, ir_value *global) { prog_section_function *fundef; @@ -2721,6 +2784,10 @@ static bool gen_global_function_code(ir_builder *ir, ir_value *global) fundef = &code_functions[irfun->code_function_def]; fundef->entry = vec_size(code_statements); + if (!gen_function_extparam_copy(irfun)) { + irerror(irfun->context, "Failed to generate extparam-copy code for function %s", irfun->name); + return false; + } if (!gen_function_code(irfun)) { irerror(irfun->context, "Failed to generate code for function %s", irfun->name); return false; diff --git a/ir.h b/ir.h index 9b5171d..00e2ddc 100644 --- a/ir.h +++ b/ir.h @@ -240,6 +240,9 @@ typedef struct ir_function_s /* locally defined variables */ ir_value **locals; + /* how many of the locals are parameters */ + size_t max_parameters; + size_t allocated_locals; ir_block* first; @@ -290,6 +293,8 @@ typedef struct ir_builder_s ir_value **globals; ir_value **fields; + ir_value **extparams; + const char **filenames; qcint *filestrings; /* we cache the #IMMEDIATE string here */ diff --git a/parser.c b/parser.c index 600b088..25c9c74 100644 --- a/parser.c +++ b/parser.c @@ -2638,7 +2638,7 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var) /* sanity check */ if (vec_size(params) > 8 && opts_standard == COMPILER_QCC) - parsewarning(parser, WARN_EXTENSIONS, "more than 8 parameters are not supported by this standard"); + (void)!parsewarning(parser, WARN_EXTENSIONS, "more than 8 parameters are not supported by this standard"); /* parse-out */ if (!parser_next(parser)) {