123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499 |
- /*
- * (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
- *
- */
- #ifndef NORCSID
- static char rcsid[] = "$Header$";
- #endif
- /*
- * Decode compact EM assembly language
- *
- * Author: Johan Stevenson, Vrije Universiteit, Amsterdam
- */
- #include <stdio.h>
- #include <assert.h>
- #include <ctype.h>
- #include <em_spec.h>
- #include <em_pseu.h>
- #include <em_flag.h>
- #include <em_ptyp.h>
- #include <em_mes.h>
- #define get8() ((unsigned)getchar())
- #define check(x) if (!(x)) fail_check()
- #define MAXSTR 256
- /*
- * global variables
- */
- int opcode;
- int offtyp;
- long argval;
- int dlbval;
- char string[MAXSTR];
- int strsiz;
- int wsize;
- int psize;
- int lineno;
- int argnum;
- int errors;
- char *progname;
- char *filename;
- long wordmask[] = { /* allowed bits in a word */
- 0x00000000,
- 0x000000FF,
- 0x0000FFFF,
- 0x00000000,
- 0xFFFFFFFF
- };
- long sizemask[] = { /* allowed bits in multiples of 'wsize' */
- 0x00000000,
- 0x7FFFFFFF,
- 0x7FFFFFFE,
- 0x00000000,
- 0x7FFFFFFC
- };
- /*
- * external tables
- */
- extern char em_flag[];
- extern short em_ptyp[];
- extern char em_mnem[][4];
- extern char em_pseu[][4];
- /*
- * routines
- */
- int get16();
- long get32();
- main(argc,argv) char **argv; {
- progname = argv[0];
- if (argc >= 2) {
- filename = argv[1];
- if (freopen(argv[1],"r",stdin) == NULL)
- fatal("can't open %s",argv[1]);
- }
- if (argc >= 3)
- if (freopen(argv[2],"w",stdout) == NULL)
- fatal("can't create %s",argv[2]);
- if (get16() != sp_magic)
- fatal("bad magic word");
- /* In System III the array is called _ctype[] without the trailing '_' */
- (_ctype_+1)['_'] = (_ctype_+1)['a'];
- while (nextline())
- ;
- return(errors ? -1 : 0);
- }
- /* ----- copy ----- */
- int nextline() {
- register t;
- lineno++;
- argnum = 1;
- switch (t = table1()) {
- case EOF:
- return(0);
- case sp_fmnem:
- instr();
- break;
- case sp_fpseu:
- pseudo();
- break;
- case sp_ilb1:
- case sp_ilb2:
- argnum = 0;
- putarg(sp_cst2);
- break;
- case sp_dlb1:
- case sp_dlb2:
- case sp_dnam:
- argnum = 0;
- putarg(t);
- break;
- default:
- error("unknown opcode %d",t);
- }
- putchar('\n');
- return(1);
- }
- instr() {
- register i,j,t;
- register long l;
- i = opcode - sp_fmnem;
- printf(" %s",em_mnem[i]);
- j = em_flag[i] & EM_PAR;
- if (j == PAR_NO)
- return;
- t = em_ptyp[j];
- t = getarg(t);
- /*
- * range checking
- */
- switch (j) {
- case PAR_N:
- check(argval >= 0);
- break;
- case PAR_G:
- if (t != sp_cst2 && t != sp_cst4)
- break;
- check(argval >= 0);
- /* fall through */
- case PAR_L:
- l = argval >= 0 ? argval : -argval;
- check((l & ~wordmask[psize]) == 0);
- break;
- case PAR_W:
- if (t == sp_cend)
- break;
- check((argval & ~wordmask[wsize]) == 0);
- /* fall through */
- case PAR_S:
- check(argval != 0);
- /* fall through */
- case PAR_Z:
- check((argval & ~sizemask[wsize]) == 0);
- break;
- case PAR_O:
- check(argval != 0);
- check((argval & ~sizemask[wsize])==0 || (wsize % argval)==0);
- break;
- case PAR_B:
- t = sp_ilb2;
- break;
- case PAR_R:
- check(argval >= 0 && argval <= 2);
- break;
- }
- putarg(t);
- }
- pseudo() {
- register i,t;
- i = opcode;
- printf(" %s",em_pseu[i - sp_fpseu]);
- switch (i) {
- case ps_bss:
- case ps_hol:
- putarg(getarg(cst_ptyp));
- putarg(getarg(val_ptyp));
- putarg(getarg(ptyp(sp_cst2)));
- check(argval==0 || argval==1);
- break;
- case ps_rom:
- case ps_con:
- putarg(getarg(val_ptyp));
- while ((t = getarg(any_ptyp)) != sp_cend)
- putarg(t);
- break;
- case ps_mes:
- putarg(getarg(ptyp(sp_cst2)));
- if (argval == ms_emx) {
- putarg(getarg(ptyp(sp_cst2)));
- check(argval > 0 && argval <= 4);
- wsize = (int) argval;
- putarg(getarg(ptyp(sp_cst2)));
- check(argval > 0 && argval <= 4);
- psize = (int) argval;
- }
- while ((t = getarg(any_ptyp)) != sp_cend)
- putarg(t);
- break;
- case ps_exa:
- case ps_ina:
- putarg(getarg(sym_ptyp));
- break;
- case ps_exp:
- case ps_inp:
- putarg(getarg(ptyp(sp_pnam)));
- break;
- case ps_exc:
- putarg(getarg(ptyp(sp_cst2)));
- putarg(getarg(ptyp(sp_cst2)));
- break;
- case ps_pro:
- putarg(getarg(ptyp(sp_pnam)));
- putarg(getarg(cst_ptyp|ptyp(sp_cend)));
- break;
- case ps_end:
- putarg(getarg(cst_ptyp|ptyp(sp_cend)));
- break;
- default:
- error("bad pseudo %d",i);
- }
- }
- /* ----- input ----- */
- int getarg(typset) {
- register t,argtyp;
- argtyp = t = table2();
- if (t == EOF)
- fatal("unexpected EOF");
- t -= sp_fspec;
- assert(t >= 0 && t < 16);
- t = 1 << t;
- if ((typset & t) == 0)
- error("bad argument type %d",argtyp);
- return(argtyp);
- }
- int table1() {
- register i;
- i = get8();
- if (i < sp_fmnem+sp_nmnem && i >= sp_fmnem) {
- opcode = i;
- return(sp_fmnem);
- }
- if (i < sp_fpseu+sp_npseu && i >= sp_fpseu) {
- opcode = i;
- return(sp_fpseu);
- }
- if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) {
- argval = i - sp_filb0;
- return(sp_ilb2);
- }
- return(table3(i));
- }
- int table2() {
- register i;
- i = get8();
- if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) {
- argval = i - sp_zcst0;
- return(sp_cst2);
- }
- return(table3(i));
- }
- int table3(i) {
- long consiz;
- switch(i) {
- case sp_ilb1:
- argval = get8();
- break;
- case sp_dlb1:
- dlbval = get8();
- break;
- case sp_dlb2:
- dlbval = get16();
- if ( dlbval<0 ) {
- error("illegal data label .%d",dlbval);
- dlbval=0 ;
- }
- break;
- case sp_cst2:
- argval = get16();
- break;
- case sp_ilb2:
- argval = get16();
- if ( argval<0 ) {
- error("illegal instruction label %ld",argval);
- argval=0 ;
- }
- break;
- case sp_cst4:
- argval = get32();
- break;
- case sp_dnam:
- case sp_pnam:
- getstring(1);
- break;
- case sp_scon:
- getstring(0);
- break;
- case sp_doff:
- offtyp = getarg(sym_ptyp);
- getarg(cst_ptyp);
- break;
- case sp_icon:
- case sp_ucon:
- case sp_fcon:
- getarg(cst_ptyp);
- consiz = (long) argval;
- getstring(0);
- argval = consiz;
- break;
- }
- return(i);
- }
- int get16() {
- register int l_byte, h_byte;
- l_byte = get8();
- h_byte = get8();
- if ( h_byte>=128 ) h_byte -= 256 ;
- return l_byte | (h_byte*256) ;
- }
- long get32() {
- register long l;
- register int h_byte;
- l = get8(); l |= (unsigned)get8()*256 ; l |= get8()*256L*256L ;
- h_byte = get8() ;
- if ( h_byte>=128 ) h_byte -= 256 ;
- return l | (h_byte*256L*256*256L) ;
- }
- getstring(ident) {
- register char *p;
- register n;
- getarg(cst_ptyp);
- if (argval < 0 || argval > MAXSTR)
- fatal("string/identifier too long");
- strsiz = n = argval;
- p = string;
- while (--n >= 0)
- *p++ = get8();
- if (ident) {
- if (!isascii(string[0]) || !isalpha(string[0])) {
- identerror();
- return;
- }
- for (n=strsiz,p=string+1;--n>0;p++)
- if (!isascii(*p) || !isalnum(*p)) {
- identerror();
- return;
- }
- }
- }
- /* ----- output ----- */
- putarg(t) {
- if (argnum != 0)
- putchar(argnum == 1 ? ' ' : ',');
- argnum++;
- puttyp(t);
- }
- puttyp(t) {
- switch (t) {
- case sp_ilb1:
- case sp_ilb2:
- printf("*%d",(int) argval);
- break;
- case sp_dlb1:
- case sp_dlb2:
- printf(".%d",dlbval);
- break;
- case sp_dnam:
- putstr(0,0);
- break;
- case sp_cst2:
- case sp_cst4:
- printf("%ld",argval);
- break;
- case sp_doff:
- puttyp(offtyp);
- if (argval >= 0) putchar('+');
- printf("%ld",argval);
- break;
- case sp_pnam:
- putstr('$',0);
- break;
- case sp_scon:
- putstr('\'','\'');
- break;
- case sp_icon:
- putstr(0,'I');
- printf("%ld",argval);
- break;
- case sp_ucon:
- putstr(0,'U');
- printf("%ld",argval);
- break;
- case sp_fcon:
- putstr(0,'F');
- printf("%ld",argval);
- break;
- case sp_cend:
- putchar('?');
- break;
- }
- }
- putstr(c,c2) register c; {
- register char *p;
- if (c)
- putchar(c);
- p = string;
- while (--strsiz >= 0) {
- c = *p++ & 0377;
- if (c >= 040 && c < 0177) {
- if (c == '\'' || c == '\\')
- putchar('\\');
- putchar(c);
- } else
- printf("\\%03o",c);
- }
- if (c2)
- putchar(c2);
- }
- /* ----- error handling ----- */
- fail_check() {
- error("argument range error");
- }
- identerror() {
- error("'%s' is not a correct identifier",string);
- }
- /* VARARGS */
- error(s,a1,a2,a3,a4) char *s; {
- fprintf(stderr,
- "%s: line %d: ",
- filename ? filename : progname,
- lineno);
- fprintf(stderr,s,a1,a2,a3,a4);
- fprintf(stderr,"\n");
- errors++;
- }
- /* VARARGS */
- fatal(s,a1,a2,a3,a4) char *s; {
- error(s,a1,a2,a3,a4);
- exit(-1);
- }
|