289 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			289 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
| 	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.
 | |
| */
 | |
| 
 | |
| /* $Header$ */
 | |
| 
 | |
| #include <stdio.h>
 | |
| 
 | |
| extern char *sprintf();
 | |
| 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 */
 | |
| 
 | |
| 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, "%s %s", 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<cnt; i++) {
 | |
| 				Mini(i, flgs, base, first, mnem);
 | |
| 			}
 | |
| 		} else if (in(flgs, 's')) {	/* Shortie */
 | |
| 			for (i = 0; i<cnt; i++) {
 | |
| 				Shortie(i, flgs, base, first, mnem);
 | |
| 			}
 | |
| 		} else if (in(flgs, '2')) {	/* Two byte signed */
 | |
| 			TwoSgn(flgs, base, first, mnem);
 | |
| 		} else if (in(flgs, 'u')) {	/* Two byte unsigned */
 | |
| 			TwoUns(flgs, base, first, mnem);
 | |
| 		} else if (in(flgs, '4')) {	/* Four byte signed */
 | |
| 			FourSgn(flgs, base, first, mnem);
 | |
| 		} else {
 | |
| 			fatal("no opcode flag in ip_spec %s\n", flgs);
 | |
| 		}
 | |
| 	}
 | |
| 	exit(0);
 | |
| }
 | |
| 
 | |
| 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);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 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);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 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");
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 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");
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 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");
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 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");
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int
 | |
| in(flgs, c)
 | |
| 	char *flgs;
 | |
| 	char c;
 | |
| {
 | |
| 	while (*flgs)
 | |
| 		if (c == *flgs++)
 | |
| 			return 1;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| fatal(fmt, str)
 | |
| 	char *fmt;
 | |
| 	char *str;
 | |
| {
 | |
| 	fprintf(stderr, "%s, (fatal error): ", progname);
 | |
| 	fprintf(stderr, fmt, str);
 | |
| 	fprintf(stderr, "\n");
 | |
| 	exit(1);
 | |
| }
 |