mkdispatch.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. *
  5. */
  6. #include "ip_spec.h"
  7. #include <stdio.h>
  8. #include "em_spec.h"
  9. #include "em_flag.h"
  10. #ifndef NORCSID
  11. static char rcs_id[] = "$Id$" ;
  12. #endif
  13. /* This program reads the human readable interpreter specification
  14. and produces a efficient machine representation that can be
  15. translated by a C-compiler.
  16. */
  17. #define NOTAB 600 /* The max no of interpreter specs */
  18. #define ESCAP1 256
  19. #define ESCAP2 257
  20. struct opform intable[NOTAB] ;
  21. struct opform *lastform = intable-1 ;
  22. int nerror = 0 ;
  23. int atend = 0 ;
  24. int line = 1 ;
  25. extern char em_mnem[][4] ;
  26. char esca1[] = "escape1" ;
  27. char esca2[] = "escape2" ;
  28. #define ename(no) ((no)==ESCAP1?esca1:(no)==ESCAP2?esca2:em_mnem[(no)])
  29. extern char em_flag[] ;
  30. main(argc,argv) char **argv ; {
  31. if ( argc>1 ) {
  32. if ( freopen(argv[1],"r",stdin)==NULL) {
  33. fatal("Cannot open %s",argv[1]) ;
  34. }
  35. }
  36. if ( argc>2 ) {
  37. if ( freopen(argv[2],"w",stdout)==NULL) {
  38. fatal("Cannot create %s",argv[2]) ;
  39. }
  40. }
  41. if ( argc>3 ) {
  42. fatal("%s [ file [ file ] ]",argv[0]) ;
  43. }
  44. atend=0 ;
  45. readin();
  46. atend=1 ;
  47. checkall();
  48. if ( nerror==0 ) {
  49. writeout();
  50. }
  51. exit(nerror) ;
  52. }
  53. readin() {
  54. register struct opform *nextform ;
  55. char *ident();
  56. char *firstid ;
  57. for ( nextform=intable ;
  58. !feof(stdin) && nextform<&intable[NOTAB] ; ) {
  59. firstid=ident() ;
  60. if ( *firstid=='\n' || feof(stdin) ) continue ;
  61. lastform=nextform ;
  62. nextform->i_opcode = getmnem(firstid) ;
  63. nextform->i_flag = decflag(ident()) ;
  64. switch ( nextform->i_flag&OPTYPE ) {
  65. case OPMINI:
  66. case OPSHORT:
  67. nextform->i_num = atoi(ident()) ;
  68. break ;
  69. }
  70. nextform->i_low = atoi(ident()) ;
  71. if ( *ident()!='\n' ) {
  72. int c ;
  73. error("End of line expected");
  74. while ( (c=readchar())!='\n' && c!=EOF ) ;
  75. }
  76. nextform++ ;
  77. }
  78. if ( !feof(stdin) ) fatal("Internal table too small") ;
  79. }
  80. char *ident() {
  81. /* skip spaces and tabs, anything up to space,tab or eof is
  82. a identifier.
  83. Anything from # to end-of-line is an end-of-line.
  84. End-of-line is an identifier all by itself.
  85. */
  86. static char array[200] ;
  87. register int c ;
  88. register char *cc ;
  89. do {
  90. c=readchar() ;
  91. } while ( c==' ' || c=='\t' ) ;
  92. for ( cc=array ; cc<&array[(sizeof array) - 1] ; cc++ ) {
  93. if ( c=='#' ) {
  94. do {
  95. c=readchar();
  96. } while ( c!='\n' && c!=EOF ) ;
  97. }
  98. *cc = c ;
  99. if ( c=='\n' && cc==array ) break ;
  100. c=readchar() ;
  101. if ( c=='\n' ) {
  102. pushback(c) ;
  103. break ;
  104. }
  105. if ( c==' ' || c=='\t' || c==EOF ) break ;
  106. }
  107. *++cc=0 ;
  108. return array ;
  109. }
  110. int getmnem(str) char *str ; {
  111. char (*ptr)[4] ;
  112. for ( ptr = em_mnem ; *ptr<= &em_mnem[sp_lmnem-sp_fmnem][0] ; ptr++ ) {
  113. if ( strcmp(*ptr,str)==0 ) return (ptr-em_mnem) ;
  114. }
  115. error("Illegal mnemonic") ;
  116. return 0 ;
  117. }
  118. error(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; {
  119. if ( !atend ) fprintf(stderr,"line %d: ",line) ;
  120. fprintf(stderr,str,a1,a2,a3,a4,a5,a6) ;
  121. fprintf(stderr,"\n");
  122. nerror++ ;
  123. }
  124. mess(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; {
  125. if ( !atend ) fprintf(stderr,"line %d: ",line) ;
  126. fprintf(stderr,str,a1,a2,a3,a4,a5,a6) ;
  127. fprintf(stderr,"\n");
  128. }
  129. fatal(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; {
  130. error(str,a1,a2,a3,a4,a5,a6) ;
  131. exit(1) ;
  132. }
  133. #define ILLGL -1
  134. check(val) int val ; {
  135. if ( val!=ILLGL ) error("Illegal flag combination") ;
  136. }
  137. int decflag(str) char *str ; {
  138. int type ;
  139. int escape ;
  140. int range ;
  141. int wordm ;
  142. int notzero ;
  143. type=escape=range=wordm=notzero= ILLGL ;
  144. while ( *str ) switch ( *str++ ) {
  145. case 'm' :
  146. check(type) ; type=OPMINI ; break ;
  147. case 's' :
  148. check(type) ; type=OPSHORT ; break ;
  149. case '-' :
  150. check(type) ; type=OPNO ; break ;
  151. case '1' :
  152. check(type) ; type=OP8 ; break ;
  153. case '2' :
  154. check(type) ; type=OP16 ; break ;
  155. case '4' :
  156. check(type) ; type=OP32 ; break ;
  157. case '8' :
  158. check(type) ; type=OP64 ; break ;
  159. case 'u' :
  160. check(type) ; type=OP16U ; break ;
  161. case 'e' :
  162. check(escape) ; escape=0 ; break ;
  163. case 'N' :
  164. check(range) ; range= 2 ; break ;
  165. case 'P' :
  166. check(range) ; range= 1 ; break ;
  167. case 'w' :
  168. check(wordm) ; wordm=0 ; break ;
  169. case 'o' :
  170. check(notzero) ; notzero=0 ; break ;
  171. default :
  172. error("Unknown flag") ;
  173. }
  174. if ( type==ILLGL ) error("Type must be specified") ;
  175. switch ( type ) {
  176. case OP64 :
  177. case OP32 :
  178. if ( escape!=ILLGL ) error("Conflicting escapes") ;
  179. escape=ILLGL ;
  180. case OP16 :
  181. case OP16U :
  182. case OP8 :
  183. case OPSHORT :
  184. case OPNO :
  185. if ( notzero!=ILLGL ) mess("Improbable OPNZ") ;
  186. if ( type==OPNO && range!=ILLGL ) {
  187. mess("No operand in range") ;
  188. }
  189. }
  190. if ( escape!=ILLGL ) type|=OPESC ;
  191. if ( wordm!=ILLGL ) type|=OPWORD ;
  192. switch ( range) {
  193. case ILLGL : type|=OP_BOTH ;
  194. if ( type==OPMINI || type==OPSHORT )
  195. error("Minies and shorties must have P or N") ;
  196. break ;
  197. case 1 : type|=OP_POS ; break ;
  198. case 2 : type|=OP_NEG ; break ;
  199. }
  200. if ( notzero!=ILLGL ) type|=OPNZ ;
  201. return type ;
  202. }
  203. /* ----------- checking --------------*/
  204. int ecodes[256],codes[256],lcodes[256] ;
  205. char eflags[256], flags[256], lflags[256] ;
  206. int elows[256], lows[256], llows[256];
  207. #define NMNEM (sp_lmnem-sp_fmnem+1)
  208. #define MUST 1
  209. #define MAY 2
  210. #define FORB 3
  211. char negc[NMNEM], zc[NMNEM], posc[NMNEM], lnegc[NMNEM], lposc[NMNEM] ;
  212. checkall() {
  213. register i,flag ;
  214. register struct opform *next ;
  215. int opc,low ;
  216. for ( i=0 ; i<NMNEM ; i++ ) negc[i]=zc[i]=posc[i]=0 ;
  217. for ( i=0 ; i<256 ; i++ ) lcodes[i]= codes[i]= ecodes[i]= -1 ;
  218. codes[254]=ESCAP1; codes[255]=ESCAP2;
  219. atend=0 ; line=0 ;
  220. for ( next=intable ; next<=lastform ; next++ ) {
  221. line++ ;
  222. flag = next->i_flag&0377 ;
  223. opc = next->i_opcode&0377 ;
  224. low = next->i_low&0377 ;
  225. chkc(flag,low,opc,low) ;
  226. switch(flag&OPTYPE) {
  227. case OPNO : zc[opc]++ ; break ;
  228. case OPMINI :
  229. case OPSHORT :
  230. for ( i=1 ; i<((next->i_num)&0377) ; i++ ) {
  231. chkc(flag,low+i,opc,low) ;
  232. }
  233. if ( !(em_flag[opc]&PAR_G) &&
  234. (flag&OPRANGE)==OP_BOTH) {
  235. mess("Mini's and shorties should have P or N");
  236. }
  237. break ;
  238. case OP8 :
  239. error("OP8 is removed") ;
  240. break ;
  241. case OP16 :
  242. if ( flag&OP_NEG )
  243. negc[opc]++ ;
  244. else if ( flag&OP_POS )
  245. posc[opc]++ ;
  246. break ;
  247. case OP32 :
  248. if ( flag&OP_NEG )
  249. lnegc[opc]++ ;
  250. else if ( flag&OP_POS )
  251. lposc[opc]++ ;
  252. break ;
  253. case OP16U :
  254. break ;
  255. default :
  256. error("Illegal type") ;
  257. break ;
  258. }
  259. }
  260. atend=1 ;
  261. for ( i=0 ; i<256 ; i++ ) if ( codes[i]== -1 ) {
  262. mess("interpreter opcode %d not used",i) ;
  263. }
  264. for ( opc=0 ; opc<NMNEM ; opc++ ) {
  265. switch(em_flag[opc]&EM_PAR) {
  266. case PAR_NO :
  267. ckop(opc,MUST,FORB,FORB) ;
  268. break ;
  269. case PAR_C:
  270. case PAR_D:
  271. case PAR_F:
  272. case PAR_B:
  273. ckop(opc,FORB,MAY,MAY) ;
  274. break ;
  275. case PAR_N:
  276. case PAR_G:
  277. case PAR_S:
  278. case PAR_Z:
  279. case PAR_O:
  280. case PAR_P:
  281. ckop(opc,FORB,MAY,FORB) ;
  282. break ;
  283. case PAR_R:
  284. ckop(opc,FORB,MAY,FORB) ;
  285. break ;
  286. case PAR_L:
  287. ckop(opc,FORB,MUST,MUST) ;
  288. break ;
  289. case PAR_W:
  290. ckop(opc,MUST,MAY,FORB) ;
  291. break ;
  292. default :
  293. error("Unknown instruction type of %s",ename(opc)) ;
  294. break ;
  295. }
  296. }
  297. }
  298. chkc(flag,icode,emc,low) {
  299. if ( flag&OPESC ) {
  300. if ( ecodes[icode]!=-1 ) {
  301. mess("Escaped opcode %d used by %s and %s",
  302. icode,ename(emc),ename(ecodes[icode])) ;
  303. }
  304. ecodes[icode]=emc;
  305. eflags[icode]=flag;
  306. elows[icode]=low;
  307. } else switch ( flag&OPTYPE ) {
  308. default:
  309. if ( codes[icode]!=-1 ) {
  310. mess("Opcode %d used by %s and %s",
  311. icode,ename(emc),ename(codes[icode])) ;
  312. }
  313. codes[icode]=emc;
  314. flags[icode]=flag;
  315. lows[icode]=low;
  316. break ;
  317. case OP32:
  318. case OP64:
  319. if ( lcodes[icode]!=-1 ) {
  320. mess("Long opcode %d used by %s and %s",
  321. icode,ename(emc),ename(lcodes[icode])) ;
  322. }
  323. lcodes[icode]=emc;
  324. lflags[icode]=flag;
  325. llows[icode]=low;
  326. break ;
  327. }
  328. }
  329. ckop(emc,zf,pf,nf) {
  330. if ( zc[emc]>1 ) mess("More then one OPNO for %s",ename(emc)) ;
  331. if ( posc[emc]>1 ) mess("More then one OP16(pos) for %s",ename(emc)) ;
  332. if ( negc[emc]>1 ) mess("More then one OP16(neg) for %s",ename(emc)) ;
  333. if ( lposc[emc]>1 ) mess("More then one OP32(pos) for %s",ename(emc)) ;
  334. if ( lnegc[emc]>1 ) mess("More then one OP32(neg) for %s",ename(emc)) ;
  335. switch(zf) {
  336. case MUST:
  337. if ( zc[emc]==0 ) mess("No OPNO for %s",ename(emc)) ;
  338. break ;
  339. case FORB:
  340. if ( zc[emc]==1 ) mess("Forbidden OPNO for %s",ename(emc)) ;
  341. break ;
  342. }
  343. switch(pf) {
  344. case MUST:
  345. if ( posc[emc]==0 ) mess("No OP16(pos) for %s",ename(emc)) ;
  346. break ;
  347. case FORB:
  348. if ( posc[emc]==1 )
  349. mess("Forbidden OP16(pos) for %s",ename(emc)) ;
  350. break ;
  351. }
  352. switch(nf) {
  353. case MUST:
  354. if ( negc[emc]==0 ) mess("No OP16(neg) for %s",ename(emc)) ;
  355. break ;
  356. case FORB:
  357. if ( negc[emc]==1 )
  358. mess("Forbidden OP16(neg) for %s",ename(emc)) ;
  359. break ;
  360. }
  361. }
  362. static int pushchar ;
  363. static int pushf ;
  364. int readchar() {
  365. int c ;
  366. if ( pushf ) {
  367. pushf=0 ;
  368. c = pushchar ;
  369. } else {
  370. if ( feof(stdin) ) return EOF ;
  371. c=getc(stdin) ;
  372. }
  373. if ( c=='\n' ) line++ ;
  374. return c ;
  375. }
  376. pushback(c) {
  377. if ( pushf ) {
  378. fatal("Double pushback") ;
  379. }
  380. pushf++ ;
  381. pushchar=c ;
  382. if ( c=='\n' ) line-- ;
  383. }
  384. writeout() {
  385. register int i;
  386. printf("DISPATCH1");
  387. for (i = 0; i < 256;) {
  388. if (!(i % 8)) printf("\n%d", i);
  389. printf("\t%s", ename(codes[i]));
  390. if (i < 254) {
  391. prx(flags[i],lows[i],i);
  392. }
  393. i++;
  394. }
  395. printf("\nDISPATCH2");
  396. for (i = 0; i < 256;) {
  397. if (ecodes[i] != -1) {
  398. if (!(i % 8)) printf("\n%d", i);
  399. printf("\t%s", ename(ecodes[i]));
  400. prx(eflags[i],elows[i],i);
  401. }
  402. else break;
  403. i++;
  404. }
  405. printf("\nDISPATCH3");
  406. i = 0;
  407. while (lcodes[i] != -1) {
  408. if (!(i % 8)) printf("\n%d", i);
  409. printf("\t%s", ename(lcodes[i]));
  410. prx(lflags[i],llows[i],i);
  411. i++;
  412. }
  413. while (i++ % 8) putchar('\t');
  414. putchar('\n');
  415. }
  416. prx(flg,low,opc)
  417. register int flg;
  418. {
  419. int arg = opc - low;
  420. putchar('.');
  421. switch(flg&OPTYPE) {
  422. case OPNO:
  423. putchar('z');
  424. break;
  425. case OP16U:
  426. putchar('u');
  427. break;
  428. case OP16:
  429. if (flg&OP_POS) putchar('p');
  430. else if (flg&OP_NEG) putchar('n');
  431. else putchar('l');
  432. if (flg&OPWORD) putchar('w');
  433. break;
  434. case OP32:
  435. if (flg&OP_POS) putchar('P');
  436. else if (flg&OP_NEG) putchar('N');
  437. else putchar('L');
  438. if (flg&OPWORD) putchar('w');
  439. break;
  440. case OPSHORT:
  441. if (flg & OPWORD) putchar('w');
  442. else putchar('s');
  443. /* fall through */
  444. case OPMINI:
  445. if (flg & OPNZ) arg++;
  446. if (flg & OP_NEG) arg = -arg - 1;
  447. printf("%d",arg);
  448. if((flg&OPTYPE) == OPMINI && (flg & OPWORD)) putchar('W');
  449. }
  450. }