#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] = {
+ INSTR_STOREP_F, /* should use I when having integer support */
+ INSTR_STOREP_S,
+ INSTR_STOREP_F,
+ INSTR_STOREP_V,
+ INSTR_STOREP_ENT,
+ INSTR_STOREP_FLD,
+ INSTR_STOREP_FNC,
+ INSTR_STOREP_ENT, /* should use I */
+#if 0
+ INSTR_STOREP_ENT, /* integer type */
+#endif
+ INSTR_STOREP_Q,
+ INSTR_STOREP_M,
+
+ INSTR_STOREP_M, /* variant, should never be accessed */
};
MEM_VEC_FUNCTIONS(ir_value_vector, ir_value*, v)
self->context.line = 0;
self->outtype = outtype;
self->value = NULL;
+ self->builtin = 0;
MEM_VECTOR_INIT(self, params);
MEM_VECTOR_INIT(self, blocks);
MEM_VECTOR_INIT(self, values);
MEM_VEC_FUNCTIONS(ir_function, ir_value*, values)
MEM_VEC_FUNCTIONS(ir_function, ir_block*, blocks)
MEM_VEC_FUNCTIONS(ir_function, ir_value*, locals)
+MEM_VEC_FUNCTIONS(ir_function, int, params)
bool ir_function_set_name(ir_function *self, const char *name)
{
bool ir_function_finalize(ir_function *self)
{
+ if (self->builtin)
+ return true;
+
if (!ir_function_naive_phi(self))
return false;
return true;
}
+bool ir_value_set_func(ir_value *self, int f)
+{
+ if (self->vtype != TYPE_FUNCTION)
+ return false;
+ self->constval.vint = f;
+ self->isconst = true;
+ return true;
+}
+
bool ir_value_set_vector(ir_value *self, vector v)
{
if (self->vtype != TYPE_VECTOR)
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)
else
vtype = target->vtype;
- switch (vtype) {
- case TYPE_FLOAT:
#if 0
- if (what->vtype == TYPE_INTEGER)
- op = INSTR_CONV_ITOF;
- else
+ if (vtype == TYPE_FLOAT && what->vtype == TYPE_INTEGER)
+ op = INSTR_CONV_ITOF;
+ else if (vtype == TYPE_INTEGER && what->vtype == TYPE_FLOAT)
+ op = INSTR_CONV_FTOI;
#endif
- op = INSTR_STORE_F;
- break;
- case TYPE_VECTOR:
- op = INSTR_STORE_V;
- break;
- case TYPE_ENTITY:
- op = INSTR_STORE_ENT;
- break;
- case TYPE_STRING:
- op = INSTR_STORE_S;
- break;
- case TYPE_FIELD:
- op = INSTR_STORE_FLD;
- break;
-#if 0
- case TYPE_INTEGER:
- if (what->vtype == TYPE_INTEGER)
- op = INSTR_CONV_FTOI;
- else
- op = INSTR_STORE_I;
- break;
-#endif
- case TYPE_POINTER:
-#if 0
- op = INSTR_STORE_I;
-#else
- op = INSTR_STORE_ENT;
-#endif
- break;
- default:
- /* Unknown type */
- return false;
- }
+ op = type_store_instr[vtype];
+
return ir_block_create_store_op(self, op, target, what);
}
*/
vtype = what->vtype;
- switch (vtype) {
- case TYPE_FLOAT:
- op = INSTR_STOREP_F;
- break;
- case TYPE_VECTOR:
- op = INSTR_STOREP_V;
- break;
- case TYPE_ENTITY:
- op = INSTR_STOREP_ENT;
- break;
- case TYPE_STRING:
- op = INSTR_STOREP_S;
- break;
- case TYPE_FIELD:
- op = INSTR_STOREP_FLD;
- break;
-#if 0
- case TYPE_INTEGER:
- op = INSTR_STOREP_I;
- break;
-#endif
- case TYPE_POINTER:
-#if 0
- op = INSTR_STOREP_I;
-#else
- op = INSTR_STOREP_ENT;
-#endif
- break;
- default:
- /* Unknown type */
- return false;
- }
+ op = type_storep_instr[vtype];
return ir_block_create_store_op(self, op, target, what);
}
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:
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;
function_allocator alloc;
+ if (!self->locals_count)
+ return true;
+
MEM_VECTOR_INIT(&alloc, locals);
MEM_VECTOR_INIT(&alloc, sizes);
MEM_VECTOR_INIT(&alloc, positions);
if (code_statements_add(stmt) < 0)
return false;
}
- return false;
+ continue;
}
if (instr->opcode == INSTR_STATE) {
static bool gen_function_code(ir_function *self)
{
ir_block *block;
+ prog_section_statement stmt;
/* Starting from entry point, we generate blocks "as they come"
* for now. Dead blocks will not be translated obviously.
printf("failed to generate blocks for '%s'\n", self->name);
return false;
}
+
+ /* otherwise code_write crashes since it debug-prints functions until AINSTR_END */
+ stmt.opcode = AINSTR_END;
+ stmt.o1.u1 = 0;
+ stmt.o2.u1 = 0;
+ stmt.o3.u1 = 0;
+ if (code_statements_add(stmt) < 0)
+ return false;
return true;
}
size_t i;
size_t local_var_end;
- if (!global->isconst ||
- !global->constval.vfunc)
+ if (!global->isconst || (!global->constval.vfunc))
{
printf("Invalid state of function-global: not constant: %s\n", global->name);
return false;
for (i = 0;i < 8; ++i) {
if (i >= fun.nargs)
fun.argsize[i] = 0;
- else if (irfun->params[i] == TYPE_VECTOR)
- fun.argsize[i] = 3;
else
- fun.argsize[i] = 1;
+ fun.argsize[i] = type_sizeof[irfun->params[i]];
}
fun.firstlocal = code_globals_elements;
code_globals_add(0);
}
- fun.entry = code_statements_elements;
- if (!gen_function_code(irfun)) {
- printf("Failed to generate code for function %s\n", irfun->name);
- return false;
+ if (irfun->builtin)
+ fun.entry = irfun->builtin;
+ else {
+ fun.entry = code_statements_elements;
+ if (!gen_function_code(irfun)) {
+ printf("Failed to generate code for function %s\n", irfun->name);
+ return false;
+ }
}
return (code_functions_add(fun) >= 0);
return global->code.globaladdr >= 0;
}
case TYPE_VECTOR:
+ case TYPE_QUATERNION:
+ case TYPE_MATRIX:
{
+ size_t d;
if (code_defs_add(def) < 0)
return false;
if (global->isconst) {
iptr = (int32_t*)&global->constval.vvec;
global->code.globaladdr = code_globals_add(iptr[0]);
- if (code_globals_add(iptr[1]) < 0 || code_globals_add(iptr[2]) < 0)
+ if (global->code.globaladdr < 0)
return false;
+ for (d = 1; d < type_sizeof[global->vtype]; ++d)
+ {
+ if (code_globals_add(iptr[d]) < 0)
+ return false;
+ }
} else {
global->code.globaladdr = code_globals_add(0);
- if (code_globals_add(0) < 0 || code_globals_add(0) < 0)
+ if (global->code.globaladdr < 0)
return false;
+ for (d = 1; d < type_sizeof[global->vtype]; ++d)
+ {
+ if (code_globals_add(0) < 0)
+ return false;
+ }
}
return global->code.globaladdr >= 0;
}
case TYPE_FUNCTION:
if (code_defs_add(def) < 0)
return false;
+ global->code.globaladdr = code_globals_elements;
code_globals_add(code_functions_elements);
return gen_global_function(self, global);
case TYPE_VARIANT:
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)
{
if (v->isconst) {
switch (v->vtype) {
+ default:
case TYPE_VOID:
oprintf("(void)");
break;