From bb7ae08ee638cf9b88a69ca89c5b6b12401c37f5 Mon Sep 17 00:00:00 2001 From: Bobby Bingham Date: Sun, 15 Jan 2017 23:13:56 -0600 Subject: nqdasm: reduce size of line structure This structure represents essentially all the run-time memory use of the disassembler, with 32k instances of it allocated. On 64-bit systems, this cuts the size of a single instance from 16 bytes to 8 bytes. On a 32-bit system, it goes from 12 bytes to 8 bytes. --- nqdasm.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/nqdasm.c b/nqdasm.c index 5449c06..f918136 100644 --- a/nqdasm.c +++ b/nqdasm.c @@ -25,27 +25,28 @@ const char *progname; } while (0) static struct line { - const struct mnemonic *mnem; - uint16_t value; int label; + uint16_t value; + uint8_t mnem; } lines[0x7fff]; static size_t maxpc; #define LINE(addr) &lines[(uint16_t)(addr) >> 1] +#define MNEM(line) ((line)->mnem < MNEM_LAST ? &mnemonics[(line)->mnem] : NULL) -static const struct mnemonic *match_instruction(unsigned bits) +static const uint8_t match_instruction(unsigned bits) { for (int i = 0; i < MNEM_LAST; i++) { const struct mnemonic *m = mnemonics + i; - if ((bits & m->mask) == m->bits) return m; + if ((bits & m->mask) == m->bits) return i; } - return NULL; + return MNEM_LAST; } static inline int get_argvalue(const struct line *line, int argidx) { - const struct operand *op = line->mnem->operands + argidx; + const struct operand *op = MNEM(line)->operands + argidx; switch (op->type) { case REG: case REGPTR: return 7 & (line->value >> op->shift); @@ -65,10 +66,11 @@ static void assign_labels(void) { /* mark those addresses that need a label */ for (size_t pc = 0; pc < maxpc; pc += 2) { - const struct line *l = LINE(pc); - if (!l->mnem) continue; + const struct line *l = LINE(pc); + const struct mnemonic *m = MNEM(l); + if (!m) continue; - const struct operand *ops = l->mnem->operands; + const struct operand *ops = m->operands; for (int j = 0; j < 3 && ops[j].type; j++) { if (ops[j].type == PCOFF) { struct line *target = get_pcoff_target(pc, j); @@ -88,7 +90,7 @@ static void assign_labels(void) static void print_operand(FILE *out, size_t pc, size_t argidx) { const struct line *inst = LINE(pc); - const struct operand *op = inst->mnem->operands + argidx; + const struct operand *op = MNEM(inst)->operands + argidx; switch (op->type) { case REG: fprintf(out, "r%d", get_argvalue(inst, argidx)); break; @@ -132,7 +134,7 @@ static void disassemble(FILE *in, FILE *out) for (size_t pc = 0; pc < maxpc; pc += 2) { const struct line *line = LINE(pc); unsigned bits = line->value; - const struct mnemonic *m = line->mnem; + const struct mnemonic *m = MNEM(line); if (line->label >= 0) fprintf(out, "L%d:", line->label); -- cgit v1.2.3