[qfcc] Chain matrix and bool types

Ruamoko doesn't really use either yet, but GLSL needs them and this
ironed out a lot of the issues related to adding the types.
This commit is contained in:
Bill Currie 2024-04-25 11:22:35 +09:00
parent 86b3d0db7b
commit c70da4fc76
16 changed files with 135 additions and 44 deletions

View file

@ -50,6 +50,7 @@ typedef enum {
ty_alias,
ty_handle,
ty_algebra,
ty_bool,
ty_meta_count
} ty_meta_e;
@ -74,7 +75,8 @@ typedef struct qfot_fldptr_s {
typedef struct qfot_basic_s {
etype_t type; ///< integral and fp scalar types
pr_int_t width; ///< components in vector (1 for vector or
///< quaternion)
///< quaternion), rows in matrix
pr_int_t columns; ///< columns in matrix (or 1)
} qfot_basic_t;
typedef struct qfot_func_s {

View file

@ -239,8 +239,10 @@ pr_debug_type_size (const progs_t *pr, const qfot_type_t *type)
pr_short_t size;
qfot_type_t *aux_type;
switch (type->meta) {
case ty_bool:
case ty_basic:
return pr_type_size[type->type] * type->basic.width;
return pr_type_size[type->type] * type->basic.width
* type->basic.columns;
case ty_handle:
return pr_type_size[type->type];
case ty_struct:
@ -1070,6 +1072,8 @@ value_string (pr_debug_data_t *data, qfot_type_t *type, pr_type_t *value)
case ty_handle:
raw_type_view.handle_view (type, value, data);
break;
case ty_bool:
//FIXME add bool view
case ty_basic:
switch (type->type) {
#define EV_TYPE(t) \

View file

@ -63,6 +63,7 @@ void print_type (qfot_type_t *type)
{
//printf ("type: %p %d %d %s", type, type.meta, type.size, type.encoding);
switch (type.meta) {
case ty_bool:
case ty_basic:
//printf (" %d", type.type);
switch (type.type) {

View file

@ -51,6 +51,7 @@ static string get_type_key (void *type, void *unused)
return nil;
}
switch (type.meta) {
case ty_bool: //FIXME special type?
case ty_basic:
if (type.type == ev_ptr) {
Type *tgt = [Type findType: type.fldptr.aux_type];

View file

@ -18,6 +18,7 @@ typedef enum {
ty_alias,
ty_handle,
ty_algebra,
ty_bool,
} ty_meta_e;
typedef struct qfot_alias_s {
@ -40,6 +41,7 @@ typedef struct qfot_fldptr_s {
typedef struct qfot_basic_s {
etype_t type;
int width;
int columns;
} qfot_basic_t;
typedef struct qfot_func_s {
@ -99,7 +101,7 @@ typedef struct qfot_type_encodings_s {
int size;
} qfot_type_encodings_t;
@extern string ty_meta_name[9];
@extern string ty_meta_name[10];
@extern string pr_type_name[ev_type_count];
@extern int pr_type_size[ev_type_count];

View file

@ -1,7 +1,7 @@
#include <runtime.h>
#include <types.h>
string ty_meta_name[9] = {
string ty_meta_name[10] = {
"basic",
"struct",
"union",
@ -11,6 +11,7 @@ string ty_meta_name[9] = {
"alias",
"handle",
"algebra",
"bool",
};
//FIXME use pr_type_names.h, but need to fix unsigned, and add missing types

View file

@ -36,6 +36,7 @@ static void type_free (void *t, void *unused)
qfot_type_t *type = (qfot_type_t *) t;
str_free (type.encoding);
switch (type.meta) {
case ty_bool:
case ty_basic:
case ty_array:
break;
@ -112,6 +113,7 @@ static void type_free (void *t, void *unused)
goto error;
}
switch (type.meta) {
case ty_bool:
case ty_basic:
if (type.type == ev_ptr || type.type == ev_field) {
t = [TypeEncodings getType:(unsigned)type.fldptr.aux_type
@ -219,8 +221,10 @@ error:
case ty_handle:
size = pr_type_size[type.type];
break;
case ty_bool:
case ty_basic:
size = pr_type_size[type.type] * type.basic.width;
size = pr_type_size[type.type] * type.basic.width
* type.basic.columns;
break;
case ty_array:
aux_type = type.array.type;

View file

@ -1,24 +1,24 @@
#ifndef MAT_TYPE
#define MAT_TYPE(type_name, base_type, align_as)
#define MAT_TYPE(type_name, base_type, cols, align_as)
#endif
MAT_TYPE(mat2x2, float, vec2)
MAT_TYPE(mat2x3, float, vec3)
MAT_TYPE(mat2x4, float, vec4)
MAT_TYPE(mat3x2, float, vec2)
MAT_TYPE(mat3x3, float, vec3)
MAT_TYPE(mat3x4, float, vec4)
MAT_TYPE(mat4x2, float, vec2)
MAT_TYPE(mat4x3, float, vec3)
MAT_TYPE(mat4x4, float, vec4)
MAT_TYPE(dmat2x2, double, dvec2)
MAT_TYPE(dmat2x3, double, dvec3)
MAT_TYPE(dmat2x4, double, dvec4)
MAT_TYPE(dmat3x2, double, dvec2)
MAT_TYPE(dmat3x3, double, dvec3)
MAT_TYPE(dmat3x4, double, dvec4)
MAT_TYPE(dmat4x2, double, dvec2)
MAT_TYPE(dmat4x3, double, dvec3)
MAT_TYPE(dmat4x4, double, dvec4)
MAT_TYPE(mat2x2, float, 2, vec2)
MAT_TYPE(mat2x3, float, 2, vec3)
MAT_TYPE(mat2x4, float, 2, vec4)
MAT_TYPE(mat3x2, float, 3, vec2)
MAT_TYPE(mat3x3, float, 3, vec3)
MAT_TYPE(mat3x4, float, 3, vec4)
MAT_TYPE(mat4x2, float, 4, vec2)
MAT_TYPE(mat4x3, float, 4, vec3)
MAT_TYPE(mat4x4, float, 4, vec4)
MAT_TYPE(dmat2x2, double, 2, dvec2)
MAT_TYPE(dmat2x3, double, 2, dvec3)
MAT_TYPE(dmat2x4, double, 2, dvec4)
MAT_TYPE(dmat3x2, double, 3, dvec2)
MAT_TYPE(dmat3x3, double, 3, dvec3)
MAT_TYPE(dmat3x4, double, 3, dvec4)
MAT_TYPE(dmat4x2, double, 4, dvec2)
MAT_TYPE(dmat4x3, double, 4, dvec3)
MAT_TYPE(dmat4x4, double, 4, dvec4)
#undef MAT_TYPE

View file

@ -70,6 +70,8 @@ typedef struct type_s {
int width; ///< components in vector types, otherwise 1
///< vector and quaternion are 1 (separate from
///< vec3 and vec4)
///< also, rows in matrix types
int columns; ///< for matrix types, otherwise 1
/// function/pointer/array/struct types are more complex
ty_meta_e meta;
union {
@ -98,7 +100,8 @@ typedef struct type_s {
#define VEC_TYPE(type_name, base_type) extern type_t type_##type_name;
#include "tools/qfcc/include/vec_types.h"
#define MAT_TYPE(type_name, base_type, align_as) extern type_t type_##type_name;
#define MAT_TYPE(type_name, base_type, cols, align_as) \
extern type_t type_##type_name;
#include "tools/qfcc/include/mat_types.h"
extern type_t type_bool;

View file

@ -80,6 +80,7 @@ type_t type_SEL = {
.name = "SEL",
.alignment = 1,
.width = 1,
.columns = 1,
.meta = ty_basic,
{{&type_selector}},
};
@ -89,6 +90,7 @@ type_t type_IMP = {
.name = "IMP",
.alignment = 1,
.width = 1,
.columns = 1,
.meta = ty_basic,
{{&type_id, -3, IMP_params, .no_va_list = 1}},
};
@ -99,6 +101,7 @@ type_t type_SuperPtr = {
.type = ev_ptr,
.alignment = 1,
.width = 1,
.columns = 1,
.meta = ty_basic,
{{&type_super}},
};
@ -108,6 +111,7 @@ type_t type_supermsg = {
.name = ".supermsg",
.alignment = 1,
.width = 1,
.columns = 1,
.meta = ty_basic,
{{&type_id, -3, supermsg_params}},
};
@ -135,6 +139,7 @@ type_t type_moduleptr = {
.type = ev_ptr,
.alignment = 1,
.width = 1,
.columns = 1,
.meta = ty_basic,
{{&type_module}},
};
@ -145,6 +150,7 @@ type_t type_exec_class = {
.type = ev_func,
.alignment = 1,
.width = 1,
.columns = 1,
.meta = ty_basic,
{{&type_void, 1, obj_exec_class_params}},
};
@ -161,6 +167,7 @@ type_t type_id = {
.name = "id",
.alignment = 1,
.width = 1,
.columns = 1,
.meta = ty_basic,
{{&type_object}},
};
@ -172,6 +179,7 @@ type_t type_Class = {
.type = ev_ptr,
.alignment = 1,
.width = 1,
.columns = 1,
.meta = ty_basic,
{{&type_class}},
};

View file

@ -446,6 +446,7 @@ static const char *ty_meta_names[] = {
"ty_alias",
"ty_handle",
"ty_algebra",
"ty_bool",
};
#define NUM_META ((int)(sizeof (ty_meta_names) / sizeof (ty_meta_names[0])))
const int vector_types = (1 << ev_float)
@ -497,6 +498,7 @@ dump_qfo_types (qfo_t *qfo, int base_address)
break;
}
switch ((ty_meta_e) type->meta) {
case ty_bool:
case ty_basic:
printf (" %-10s", get_ev_type_name (type->type));
if (type->type == ev_func) {
@ -509,9 +511,13 @@ dump_qfo_types (qfo_t *qfo, int base_address)
} else if (type->type == ev_ptr
|| type->type == ev_field) {
printf (" %4x", type->fldptr.aux_type);
} else if ((1 << type->type) & vector_types
&& type->basic.width > 1) {
printf ("[%d]", type->basic.width);
} else if ((1 << type->type) & vector_types) {
if (type->basic.columns > 1) {
printf ("[%d]", type->basic.columns);
}
if (type->basic.width > 1) {
printf ("[%d]", type->basic.width);
}
}
printf ("\n");
break;

View file

@ -189,6 +189,7 @@ parse_params (const type_t *return_type, param_t *parms)
new->type = ev_func;
new->alignment = 1;
new->width = 1;
new->columns = 1;
new->t.func.type = return_type;
new->t.func.num_params = 0;

View file

@ -704,6 +704,7 @@ get_def_type (qfo_t *qfo, pr_ptr_t type)
case ty_basic:
case ty_handle: //XXX
case ty_algebra:
case ty_bool:
// field, pointer and function types store their basic type in
// the same location.
return type_def->type;
@ -736,6 +737,7 @@ get_type_size (qfo_t *qfo, pr_ptr_t type)
return get_type_size (qfo, type_def->alias.aux_type);
case ty_handle: //XXX
case ty_basic:
case ty_bool:
// field, pointer and function types store their basic type in
// the same location.
return pr_type_size[type_def->type];
@ -790,6 +792,7 @@ get_type_alignment_log (qfo_t *qfo, pr_ptr_t type)
return get_type_alignment_log (qfo, type_def->alias.aux_type);
case ty_handle: //XXX
case ty_basic:
case ty_bool:
// field, pointer and function types store their basic type in
// the same location.
return qfo_log2 (ev_types[type_def->type]->alignment);

View file

@ -157,6 +157,7 @@ qfo_encode_basic (const type_t *type, defspace_t *space)
enc = D_POINTER (qfot_type_t, def);
enc->basic.type = type->type;
enc->basic.width = type->width;
enc->basic.columns = type->columns;
return def;
}
@ -330,6 +331,7 @@ qfo_encode_type (const type_t *type, defspace_t *space)
[ty_alias] = qfo_encode_alias,
[ty_handle] = qfo_encode_handle,
[ty_algebra] = qfo_encode_algebra,
[ty_bool] = qfo_encode_basic,
};
if (type->type_def && type->type_def->external) {

View file

@ -138,6 +138,7 @@ find_handle (symbol_t *tag, const type_t *type)
type_t *t = (type_t *) sym->type;//FIXME
t->type = type->type;
t->width = 1;
t->columns = 1;
t->alignment = type->alignment;
}
return sym;
@ -245,6 +246,7 @@ start_enum (symbol_t *sym)
((type_t *) sym->type)->t.symtab = new_symtab (current_symtab, stab_enum);
((type_t *) sym->type)->alignment = 1;
((type_t *) sym->type)->width = 1;
((type_t *) sym->type)->columns = 1;
return sym->type->t.symtab;
}

View file

@ -68,6 +68,7 @@
.alignment = PR_ALIGNOF(t), \
.width = __builtin_choose_expr (ev_##t == ev_short \
|| ev_##t == ev_ushort, 0, 1), \
.columns = 1, \
.meta = ty_basic, \
{{ __builtin_choose_expr (ev_##t == ev_field \
|| ev_##t == ev_func \
@ -91,47 +92,53 @@ type_t type_auto = {
.name = #type_name, \
.alignment = PR_ALIGNOF(type_name), \
.width = PR_SIZEOF(type_name) / PR_SIZEOF (base_type), \
.columns = 1, \
.meta = ty_basic, \
};
#include "tools/qfcc/include/vec_types.h"
#define MAT_TYPE(type_name, base_type, align_as) \
#define MAT_TYPE(type_name, base_type, cols, align_as) \
type_t type_##type_name = { \
.type = ev_##base_type, \
.name = #type_name, \
.alignment = PR_ALIGNOF(align_as), \
.width = 0, /*FIXME what width? */ \
.width = PR_SIZEOF(align_as) / PR_SIZEOF (base_type), \
.columns = cols, \
.meta = ty_basic, \
};
#include "tools/qfcc/include/mat_types.h"
type_t type_bool = {
.type = ev_int, //FIXME create bool type?
.type = ev_int,
.name = "bool",
.alignment = PR_ALIGNOF(int),
.width = PR_SIZEOF(int) / PR_SIZEOF (int),
.meta = ty_basic,
.columns = 1,
.meta = ty_bool,
};
type_t type_bvec2 = {
.type = ev_int, //FIXME create bool type?
.type = ev_int,
.name = "bvec2",
.alignment = PR_ALIGNOF(ivec2),
.width = PR_SIZEOF(ivec2) / PR_SIZEOF (int),
.meta = ty_basic,
.columns = 1,
.meta = ty_bool,
};
type_t type_bvec3 = {
.type = ev_int, //FIXME create bool type?
.type = ev_int,
.name = "bvec3",
.alignment = PR_ALIGNOF(ivec3),
.width = PR_SIZEOF(ivec3) / PR_SIZEOF (int),
.meta = ty_basic,
.columns = 1,
.meta = ty_bool,
};
type_t type_bvec4 = {
.type = ev_int, //FIXME create bool type?
.type = ev_int,
.name = "bvec4",
.alignment = PR_ALIGNOF(ivec4),
.width = PR_SIZEOF(ivec4) / PR_SIZEOF (int),
.meta = ty_basic,
.columns = 1,
.meta = ty_bool,
};
#define VEC_TYPE(type_name, base_type) &type_##type_name,
@ -144,7 +151,7 @@ static type_t *vec_types[] = {
0
};
#define MAT_TYPE(type_name, base_type, align_as) &type_##type_name,
#define MAT_TYPE(type_name, base_type, cols, align_as) &type_##type_name,
static type_t *mat_types[] = {
#include "tools/qfcc/include/mat_types.h"
0
@ -182,6 +189,7 @@ type_t type_xdef_pointer = {
.type = ev_ptr,
.alignment = 1,
.width = 1,
.columns = 1,
.meta = ty_basic,
{{&type_xdef}},
};
@ -196,6 +204,7 @@ type_t type_floatfield = {
.name = ".float",
.alignment = 1,
.width = 1,
.columns = 1,
.meta = ty_basic,
{{&type_float}},
};
@ -325,6 +334,7 @@ copy_chain (type_t *type, type_t *append)
*n = new_type ();
**n = *type;
switch (type->meta) {
case ty_bool:
case ty_basic:
switch (type->type) {
case ev_void:
@ -382,6 +392,7 @@ append_type (const type_t *type, const type_t *new)
while (*t) {
switch ((*t)->meta) {
case ty_bool:
case ty_basic:
switch ((*t)->type) {
case ev_void:
@ -404,11 +415,13 @@ append_type (const type_t *type, const type_t *new)
t = (const type_t **) &(*t)->t.fldptr.type;
((type_t *) type)->alignment = 1;
((type_t *) type)->width = 1;
((type_t *) type)->columns = 1;
break;
case ev_func:
t = (const type_t **) &(*t)->t.func.type;
((type_t *) type)->alignment = 1;
((type_t *) type)->width = 1;
((type_t *) type)->columns = 1;
break;
case ev_invalid:
internal_error (0, "invalid basic type");
@ -419,6 +432,7 @@ append_type (const type_t *type, const type_t *new)
t = (const type_t **) &(*t)->t.array.type;
((type_t *) type)->alignment = new->alignment;
((type_t *) type)->width = new->width;
((type_t *) type)->columns = new->columns;
break;
case ty_struct:
case ty_union:
@ -539,6 +553,7 @@ find_type (const type_t *type)
if (type->freeable) {
switch (type->meta) {
case ty_bool:
case ty_basic:
switch (type->type) {
case ev_field:
@ -622,6 +637,7 @@ field_type (const type_t *aux)
new->type = ev_field;
new->alignment = 1;
new->width = 1;
new->columns = 1;
if (aux) {
return find_type (append_type (new, aux));
}
@ -641,6 +657,7 @@ pointer_type (const type_t *aux)
new->type = ev_ptr;
new->alignment = 1;
new->width = 1;
new->columns = 1;
if (aux) {
return find_type (append_type (new, aux));
}
@ -658,8 +675,10 @@ vector_type (const type_t *ele_type, int width)
}
}
for (type_t **vtype = vec_types; *vtype; vtype++) {
if ((*vtype)->type == ele_type->type
&& (*vtype)->width == width) {
if ((*vtype)->meta == ele_type->meta
&& (*vtype)->type == ele_type->type
&& (*vtype)->width == width
&& (*vtype)->columns == 1) {
if (options.code.progsversion < PROG_VERSION) {
if (*vtype == &type_vec3) {
return &type_vector;
@ -682,7 +701,8 @@ matrix_type (const type_t *ele_type, int cols, int rows)
}
for (type_t **mtype = mat_types; *mtype; mtype++) {
if ((*mtype)->type == ele_type->type
&& (*mtype)->width == rows) {
&& (*mtype)->width == rows
&& (*mtype)->columns == cols) {
return *mtype;
}
}
@ -911,6 +931,11 @@ print_type_str (dstring_t *str, const type_t *type)
dasprintf (str, "[%d]", type->t.array.size);
}
return;
case ty_bool:
dasprintf (str, " %s%s", type->type == ev_int ? "bool" : "lbool",
type->width > 1 ? va (0, "{%d}", type->width)
: "");
return;
case ty_basic:
switch (type->type) {
case ev_field:
@ -1104,6 +1129,14 @@ encode_type (dstring_t *encoding, const type_t *type)
encode_type (encoding, type->t.array.type);
dasprintf (encoding, "]");
return;
case ty_bool:
char bool_char = type->type == ev_int ? 'b' : 'B';
if (type->width > 1) {
dasprintf (encoding, "%c%d", bool_char, type->width);
} else {
dasprintf (encoding, "%c", bool_char);
}
return;
case ty_basic:
switch (type->type) {
case ev_void:
@ -1113,14 +1146,20 @@ encode_type (dstring_t *encoding, const type_t *type)
dasprintf (encoding, "*");
return;
case ev_double:
if (type->width > 1) {
if (type->columns > 1) {
dasprintf (encoding, "d%d%d",
type->columns, type->width);
} else if (type->width > 1) {
dasprintf (encoding, "d%d", type->width);
} else {
dasprintf (encoding, "d");
}
return;
case ev_float:
if (type->width > 1) {
if (type->columns > 1) {
dasprintf (encoding, "f%d%d",
type->columns, type->width);
} else if (type->width > 1) {
dasprintf (encoding, "f%d", type->width);
} else {
dasprintf (encoding, "f");
@ -1439,7 +1478,12 @@ type_size (const type_t *type)
{
switch (type->meta) {
case ty_handle:
case ty_bool:
case ty_basic:
if (type->type != ev_short && (!type->columns || !type->width)) {
internal_error (0, "%s:%d:%d", pr_type_name[type->type],
type->columns, type->width);
}
return pr_type_size[type->type] * type->width;
case ty_struct:
case ty_union:
@ -1477,6 +1521,7 @@ int
type_width (const type_t *type)
{
switch (type->meta) {
case ty_bool:
case ty_basic:
if (type->type == ev_vector) {
return 3;
@ -1567,6 +1612,12 @@ chain_basic_types (void)
chain_type (&type_ushort);
#define VEC_TYPE(name, type) chain_type (&type_##name);
#include "tools/qfcc/include/vec_types.h"
#define MAT_TYPE(name, type, cols, align_as) chain_type (&type_##name);
#include "tools/qfcc/include/mat_types.h"
chain_type (&type_bool);
chain_type (&type_bvec2);
chain_type (&type_bvec3);
chain_type (&type_bvec4);
}
}
}