From: ceriel Date: Fri, 6 Mar 1987 14:41:52 +0000 (+0000) Subject: Initial revision X-Git-Tag: release-5-5~4495 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=742a4d91d4045c25739c2b9bd8033396b889f284;p=ack.git Initial revision --- diff --git a/doc/em/mkdispatch.c b/doc/em/mkdispatch.c new file mode 100644 index 000000000..2cb5d899a --- /dev/null +++ b/doc/em/mkdispatch.c @@ -0,0 +1,489 @@ +/* + * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. + * + * This product is part of the Amsterdam Compiler Kit. + * + * Permission to use, sell, duplicate or disclose this software must be + * obtained in writing. Requests for such permissions may be sent to + * + * Dr. Andrew S. Tanenbaum + * Wiskundig Seminarium + * Vrije Universiteit + * Postbox 7161 + * 1007 MC Amsterdam + * The Netherlands + * + */ + +#include "ip_spec.h" +#include +#include "em_spec.h" +#include "em_flag.h" + +#ifndef NORCSID +static char rcs_id[] = "$Header$" ; +#endif + +/* This program reads the human readable interpreter specification + and produces a efficient machine representation that can be + translated by a C-compiler. +*/ + +#define NOTAB 600 /* The max no of interpreter specs */ +#define ESCAP1 256 +#define ESCAP2 257 + +struct opform intable[NOTAB] ; +struct opform *lastform = intable-1 ; + +int nerror = 0 ; +int atend = 0 ; +int line = 1 ; + +extern char em_mnem[][4] ; +char esca1[] = "escape1" ; +char esca2[] = "escape2" ; +#define ename(no) ((no)==ESCAP1?esca1:(no)==ESCAP2?esca2:em_mnem[(no)]) + +extern char em_flag[] ; + +main(argc,argv) char **argv ; { + if ( argc>1 ) { + if ( freopen(argv[1],"r",stdin)==NULL) { + fatal("Cannot open %s",argv[1]) ; + } + } + if ( argc>2 ) { + if ( freopen(argv[2],"w",stdout)==NULL) { + fatal("Cannot create %s",argv[2]) ; + } + } + if ( argc>3 ) { + fatal("%s [ file [ file ] ]",argv[0]) ; + } + atend=0 ; + readin(); + atend=1 ; + checkall(); + if ( nerror==0 ) { + writeout(); + } + return nerror ; +} + +readin() { + register struct opform *nextform ; + char *ident(); + char *firstid ; + + for ( nextform=intable ; + !feof(stdin) && nextform<&intable[NOTAB] ; ) { + firstid=ident() ; + if ( *firstid=='\n' || feof(stdin) ) continue ; + lastform=nextform ; + nextform->i_opcode = getmnem(firstid) ; + nextform->i_flag = decflag(ident()) ; + switch ( nextform->i_flag&OPTYPE ) { + case OPMINI: + case OPSHORT: + nextform->i_num = atoi(ident()) ; + break ; + } + nextform->i_low = atoi(ident()) ; + if ( *ident()!='\n' ) { + int c ; + error("End of line expected"); + while ( (c=readchar())!='\n' && c!=EOF ) ; + } + nextform++ ; + } + if ( !feof(stdin) ) fatal("Internal table too small") ; +} + +char *ident() { + /* skip spaces and tabs, anything up to space,tab or eof is + a identifier. + Anything from # to end-of-line is an end-of-line. + End-of-line is an identifier all by itself. + */ + + static char array[200] ; + register int c ; + register char *cc ; + + do { + c=readchar() ; + } while ( c==' ' || c=='\t' ) ; + for ( cc=array ; cc<&array[(sizeof array) - 1] ; cc++ ) { + if ( c=='#' ) { + do { + c=readchar(); + } while ( c!='\n' && c!=EOF ) ; + } + *cc = c ; + if ( c=='\n' && cc==array ) break ; + c=readchar() ; + if ( c=='\n' ) { + pushback(c) ; + break ; + } + if ( c==' ' || c=='\t' || c==EOF ) break ; + } + *++cc=0 ; + return array ; +} + +int getmnem(str) char *str ; { + char (*ptr)[4] ; + + for ( ptr = em_mnem ; *ptr<= &em_mnem[sp_lmnem-sp_fmnem][0] ; ptr++ ) { + if ( strcmp(*ptr,str)==0 ) return (ptr-em_mnem) ; + } + error("Illegal mnemonic") ; + return 0 ; +} + +error(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; { + if ( !atend ) fprintf(stderr,"line %d: ",line) ; + fprintf(stderr,str,a1,a2,a3,a4,a5,a6) ; + fprintf(stderr,"\n"); + nerror++ ; +} + +mess(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; { + if ( !atend ) fprintf(stderr,"line %d: ",line) ; + fprintf(stderr,str,a1,a2,a3,a4,a5,a6) ; + fprintf(stderr,"\n"); +} + +fatal(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; { + error(str,a1,a2,a3,a4,a5,a6) ; + exit(1) ; +} + +#define ILLGL -1 + +check(val) int val ; { + if ( val!=ILLGL ) error("Illegal flag combination") ; +} + +int decflag(str) char *str ; { + int type ; + int escape ; + int range ; + int wordm ; + int notzero ; + + type=escape=range=wordm=notzero= ILLGL ; + while ( *str ) switch ( *str++ ) { + case 'm' : + check(type) ; type=OPMINI ; break ; + case 's' : + check(type) ; type=OPSHORT ; break ; + case '-' : + check(type) ; type=OPNO ; break ; + case '1' : + check(type) ; type=OP8 ; break ; + case '2' : + check(type) ; type=OP16 ; break ; + case '4' : + check(type) ; type=OP32 ; break ; + case '8' : + check(type) ; type=OP64 ; break ; + case 'e' : + check(escape) ; escape=0 ; break ; + case 'N' : + check(range) ; range= 2 ; break ; + case 'P' : + check(range) ; range= 1 ; break ; + case 'w' : + check(wordm) ; wordm=0 ; break ; + case 'o' : + check(notzero) ; notzero=0 ; break ; + default : + error("Unknown flag") ; + } + if ( type==ILLGL ) error("Type must be specified") ; + switch ( type ) { + case OP64 : + case OP32 : + if ( escape!=ILLGL ) error("Conflicting escapes") ; + escape=ILLGL ; + case OP16 : + case OP8 : + case OPSHORT : + case OPNO : + if ( notzero!=ILLGL ) mess("Improbable OPNZ") ; + if ( type==OPNO && range!=ILLGL ) { + mess("No operand in range") ; + } + } + if ( escape!=ILLGL ) type|=OPESC ; + if ( wordm!=ILLGL ) type|=OPWORD ; + switch ( range) { + case ILLGL : type|=OP_BOTH ; + if ( type==OPMINI || type==OPSHORT ) + error("Minies and shorties must have P or N") ; + break ; + case 1 : type|=OP_POS ; break ; + case 2 : type|=OP_NEG ; break ; + } + if ( notzero!=ILLGL ) type|=OPNZ ; + return type ; +} + +/* ----------- checking --------------*/ + +int ecodes[256],codes[256],lcodes[256] ; +char eflags[256], flags[256]; +int elows[256], lows[256]; + +#define NMNEM (sp_lmnem-sp_fmnem+1) +#define MUST 1 +#define MAY 2 +#define FORB 3 + +char negc[NMNEM], zc[NMNEM], posc[NMNEM] ; + +checkall() { + register i,flag ; + register struct opform *next ; + int opc,low ; + + for ( i=0 ; ii_flag&0377 ; + opc = next->i_opcode&0377 ; + low = next->i_low&0377 ; + chkc(flag,low,opc,low) ; + switch(flag&OPTYPE) { + case OPNO : zc[opc]++ ; break ; + case OPMINI : + case OPSHORT : + for ( i=1 ; i<((next->i_num)&0377) ; i++ ) { + chkc(flag,low+i,opc,low) ; + } + if ( !(em_flag[opc]&PAR_G) && + (flag&OPRANGE)==OP_BOTH) { + mess("Mini's and shorties should have P or N"); + } + break ; + case OP8 : + error("OP8 is removed") ; + break ; + case OP16 : + if ( flag&OP_NEG ) + negc[opc]++ ; + else if ( flag&OP_POS ) + posc[opc]++ ; + break ; + case OP32 : + case OP64 : + break ; + default : + error("Illegal type") ; + break ; + } + } + atend=1 ; + for ( i=0 ; i<256 ; i++ ) if ( codes[i]== -1 ) { + mess("interpreter opcode %d not used",i) ; + } + for ( opc=0 ; opc1 ) mess("More then one OPNO for %s",ename(emc)) ; + if ( posc[emc]>1 ) mess("More then one OP16(pos) for %s",ename(emc)) ; + if ( negc[emc]>1 ) mess("More then one OP16(neg) for %s",ename(emc)) ; + switch(zf) { + case MUST: + if ( zc[emc]==0 ) mess("No OPNO for %s",ename(emc)) ; + break ; + case FORB: + if ( zc[emc]==1 ) mess("Forbidden OPNO for %s",ename(emc)) ; + break ; + } + switch(pf) { + case MUST: + if ( posc[emc]==0 ) mess("No OP16(pos) for %s",ename(emc)) ; + break ; + case FORB: + if ( posc[emc]==1 ) + mess("Forbidden OP16(pos) for %s",ename(emc)) ; + break ; + } + switch(nf) { + case MUST: + if ( negc[emc]==0 ) mess("No OP16(neg) for %s",ename(emc)) ; + break ; + case FORB: + if ( negc[emc]==1 ) + mess("Forbidden OP16(neg) for %s",ename(emc)) ; + break ; + } +} + +static int pushchar ; +static int pushf ; + +int readchar() { + int c ; + + if ( pushf ) { + pushf=0 ; + c = pushchar ; + } else { + if ( feof(stdin) ) return EOF ; + c=getc(stdin) ; + } + if ( c=='\n' ) line++ ; + return c ; +} + +pushback(c) { + if ( pushf ) { + fatal("Double pushback") ; + } + pushf++ ; + pushchar=c ; + if ( c=='\n' ) line-- ; +} + +writeout() { + register int i; + + printf("DISPATCH\n"); + for (i = 0; i < 256;) { + if (!(i % 8)) printf("%d\t", i); + printf(ename(codes[i])); + if (i < 254) { + prx(flags[i],lows[i],i); + } + else putchar('\t'); + i++; + if (!(i % 8)) putchar('\n'); + } + + printf("DISPATCH2\n"); + for (i = 0; i < 256;) { + int x = 0; + if (ecodes[i] != -1) { + if (!(i % 8)) printf("%d\t", i); + printf(ename(ecodes[i])); + prx(eflags[i],elows[i],i); + } + else x = 1; + i++; + if (!(i % 8)) { + putchar('\n'); + if (x) break; + } + } + + printf("DISPATCH3\n"); + i = 0; + while (lcodes[i] != -1) { + if (!(i % 8)) printf("%d\t", i); + printf("%s\t", ename(ecodes[i])); + i++; + if (!(i % 8)) putchar('\n'); + } + if (i % 8) putchar('\n'); +} + +prx(flg,low,opc) + register int flg; +{ + int arg = opc - low; + + putchar('.'); + switch(flg&OPTYPE) { + case OPNO: + putchar('z'); + break; + case OP16: + if (flg&OP_POS) putchar('p'); + else if (flg&OP_NEG) putchar('n'); + else putchar('l'); + if (flg&OPWORD) putchar('w'); + break; + case OPSHORT: + if (flg & OPWORD) putchar('w'); + else putchar('s'); + /* fall through */ + case OPMINI: + if (flg & OPNZ) arg++; + if (flg & OP_NEG) arg = -arg - 1; + printf("%d",arg); + if((flg&OPTYPE) == OPMINI && (flg & OPWORD)) putchar('W'); + } + putchar('\t'); +}