diff options
Diffstat (limited to 'nqdasm.c')
-rw-r--r-- | nqdasm.c | 38 |
1 files changed, 28 insertions, 10 deletions
@@ -1,3 +1,4 @@ +#include <assert.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -38,13 +39,29 @@ static const struct mnemonic *match_instruction(unsigned bits) return NULL; } -static void print_operand(FILE *out, unsigned bits, const struct operand *op) +static inline int get_argvalue(const struct line *line, int argidx) { + const struct operand *op = line->mnem->operands + argidx; switch (op->type) { - case REG: fprintf(out, "r%d", 7 & (bits >> op->shift)); break; - case REGPTR: fprintf(out, "@r%d", 7 & (bits >> op->shift)); break; - case IMM: fprintf(out, "%d", (uint8_t)(bits >> op->shift)); break; - case PCOFF: fprintf(out, "%d", (int8_t)(bits >> op->shift)); break; + case REG: + case REGPTR: return 7 & (line->value >> op->shift); + case IMM: return (uint8_t) (line->value >> op->shift); + case PCOFF: return (int8_t) (line->value >> op->shift); + } + assert(0); +} + +static void print_operand(FILE *out, const struct line *lines, size_t count, size_t lineidx, size_t argidx) +{ + const struct line *inst = lines + lineidx; + const struct operand *op = inst->mnem->operands + argidx; + + switch (op->type) { + case REG: fprintf(out, "r%d", get_argvalue(inst, argidx)); break; + case REGPTR: fprintf(out, "@r%d", get_argvalue(inst, argidx)); break; + case IMM: fprintf(out, "%d", get_argvalue(inst, argidx)); break; + case PCOFF: fprintf(out, "%d", get_argvalue(inst, argidx)); break; + default: assert(0); } } @@ -98,8 +115,9 @@ static void disassemble(FILE *in, FILE *out) if (!lines) return; for (size_t i = 0; i < count; i++) { - unsigned bits = lines[i].value; - const struct mnemonic *m = lines[i].mnem; + const struct line *line = lines + i; + unsigned bits = line->value; + const struct mnemonic *m = line->mnem; if (!m) { fprintf(out, "\t.word 0x%04x\n", bits); @@ -107,10 +125,10 @@ static void disassemble(FILE *in, FILE *out) } fprintf(out, "\t%s", m->mnem); - for (int i = 0; i < 3 && m->operands[i].type; i++) { - if (i) fprintf(out, ", "); + for (int j = 0; j < 3 && m->operands[j].type; j++) { + if (j) fprintf(out, ", "); else fprintf(out, "%*s", 8 - (int)strlen(m->mnem), ""); - print_operand(out, bits, m->operands + i); + print_operand(out, lines, count, i, j); } fprintf(out, "\n"); } |