*IR Value
*/
+void ir_value_code_setaddr(ir_value *self, int32_t gaddr)
+{
+ self->code.globaladdr = gaddr;
+ if (self->members[0]) self->members[0]->code.globaladdr = gaddr;
+ if (self->members[1]) self->members[1]->code.globaladdr = gaddr;
+ if (self->members[2]) self->members[2]->code.globaladdr = gaddr;
+}
+
+int32_t ir_value_code_addr(const ir_value *self)
+{
+ return self->code.globaladdr + self->code.addroffset;
+}
+
ir_value* ir_value_var(const char *name, int storetype, int vtype)
{
ir_value *self;
MEM_VECTOR_INIT(self, life);
return self;
}
+
+ir_value* ir_value_vector_member(ir_value *self, unsigned int member)
+{
+ ir_value *m;
+ if (member >= 3)
+ return NULL;
+
+ if (self->members[member])
+ return self->members[member];
+
+ m = ir_value_var(self->name, self->store, TYPE_FLOAT);
+ if (!m)
+ return NULL;
+ m->context = self->context;
+
+ self->members[member] = m;
+ m->code.addroffset = member;
+
+ return m;
+}
+
MEM_VEC_FUNCTIONS(ir_value, ir_life_entry_t, life)
MEM_VEC_FUNCTIONS_ALL(ir_value, ir_instr*, reads)
MEM_VEC_FUNCTIONS_ALL(ir_value, ir_instr*, writes)
void ir_value_delete(ir_value* self)
{
+ size_t i;
if (self->name)
mem_d((void*)self->name);
if (self->isconst)
if (self->vtype == TYPE_STRING)
mem_d((void*)self->constval.vstring);
}
+ for (i = 0; i < 3; ++i) {
+ if (self->members[i])
+ ir_value_delete(self->members[i]);
+ }
MEM_VECTOR_CLEAR(self, reads);
MEM_VECTOR_CLEAR(self, writes);
MEM_VECTOR_CLEAR(self, life);
return true;
}
+bool ir_value_set_field(ir_value *self, ir_value *fld)
+{
+ if (self->vtype != TYPE_FIELD)
+ return false;
+ self->constval.vpointer = fld;
+ self->isconst = true;
+ return true;
+}
+
bool ir_value_set_string(ir_value *self, const char *str)
{
if (self->vtype != TYPE_STRING)
}
/* copy the field's value */
- global->code.globaladdr = code_globals_add(code_globals_data[fld->code.globaladdr]);
+ ir_value_code_setaddr(global, code_globals_add(code_globals_data[fld->code.globaladdr]));
}
else
{
- global->code.globaladdr = code_globals_add(0);
+ ir_value_code_setaddr(global, code_globals_add(0));
}
if (global->code.globaladdr < 0)
return false;
return false;
}
- global->code.globaladdr = code_globals_add(target->code.globaladdr);
+ ir_value_code_setaddr(global, code_globals_add(target->code.globaladdr));
}
else
{
- global->code.globaladdr = code_globals_add(0);
+ ir_value_code_setaddr(global, code_globals_add(0));
}
if (global->code.globaladdr < 0)
return false;
* come first: eg. optimize IFs without ELSE...
*/
- stmt.o1.u1 = instr->_ops[0]->code.globaladdr;
+ stmt.o1.u1 = ir_value_code_addr(instr->_ops[0]);
stmt.o2.u1 = 0;
stmt.o3.s1 = 0;
stmt.o3.u1 = 0;
stmt.opcode = type_store_instr[param->vtype];
- stmt.o1.u1 = param->code.globaladdr;
+ stmt.o1.u1 = ir_value_code_addr(param);
stmt.o2.u1 = OFS_PARM0 + 3 * p;
if (code_statements_add(stmt) < 0)
return false;
stmt.opcode = INSTR_CALL0 + instr->params_count;
if (stmt.opcode > INSTR_CALL8)
stmt.opcode = INSTR_CALL8;
- stmt.o1.u1 = instr->_ops[1]->code.globaladdr;
+ stmt.o1.u1 = ir_value_code_addr(instr->_ops[1]);
stmt.o2.u1 = 0;
stmt.o3.u1 = 0;
if (code_statements_add(stmt) < 0)
/* not to be kept in OFS_RETURN */
stmt.opcode = type_store_instr[retvalue->vtype];
stmt.o1.u1 = OFS_RETURN;
- stmt.o2.u1 = retvalue->code.globaladdr;
+ stmt.o2.u1 = ir_value_code_addr(retvalue);
stmt.o3.u1 = 0;
if (code_statements_add(stmt) < 0)
return false;
/* This is the general order of operands */
if (instr->_ops[0])
- stmt.o3.u1 = instr->_ops[0]->code.globaladdr;
+ stmt.o3.u1 = ir_value_code_addr(instr->_ops[0]);
if (instr->_ops[1])
- stmt.o1.u1 = instr->_ops[1]->code.globaladdr;
+ stmt.o1.u1 = ir_value_code_addr(instr->_ops[1]);
if (instr->_ops[2])
- stmt.o2.u1 = instr->_ops[2]->code.globaladdr;
+ stmt.o2.u1 = ir_value_code_addr(instr->_ops[2]);
if (stmt.opcode == INSTR_RETURN || stmt.opcode == INSTR_DONE)
{
{
/* generate code.globaladdr for ssa values */
ir_value *v = irfun->values[i];
- v->code.globaladdr = local_var_end + v->code.local;
+ ir_value_code_setaddr(v, local_var_end + v->code.local);
}
for (i = 0; i < irfun->locals_count; ++i) {
/* fill the locals with zeros */
if (global->isconst) {
iptr = (int32_t*)&global->constval.vfloat;
- global->code.globaladdr = code_globals_add(*iptr);
+ ir_value_code_setaddr(global, code_globals_add(*iptr));
} else
- global->code.globaladdr = code_globals_add(0);
+ ir_value_code_setaddr(global, code_globals_add(0));
return global->code.globaladdr >= 0;
}
if (code_defs_add(def) < 0)
return false;
if (global->isconst)
- global->code.globaladdr = code_globals_add(code_cachedstring(global->constval.vstring));
+ ir_value_code_setaddr(global, code_globals_add(code_cachedstring(global->constval.vstring)));
else
- global->code.globaladdr = code_globals_add(0);
+ ir_value_code_setaddr(global, code_globals_add(0));
return global->code.globaladdr >= 0;
}
case TYPE_VECTOR:
if (global->isconst) {
iptr = (int32_t*)&global->constval.vvec;
- global->code.globaladdr = code_globals_add(iptr[0]);
+ ir_value_code_setaddr(global, code_globals_add(iptr[0]));
if (global->code.globaladdr < 0)
return false;
for (d = 1; d < type_sizeof[global->vtype]; ++d)
return false;
}
} else {
- global->code.globaladdr = code_globals_add(0);
+ ir_value_code_setaddr(global, code_globals_add(0));
if (global->code.globaladdr < 0)
return false;
for (d = 1; d < type_sizeof[global->vtype]; ++d)
case TYPE_FUNCTION:
if (code_defs_add(def) < 0)
return false;
- global->code.globaladdr = code_globals_elements;
+ ir_value_code_setaddr(global, code_globals_elements);
code_globals_add(code_functions_elements);
return gen_global_function(self, global);
case TYPE_VARIANT:
/* assume biggest type */
- global->code.globaladdr = code_globals_add(0);
+ ir_value_code_setaddr(global, code_globals_add(0));
for (i = 1; i < type_sizeof[TYPE_VARIANT]; ++i)
code_globals_add(0);
return true;
if (!code_globals_add(code_alloc_field(type_sizeof[field->fieldtype])))
return false;
- field->code.globaladdr = code_globals_add(fld.offset);
+ ir_value_code_setaddr(field, code_globals_add(fld.offset));
return field->code.globaladdr >= 0;
}