mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 13:11:00 +00:00
[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:
parent
c7e35994b5
commit
9cd8bc0d45
9 changed files with 42 additions and 31 deletions
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue