First thing: we want quaternions and 4x4 matrices

This commit is contained in:
Wolfgang Bumiller 2012-07-10 19:26:07 +02:00
parent 3987509493
commit e9ac1c9e21
4 changed files with 115 additions and 11 deletions

2
ast.h
View file

@ -107,6 +107,8 @@ struct ast_value_s
const char *vstring;
int ventity;
ast_function *vfunc;
quaternion vquat;
matrix vmat;
} constval;
ir_value *ir_v;

44
gmqcc.h
View file

@ -365,6 +365,8 @@ enum {
TYPE_FUNCTION ,
TYPE_POINTER ,
/* TYPE_INTEGER , */
TYPE_QUATERNION ,
TYPE_MATRIX ,
TYPE_VARIANT ,
TYPE_COUNT
@ -457,8 +459,11 @@ enum {
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,
@ -469,11 +474,15 @@ enum {
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,
@ -484,6 +493,8 @@ enum {
INSTR_LOAD_ENT,
INSTR_LOAD_FLD,
INSTR_LOAD_FNC,
INSTR_LOAD_Q,
INSTR_LOAD_M,
INSTR_ADDRESS,
INSTR_STORE_F,
INSTR_STORE_V,
@ -491,18 +502,24 @@ enum {
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,
@ -576,8 +593,11 @@ static const struct {
{ "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 },
@ -588,11 +608,15 @@ static const struct {
{ "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 },
@ -603,6 +627,8 @@ static const struct {
{ "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 },
@ -610,18 +636,24 @@ static const struct {
{ "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 },
@ -783,6 +815,14 @@ typedef struct {
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.

76
ir.c
View file

@ -41,7 +41,9 @@ size_t type_sizeof[TYPE_COUNT] = {
#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] = {
@ -54,9 +56,12 @@ 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 */
};
MEM_VEC_FUNCTIONS(ir_value_vector, ir_value*, v)
@ -552,6 +557,24 @@ bool ir_value_set_vector(ir_value *self, vector 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)
@ -866,6 +889,12 @@ bool ir_block_create_store(ir_block *self, ir_value *target, ir_value *what)
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;
@ -914,6 +943,12 @@ bool ir_block_create_storep(ir_block *self, ir_value *target, ir_value *what)
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;
@ -1175,7 +1210,6 @@ ir_value* ir_block_create_binop(ir_block *self,
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:
@ -1275,6 +1309,8 @@ ir_value* ir_block_create_load_from_ent(ir_block *self, const char *label, ir_va
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;
}
@ -1378,12 +1414,22 @@ ir_value* ir_block_create_mul(ir_block *self,
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;
@ -2363,10 +2409,8 @@ static bool gen_global_function(ir_builder *ir, ir_value *global)
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;
@ -2453,19 +2497,32 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
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;
}
@ -2652,6 +2709,7 @@ void ir_value_dump(ir_value* v, int (*oprintf)(const char*, ...))
{
if (v->isconst) {
switch (v->vtype) {
default:
case TYPE_VOID:
oprintf("(void)");
break;

4
ir.h
View file

@ -55,6 +55,8 @@ typedef struct ir_value_s {
char *vstring;
struct ir_value_s *vpointer;
struct ir_function_s *vfunc;
quaternion vquat;
matrix vmat;
} constval;
struct {
@ -89,6 +91,8 @@ bool GMQCC_WARN ir_value_set_string(ir_value*, const char *s);
bool GMQCC_WARN ir_value_set_vector(ir_value*, vector v);
/*bool ir_value_set_pointer_v(ir_value*, ir_value* p); */
/*bool ir_value_set_pointer_i(ir_value*, int i); */
bool GMQCC_WARN ir_value_set_quaternion(ir_value*, quaternion v);
bool GMQCC_WARN ir_value_set_matrix(ir_value*, matrix v);
MEM_VECTOR_PROTO(ir_value, ir_life_entry_t, life);
/* merge an instruction into the life-range */