* 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 */
#if 0
1, /* TYPE_INTEGER */
#endif
- 3, /* TYPE_VARIANT */
+ 4, /* TYPE_QUATERNION */
+ 16, /* TYPE_MATRIX */
+ 16, /* TYPE_VARIANT */
};
uint16_t type_store_instr[TYPE_COUNT] = {
INSTR_STORE_FNC,
INSTR_STORE_ENT, /* should use I */
#if 0
- INSTR_STORE_ENT, /* integer type */
+ INSTR_STORE_I, /* integer type */
#endif
- INSTR_STORE_V, /* variant, should never be accessed */
+ INSTR_STORE_Q,
+ INSTR_STORE_M,
+
+ INSTR_STORE_M, /* variant, should never be accessed */
};
uint16_t type_storep_instr[TYPE_COUNT] = {
#if 0
INSTR_STOREP_ENT, /* integer type */
#endif
- INSTR_STOREP_V, /* variant, should never be accessed */
+ INSTR_STOREP_Q,
+ INSTR_STOREP_M,
+
+ INSTR_STOREP_M, /* variant, should never be accessed */
};
MEM_VEC_FUNCTIONS(ir_value_vector, ir_value*, v)
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);
*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;
return true;
}
+bool ir_value_set_quaternion(ir_value *self, quaternion v)
+{
+ if (self->vtype != TYPE_QUATERNION)
+ return false;
+ memcpy(&self->constval.vquat, v, sizeof(self->constval.vquat));
+ self->isconst = true;
+ return true;
+}
+
+bool ir_value_set_matrix(ir_value *self, matrix v)
+{
+ if (self->vtype != TYPE_MATRIX)
+ return false;
+ memcpy(&self->constval.vmat, v, sizeof(self->constval.vmat));
+ self->isconst = true;
+ return true;
+}
+
bool ir_value_set_string(ir_value *self, const char *str)
{
if (self->vtype != TYPE_STRING)
vtype = what->vtype;
op = type_storep_instr[vtype];
-
return ir_block_create_store_op(self, op, target, what);
}
case TYPE_POINTER: op = INSTR_LOAD_I; break;
case TYPE_INTEGER: op = INSTR_LOAD_I; break;
#endif
+ case TYPE_QUATERNION: op = INSTR_LOAD_Q; break;
+ case TYPE_MATRIX: op = INSTR_LOAD_M; break;
default:
return NULL;
}
case TYPE_VECTOR:
op = INSTR_MUL_V;
break;
+ case TYPE_QUATERNION:
+ op = INSTR_MUL_Q;
+ break;
+ case TYPE_MATRIX:
+ op = INSTR_MUL_M;
+ break;
}
} else {
if ( (l == TYPE_VECTOR && r == TYPE_FLOAT) )
op = INSTR_MUL_VF;
else if ( (l == TYPE_FLOAT && r == TYPE_VECTOR) )
op = INSTR_MUL_FV;
+ else if ( (l == TYPE_QUATERNION && r == TYPE_FLOAT) )
+ op = INSTR_MUL_QF;
+ else if ( (l == TYPE_MATRIX && r == TYPE_FLOAT) )
+ op = INSTR_MUL_MF;
#if 0
else if ( (l == TYPE_VECTOR && r == TYPE_INTEGER) )
op = INSTR_MUL_VI;
}
/* 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;
{
/* 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:
+ case TYPE_QUATERNION:
+ case TYPE_MATRIX:
{
size_t d;
if (code_defs_add(def) < 0)
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;
}
{
if (v->isconst) {
switch (v->vtype) {
+ default:
case TYPE_VOID:
oprintf("(void)");
break;