decode.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. /*
  2. * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. *
  4. * This product is part of the Amsterdam Compiler Kit.
  5. *
  6. * Permission to use, sell, duplicate or disclose this software must be
  7. * obtained in writing. Requests for such permissions may be sent to
  8. *
  9. * Dr. Andrew S. Tanenbaum
  10. * Wiskundig Seminarium
  11. * Vrije Universiteit
  12. * Postbox 7161
  13. * 1007 MC Amsterdam
  14. * The Netherlands
  15. *
  16. */
  17. #ifndef NORCSID
  18. static char rcsid[] = "$Header$";
  19. #endif
  20. /*
  21. * Decode compact EM assembly language
  22. *
  23. * Author: Johan Stevenson, Vrije Universiteit, Amsterdam
  24. */
  25. #include <stdio.h>
  26. #include <assert.h>
  27. #include <ctype.h>
  28. #include <em_spec.h>
  29. #include <em_pseu.h>
  30. #include <em_flag.h>
  31. #include <em_ptyp.h>
  32. #include <em_mes.h>
  33. #define get8() ((unsigned)getchar())
  34. #define check(x) if (!(x)) fail_check()
  35. #define MAXSTR 256
  36. /*
  37. * global variables
  38. */
  39. int opcode;
  40. int offtyp;
  41. long argval;
  42. int dlbval;
  43. char string[MAXSTR];
  44. int strsiz;
  45. int wsize;
  46. int psize;
  47. int lineno;
  48. int argnum;
  49. int errors;
  50. char *progname;
  51. char *filename;
  52. long wordmask[] = { /* allowed bits in a word */
  53. 0x00000000,
  54. 0x000000FF,
  55. 0x0000FFFF,
  56. 0x00000000,
  57. 0xFFFFFFFF
  58. };
  59. long sizemask[] = { /* allowed bits in multiples of 'wsize' */
  60. 0x00000000,
  61. 0x7FFFFFFF,
  62. 0x7FFFFFFE,
  63. 0x00000000,
  64. 0x7FFFFFFC
  65. };
  66. /*
  67. * external tables
  68. */
  69. extern char em_flag[];
  70. extern short em_ptyp[];
  71. extern char em_mnem[][4];
  72. extern char em_pseu[][4];
  73. /*
  74. * routines
  75. */
  76. int get16();
  77. long get32();
  78. main(argc,argv) char **argv; {
  79. progname = argv[0];
  80. if (argc >= 2) {
  81. filename = argv[1];
  82. if (freopen(argv[1],"r",stdin) == NULL)
  83. fatal("can't open %s",argv[1]);
  84. }
  85. if (argc >= 3)
  86. if (freopen(argv[2],"w",stdout) == NULL)
  87. fatal("can't create %s",argv[2]);
  88. if (get16() != sp_magic)
  89. fatal("bad magic word");
  90. /* In System III the array is called _ctype[] without the trailing '_' */
  91. (_ctype_+1)['_'] = (_ctype_+1)['a'];
  92. while (nextline())
  93. ;
  94. return(errors ? -1 : 0);
  95. }
  96. /* ----- copy ----- */
  97. int nextline() {
  98. register t;
  99. lineno++;
  100. argnum = 1;
  101. switch (t = table1()) {
  102. case EOF:
  103. return(0);
  104. case sp_fmnem:
  105. instr();
  106. break;
  107. case sp_fpseu:
  108. pseudo();
  109. break;
  110. case sp_ilb1:
  111. case sp_ilb2:
  112. argnum = 0;
  113. putarg(sp_cst2);
  114. break;
  115. case sp_dlb1:
  116. case sp_dlb2:
  117. case sp_dnam:
  118. argnum = 0;
  119. putarg(t);
  120. break;
  121. default:
  122. error("unknown opcode %d",t);
  123. }
  124. putchar('\n');
  125. return(1);
  126. }
  127. instr() {
  128. register i,j,t;
  129. register long l;
  130. i = opcode - sp_fmnem;
  131. printf(" %s",em_mnem[i]);
  132. j = em_flag[i] & EM_PAR;
  133. if (j == PAR_NO)
  134. return;
  135. t = em_ptyp[j];
  136. t = getarg(t);
  137. /*
  138. * range checking
  139. */
  140. switch (j) {
  141. case PAR_N:
  142. check(argval >= 0);
  143. break;
  144. case PAR_G:
  145. if (t != sp_cst2 && t != sp_cst4)
  146. break;
  147. check(argval >= 0);
  148. /* fall through */
  149. case PAR_L:
  150. l = argval >= 0 ? argval : -argval;
  151. check((l & ~wordmask[psize]) == 0);
  152. break;
  153. case PAR_W:
  154. if (t == sp_cend)
  155. break;
  156. check((argval & ~wordmask[wsize]) == 0);
  157. /* fall through */
  158. case PAR_S:
  159. check(argval != 0);
  160. /* fall through */
  161. case PAR_Z:
  162. check((argval & ~sizemask[wsize]) == 0);
  163. break;
  164. case PAR_O:
  165. check(argval != 0);
  166. check((argval & ~sizemask[wsize])==0 || (wsize % argval)==0);
  167. break;
  168. case PAR_B:
  169. t = sp_ilb2;
  170. break;
  171. case PAR_R:
  172. check(argval >= 0 && argval <= 2);
  173. break;
  174. }
  175. putarg(t);
  176. }
  177. pseudo() {
  178. register i,t;
  179. i = opcode;
  180. printf(" %s",em_pseu[i - sp_fpseu]);
  181. switch (i) {
  182. case ps_bss:
  183. case ps_hol:
  184. putarg(getarg(cst_ptyp));
  185. putarg(getarg(val_ptyp));
  186. putarg(getarg(ptyp(sp_cst2)));
  187. check(argval==0 || argval==1);
  188. break;
  189. case ps_rom:
  190. case ps_con:
  191. putarg(getarg(val_ptyp));
  192. while ((t = getarg(any_ptyp)) != sp_cend)
  193. putarg(t);
  194. break;
  195. case ps_mes:
  196. putarg(getarg(ptyp(sp_cst2)));
  197. if (argval == ms_emx) {
  198. putarg(getarg(ptyp(sp_cst2)));
  199. check(argval > 0 && argval <= 4);
  200. wsize = (int) argval;
  201. putarg(getarg(ptyp(sp_cst2)));
  202. check(argval > 0 && argval <= 4);
  203. psize = (int) argval;
  204. }
  205. while ((t = getarg(any_ptyp)) != sp_cend)
  206. putarg(t);
  207. break;
  208. case ps_exa:
  209. case ps_ina:
  210. putarg(getarg(sym_ptyp));
  211. break;
  212. case ps_exp:
  213. case ps_inp:
  214. putarg(getarg(ptyp(sp_pnam)));
  215. break;
  216. case ps_exc:
  217. putarg(getarg(ptyp(sp_cst2)));
  218. putarg(getarg(ptyp(sp_cst2)));
  219. break;
  220. case ps_pro:
  221. putarg(getarg(ptyp(sp_pnam)));
  222. putarg(getarg(cst_ptyp|ptyp(sp_cend)));
  223. break;
  224. case ps_end:
  225. putarg(getarg(cst_ptyp|ptyp(sp_cend)));
  226. break;
  227. default:
  228. error("bad pseudo %d",i);
  229. }
  230. }
  231. /* ----- input ----- */
  232. int getarg(typset) {
  233. register t,argtyp;
  234. argtyp = t = table2();
  235. if (t == EOF)
  236. fatal("unexpected EOF");
  237. t -= sp_fspec;
  238. assert(t >= 0 && t < 16);
  239. t = 1 << t;
  240. if ((typset & t) == 0)
  241. error("bad argument type %d",argtyp);
  242. return(argtyp);
  243. }
  244. int table1() {
  245. register i;
  246. i = get8();
  247. if (i < sp_fmnem+sp_nmnem && i >= sp_fmnem) {
  248. opcode = i;
  249. return(sp_fmnem);
  250. }
  251. if (i < sp_fpseu+sp_npseu && i >= sp_fpseu) {
  252. opcode = i;
  253. return(sp_fpseu);
  254. }
  255. if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) {
  256. argval = i - sp_filb0;
  257. return(sp_ilb2);
  258. }
  259. return(table3(i));
  260. }
  261. int table2() {
  262. register i;
  263. i = get8();
  264. if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) {
  265. argval = i - sp_zcst0;
  266. return(sp_cst2);
  267. }
  268. return(table3(i));
  269. }
  270. int table3(i) {
  271. long consiz;
  272. switch(i) {
  273. case sp_ilb1:
  274. argval = get8();
  275. break;
  276. case sp_dlb1:
  277. dlbval = get8();
  278. break;
  279. case sp_dlb2:
  280. dlbval = get16();
  281. if ( dlbval<0 ) {
  282. error("illegal data label .%d",dlbval);
  283. dlbval=0 ;
  284. }
  285. break;
  286. case sp_cst2:
  287. argval = get16();
  288. break;
  289. case sp_ilb2:
  290. argval = get16();
  291. if ( argval<0 ) {
  292. error("illegal instruction label %ld",argval);
  293. argval=0 ;
  294. }
  295. break;
  296. case sp_cst4:
  297. argval = get32();
  298. break;
  299. case sp_dnam:
  300. case sp_pnam:
  301. getstring(1);
  302. break;
  303. case sp_scon:
  304. getstring(0);
  305. break;
  306. case sp_doff:
  307. offtyp = getarg(sym_ptyp);
  308. getarg(cst_ptyp);
  309. break;
  310. case sp_icon:
  311. case sp_ucon:
  312. case sp_fcon:
  313. getarg(cst_ptyp);
  314. consiz = (long) argval;
  315. getstring(0);
  316. argval = consiz;
  317. break;
  318. }
  319. return(i);
  320. }
  321. int get16() {
  322. register int l_byte, h_byte;
  323. l_byte = get8();
  324. h_byte = get8();
  325. if ( h_byte>=128 ) h_byte -= 256 ;
  326. return l_byte | (h_byte*256) ;
  327. }
  328. long get32() {
  329. register long l;
  330. register int h_byte;
  331. l = get8(); l |= (unsigned)get8()*256 ; l |= get8()*256L*256L ;
  332. h_byte = get8() ;
  333. if ( h_byte>=128 ) h_byte -= 256 ;
  334. return l | (h_byte*256L*256*256L) ;
  335. }
  336. getstring(ident) {
  337. register char *p;
  338. register n;
  339. getarg(cst_ptyp);
  340. if (argval < 0 || argval > MAXSTR)
  341. fatal("string/identifier too long");
  342. strsiz = n = argval;
  343. p = string;
  344. while (--n >= 0)
  345. *p++ = get8();
  346. if (ident) {
  347. if (!isascii(string[0]) || !isalpha(string[0])) {
  348. identerror();
  349. return;
  350. }
  351. for (n=strsiz,p=string+1;--n>0;p++)
  352. if (!isascii(*p) || !isalnum(*p)) {
  353. identerror();
  354. return;
  355. }
  356. }
  357. }
  358. /* ----- output ----- */
  359. putarg(t) {
  360. if (argnum != 0)
  361. putchar(argnum == 1 ? ' ' : ',');
  362. argnum++;
  363. puttyp(t);
  364. }
  365. puttyp(t) {
  366. switch (t) {
  367. case sp_ilb1:
  368. case sp_ilb2:
  369. printf("*%d",(int) argval);
  370. break;
  371. case sp_dlb1:
  372. case sp_dlb2:
  373. printf(".%d",dlbval);
  374. break;
  375. case sp_dnam:
  376. putstr(0,0);
  377. break;
  378. case sp_cst2:
  379. case sp_cst4:
  380. printf("%ld",argval);
  381. break;
  382. case sp_doff:
  383. puttyp(offtyp);
  384. if (argval >= 0) putchar('+');
  385. printf("%ld",argval);
  386. break;
  387. case sp_pnam:
  388. putstr('$',0);
  389. break;
  390. case sp_scon:
  391. putstr('\'','\'');
  392. break;
  393. case sp_icon:
  394. putstr(0,'I');
  395. printf("%ld",argval);
  396. break;
  397. case sp_ucon:
  398. putstr(0,'U');
  399. printf("%ld",argval);
  400. break;
  401. case sp_fcon:
  402. putstr(0,'F');
  403. printf("%ld",argval);
  404. break;
  405. case sp_cend:
  406. putchar('?');
  407. break;
  408. }
  409. }
  410. putstr(c,c2) register c; {
  411. register char *p;
  412. if (c)
  413. putchar(c);
  414. p = string;
  415. while (--strsiz >= 0) {
  416. c = *p++ & 0377;
  417. if (c >= 040 && c < 0177) {
  418. if (c == '\'' || c == '\\')
  419. putchar('\\');
  420. putchar(c);
  421. } else
  422. printf("\\%03o",c);
  423. }
  424. if (c2)
  425. putchar(c2);
  426. }
  427. /* ----- error handling ----- */
  428. fail_check() {
  429. error("argument range error");
  430. }
  431. identerror() {
  432. error("'%s' is not a correct identifier",string);
  433. }
  434. /* VARARGS */
  435. error(s,a1,a2,a3,a4) char *s; {
  436. fprintf(stderr,
  437. "%s: line %d: ",
  438. filename ? filename : progname,
  439. lineno);
  440. fprintf(stderr,s,a1,a2,a3,a4);
  441. fprintf(stderr,"\n");
  442. errors++;
  443. }
  444. /* VARARGS */
  445. fatal(s,a1,a2,a3,a4) char *s; {
  446. error(s,a1,a2,a3,a4);
  447. exit(-1);
  448. }