/* Generates contents of opcode switch from ip_spec.t Call is: mkswitch prefix ip_spec.t cases [ functions ] Note: The u flag has been implemented by just copying and adjusting the code for 2, which is almost identical to that for 4. When this has stabilized, combine. */ /* $Id$ */ #include #include extern FILE *popen(); char *progname; FILE *ifp; /* Input File Pointer */ FILE *ofp; /* Output File Pointer */ FILE *ffp = 0; /* Function File Pointer */ char *Prefix; /* Prefix for function name */ int in(char *flgs, char c) { while (*flgs) if (c == *flgs++) return 1; return 0; } void NoArgs(base, first, mnem) char *base; int first; char *mnem; { fprintf(ofp, "\t\tcase %s+%d:\t%s%sz(); break;\n", base, first, Prefix, mnem); if (ffp) { fprintf(ffp, "%s%sz() {", Prefix, mnem); fprintf(ffp, "LOG((\"@ %s%sz()\"));}\n", Prefix, mnem); } } void Mini(i, flgs, base, first, mnem) int i; char *flgs; char *base; int first; char *mnem; { char arg[16]; int newi = in(flgs, 'N') ? (-i-1) : in(flgs, 'o') ? (i+1) : i; switch (newi) { case -1: sprintf(arg, "%s", in(flgs, 'w') ? "-wsize" : "-1L"); break; case 0: sprintf(arg, "0L"); break; case 1: sprintf(arg, "%s", in(flgs, 'w') ? "wsize" : "1L"); break; default: sprintf(arg, "%dL%s", newi, in(flgs, 'w') ? "*wsize" : ""); break; } fprintf(ofp, "\t\tcase %s+%d:\t%s%sm(%s); break;\n", base, first+i, Prefix, mnem, arg); if (ffp) { fprintf(ffp, "%s%sm(arg) long arg; {", Prefix, mnem); fprintf(ffp, "LOG((\"@ %s%sm(%%d)\", arg));}\n", Prefix, mnem); } } void Shortie(i, flgs, base, first, mnem) int i; char *flgs; char *base; int first; char *mnem; { char arg[16]; int newi = in(flgs, 'N') ? (-i-1) : in(flgs, 'o') ? (i+1) : i; sprintf(arg, "%dL, %s", newi, (in(flgs, 'w') ? "wsize" : "1L")); fprintf(ofp, "\t\tcase %s+%d:\t%s%ss(%s); break;\n", base, first+i, Prefix, mnem, arg); if (ffp) { fprintf(ffp, "%s%ss(hob, wfac) long hob; size wfac; {", Prefix, mnem); fprintf(ffp, "LOG((\"@ %s%ss(%%d)\", hob, wfac));", Prefix, mnem); fprintf(ffp, " newPC(PC+1);}\n"); } } void TwoSgn(flgs, base, first, mnem) char *flgs; char *base; int first; char *mnem; { char *xy = in(flgs, 'P') ? "p2" : in(flgs, 'N') ? "n2" : "l2"; fprintf(ofp, "\t\tcase %s+%d:\t%s%s%s(%s); break;\n", base, first, Prefix, mnem, xy, in(flgs, 'w') ? "wsize" : "1L"); if (ffp) { fprintf(ffp, "%s%s%s(arg) long arg; {", Prefix, mnem, xy); fprintf(ffp, "LOG((\"@ %s%s%s(%%d)\", arg));", Prefix, mnem, xy); fprintf(ffp, " newPC(PC+2);}\n"); } } void TwoUns(flgs, base, first, mnem) char *flgs; char *base; int first; char *mnem; { char *xy = "u"; fprintf(ofp, "\t\tcase %s+%d:\t%s%s%s(%s); break;\n", base, first, Prefix, mnem, xy, in(flgs, 'w') ? "wsize" : "1L"); if (ffp) { fprintf(ffp, "%s%s%s(arg) long arg; {", Prefix, mnem, xy); fprintf(ffp, "LOG((\"@ %s%s%s(%%d)\", arg));", Prefix, mnem, xy); fprintf(ffp, " newPC(PC+2);}\n"); } } void FourSgn(flgs, base, first, mnem) char *flgs; char *base; int first; char *mnem; { char *xy = in(flgs, 'P') ? "p4" : in(flgs, 'N') ? "n4" : "l4"; fprintf(ofp, "\t\tcase %s+%d:\t%s%s%s(%s); break;\n", base, first, Prefix, mnem, xy, in(flgs, 'w') ? "wsize" : "1L"); if (ffp) { fprintf(ffp, "%s%s%s(arg) long arg; {", Prefix, mnem, xy); fprintf(ffp, "LOG((\"@ %s%s%s(%%d)\", arg));", Prefix, mnem, xy); fprintf(ffp, " newPC(PC+4);}\n"); } } void fatal(char *fmt, char *str) { fprintf(stderr, "%s, (fatal error): ", progname); fprintf(stderr, fmt, str); fprintf(stderr, "\n"); exit(1); } int main(argc, argv) int argc; char **argv; { char mnem[8]; /* Mnemonic */ char flgs[8]; /* Flags */ char command[32]; progname = argv[0]; if (argc < 4 || argc >5) { fatal("usage is: %s prefix ip_spec.t cases [ functions ]\n", argv[0]); } Prefix = argv[1]; if ((ifp = fopen(argv[2], "r")) == 0) { fatal("cannot open '%s' for reading\n", argv[2]); } if ((ofp = fopen(argv[3], "w")) == 0) { fatal("cannot open '%s' for writing\n", argv[3]); } if (argc == 5) { /* Need to store functions */ sprintf(command, "sort | uniq > %s", argv[4]); if ((ffp = popen(command, "w")) == 0) { fatal("cannot popen '%s'\n", command); } } /* Start reading the input file */ while (fscanf(ifp, "%7s %7s", mnem, flgs) >= 0) { int i; char *p; char *base; int cnt, first; /* check flags */ for (p = flgs; *p; p++) { if (!in("-ms2u4eNPwo", *p)) { fatal("bad flags ip_spec: %s\n", flgs); } } if ( in(flgs, '-') + in(flgs, 'm') + in(flgs, 's') + in(flgs, '2') + in(flgs, 'u') + in(flgs, '4') != 1 ) { fatal("duplicate or missing opcode flag ip_spec: %s\n", flgs); } if ( in(flgs, 'N') + in(flgs, 'P') > 1 ) { fatal("duplicate restriction flags ip_spec: %s\n", flgs); } /* capitalize mnemonic */ for (p = mnem; *p; p++) { *p += ('A' - 'a'); } /* scan rest of line */ if ( in(flgs, '-') || in(flgs, '2') || in(flgs, 'u') || in(flgs, '4') ) { fscanf(ifp, " %d \n", &first); } else { fscanf(ifp, " %d %d \n", &cnt, &first); } /* determine base */ if (in(flgs, 'e')) /* Escaped (secondary) opcode */ base = "SEC_BASE"; else if (in(flgs, '4')) /* Escaped (tertiary) opcode */ base = "TERT_BASE"; else base = "PRIM_BASE"; /* analyse the opcode */ if (in(flgs, '-')) { /* No arguments */ NoArgs(base, first, mnem); } else if (in(flgs, 'm')) { /* Mini */ for (i = 0; i