/* Copyright 1982 Alcyon Corporation 8716 Production Ave. San Diego, Ca. 92121 */ char *version "@(#) c168 code generator 4.0 - Mar 18, 1983"; #include "cgen.h" #include "cskel.h" char *opap; int errflg; int nextlabel 10000; char *readtree(); char *readsym(); /* main - main routine, handles arguments and files*/ main(argc,argv) /* returns - none*/ int argc; /* arg count*/ char **argv; /* arg pointers*/ { register char *q; register int i; #ifdef VERSADOS lflag++; #endif for( i = 3; i < argc; i++ ) { q = argv[i]; if( *q++ != '-' ) usage(argc,argv,1); while( 1 ) { switch( *q++ ) { case 'D': dflag++; continue; case 'L': lflag++; continue; case 'e': eflag++; continue; case 'f': fflag++; continue; case 'm': mflag++; continue; case 'o': oflag++; continue; case 'c': cflag++; continue; case '\0': break; default: usage(argc,argv,2); } break; } } if( argc < 3 ) usage(argc,argv,3); if( fopen(argv[1],&ibuf,0) < 0 ) /* 3rd arg for versados */ ferror("can't open %s\n",argv[1]); if( fcreat(argv[2],&obuf,0) < 0 ) /* 3rd arg for versados */ ferror("can't create %s\n",argv[2]); readicode(); v6flush(&obuf); exit(errcnt!=0); } /* readicode - read intermediate code and dispatch output*/ /* This copies assembler lines beginning with '(' to assembler*/ /* output and builds trees starting with '.' line.*/ readicode() /*returns - none*/ { register int c; register struct tnode *tp; while( (c=getc(&ibuf)) > 0 ) { switch(c) { case '.': lineno = readint(); opap = exprarea; if( tp = readtree() ) { #ifndef NODEBUG if( cflag ) putexpr("readicode",tp); #endif switch( tp->t_op ) { case INIT: outinit(tp->t_left); break; case CFORREG: outcforreg(tp->t_left); break; case IFGOTO: outifgoto(tp->t_left,tp->t_type,tp->t_su); break; default: outexpr(tp); break; } } break; case '(': while( (c=getc(&ibuf)) != '\n' ) putchar(c); putchar(c); break; default: error("intermediate code error %c,%d",c,c); break; } } } /* readtree - recursive intermediate code tree read*/ char *readtree() /* returns ptr to expression tree*/ { register int op, type, sc; register struct tnode *tp, *rtp; char sym[SSIZE]; long l; if( (op=readint()) <= 0 ) return(0); type = readint(); switch( op ) { case SYMBOL: if( (sc=readint()) == EXTERNAL ) tp = cenalloc(type,sc,readsym(sym)); else tp = snalloc(type,sc,readint(),0,0); break; case CINT: tp = cnalloc(type,readint()); break; case CLONG: l.hiword = readint(); l.loword = readint(); tp = lcnalloc(type,l); break; case CFLOAT: /* [vlh] 3.4 */ l.hiword = readint(); l.loword = readint(); tp = fpcnalloc(type,l); break; case IFGOTO: case BFIELD: sc = readint(); if( tp = readtree() ) tp = tnalloc(op,type,sc,0,tp,null); break; default: if( binop(op) ) { if( !(tp=readtree()) ) return(0); if( !(rtp=readtree()) ) return(0); tp = tnalloc(op,type,0,0,tp,rtp); } else if( tp = readtree() ) tp = tnalloc(op,type,0,0,tp,null); break; } return(tp); } /* readint - reads an integer value from intermediate code*/ readint() { register int i, c; i = 0; while(1) { switch( c = getc(&ibuf) ) { case '.': case '\n': return(i); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': i =<< 4; i =+ (c-'0'); break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': i =<< 4; i =+ (c-('a'-10)); break; default: error("intermediate code error - %c,%d",c,c); } } } /* readsym - read a symbol from intermediate code*/ char *readsym(sym) char *sym; { register int i, c; register char *s; for( i = SSIZE, s = sym; (c=getc(&ibuf)) != '\n'; ) if( --i >= 0 ) *s++ = c; if( i > 0 ) *s = '\0'; return(sym); } /* error - output an error message*/ error(s,x1,x2,x3,x4,x5,x6) char *s; int x1, x2, x3, x4, x5, x6; { errcnt++; errflg++; if( lineno != 0 ) printf("** %d: ",lineno); printf(s,x1,x2,x3,x4,x5,x6); putchar('\n'); errflg--; } /* ferror - output error message and die*/ ferror(s,x1,x2,x3,x4,x5,x6) char *s; int x1, x2, x3, x4, x5, x6; { error(s,x1,x2,x3,x4,x5,x6); exit(1); } /* tnalloc - allocate binary expression tree node*/ /* returns ptr to node made.*/ char *tnalloc(op,type,info,dummy,left,right) int op; /* operator*/ int type; /* resultant node type*/ int info; /* info field*/ int dummy; /* dummy field - used to match pass1 args*/ struct tnode *left; /* left sub-tree*/ struct tnode *right; /* righst sub-tree*/ { register struct tnode *tp; tp = talloc(sizeof(*tp)); tp->t_op = op; tp->t_type = type; tp->t_su = info; /* info for bit-field & condbr's*/ tp->t_left = left; tp->t_right = right; return(tp); } /* cnalloc - allocate constant expression tree node*/ char *cnalloc(type,value) /* returns pointer to node alloced*/ int type; /* type of constant*/ int value; /* value of constant*/ { register struct conode *cp; cp = talloc(sizeof(*cp)); cp->t_op = CINT; cp->t_type = type; cp->t_value = value; return(cp); } /* lcnalloc - allocate constant expression tree node*/ char *lcnalloc(type,value) /* returns pointer to node alloced*/ int type; /* type of constant*/ long value; /* value of constant*/ { register struct lconode *cp; cp = talloc(sizeof(*cp)); cp->t_op = CLONG; cp->t_type = type; cp->t_lvalue = value; return(cp); } /* fpcnalloc - allocate constant expression tree node*/ char *fpcnalloc(type,value) /* returns pointer to node alloced*/ int type; /* type of constant*/ long value; /* value of constant*/ { /* [vlh] 3.4 */ register struct lconode *cp; cp = talloc(sizeof(*cp)); cp->t_op = CFLOAT; cp->t_type = type; cp->t_lvalue = value; return(cp); } /* talloc - allocate expression tree area*/ char *talloc(size) /* returns pointer to area alloced*/ int size; /* number of bytes to alloc*/ { register char *p; p = opap; if( p + size >= &exprarea[EXPSIZE] ) ferror("expression too complex"); opap = p + size; return(p); } /* symcopy - copy symbol*/ symcopy(sym1,sym2) /* returns - none*/ char *sym1; /* from symbol*/ char *sym2; /* to symbol*/ { register char *p, *q; register int i; for( p = sym1, q = sym2, i = SSIZE; --i >= 0; ) *q++ = (*p ? *p++ : '\0'); } /* usage - ouput usage message*/ usage(argc,argv,n) char *argv[]; { register int i; error("usage call #%d:\n",n); for (i=0; i 1 ) write(1,&c,1); /*to standard output*/ putc(c,&obuf); /*put to assembler file*/ } } v6flush(v6b) struct iobuf *v6b; { register i; i = BLEN - v6b->nunused; v6b->nunused = BLEN; v6b->xfree = &(v6b->buff[0]); if(write(v6b->fildes,v6b->xfree,i) != i) return(-1); return(0); }