Model 3 (intelligent calls) implemented
authorceriel <none@none>
Thu, 21 Jun 1990 12:11:50 +0000 (12:11 +0000)
committerceriel <none@none>
Thu, 21 Jun 1990 12:11:50 +0000 (12:11 +0000)
util/int/switch/Makefile
util/int/switch/READ_ME
util/int/switch/mkiswitch.c [new file with mode: 0644]

index ca9bc10..25aa618 100644 (file)
@@ -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
 
index 7aa1f94..f0e7484 100644 (file)
@@ -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.
-
-mkfuncs:
-       shell script that can be used to generate new function
-       files, if a new implementation is needed.
+       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".
+
+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 (file)
index 0000000..3209cbc
--- /dev/null
@@ -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 ;
+}
+