Model 3 (intelligent calls) implemented
This commit is contained in:
		
							parent
							
								
									472ee0cea4
								
							
						
					
					
						commit
						c7c79e9b42
					
				
					 3 changed files with 305 additions and 14 deletions
				
			
		|  | @ -1,15 +1,20 @@ | ||||||
| # $Header$
 | # $Header$
 | ||||||
| 
 | 
 | ||||||
| IP_SPEC =	../../../etc/ip_spec.t | EM =		../../.. | ||||||
|  | IP_SPEC =	$(EM)/etc/ip_spec.t | ||||||
|  | CFLAGS =	-I$(EM) | ||||||
| 
 | 
 | ||||||
| SRC =	 	mkswitch.c | SRC =		mkiswitch.c	mkswitch.c | ||||||
| OBJ =		mkswitch.o | OBJ =		mkiswitch.o	mkswitch.o | ||||||
| 
 | 
 | ||||||
| mkswitch:	$(OBJ) | mkiswitch:	mkiswitch.o | ||||||
| 	$(CC) -o mkswitch $(OBJ) | 	$(CC) -o mkiswitch mkiswitch.o $(EM)/lib/em_data.a | ||||||
| 
 | 
 | ||||||
| DoCases:	mkswitch $(IP_SPEC) | mkswitch:	mkswitch.o | ||||||
| 	mkswitch Do $(IP_SPEC) DoCases | 	$(CC) -o mkswitch mkswitch.o | ||||||
|  | 
 | ||||||
|  | DoCases:	mkiswitch $(IP_SPEC) | ||||||
|  | 	mkiswitch Do $(IP_SPEC) DoCases | ||||||
| 	wc DoCases | 	wc DoCases | ||||||
| 
 | 
 | ||||||
| PrCases:	mkswitch $(IP_SPEC) | PrCases:	mkswitch $(IP_SPEC) | ||||||
|  | @ -29,10 +34,10 @@ distr:		.distr | ||||||
| 	$(CC) $(CFLAGS) -c $< | 	$(CC) $(CFLAGS) -c $< | ||||||
| 
 | 
 | ||||||
| clean:						# NOT the cases files !
 | clean:						# NOT the cases files !
 | ||||||
| 	/bin/rm -f a.out core $(OBJ) mkswitch | 	rm -f a.out core $(OBJ) mkswitch mkiswitch | ||||||
| 
 | 
 | ||||||
| bare:		clean | bare:		clean | ||||||
| 	/bin/rm -f DoCases PrCases | 	rm -f DoCases PrCases | ||||||
| 
 | 
 | ||||||
| all:	mkswitch | all:	mkswitch | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3,12 +3,20 @@ | ||||||
| This directory contains two programs: | This directory contains two programs: | ||||||
| 
 | 
 | ||||||
| mkswitch: | mkswitch: | ||||||
| 	C program, necessary for regenerating the giant switches | 	C program, necessary for regenerating the giant switch | ||||||
| 	which are part of the INT project. | 	needed for the disassembly function of the interpreter,  | ||||||
|  | 	which (still) works with Operand access method 2 | ||||||
|  | 	(Intelligent Routines) as described in "The EM | ||||||
|  | 	interpreter". | ||||||
| 
 | 
 | ||||||
| mkfuncs: | mkiswitch: | ||||||
| 	shell script that can be used to generate new function | 	C program, necessary for regenerating the giant switch | ||||||
| 	files, if a new implementation is needed. | 	needed for finding the correct instruction handling routine  | ||||||
|  | 	for each opcode.  It works with Operand access method 3 | ||||||
|  | 	(Intelligent Calls) as described in "The EM interpreter". | ||||||
|  | 	It constructs the operand of the instruction and passes | ||||||
|  | 	it to the appropriate routine with the operand as | ||||||
|  | 	argument. | ||||||
| 
 | 
 | ||||||
| The first program reads an input file which holds the interpreter | The first program reads an input file which holds the interpreter | ||||||
| opcode table (as shown in the [IR-81] report appendix B), | opcode table (as shown in the [IR-81] report appendix B), | ||||||
|  | @ -86,3 +94,5 @@ message, and a call to newPC() which is necessary to skip the | ||||||
| arguments.  The names of the generated files are: do_XXX.c, where | arguments.  The names of the generated files are: do_XXX.c, where | ||||||
| XXX is the name of the corresponding instruction group. | XXX is the name of the corresponding instruction group. | ||||||
| 
 | 
 | ||||||
