X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=ir.c;h=7f9cdb1e4d7a57359fb3dc14d2fdba8ad6bce021;hb=2bfd27271444c99d02ac8de3135c6a7981b18286;hp=1bf5513de82df32c00b76b6bd28495e3c4c48c79;hpb=49f398036092a9323643c4384a3cbd537edfd5e8;p=xonotic%2Fgmqcc.git diff --git a/ir.c b/ir.c index 1bf5513..7f9cdb1 100644 --- a/ir.c +++ b/ir.c @@ -29,6 +29,23 @@ * Type sizes used at multiple points in the IR codegen */ +const char *type_name[TYPE_COUNT] = { + "void", + "string", + "float", + "vector", + "entity", + "field", + "function", + "pointer", +#if 0 + "integer", +#endif + "quaternion", + "matrix", + "variant" +}; + size_t type_sizeof[TYPE_COUNT] = { 1, /* TYPE_VOID */ 1, /* TYPE_STRING */ @@ -64,7 +81,7 @@ uint16_t type_store_instr[TYPE_COUNT] = { INSTR_STORE_M, /* variant, should never be accessed */ }; -uint16_t type_store_instr[TYPE_COUNT] = { +uint16_t type_storep_instr[TYPE_COUNT] = { INSTR_STOREP_F, /* should use I when having integer support */ INSTR_STOREP_S, INSTR_STOREP_F, @@ -189,9 +206,14 @@ ir_value* ir_builder_get_global(ir_builder *self, const char *name) ir_value* ir_builder_create_global(ir_builder *self, const char *name, int vtype) { - ir_value *ve = ir_builder_get_global(self, name); - if (ve) { - return NULL; + ir_value *ve; + + if (name && name[0] != '#') + { + ve = ir_builder_get_global(self, name); + if (ve) { + return NULL; + } } ve = ir_value_var(name, store_global, vtype); @@ -319,14 +341,21 @@ ir_value* ir_function_get_local(ir_function *self, const char *name) return NULL; } -ir_value* ir_function_create_local(ir_function *self, const char *name, int vtype) +ir_value* ir_function_create_local(ir_function *self, const char *name, int vtype, bool param) { ir_value *ve = ir_function_get_local(self, name); if (ve) { return NULL; } - ve = ir_value_var(name, store_local, vtype); + if (param && + self->locals_count && + self->locals[self->locals_count-1]->store != store_param) { + printf("cannot add parameters after adding locals\n"); + return NULL; + } + + ve = ir_value_var(name, (param ? store_param : store_local), vtype); if (!ir_function_locals_add(self, ve)) { ir_value_delete(ve); return NULL; @@ -579,7 +608,7 @@ bool ir_value_set_quaternion(ir_value *self, quaternion v) { if (self->vtype != TYPE_QUATERNION) return false; - self->constval.vquat = v; + memcpy(&self->constval.vquat, v, sizeof(self->constval.vquat)); self->isconst = true; return true; } @@ -588,7 +617,7 @@ bool ir_value_set_matrix(ir_value *self, matrix v) { if (self->vtype != TYPE_MATRIX) return false; - self->constval.vmat = v; + memcpy(&self->constval.vmat, v, sizeof(self->constval.vmat)); self->isconst = true; return true; } @@ -1153,6 +1182,7 @@ ir_value* ir_block_create_binop(ir_block *self, case INSTR_ADD_V: case INSTR_SUB_V: case INSTR_MUL_VF: + case INSTR_MUL_FV: #if 0 case INSTR_DIV_VF: case INSTR_MUL_IV: @@ -1493,7 +1523,7 @@ static bool ir_block_naive_phi(ir_block *self) if (v->writes[w]->_ops[0] == v) v->writes[w]->_ops[0] = instr->_ops[0]; - if (old->store != store_value && old->store != store_local) + if (old->store != store_value && old->store != store_local && old->store != store_param) { /* If it originally wrote to a global we need to store the value * there as welli @@ -1873,8 +1903,11 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change value = instr->_ops[o]; /* We only care about locals */ + /* we also calculate parameter liferanges so that locals + * can take up parameter slots */ if (value->store != store_value && - value->store != store_local) + value->store != store_local && + value->store != store_param) continue; /* read operands */ @@ -2397,6 +2430,7 @@ static bool gen_global_function(ir_builder *ir, ir_value *global) static bool ir_builder_gen_global(ir_builder *self, ir_value *global) { + size_t i; int32_t *iptr; prog_section_def def; @@ -2478,8 +2512,8 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global) case TYPE_VARIANT: /* assume biggest type */ global->code.globaladdr = code_globals_add(0); - code_globals_add(0); - code_globals_add(0); + for (i = 1; i < type_sizeof[TYPE_VARIANT]; ++i) + code_globals_add(0); return true; default: /* refuse to create 'void' type or any other fancy business. */ @@ -2549,6 +2583,10 @@ void ir_function_dump(ir_function *f, char *ind, int (*oprintf)(const char*, ...)) { size_t i; + if (f->builtin != 0) { + oprintf("%sfunction %s = builtin %i\n", ind, f->name, -f->builtin); + return; + } oprintf("%sfunction %s\n", ind, f->name); strncat(ind, "\t", IND_BUFSZ); if (f->locals_count)