[gamecode] Switch to using indexed initializers

The opcode table is a nightmare to maintain, but this does clean it up
and speed up opcode lookups since they can now be indexed. Of course, it
turns out I had missed adding several instructions, so had to fix that,
and qfcc needed a bit of a re-jigger to get the opcode out of the table.
This commit is contained in:
Bill Currie 2021-12-31 19:16:02 +09:00
parent be474d9937
commit 365762b8a6
6 changed files with 354 additions and 344 deletions

View file

@ -403,17 +403,16 @@ typedef enum {
#define OP_BREAK 0x8000
typedef struct opcode_s {
const char *name;
const char *opname;
pr_opcode_e opcode;
qboolean right_associative;
etype_t type_a, type_b, type_c;
const char *name;
const char *opname;
qboolean right_associative;
etype_t type_a, type_b, type_c;
unsigned int min_version;
const char *fmt;
const char *fmt;
} opcode_t;
extern const opcode_t pr_opcodes[];
opcode_t *PR_Opcode (pr_short_t opcode);
const opcode_t *PR_Opcode (pr_short_t opcode) __attribute__((const));
void PR_Opcode_Init (void); // idempotent
typedef struct dstatement_s {

View file

@ -1482,7 +1482,7 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
int addr = s - pr->pr_statements;
int dump_code = contents & 2;
const char *fmt;
opcode_t *op;
const opcode_t *op;
dfunction_t *call_func = 0;
pr_def_t *parm_def = 0;
pr_auxfunction_t *aux_func = 0;

File diff suppressed because it is too large Load diff

View file

@ -48,6 +48,8 @@ extern struct opcode_s *op_jumpb;
struct operand_s;
extern struct opcode_s *opcode_map;
struct opcode_s *opcode_find (const char *name, struct operand_s *op_a,
struct operand_s *op_b, struct operand_s *op_c);
void opcode_init (void);

View file

@ -213,7 +213,7 @@ emit_statement (statement_t *statement)
}
}
s = codespace_newstatement (pr.code);
s->op = op->opcode;
s->op = op - opcode_map;
s->a = def_a ? def_a->offset : 0;
s->b = def_b ? def_b->offset : 0;
s->c = def_c ? def_c->offset : 0;

View file

@ -49,6 +49,7 @@
hashtab_t *opcode_type_table;
hashtab_t *opcode_void_table;
opcode_t *opcode_map;
#define ROTL(x,n) ((((unsigned)(x))<<(n))|((unsigned)(x))>>(32-n))
@ -95,7 +96,7 @@ opcode_t *
opcode_find (const char *name, operand_t *op_a, operand_t *op_b,
operand_t *op_c)
{
opcode_t search_op;
opcode_t search_op = {};
opcode_t *op;
opcode_t *sop;
void **op_list;
@ -122,12 +123,6 @@ opcode_find (const char *name, operand_t *op_a, operand_t *op_b,
return op;
}
static void
opcode_free (void *_op, void *unused)
{
free (_op);
}
void
opcode_init (void)
{
@ -139,14 +134,23 @@ opcode_init (void)
Hash_FlushTable (opcode_type_table);
} else {
PR_Opcode_Init ();
opcode_type_table = Hash_NewTable (1021, 0, opcode_free, 0, 0);
opcode_type_table = Hash_NewTable (1021, 0, 0, 0, 0);
Hash_SetHashCompare (opcode_type_table, get_hash, compare);
opcode_void_table = Hash_NewTable (1021, get_key, 0, 0, 0);
}
int num_opcodes = 0;
for (op = pr_opcodes; op->name; op++) {
num_opcodes++;
}
if (!opcode_map) {
opcode_map = calloc (num_opcodes, sizeof (opcode_t));
}
for (int i = 0; i < num_opcodes; i++) {
op = pr_opcodes + i;
if (op->min_version > options.code.progsversion)
continue;
mop = malloc (sizeof (opcode_t));
mop = opcode_map + i;
*mop = *op;
if (options.code.progsversion == PROG_ID_VERSION) {
// v6 progs have no concept of integer, but the QF engine