|  | (Note: these remarks about mkfuncs are probably outdated now, | ||||||
|  | since mkfuncs has disappeared. -rbf) | ||||||
|  |  | ||||||
							
								
								
									
										276
									
								
								util/int/switch/mkiswitch.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								util/int/switch/mkiswitch.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,276 @@ | ||||||
|  | /*
 | ||||||
|  | 	Generates contents of opcode switch from ip_spec.t, | ||||||
|  | 	and parameter descriptions of em_flag.h. | ||||||
|  | 
 | ||||||
|  | 	Call is: | ||||||
|  | 		mkiswitch prefix ip_spec.t cases  | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /* $Header$ */ | ||||||
|  | 
 | ||||||
|  | #include <stdio.h> | ||||||
|  | 
 | ||||||
|  | extern char *sprintf(); | ||||||
|  | extern FILE *popen(); | ||||||
|  | 
 | ||||||
|  | #include <util/ass/ip_spec.h> | ||||||
|  | #include <h/em_spec.h> | ||||||
|  | #include <h/em_flag.h> | ||||||
|  | 
 | ||||||
|  | extern char em_mnem[][4] ; | ||||||
|  | extern char em_flag[] ; | ||||||
|  | 
 | ||||||
|  | char *progname; | ||||||
|  | 
 | ||||||
|  | FILE	*ifp;			/* Input File Pointer */ | ||||||
|  | FILE	*ofp;			/* Output File Pointer */ | ||||||
|  | char	*Prefix;		/* Prefix for function name */ | ||||||
|  | 
 | ||||||
