[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
#define __type_h
#include "QF/darray.h"
#include "QF/progs/pr_type.h"
#include "specifier.h"
@ -93,7 +94,6 @@ typedef struct type_s {
int allocated;
struct protocollist_s *protos;
const char *encoding; ///< Objective-QC encoding
struct def_s *type_def; ///< offset of qfo encodoing
} type_t;
#define EV_TYPE(type) extern type_t type_##type;
@ -248,7 +248,12 @@ void chain_initial_types (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[];
#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");
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)

View file

@ -876,7 +876,8 @@ compute_type (const expr_t *arg, comp_ctx_t *ctx)
internal_error (arg, "no type in reference");
}
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;
}
int op = arg->typ.op;

View file

@ -892,10 +892,10 @@ type_specifier
;
array_specifier
: array_size { $$ = (type_t *) array_type (nullptr, $1); }
: array_size { $$ = array_type (nullptr, $1); }
| 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;
// defs in the type data space do not have types
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->offset = d->offset;
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++) {
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->line = f->def->loc.line;
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);
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 *));
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) {
field_types[i] = qfo_encode_type (sym->type, space);
} else {
field_types[i] = type_default->type_def;
field_types[i] = type_encodings.a[type_default->id];
}
i++;
}
@ -333,17 +333,16 @@ qfo_encode_type (const type_t *type, defspace_t *space)
[ty_bool] = qfo_encode_basic,
};
if (type->type_def && type->type_def->external) {
relocs = type->type_def->relocs;
((type_t *) type)->type_def = 0;
auto type_def = &type_encodings.a[type->id];
if (*type_def && (*type_def)->external) {
relocs = type_encodings.a[type->id]->relocs;
type_encodings.a[type->id] = nullptr;
}
if (type->type_def)
return type->type_def;
if (*type_def)
return *type_def;
if (type->meta >= sizeof (funcs) / (sizeof (funcs[0])))
internal_error (0, "bad type meta type");
if (!type->encoding)
((type_t *) type)->encoding = type_get_encoding (type);
((type_t *) type)->type_def = funcs[type->meta] (type, space);
reloc_attach_relocs (relocs, &type->type_def->relocs);
return type->type_def;
*type_def = funcs[type->meta] (type, space);
reloc_attach_relocs (relocs, &(*type_def)->relocs);
return *type_def;
}

View file

@ -124,7 +124,6 @@ InitData (void)
for (type = pr.types; type; type = ntype) {
ntype = type->next;
free_type (type);
type->type_def = 0;
}
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) {
((type_t *) sym->type)->alignment = alignment;
}
if (!type && sym->type->type_def->external) //FIXME should not be necessary
((type_t *) sym->type)->type_def = qfo_encode_type (sym->type,
pr.type_data);
//FIXME should not be necessary
if (!type && type_encodings.a[sym->type->id]->external) {
unsigned id = sym->type->id;
type_encodings.a[id] = qfo_encode_type (sym->type, pr.type_data);
}
return sym;
}

View file

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