int main (int argc, char **argv) { unsigned int insn; FILE *fas; int aline = 0; char s[81], *name; if (argc < 3) { printf ("usage: %s itbl asm.s\n", argv[0]); exit (0); } if (itbl_parse (argv[1]) != 0) { printf ("failed to parse itbl\n"); exit (0); } fas = fopen (argv[2], "r"); if (fas == 0) { printf ("failed to open asm file %s\n", argv[2]); exit (0); } while (fgets (s, 80, fas)) { char *p; aline++; if (p = strchr (s, ';'), p) /* strip comments */ *p = 0; if (p = strchr (s, '#'), p) /* strip comments */ *p = 0; p = s + strlen (s) - 1; while (p >= s && (*p == ' ' || *p == '\t' || *p == '\n')) /* strip trailing spaces */ p--; *(p + 1) = 0; p = s; while (*p && (*p == ' ' || *p == '\t' || *p == '\n')) /* strip leading spaces */ p++; if (!*p) continue; name = itbl_get_field (&p); insn = itbl_assemble (name, p); if (insn == 0) printf ("line %d: Invalid instruction (%s)\n", aline, s); else { char buf[128]; printf ("line %d: insn(%s) = 0x%x)\n", aline, s, insn); if (!itbl_disassemble (buf, insn)) printf ("line %d: Can't disassemble instruction " "(0x%x)\n", aline, insn); else printf ("line %d: disasm(0x%x) = %s)\n", aline, insn, buf); } } test_reg (1, e_dreg, "d1", 1); test_reg (3, e_creg, "c2", 22); test_reg (3, e_dreg, "d3", 3); fclose (fas); return 0; }
unsigned long itbl_assemble (char *name, char *s) { unsigned long opcode; struct itbl_entry *e = NULL; struct itbl_field *f; char *n; int processor; if (!name || !*name) return 0; /* error! must have an opcode name/expr */ /* find entry in list of instructions for all processors */ for (processor = 0; processor < e_nprocs; processor++) { e = find_entry_byname (processor, e_insn, name); if (e) break; } if (!e) return 0; /* opcode not in table; invalid instruction */ opcode = build_opcode (e); /* parse opcode's args (if any) */ for (f = e->fields; f; f = f->next) /* for each arg, ... */ { struct itbl_entry *r; unsigned long value; if (!s || !*s) return 0; /* error - not enough operands */ n = itbl_get_field (&s); /* n should be in form $n or 0xhhh (are symbol names valid?? */ switch (f->type) { case e_dreg: case e_creg: case e_greg: /* Accept either a string name * or '$' followed by the register number */ if (*n == '$') { n++; value = strtol (n, 0, 10); /* FIXME! could have "0l"... then what?? */ if (value == 0 && *n != '0') return 0; /* error; invalid operand */ } else { r = find_entry_byname (e->processor, f->type, n); if (r) value = r->value; else return 0; /* error; invalid operand */ } break; case e_addr: /* use assembler's symbol table to find symbol */ /* FIXME!! Do we need this? if so, what about relocs?? my_getExpression (&imm_expr, s); return 0; /-* error; invalid operand *-/ break; */ /* If not a symbol, fall thru to IMMED */ case e_immed: if (*n == '0' && *(n + 1) == 'x') /* hex begins 0x... */ { n += 2; value = strtol (n, 0, 16); /* FIXME! could have "0xl"... then what?? */ } else { value = strtol (n, 0, 10); /* FIXME! could have "0l"... then what?? */ if (value == 0 && *n != '0') return 0; /* error; invalid operand */ } break; default: return 0; /* error; invalid field spec */ } opcode |= apply_range (value, f->range); } if (s && *s) return 0; /* error - too many operands */ return opcode; /* done! */ }