diff options
author | Bobby Bingham <koorogi@koorogi.info> | 2017-01-15 23:13:56 -0600 |
---|---|---|
committer | Bobby Bingham <koorogi@koorogi.info> | 2017-01-15 23:19:47 -0600 |
commit | bb7ae08ee638cf9b88a69ca89c5b6b12401c37f5 (patch) | |
tree | 8655183d15ea7efe77607eb12d8fe3b9483c29e3 | |
parent | 19458565441227f4981681a8de126517d734da3e (diff) |
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.
-rw-r--r-- | nqdasm.c | 24 |
1 files changed, 13 insertions, 11 deletions
@@ -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); |