summaryrefslogtreecommitdiff
path: root/nqdasm.c
diff options
context:
space:
mode:
authorBobby Bingham <koorogi@koorogi.info>2017-01-15 23:13:56 -0600
committerBobby Bingham <koorogi@koorogi.info>2017-01-15 23:19:47 -0600
commitbb7ae08ee638cf9b88a69ca89c5b6b12401c37f5 (patch)
tree8655183d15ea7efe77607eb12d8fe3b9483c29e3 /nqdasm.c
parent19458565441227f4981681a8de126517d734da3e (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.
Diffstat (limited to 'nqdasm.c')
-rw-r--r--nqdasm.c24
1 files 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);