summaryrefslogtreecommitdiff
path: root/nqdasm.c
diff options
context:
space:
mode:
Diffstat (limited to 'nqdasm.c')
-rw-r--r--nqdasm.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/nqdasm.c b/nqdasm.c
index 86f8560..e0f78fc 100644
--- a/nqdasm.c
+++ b/nqdasm.c
@@ -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");
}