INSTR_STORE_V, /* variant, should never be accessed */
};
+uint16_t field_store_instr[TYPE_COUNT] = {
+ INSTR_STORE_FLD,
+ INSTR_STORE_FLD,
+ INSTR_STORE_FLD,
+ INSTR_STORE_V,
+ INSTR_STORE_FLD,
+ INSTR_STORE_FLD,
+ INSTR_STORE_FLD,
+ INSTR_STORE_FLD,
+#if 0
+ INSTR_STORE_FLD, /* integer type */
+#endif
+
+ INSTR_STORE_V, /* variant, should never be accessed */
+};
+
uint16_t type_storep_instr[TYPE_COUNT] = {
INSTR_STOREP_F, /* should use I when having integer support */
INSTR_STOREP_S,
*IR Builder
*/
+static void ir_block_delete_quick(ir_block* self);
+static void ir_instr_delete_quick(ir_instr *self);
+static void ir_function_delete_quick(ir_function *self);
+
ir_builder* ir_builder_new(const char *modulename)
{
ir_builder* self;
size_t i;
mem_d((void*)self->name);
for (i = 0; i != self->functions_count; ++i) {
- ir_function_delete(self->functions[i]);
+ ir_function_delete_quick(self->functions[i]);
}
MEM_VECTOR_CLEAR(self, functions);
for (i = 0; i != self->globals_count; ++i) {
return !!self->name;
}
+static void ir_function_delete_quick(ir_function *self)
+{
+ size_t i;
+ mem_d((void*)self->name);
+
+ for (i = 0; i != self->blocks_count; ++i)
+ ir_block_delete_quick(self->blocks[i]);
+ MEM_VECTOR_CLEAR(self, blocks);
+
+ MEM_VECTOR_CLEAR(self, params);
+
+ for (i = 0; i != self->values_count; ++i)
+ ir_value_delete(self->values[i]);
+ MEM_VECTOR_CLEAR(self, values);
+
+ for (i = 0; i != self->locals_count; ++i)
+ ir_value_delete(self->locals[i]);
+ MEM_VECTOR_CLEAR(self, locals);
+
+ /* self->value is deleted by the builder */
+
+ mem_d(self);
+}
+
void ir_function_delete(ir_function *self)
{
size_t i;
MEM_VEC_FUNCTIONS_ALL(ir_block, ir_block*, exits)
MEM_VEC_FUNCTIONS_ALL(ir_block, ir_value*, living)
+static void ir_block_delete_quick(ir_block* self)
+{
+ size_t i;
+ if (self->label) mem_d(self->label);
+ for (i = 0; i != self->instr_count; ++i)
+ ir_instr_delete_quick(self->instr[i]);
+ MEM_VECTOR_CLEAR(self, instr);
+ MEM_VECTOR_CLEAR(self, entries);
+ MEM_VECTOR_CLEAR(self, exits);
+ MEM_VECTOR_CLEAR(self, living);
+ mem_d(self);
+}
+
void ir_block_delete(ir_block* self)
{
size_t i;
MEM_VEC_FUNCTIONS(ir_instr, ir_phi_entry_t, phi)
MEM_VEC_FUNCTIONS(ir_instr, ir_value*, params)
+static void ir_instr_delete_quick(ir_instr *self)
+{
+ MEM_VECTOR_CLEAR(self, phi);
+ MEM_VECTOR_CLEAR(self, params);
+ mem_d(self);
+}
+
void ir_instr_delete(ir_instr *self)
{
size_t i;
stmt.opcode = INSTR_STORE_F;
stmt.o3.u1 = 0;
- stmt.opcode = type_store_instr[param->vtype];
+ if (param->vtype == TYPE_FIELD)
+ stmt.opcode = field_store_instr[param->fieldtype];
+ else
+ stmt.opcode = type_store_instr[param->vtype];
stmt.o1.u1 = ir_value_code_addr(param);
stmt.o2.u1 = OFS_PARM0 + 3 * p;
if (code_statements_add(stmt) < 0)
if (retvalue && retvalue->store != store_return && retvalue->life_count)
{
/* not to be kept in OFS_RETURN */
- stmt.opcode = type_store_instr[retvalue->vtype];
+ if (retvalue->vtype == TYPE_FIELD)
+ stmt.opcode = field_store_instr[retvalue->vtype];
+ else
+ stmt.opcode = type_store_instr[retvalue->vtype];
stmt.o1.u1 = OFS_RETURN;
stmt.o2.u1 = ir_value_code_addr(retvalue);
stmt.o3.u1 = 0;
case TYPE_FLOAT:
{
if (global->isconst) {
- iptr = (int32_t*)&global->constval.vfloat;
+ iptr = (int32_t*)&global->constval.ivec[0];
ir_value_code_setaddr(global, code_globals_add(*iptr));
} else {
ir_value_code_setaddr(global, code_globals_add(0));
{
size_t d;
if (global->isconst) {
- iptr = (int32_t*)&global->constval.vvec;
+ iptr = (int32_t*)&global->constval.ivec[0];
ir_value_code_setaddr(global, code_globals_add(iptr[0]));
if (global->code.globaladdr < 0)
return false;
#ifdef WIN32
# define strncat(dst, src, sz) strncat_s(dst, sz, src, _TRUNCATE)
-#else
-# define strncat strncat
#endif
const char *qc_opname(int op)