va_list ap;
int lvl = LVL_WARNING;
- if (!OPTS_WARN(warntype))
+ if (warntype && !OPTS_WARN(warntype))
return false;
if (opts_werror)
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) {
+ ir_value *ve;
+
+ /*
+ if (ir_function_get_local(self, name))
return NULL;
- }
+ */
if (param &&
self->locals_count &&
{
if (self->blocks[i]->is_return)
{
+ self->blocks[i]->living_count = 0;
if (!ir_block_life_propagate(self->blocks[i], NULL, &changed))
return false;
}
/* See which operands are read and write operands */
ir_op_read_write(instr->opcode, &read, &write);
+ if (instr->opcode == INSTR_MUL_VF)
+ {
+ /* the float source will get an additional lifetime */
+ tempbool = ir_value_life_merge(instr->_ops[2], instr->eid+1);
+ *changed = *changed || tempbool;
+ }
+ else if (instr->opcode == INSTR_MUL_FV)
+ {
+ /* the float source will get an additional lifetime */
+ tempbool = ir_value_life_merge(instr->_ops[1], instr->eid+1);
+ *changed = *changed || tempbool;
+ }
+
/* Go through the 3 main operands */
for (o = 0; o < 3; ++o)
{
*
* Breaking conventions is annoying...
*/
-static bool ir_builder_gen_global(ir_builder *self, ir_value *global);
+static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool islocal);
static bool gen_global_field(ir_value *global)
{
}
fun.firstlocal = code_globals_elements;
- fun.locals = irfun->allocated_locals + irfun->locals_count;
local_var_end = fun.firstlocal;
for (i = 0; i < irfun->locals_count; ++i) {
- if (!ir_builder_gen_global(ir, irfun->locals[i])) {
+ if (!ir_builder_gen_global(ir, irfun->locals[i], true)) {
irerror(irfun->locals[i]->context, "Failed to generate local %s", irfun->locals[i]->name);
return false;
}
code_globals_add(0);
}
+ fun.locals = code_globals_elements - fun.firstlocal;
+
if (irfun->builtin)
fun.entry = irfun->builtin;
else {
return true;
}
-static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
+static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool islocal)
{
size_t i;
int32_t *iptr;
/* I'd argue setting it to 0 is sufficient, but maybe some depend on knowing how far
* the system fields actually go? Though the engine knows this anyway...
* Maybe this could be an -foption
+ * fteqcc creates data for end_sys_* - of size 1, so let's do the same
*/
- ir_value_code_setaddr(global, def.offset);
+ ir_value_code_setaddr(global, code_globals_add(0));
/* Add the def */
if (code_defs_add(def) < 0)
return false;
/* fall through */
case TYPE_FLOAT:
{
- if (code_defs_add(def) < 0)
- return false;
-
if (global->isconst) {
iptr = (int32_t*)&global->constval.vfloat;
ir_value_code_setaddr(global, code_globals_add(*iptr));
- } else
+ } else {
ir_value_code_setaddr(global, code_globals_add(0));
+ if (!islocal)
+ def.type |= DEF_SAVEGLOBAL;
+ }
+ if (code_defs_add(def) < 0)
+ return false;
return global->code.globaladdr >= 0;
}
case TYPE_STRING:
{
- if (code_defs_add(def) < 0)
- return false;
if (global->isconst)
ir_value_code_setaddr(global, code_globals_add(code_cachedstring(global->constval.vstring)));
- else
+ else {
ir_value_code_setaddr(global, code_globals_add(0));
+ if (!islocal)
+ def.type |= DEF_SAVEGLOBAL;
+ }
+ if (code_defs_add(def) < 0)
+ return false;
return global->code.globaladdr >= 0;
}
case TYPE_VECTOR:
{
size_t d;
- if (code_defs_add(def) < 0)
- return false;
-
if (global->isconst) {
iptr = (int32_t*)&global->constval.vvec;
ir_value_code_setaddr(global, code_globals_add(iptr[0]));
if (code_globals_add(0) < 0)
return false;
}
+ if (!islocal)
+ def.type |= DEF_SAVEGLOBAL;
}
+
+ if (code_defs_add(def) < 0)
+ return false;
return global->code.globaladdr >= 0;
}
case TYPE_FUNCTION:
- if (code_defs_add(def) < 0)
- return false;
if (!global->isconst) {
ir_value_code_setaddr(global, code_globals_add(0));
- return global->code.globaladdr >= 0;
+ if (global->code.globaladdr < 0)
+ return false;
} else {
ir_value_code_setaddr(global, code_globals_elements);
code_globals_add(code_functions_elements);
- return gen_global_function(self, global);
+ if (!gen_global_function(self, global))
+ return false;
+ if (!islocal)
+ def.type |= DEF_SAVEGLOBAL;
}
+ if (code_defs_add(def) < 0)
+ return false;
+ return true;
case TYPE_VARIANT:
/* assume biggest type */
ir_value_code_setaddr(global, code_globals_add(0));
for (i = 0; i < self->globals_count; ++i)
{
- if (!ir_builder_gen_global(self, self->globals[i])) {
+ if (!ir_builder_gen_global(self, self->globals[i], false)) {
return false;
}
}
for (i = 0; i < f->locals_count; ++i) {
size_t l;
ir_value *v = f->locals[i];
- oprintf("%s\t%s: ", ind, v->name);
+ oprintf("%s\t%s: unique ", ind, v->name);
for (l = 0; l < v->life_count; ++l) {
oprintf("[%i,%i] ", v->life[l].start, v->life[l].end);
}
for (i = 0; i < f->values_count; ++i) {
size_t l;
ir_value *v = f->values[i];
- oprintf("%s\t%s: (%i)", ind, v->name, (int)v->life_count);
+ oprintf("%s\t%s: @%i ", ind, v->name, (int)v->code.local);
for (l = 0; l < v->life_count; ++l) {
oprintf("[%i,%i] ", v->life[l].start, v->life[l].end);
}