mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-01-31 03:50:36 +00:00
First thing: we want quaternions and 4x4 matrices
This commit is contained in:
parent
3987509493
commit
e9ac1c9e21
4 changed files with 115 additions and 11 deletions
2
ast.h
2
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;
|
||||
|
|
44
gmqcc.h
44
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.
|
||||
|
|
76
ir.c
76
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;
|
||||
|
|
4
ir.h
4
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 */
|
||||
|
|
Loading…
Reference in a new issue