#include #include #include #include #include "mnemonics.h" #define ERROR(prog,...) \ do { \ fprintf(stderr, "%s: ", prog); \ fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, "\n"); \ } while (0) #define PERROR(prog,str) \ do { \ int err = errno; \ fprintf(stderr, "%s: ", prog); \ errno = err; \ perror(str); \ } while (0) static const struct mnemonic *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; } return NULL; } static void print_operand(FILE *out, unsigned bits, const struct operand *op) { 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; } } static void usage(const char *progname) { printf("usage: %s [-o output] [input]\n", progname); printf(" %s -h\n", progname); printf("\n"); printf("\t%-16s %s\n", "-h", "display this help text and exit"); printf("\t%-16s %s\n", "-o output", "write output to 'output' (default=stdout)"); printf("\t%-16s %s\n", "input", "read input from 'input' (default=stdin)"); } int main(int argc, char **argv) { const char *outname = NULL; int error = 0; extern int optind; extern char *optarg; for (int opt; (opt = getopt(argc, argv, "+ho:")) != -1;) { switch (opt) { case 'h': usage(argv[0]); return 0; case 'o': outname = optarg; break; default: error = 1; } } if (optind < argc - 1) { ERROR(argv[0], "Too many input files"); return 1; } if (error) return 1; FILE *in = stdin; FILE *out = stdout; if (optind < argc && !(in = fopen(argv[optind], "r"))) { PERROR(argv[0], "Error opening input file"); return 1; } if (outname && !(out = fopen(outname, "w"))) { PERROR(argv[0], "Error opening output file"); fclose(in); return 1; } unsigned bits; while (fscanf(in, " %x\n", &bits) > 0) { const struct mnemonic *m = match_instruction(bits); if (!m) { fprintf(out, "\t.word 0x%04x\n", bits); continue; } fprintf(out, "\t%s", m->mnem); for (int i = 0; i < 3 && m->operands[i].type; i++) { if (i) fprintf(out, ", "); else fprintf(out, "%*s", 8 - (int)strlen(m->mnem), ""); print_operand(out, bits, m->operands + i); } fprintf(out, "\n"); } fclose(in); fclose(out); return 0; }