TYPE_FUNCTION ,
TYPE_POINTER ,
/* TYPE_INTEGER , */
+ TYPE_QUATERNION ,
+ TYPE_MATRIX ,
TYPE_VARIANT ,
TYPE_COUNT
extern size_t type_sizeof[TYPE_COUNT];
extern uint16_t type_store_instr[TYPE_COUNT];
+ /* could use type_store_instr + INSTR_STOREP_F - INSTR_STORE_F
+ * but this breaks when TYPE_INTEGER is added, since with the enhanced
+ * instruction set, the old ones are left untouched, thus the _I instructions
+ * are at a seperate place.
+ */
+ extern uint16_t type_storep_instr[TYPE_COUNT];
/*
* Each paramater incerements by 3 since vector types hold
INSTR_DONE,
INSTR_MUL_F,
INSTR_MUL_V,
- INSTR_MUL_FV,
INSTR_MUL_VF,
+ INSTR_MUL_Q,
+ INSTR_MUL_QF,
+ INSTR_MUL_M,
+ INSTR_MUL_MF,
INSTR_DIV_F,
INSTR_ADD_F,
INSTR_ADD_V,
INSTR_EQ_S,
INSTR_EQ_E,
INSTR_EQ_FNC,
+ INSTR_EQ_Q,
+ INSTR_EQ_M,
INSTR_NE_F,
INSTR_NE_V,
INSTR_NE_S,
INSTR_NE_E,
INSTR_NE_FNC,
+ INSTR_NE_Q,
+ INSTR_NE_M,
INSTR_LE,
INSTR_GE,
INSTR_LT,
INSTR_LOAD_ENT,
INSTR_LOAD_FLD,
INSTR_LOAD_FNC,
+ INSTR_LOAD_Q,
+ INSTR_LOAD_M,
INSTR_ADDRESS,
INSTR_STORE_F,
INSTR_STORE_V,
INSTR_STORE_ENT,
INSTR_STORE_FLD,
INSTR_STORE_FNC,
+ INSTR_STORE_Q,
+ INSTR_STORE_M,
INSTR_STOREP_F,
INSTR_STOREP_V,
INSTR_STOREP_S,
INSTR_STOREP_ENT,
INSTR_STOREP_FLD,
INSTR_STOREP_FNC,
+ INSTR_STOREP_Q,
+ INSTR_STOREP_M,
INSTR_RETURN,
INSTR_NOT_F,
INSTR_NOT_V,
INSTR_NOT_S,
INSTR_NOT_ENT,
INSTR_NOT_FNC,
+ INSTR_INV_Q,
+ INSTR_INV_M,
INSTR_IF,
INSTR_IFNOT,
INSTR_CALL0,
{ "DONE" , 1, 4 },
{ "MUL_F" , 3, 5 },
{ "MUL_V" , 3, 5 },
- { "MUL_FV" , 3, 6 },
{ "MUL_VF" , 3, 6 },
+ { "MUL_Q" , 3, 5 },
+ { "MUL_QF" , 3, 6 },
+ { "MUL_M" , 3, 5 },
+ { "MUL_MF" , 3, 6 },
{ "DIV" , 0, 3 },
{ "ADD_F" , 3, 5 },
{ "ADD_V" , 3, 5 },
{ "EQ_S" , 0, 4 },
{ "EQ_E" , 0, 4 },
{ "EQ_FNC" , 0, 6 },
+ { "EQ_Q" , 0, 4 },
+ { "EQ_M" , 0, 4 },
{ "NE_F" , 0, 4 },
{ "NE_V" , 0, 4 },
{ "NE_S" , 0, 4 },
{ "NE_E" , 0, 4 },
{ "NE_FNC" , 0, 6 },
+ { "NE_Q" , 0, 4 },
+ { "NE_M" , 0, 4 },
{ "LE" , 0, 2 },
{ "GE" , 0, 2 },
{ "LT" , 0, 2 },
{ "FIELD_ENT" , 0, 9 },
{ "FIELD_FLD" , 0, 9 },
{ "FIELD_FNC" , 0, 9 },
+ { "FIELD_Q" , 0, 7 },
+ { "FIELD_M" , 0, 7 },
{ "ADDRESS" , 0, 7 },
{ "STORE_F" , 0, 7 },
{ "STORE_V" , 0, 7 },
{ "STORE_ENT" , 0, 9 },
{ "STORE_FLD" , 0, 9 },
{ "STORE_FNC" , 0, 9 },
+ { "STORE_Q" , 0, 7 },
+ { "STORE_M" , 0, 7 },
{ "STOREP_F" , 0, 8 },
{ "STOREP_V" , 0, 8 },
{ "STOREP_S" , 0, 8 },
{ "STOREP_ENT", 0, 10},
{ "STOREP_FLD", 0, 10},
{ "STOREP_FNC", 0, 10},
+ { "STOREP_Q" , 0, 8 },
+ { "STOREP_M" , 0, 8 },
{ "RETURN" , 0, 6 },
{ "NOT_F" , 0, 5 },
{ "NOT_V" , 0, 5 },
{ "NOT_S" , 0, 5 },
{ "NOT_ENT" , 0, 7 },
{ "NOT_FNC" , 0, 7 },
+ { "INV_Q" , 0, 5 },
+ { "INV_M" , 0, 5 },
{ "IF" , 0, 2 },
{ "IFNOT" , 0, 5 },
{ "CALL0" , 1, 5 },
float x, y, z;
} vector;
+typedef float matrix[4][4]; /* OpenGL layout */
+typedef float quaternion[4]; /* order: x, y, z, w */
+#define MATRIX(axis, elem) ((4*(axis)) + (elem))
+#define QUAT_X 0
+#define QUAT_Y 1
+#define QUAT_Z 2
+#define QUAT_W 3
+
/*
* A shallow copy of a lex_file to remember where which ast node
* came from.
#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 */
};
- INSTR_STOREP_V, /* variant, should never be accessed */
+ uint16_t type_store_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)
/***********************************************************************
return true;
}
+bool ir_value_set_quaternion(ir_value *self, quaternion v)
+{
+ if (self->vtype != TYPE_QUATERNION)
+ return false;
+ self->constval.vquat = v;
+ self->isconst = true;
+ return true;
+}
+
+bool ir_value_set_matrix(ir_value *self, matrix v)
+{
+ if (self->vtype != TYPE_MATRIX)
+ return false;
+ self->constval.vmat = v;
+ 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;
- case TYPE_QUATERNION:
- op = INSTR_STORE_Q;
- break;
- case TYPE_MATRIX:
- op = INSTR_STORE_M;
- 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;
- case TYPE_QUATERNION:
- op = INSTR_STOREP_Q;
- break;
- case TYPE_MATRIX:
- op = INSTR_STOREP_M;
- 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;
return global->code.globaladdr >= 0;
}
case TYPE_VECTOR:
+ case TYPE_QUATERNION:
+ case TYPE_MATRIX:
{
size_t d;
if (code_defs_add(def) < 0)
global->code.globaladdr = code_globals_add(iptr[0]);
if (global->code.globaladdr < 0)
return false;
- for (d = 1; d < jype_sizeof[global->vtype]; ++d)
+ for (d = 1; d < type_sizeof[global->vtype]; ++d)
{
if (code_globals_add(iptr[d]) < 0)
return false;
{
if (v->isconst) {
switch (v->vtype) {
+ default:
case TYPE_VOID:
oprintf("(void)");
break;