[qfcc] Move type encoding defs into an array

This allows the defs to be updated without having to modify the type
struct itself, and also allows for alternative encodings (eg, spir-v).
This commit is contained in:
Bill Currie 2024-09-15 12:04:11 +09:00
parent c7e35994b5
commit 9cd8bc0d45
9 changed files with 42 additions and 31 deletions

View file

@ -31,6 +31,7 @@
#ifndef __type_h #ifndef __type_h
#define __type_h #define __type_h
#include "QF/darray.h"
#include "QF/progs/pr_type.h" #include "QF/progs/pr_type.h"
#include "specifier.h" #include "specifier.h"
@ -93,7 +94,6 @@ typedef struct type_s {
int allocated; int allocated;
struct protocollist_s *protos; struct protocollist_s *protos;
const char *encoding; ///< Objective-QC encoding const char *encoding; ///< Objective-QC encoding
struct def_s *type_def; ///< offset of qfo encodoing
} type_t; } type_t;
#define EV_TYPE(type) extern type_t type_##type; #define EV_TYPE(type) extern type_t type_##type;
@ -248,7 +248,12 @@ void chain_initial_types (void);
void clear_typedefs (void); void clear_typedefs (void);
extern type_t *ev_types[]; typedef struct def_s def_t;
typedef struct defset_s DARRAY_TYPE (def_t *) defset_t;
extern defset_t type_encodings; ///< qfo encodoing
extern const type_t *ev_types[];
extern int type_cast_map[]; extern int type_cast_map[];
#define TYPE_CAST_CODE(from, to, width) (((width) << 6) | ((from) << 3) | (to)) #define TYPE_CAST_CODE(from, to, width) (((width) << 6) | ((from) << 3) | (to))

View file

@ -140,7 +140,8 @@ tf_gentype_func (progs_t *pr, void *data)
error (ctx->expr, "refernce to unresolved type"); error (ctx->expr, "refernce to unresolved type");
Sys_longjmp (ctx->jmpbuf); Sys_longjmp (ctx->jmpbuf);
} }
R_POINTER (pr) = type->type_def->offset; auto type_def = type_encodings.a[type->id];
R_POINTER (pr) = type_def->offset;
} }
#define BASE(b, base) (((base) & 3) << OP_##b##_SHIFT) #define BASE(b, base) (((base) & 3) << OP_##b##_SHIFT)

View file

@ -876,7 +876,8 @@ compute_type (const expr_t *arg, comp_ctx_t *ctx)
internal_error (arg, "no type in reference"); internal_error (arg, "no type in reference");
} }
auto val = compute_tmp (ctx); auto val = compute_tmp (ctx);
D_INT (val) = arg->typ.type->type_def->offset; auto type_def = type_encodings.a[arg->typ.type->id];
D_INT (val) = type_def->offset;
return val; return val;
} }
int op = arg->typ.op; int op = arg->typ.op;

View file

@ -892,10 +892,10 @@ type_specifier
; ;
array_specifier array_specifier
: array_size { $$ = (type_t *) array_type (nullptr, $1); } : array_size { $$ = array_type (nullptr, $1); }
| array_specifier array_size | array_specifier array_size
{ {
$$ = (type_t *) append_type ($1, array_type (nullptr, $2)); $$ = append_type ($1, array_type (nullptr, $2));
} }
; ;

View file

@ -137,7 +137,7 @@ qfo_encode_defs (qfo_t *qfo, def_t *defs, qfo_def_t **qfo_defs,
d->qfo_def = q - qfo->defs; d->qfo_def = q - qfo->defs;
// defs in the type data space do not have types // defs in the type data space do not have types
if (d->type) if (d->type)
q->type = d->type->type_def->offset; q->type = type_encodings.a[d->type->id]->offset;
q->name = ReuseString (d->name); q->name = ReuseString (d->name);
q->offset = d->offset; q->offset = d->offset;
q->relocs = *qfo_relocs - qfo->relocs; q->relocs = *qfo_relocs - qfo->relocs;
@ -299,7 +299,7 @@ qfo_encode_functions (qfo_t *qfo, qfo_def_t **defs, qfo_reloc_t **relocs,
for (f = functions, q = qfo->funcs; f; f = f->next, q++) { for (f = functions, q = qfo->funcs; f; f = f->next, q++) {
q->name = f->s_name; q->name = f->s_name;
q->type = f->def->type->type_def->offset; q->type = type_encodings.a[f->def->type->id]->offset;
q->file = f->s_file; q->file = f->s_file;
q->line = f->def->loc.line; q->line = f->def->loc.line;
q->code = f->code; q->code = f->code;

View file

@ -194,7 +194,7 @@ qfo_encode_struct (const type_t *type, defspace_t *space)
ENC_STR (strct->tag, type->name); ENC_STR (strct->tag, type->name);
strct->num_fields = num_fields; strct->num_fields = num_fields;
((type_t *)type)->type_def = def; // avoid infinite recursion type_encodings.a[type->id] = def; // avoid infinite recursion
field_types = alloca (num_fields * sizeof (def_t *)); field_types = alloca (num_fields * sizeof (def_t *));
for (i = 0, sym = type->symtab->symbols; sym; sym = sym->next) { for (i = 0, sym = type->symtab->symbols; sym; sym = sym->next) {
@ -205,7 +205,7 @@ qfo_encode_struct (const type_t *type, defspace_t *space)
if (type->meta != ty_enum) { if (type->meta != ty_enum) {
field_types[i] = qfo_encode_type (sym->type, space); field_types[i] = qfo_encode_type (sym->type, space);
} else { } else {
field_types[i] = type_default->type_def; field_types[i] = type_encodings.a[type_default->id];
} }
i++; i++;
} }
@ -333,17 +333,16 @@ qfo_encode_type (const type_t *type, defspace_t *space)
[ty_bool] = qfo_encode_basic, [ty_bool] = qfo_encode_basic,
}; };
if (type->type_def && type->type_def->external) { auto type_def = &type_encodings.a[type->id];
relocs = type->type_def->relocs; if (*type_def && (*type_def)->external) {
((type_t *) type)->type_def = 0; relocs = type_encodings.a[type->id]->relocs;
type_encodings.a[type->id] = nullptr;
} }
if (type->type_def) if (*type_def)
return type->type_def; return *type_def;
if (type->meta >= sizeof (funcs) / (sizeof (funcs[0]))) if (type->meta >= sizeof (funcs) / (sizeof (funcs[0])))
internal_error (0, "bad type meta type"); internal_error (0, "bad type meta type");
if (!type->encoding) *type_def = funcs[type->meta] (type, space);
((type_t *) type)->encoding = type_get_encoding (type); reloc_attach_relocs (relocs, &(*type_def)->relocs);
((type_t *) type)->type_def = funcs[type->meta] (type, space); return *type_def;
reloc_attach_relocs (relocs, &type->type_def->relocs);
return type->type_def;
} }