|  | main(argc, argv) | ||||||
|  | 	int argc; | ||||||
|  | 	char **argv; | ||||||
|  | { | ||||||
|  | 	char	mnem[8];		/* Mnemonic */ | ||||||
|  | 	char	flgs[8];		/* Flags */ | ||||||
|  | 	char	argstr[256];		/* To build argument */ | ||||||
|  | 
 | ||||||
|  | 	progname = argv[0]; | ||||||
|  | 
 | ||||||
|  | 	if (argc != 4 ) { | ||||||
|  | 		fatal("usage is: %s prefix ip_spec.t cases\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]); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Start reading the input file */ | ||||||
|  | 	while (fscanf(ifp, "%s %s", mnem, flgs) >= 0) { | ||||||
|  | 		int i; | ||||||
|  | 		char *p; | ||||||
|  | 		char *base; | ||||||
|  | 		int cnt, first; | ||||||
|  | 		int mnemcode; | ||||||
|  | 
 | ||||||
|  | 		/* 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); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		mnemcode = getmnem(mnem); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 		/* 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, '-')) { | ||||||
|  | 			if ((em_flag[mnemcode] & EM_PAR) == PAR_W) { | ||||||
|  | 				/* Implicit argument on stack */ | ||||||
|  | 				ImplicitArg(argstr); | ||||||
|  | 				OutCase(mnem, base, first, 0, argstr); | ||||||
|  | 			} else { | ||||||
|  | 				/* No arguments */ | ||||||
|  | 				NoArgs(argstr); | ||||||
|  | 				OutCase(mnem, base, first, 0, argstr); | ||||||
|  | 			} | ||||||
|  | 		} else if (in(flgs, 'm')) {	/* Mini */ | ||||||
|  | 			for (i = 0; i<cnt; i++) { | ||||||
|  | 				Mini(argstr, i, flgs); | ||||||
|  | 				OutCase(mnem, base, first, i, argstr); | ||||||
|  | 			} | ||||||
|  | 		} else if (in(flgs, 's')) {	/* Shortie */ | ||||||
|  | 			for (i = 0; i<cnt; i++) { | ||||||
|  | 				Shortie(argstr, i, flgs); | ||||||
|  | 				OutCase(mnem, base, first, i, argstr); | ||||||
|  | 			} | ||||||
|  | 		} else if (in(flgs, '2')) {	/* Two byte signed */ | ||||||
|  | 			TwoSgn(argstr, flgs); | ||||||
|  | 			OutCase(mnem, base, first, 0, argstr); | ||||||
|  | 		} else if (in(flgs, 'u')) {	/* Two byte unsigned */ | ||||||
|  | 			TwoUns(argstr, flgs); | ||||||
|  | 			OutCase(mnem, base, first, 0, argstr); | ||||||
|  | 		} else if (in(flgs, '4')) {	/* Four byte signed */ | ||||||
|  | 			FourSgn(argstr, flgs); | ||||||
|  | 			OutCase(mnem, base, first, 0, argstr); | ||||||
|  | 		} else { | ||||||
|  | 			fatal("no opcode flag in ip_spec %s\n", flgs); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	exit(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | OutCase(mnem, base, first, i, argstr) | ||||||
|  | 	char *mnem; | ||||||
|  | 	char *base; | ||||||
|  | 	int first; | ||||||
|  | 	int i; | ||||||
|  | 	char *argstr; | ||||||
|  | { | ||||||
|  | 	/* Output a case in the switch statement */ | ||||||
|  | 	fprintf(ofp, "\t\tcase %s+%d:\t%s%s(%s); break;\n", | ||||||
|  | 		base, first+i, Prefix, mnem, argstr); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 		 | ||||||
|  | ImplicitArg(argstr) | ||||||
|  | 	char *argstr; | ||||||
|  | { | ||||||
|  | 	sprintf(argstr, "uwpop()"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | NoArgs(argstr) | ||||||
|  | 	char *argstr; | ||||||
|  | { | ||||||
|  | 	sprintf(argstr, ""); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Mini(argstr, i, flgs) | ||||||
|  | 	char *argstr; | ||||||
|  | 	int i; | ||||||
|  | 	char *flgs; | ||||||
|  | { | ||||||
|  | 	int newi = in(flgs, 'N') ? (-i-1) : in(flgs, 'o') ? (i+1) : i; | ||||||
|  | 
 | ||||||
|  | 	switch (newi) { | ||||||
|  | 	case -1: | ||||||
|  | 		sprintf(argstr, "%s", | ||||||
|  | 			in(flgs, 'w') ? "-wsize" : "-1L"); | ||||||
|  | 		break; | ||||||
|  | 	case 0: | ||||||
|  | 		sprintf(argstr, "0L"); | ||||||
|  | 		break; | ||||||
|  | 	case 1: | ||||||
|  | 		sprintf(argstr, "%s", | ||||||
|  | 			in(flgs, 'w') ? "wsize" : "1L"); | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		sprintf(argstr, "%dL%s", | ||||||
|  | 			newi, in(flgs, 'w') ? "*wsize" : ""); | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Shortie(argstr, i, flgs) | ||||||
|  | 	char *argstr; | ||||||
|  | 	int i; | ||||||
|  | 	char *flgs; | ||||||
|  | { | ||||||
|  | 	int newi = in(flgs, 'N') ? (-i-1) : in(flgs, 'o') ? (i+1) : i; | ||||||
|  | 
 | ||||||
|  | 	sprintf(argstr, "S_arg(%d)*%s", | ||||||
|  | 		newi, in(flgs, 'w') ? "wsize" : "1L"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TwoSgn(argstr, flgs) | ||||||
|  | 	char *argstr; | ||||||
|  | 	char *flgs; | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | 	sprintf(argstr, "%s*%s", in(flgs, 'P') ? "P_arg_2()" : in(flgs, 'N') ? "N_arg_2()" : "L_arg_2()",  | ||||||
|  | 			in(flgs, 'w') ? "wsize" : "1L"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TwoUns(argstr, flgs) | ||||||
|  | 	char *argstr; | ||||||
|  | 	char *flgs; | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | 	sprintf(argstr,	"%s*%s", "U_arg()",  | ||||||
|  | 			in(flgs, 'w') ? "wsize" : "((unsigned long) 1)"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FourSgn(argstr, flgs) | ||||||
|  | 	char *argstr; | ||||||
|  | 	char *flgs; | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | 	sprintf(argstr,	"%s*%s", in(flgs, 'P') ? "P_arg_4()" : in(flgs, 'N') ? "N_arg_4()" : "L_arg_4()", | ||||||
|  | 			in(flgs, 'w') ? "wsize" : "1L"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 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); | ||||||
|  | } | ||||||
|  | int getmnem(str) char *str ; { | ||||||
|  | 	char (*ptr)[4] ; | ||||||
|  | 
 | ||||||
|  | 	for ( ptr = em_mnem ; *ptr<= &em_mnem[sp_lmnem][0] ; ptr++ ) { | ||||||
|  | 		if ( strcmp(*ptr,str)==0 ) return (ptr-em_mnem) ; | ||||||
|  | 	} | ||||||
|  | 	fatal("Illegal mnemonic") ; | ||||||
|  | 	return 0 ; | ||||||
|  | } | ||||||
|  | 
 | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue