From: Wolfgang Bumiller Date: Tue, 10 Jul 2012 17:26:07 +0000 (+0200) Subject: First thing: we want quaternions and 4x4 matrices X-Git-Tag: 0.1-rc1~446 X-Git-Url: http://de.git.xonotic.org/?a=commitdiff_plain;h=e9ac1c9e2117b6adb6f78f6d9ed1a71679e82606;p=xonotic%2Fgmqcc.git First thing: we want quaternions and 4x4 matrices --- diff --git a/ast.h b/ast.h index a08c4c0..37ee171 100644 --- a/ast.h +++ b/ast.h @@ -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; diff --git a/gmqcc.h b/gmqcc.h index 6a56675..38db700 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -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. diff --git a/ir.c b/ir.c index e8b7382..78dbc8a 100644 --- a/ir.c +++ b/ir.c @@ -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; diff --git a/ir.h b/ir.h index 7aa889b..721799b 100644 --- a/ir.h +++ b/ir.h @@ -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 */