View file

@ -124,7 +124,6 @@ InitData (void)
for (type = pr.types; type; type = ntype) { for (type = pr.types; type; type = ntype) {
ntype = type->next; ntype = type->next;
free_type (type); free_type (type);
type->type_def = 0;
} }
if (pr.code) { if (pr.code) {

View file

@ -225,9 +225,11 @@ build_struct (int su, symbol_t *tag, symtab_t *symtab, const type_t *type,
if (alignment > sym->type->alignment) { if (alignment > sym->type->alignment) {
((type_t *) sym->type)->alignment = alignment; ((type_t *) sym->type)->alignment = alignment;
} }
if (!type && sym->type->type_def->external) //FIXME should not be necessary //FIXME should not be necessary
((type_t *) sym->type)->type_def = qfo_encode_type (sym->type, if (!type && type_encodings.a[sym->type->id]->external) {
pr.type_data); unsigned id = sym->type->id;
type_encodings.a[id] = qfo_encode_type (sym->type, pr.type_data);
}
return sym; return sym;
} }

View file

@ -206,7 +206,7 @@ type_t type_floatfield = {
}; };
#define EV_TYPE(type) &type_##type, #define EV_TYPE(type) &type_##type,
type_t *ev_types[ev_type_count] = { const type_t *ev_types[ev_type_count] = {
#include "QF/progs/pr_type_names.h" #include "QF/progs/pr_type_names.h"
&type_invalid, &type_invalid,
}; };
@ -222,9 +222,10 @@ int type_cast_map[ev_type_count] = {
//[ev_bool64] = 7, //[ev_bool64] = 7,
}; };
defset_t type_encodings = DARRAY_STATIC_INIT (64);
ALLOC_STATE (type_t, types); ALLOC_STATE (type_t, types);
static unsigned type_id_number;
static hashtab_t *type_tab; static hashtab_t *type_tab;
etype_t etype_t
@ -265,13 +266,13 @@ chain_type (type_t *type)
if (type->id) { if (type->id) {
internal_error (0, "type already has id"); internal_error (0, "type already has id");
} }
type->id = ++type_id_number; type->id = type_encodings.size;
DARRAY_APPEND (&type_encodings, nullptr);
type->next = pr.types; type->next = pr.types;
pr.types = type; pr.types = type;
if (!type->encoding) if (!type->encoding)
type->encoding = type_get_encoding (type); type->encoding = type_get_encoding (type);
if (!type->type_def) type_encodings.a[type->id] = qfo_encode_type (type, pr.type_data);
type->type_def = qfo_encode_type (type, pr.type_data);
Hash_Add (type_tab, type); Hash_Add (type_tab, type);
} }
@ -677,7 +678,7 @@ matrix_type (const type_t *ele_type, int cols, int rows)
return nullptr; return nullptr;
} }
if (rows == 1 && cols == 1) { if (rows == 1 && cols == 1) {
for (type_t **t = ev_types; t - ev_types < ev_type_count; t++) { for (auto t = ev_types; t - ev_types < ev_type_count; t++) {
if ((*t)->type == ele_type->type && (*t)->width == 1) { if ((*t)->type == ele_type->type && (*t)->width == 1) {
return *t; return *t;
} }
@ -687,7 +688,7 @@ matrix_type (const type_t *ele_type, int cols, int rows)
// no horizontal matrices // no horizontal matrices
return nullptr; return nullptr;
} }
for (type_t **mtype = matrix_types; *mtype; mtype++) { for (auto mtype = matrix_types; *mtype; mtype++) {
if ((*mtype)->meta == ele_type->meta if ((*mtype)->meta == ele_type->meta
&& (*mtype)->type == ele_type->type && (*mtype)->type == ele_type->type
&& (*mtype)->width == rows && (*mtype)->width == rows
@ -1633,6 +1634,9 @@ type_aligned_size (const type_t *type)
static void static void
chain_basic_types (void) chain_basic_types (void)
{ {
type_encodings.size = 0;
DARRAY_APPEND (&type_encodings, nullptr);
type_entity.symtab = pr.entity_fields; type_entity.symtab = pr.entity_fields;
if (options.code.progsversion == PROG_VERSION) { if (options.code.progsversion == PROG_VERSION) {
type_quaternion.alignment = 4; type_quaternion.alignment = 4;