From c7c79e9b4237a0e15ca624eee1b0febc8f4d183e Mon Sep 17 00:00:00 2001 From: ceriel Date: Thu, 21 Jun 1990 12:11:50 +0000 Subject: [PATCH] Model 3 (intelligent calls) implemented --- util/int/switch/Makefile | 23 +-- util/int/switch/READ_ME | 20 ++- util/int/switch/mkiswitch.c | 276 ++++++++++++++++++++++++++++++++++++ 3 files changed, 305 insertions(+), 14 deletions(-) create mode 100644 util/int/switch/mkiswitch.c diff --git a/util/int/switch/Makefile b/util/int/switch/Makefile index ca9bc10ae..25aa6188e 100644 --- a/util/int/switch/Makefile +++ b/util/int/switch/Makefile @@ -1,15 +1,20 @@ # $Header$ -IP_SPEC = ../../../etc/ip_spec.t +EM = ../../.. +IP_SPEC = $(EM)/etc/ip_spec.t +CFLAGS = -I$(EM) -SRC = mkswitch.c -OBJ = mkswitch.o +SRC = mkiswitch.c mkswitch.c +OBJ = mkiswitch.o mkswitch.o -mkswitch: $(OBJ) - $(CC) -o mkswitch $(OBJ) +mkiswitch: mkiswitch.o + $(CC) -o mkiswitch mkiswitch.o $(EM)/lib/em_data.a -DoCases: mkswitch $(IP_SPEC) - mkswitch Do $(IP_SPEC) DoCases +mkswitch: mkswitch.o + $(CC) -o mkswitch mkswitch.o + +DoCases: mkiswitch $(IP_SPEC) + mkiswitch Do $(IP_SPEC) DoCases wc DoCases PrCases: mkswitch $(IP_SPEC) @@ -29,10 +34,10 @@ distr: .distr $(CC) $(CFLAGS) -c $< clean: # NOT the cases files ! - /bin/rm -f a.out core $(OBJ) mkswitch + rm -f a.out core $(OBJ) mkswitch mkiswitch bare: clean - /bin/rm -f DoCases PrCases + rm -f DoCases PrCases all: mkswitch diff --git a/util/int/switch/READ_ME b/util/int/switch/READ_ME index 7aa1f946d..f0e74848e 100644 --- a/util/int/switch/READ_ME +++ b/util/int/switch/READ_ME @@ -3,12 +3,20 @@ This directory contains two programs: mkswitch: - C program, necessary for regenerating the giant switches - which are part of the INT project. + C program, necessary for regenerating the giant switch + 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: - shell script that can be used to generate new function - files, if a new implementation is needed. +mkiswitch: + C program, necessary for regenerating the giant switch + 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 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 XXX is the name of the corresponding instruction group. +(Note: these remarks about mkfuncs are probably outdated now, +since mkfuncs has disappeared. -rbf) diff --git a/util/int/switch/mkiswitch.c b/util/int/switch/mkiswitch.c new file mode 100644 index 000000000..3209cbc00 --- /dev/null +++ b/util/int/switch/mkiswitch.c @@ -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 + +extern char *sprintf(); +extern FILE *popen(); + +#include +#include +#include + +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