BSD 3 development
authorBill Joy <wnj@ucbvax.Berkeley.EDU>
Wed, 21 Nov 1979 02:48:50 +0000 (18:48 -0800)
committerBill Joy <wnj@ucbvax.Berkeley.EDU>
Wed, 21 Nov 1979 02:48:50 +0000 (18:48 -0800)
Work on file usr/src/cmd/pcc/local2.c
Work on file usr/src/cmd/pcc/local2.c.old
Work on file usr/src/cmd/pcc/mac2defs
Work on file usr/src/cmd/pcc/macdefs
Work on file usr/src/cmd/pcc/order.c
Work on file usr/src/cmd/pcc/rodata.c

Synthesized-from: 3bsd

usr/src/cmd/pcc/local2.c [new file with mode: 0644]
usr/src/cmd/pcc/local2.c.old [new file with mode: 0644]
usr/src/cmd/pcc/mac2defs [new file with mode: 0644]
usr/src/cmd/pcc/macdefs [new file with mode: 0644]
usr/src/cmd/pcc/order.c [new file with mode: 0644]
usr/src/cmd/pcc/rodata.c [new file with mode: 0644]

diff --git a/usr/src/cmd/pcc/local2.c b/usr/src/cmd/pcc/local2.c
new file mode 100644 (file)
index 0000000..ca4e7db
--- /dev/null
@@ -0,0 +1,909 @@
+# include "mfile2"
+# include "ctype.h"
+/* a lot of the machine dependent parts of the second pass */
+
+# define BITMASK(n) ((1L<<n)-1)
+
+where(c){
+       fprintf( stderr, "%s, line %d: ", filename, lineno );
+       }
+
+lineid( l, fn ) char *fn; {
+       /* identify line l and file fn */
+       printf( "#      line %d, file %s\n", l, fn );
+       }
+
+
+eobl2(){
+       OFFSZ spoff;    /* offset from stack pointer */
+#ifdef FORT
+       spoff = maxoff;
+       if( spoff >= AUTOINIT ) spoff -= AUTOINIT;
+       spoff /= SZCHAR;
+       SETOFF(spoff,4);
+       printf( "       .set    .F%d,%ld\n", ftnno, spoff );
+#else
+       extern int ftlab1, ftlab2;
+
+       spoff = maxoff;
+       if( spoff >= AUTOINIT ) spoff -= AUTOINIT;
+       spoff /= SZCHAR;
+       SETOFF(spoff,4);
+       printf( "L%d:\n", ftlab1);
+       if( spoff!=0 )
+               if( spoff < 64 )
+                       printf( "       subl2   $%ld,sp\n", spoff);
+               else
+                       printf( "       movab   -%ld(sp),sp\n", spoff);
+       printf( "       jbr     L%d\n", ftlab2);
+#endif
+       maxargs = -1;
+       }
+
+struct hoptab { int opmask; char * opstring; } ioptab[] = {
+
+       ASG PLUS, "add",
+       ASG MINUS, "sub",
+       ASG MUL, "mul",
+       ASG DIV, "div",
+       ASG OR, "bis",
+       ASG ER, "xor",
+       ASG AND, "bic",
+       PLUS,   "add",
+       MINUS,  "sub",
+       MUL,    "mul",
+       DIV,    "div",
+       OR,     "bis",
+       ER,     "xor",
+       AND,    "bic",
+       -1, ""    };
+
+hopcode( f, o ){
+       /* output the appropriate string from the above table */
+
+       register struct hoptab *q;
+
+       for( q = ioptab;  q->opmask>=0; ++q ){
+               if( q->opmask == o ){
+                       printf( "%s", q->opstring );
+/* tbl
+                       if( f == 'F' ) printf( "e" );
+                       else if( f == 'D' ) printf( "d" );
+   tbl */
+/* tbl */
+                       switch( f ) {
+                               case 'L':
+                               case 'W':
+                               case 'B':
+                               case 'D':
+                               case 'F':
+                                       printf("%c", tolower(f));
+                                       break;
+
+                               }
+/* tbl */
+                       return;
+                       }
+               }
+       cerror( "no hoptab for %s", opst[o] );
+       }
+
+char *
+rnames[] = {  /* keyed to register number tokens */
+
+       "r0", "r1",
+       "r2", "r3", "r4", "r5",
+       "r6", "r7", "r8", "r9", "r10", "r11",
+       "ap", "fp", "sp", "pc",
+
+       };
+
+int rstatus[] = {
+       SAREG|STAREG, SAREG|STAREG,
+       SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG,
+       SAREG, SAREG, SAREG, SAREG, SAREG, SAREG,
+       SAREG, SAREG, SAREG, SAREG,
+
+       };
+
+tlen(p) NODE *p;
+{
+       switch(p->type) {
+               case CHAR:
+               case UCHAR:
+                       return(1);
+
+               case SHORT:
+               case USHORT:
+                       return(2);
+
+               case DOUBLE:
+                       return(8);
+
+               default:
+                       return(4);
+               }
+}
+
+mixtypes(p, q) NODE *p, *q;
+{
+       register tp, tq;
+
+       tp = p->type;
+       tq = q->type;
+
+       return( (tp==FLOAT || tp==DOUBLE) !=
+               (tq==FLOAT || tq==DOUBLE) );
+}
+
+prtype(n) NODE *n;
+{
+       switch (n->type)
+               {
+               case DOUBLE:
+                       printf("d");
+                       return;
+
+               case FLOAT:
+                       printf("f");
+                       return;
+
+               case LONG:
+               case ULONG:
+               case INT:
+               case UNSIGNED:
+                       printf("l");
+                       return;
+
+               case SHORT:
+               case USHORT:
+                       printf("w");
+                       return;
+
+               case CHAR:
+               case UCHAR:
+                       printf("b");
+                       return;
+
+               default:
+                       if ( !ISPTR( n->type ) ) cerror("zzzcode- bad type");
+                       else {
+                               printf("l");
+                               return;
+                               }
+               }
+}
+
+zzzcode( p, c ) register NODE *p; {
+       register m;
+       CONSZ val;
+       switch( c ){
+
+       case 'N':  /* logical ops, turned into 0-1 */
+               /* use register given by register 1 */
+               cbgen( 0, m=getlab(), 'I' );
+               deflab( p->label );
+               printf( "       clrl    %s\n", rnames[getlr( p, '1' )->rval] );
+               deflab( m );
+               return;
+
+       case 'I':
+       case 'P':
+               cbgen( p->op, p->label, c );
+               return;
+
+       case 'A':
+               {
+               register NODE *l, *r;
+
+               if (xdebug) eprint(p, 0, &val, &val);
+               r = getlr(p, 'R');
+               if (optype(p->op) == LTYPE || p->op == UNARY MUL)
+                       {
+                       l = resc;
+                       l->type = (r->type==FLOAT || r->type==DOUBLE ? DOUBLE : INT);
+                       }
+               else
+                       l = getlr(p, 'L');
+               if (r->op == ICON  && r->name[0] == '\0')
+                       {
+                       if (r->lval == 0)
+                               {
+                               printf("clr");
+                               prtype(l);
+                               printf("        ");
+                               adrput(l);
+                               return;
+                               }
+                       if (r->lval < 0 && r->lval >= -63)
+                               {
+                               printf("mneg");
+                               prtype(l);
+                               r->lval = -r->lval;
+                               goto ops;
+                               }
+                       r->type = (r->lval < 0 ?
+                                       (r->lval >= -128 ? CHAR
+                                       : (r->lval >= -32768 ? SHORT
+                                       : INT )) : r->type);
+                       r->type = (r->lval >= 0 ?
+                                       (r->lval <= 63 ? INT
+                                       : ( r->lval <= 127 ? CHAR
+                                       : (r->lval <= 255 ? UCHAR
+                                       : (r->lval <= 32767 ? SHORT
+                                       : (r->lval <= 65535 ? USHORT
+                                       : INT ))))) : r->type );
+                       }
+               if (l->op == REG && l->type != FLOAT && l->type != DOUBLE)
+                       l->type = INT;
+               if (!mixtypes(l,r))
+                       {
+                       if (tlen(l) == tlen(r))
+                               {
+                               printf("mov");
+                               prtype(l);
+                               goto ops;
+                               }
+                       else if (tlen(l) > tlen(r) && ISUNSIGNED(r->type))
+                               {
+                               printf("movz");
+                               }
+                       else
+                               {
+                               printf("cvt");
+                               }
+                       }
+               else
+                       {
+                       printf("cvt");
+                       }
+               prtype(r);
+               prtype(l);
+       ops:
+               printf("        ");
+               adrput(r);
+               printf(",");
+               adrput(l);
+               return;
+               }
+
+       case 'C':       /* num words pushed on arg stack */
+               {
+               extern int gc_numbytes;
+               extern int xdebug;
+
+               if (xdebug) printf("->%d<-",gc_numbytes);
+
+               printf("$%d", gc_numbytes/(SZLONG/SZCHAR) );
+               return;
+               }
+
+       case 'D':       /* INCR and DECR */
+               zzzcode(p->left, 'A');
+               printf("\n      ");
+
+       case 'E':       /* INCR and DECR, FOREFF */
+               if (p->right->lval == 1)
+                       {
+                       printf("%s", (p->op == INCR ? "inc" : "dec") );
+                       prtype(p->left);
+                       printf("        ");
+                       adrput(p->left);
+                       return;
+                       }
+               printf("%s", (p->op == INCR ? "add" : "sub") );
+               prtype(p->left);
+               printf("2       ");
+               adrput(p->right);
+               printf(",");
+               adrput(p->left);
+               return;
+
+       case 'F':       /* register type of right operand */
+               {
+               register NODE *n;
+               extern int xdebug;
+               register int ty;
+
+               n = getlr( p, 'R' );
+               ty = n->type;
+
+               if (xdebug) printf("->%d<-", ty);
+
+               if ( ty==DOUBLE) printf("d");
+               else if ( ty==FLOAT ) printf("f");
+               else printf("l");
+               return;
+               }
+
+       case 'L':       /* type of left operand */
+       case 'R':       /* type of right operand */
+               {
+               register NODE *n;
+               extern int xdebug;
+
+               n = getlr ( p, c);
+               if (xdebug) printf("->%d<-", n->type);
+
+               prtype(n);
+               return;
+               }
+
+       case 'Z':       /* complement mask for bit instr */
+               printf("$%ld", ~p->right->lval);
+               return;
+
+       case 'U':       /* 32 - n, for unsigned right shifts */
+               printf("$%d", 32 - p->right->lval );
+               return;
+
+       case 'T':       /* rounded structure length for arguments */
+               {
+               int size;
+
+               size = p->stsize;
+               SETOFF( size, 4);
+               printf("$%d", size);
+               return;
+               }
+
+       case 'S':  /* structure assignment */
+               {
+                       register NODE *l, *r;
+                       register size;
+
+                       if( p->op == STASG ){
+                               l = p->left;
+                               r = p->right;
+
+                               }
+                       else if( p->op == STARG ){  /* store an arg into a temporary */
+                               l = getlr( p, '3' );
+                               r = p->left;
+                               }
+                       else cerror( "STASG bad" );
+
+                       if( r->op == ICON ) r->op = NAME;
+                       else if( r->op == REG ) r->op = OREG;
+                       else if( r->op != OREG ) cerror( "STASG-r" );
+
+                       size = p->stsize;
+
+                       if( size <= 0 || size > 65535 )
+                               cerror("structure size <0=0 or >65535");
+
+                       switch(size) {
+                               case 1:
+                                       printf("        movb    ");
+                                       break;
+                               case 2:
+                                       printf("        movw    ");
+                                       break;
+                               case 4:
+                                       printf("        movl    ");
+                                       break;
+                               case 8:
+                                       printf("        movq    ");
+                                       break;
+                               default:
+                                       printf("        movc3   $%d,", size);
+                                       break;
+                       }
+                       adrput(r);
+                       printf(",");
+                       adrput(l);
+                       printf("\n");
+
+                       if( r->op == NAME ) r->op = ICON;
+                       else if( r->op == OREG ) r->op = REG;
+
+                       }
+               break;
+
+       default:
+               cerror( "illegal zzzcode" );
+               }
+       }
+
+rmove( rt, rs, t ){
+       printf( "       %s      %s,%s\n",
+               (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")),
+               rnames[rs], rnames[rt] );
+       }
+
+struct respref
+respref[] = {
+       INTAREG|INTBREG,        INTAREG|INTBREG,
+       INAREG|INBREG,  INAREG|INBREG|SOREG|STARREG|STARNM|SNAME|SCON,
+       INTEMP, INTEMP,
+       FORARG, FORARG,
+       INTEMP, INTAREG|INAREG|INTBREG|INBREG|SOREG|STARREG|STARNM,
+       0,      0 };
+
+setregs(){ /* set up temporary registers */
+       fregs = 6;      /* tbl- 6 free regs on VAX (0-5) */
+       ;
+       }
+
+szty(t){ /* size, in registers, needed to hold thing of type t */
+       return( (t==DOUBLE||t==FLOAT) ? 2 : 1 );
+       }
+
+rewfld( p ) NODE *p; {
+       return(1);
+       }
+
+callreg(p) NODE *p; {
+       return( R0 );
+       }
+
+base( p ) register NODE *p; {
+       register int o = p->op;
+
+       if( (o==ICON && p->name[0] != '\0')) return( 100 ); /* ie no base reg */
+       if( o==REG ) return( p->rval );
+    if( (o==PLUS || o==MINUS) && p->left->op == REG && p->right->op==ICON)
+               return( p->left->rval );
+    if( o==OREG && !R2TEST(p->rval) && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
+               return( p->rval + 0200*1 );
+       if( o==INCR && p->left->op==REG ) return( p->left->rval + 0200*2 );
+       if( o==ASG MINUS && p->left->op==REG) return( p->left->rval + 0200*4 );
+       if( o==UNARY MUL && p->left->op==INCR && p->left->left->op==REG
+         && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
+               return( p->left->left->rval + 0200*(1+2) );
+       return( -1 );
+       }
+
+offset( p, tyl ) register NODE *p; int tyl; {
+
+       if( tyl==1 && p->op==REG && (p->type==INT || p->type==UNSIGNED) ) return( p->rval );
+       if( (p->op==LS && p->left->op==REG && (p->left->type==INT || p->left->type==UNSIGNED) &&
+             (p->right->op==ICON && p->right->name[0]=='\0')
+             && (1<<p->right->lval)==tyl))
+               return( p->left->rval );
+       return( -1 );
+       }
+
+makeor2( p, q, b, o) register NODE *p, *q; register int b, o; {
+       register NODE *t;
+       register int i;
+       NODE *f;
+
+       p->op = OREG;
+       f = p->left;    /* have to free this subtree later */
+
+       /* init base */
+       switch (q->op) {
+               case ICON:
+               case REG:
+               case OREG:
+                       t = q;
+                       break;
+
+               case MINUS:
+                       q->right->lval = -q->right->lval;
+               case PLUS:
+                       t = q->right;
+                       break;
+
+               case INCR:
+               case ASG MINUS:
+                       t = q->left;
+                       break;
+
+               case UNARY MUL:
+                       t = q->left->left;
+                       break;
+
+               default:
+                       cerror("illegal makeor2");
+       }
+
+       p->lval = t->lval;
+       for(i=0; i<NCHNAM; ++i)
+               p->name[i] = t->name[i];
+
+       /* init offset */
+       p->rval = R2PACK( (b & 0177), o, (b>>7) );
+
+       tfree(f);
+       return;
+       }
+
+canaddr( p ) NODE *p; {
+       register int o = p->op;
+
+       if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->left)) ) return(1);
+       return(0);
+       }
+
+shltype( o, p ) register NODE *p; {
+       return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UNARY MUL && shumul(p->left)) );
+       }
+
+flshape( p ) register NODE *p; {
+       return( p->op == REG || p->op == NAME || p->op == ICON ||
+               (p->op == OREG && (!R2TEST(p->rval) || tlen(p) == 1)) );
+       }
+
+shtemp( p ) register NODE *p; {
+       if( p->op == STARG ) p = p->left;
+       return( p->op==NAME || p->op ==ICON || p->op == OREG || (p->op==UNARY MUL && shumul(p->left)) );
+       }
+
+shumul( p ) register NODE *p; {
+       register o;
+       extern int xdebug;
+
+       if (xdebug) {
+                printf("\nshumul:op=%d,lop=%d,rop=%d", p->op, p->left->op, p->right->op);
+               printf(" prname=%s,plty=%d, prlval=%D\n", p->right->name, p->left->type, p->right->lval);
+               }
+
+
+       o = p->op;
+       if( o == NAME || (o == OREG && !R2TEST(p->rval)) || o == ICON ) return( STARNM );
+
+       if( ( o == INCR || o == ASG MINUS ) &&
+           ( p->left->op == REG && p->right->op == ICON ) &&
+           p->right->name[0] == '\0' )
+               {
+               switch (p->left->type)
+                       {
+                       case CHAR|PTR:
+                       case UCHAR|PTR:
+                               o = 1;
+                               break;
+
+                       case SHORT|PTR:
+                       case USHORT|PTR:
+                               o = 2;
+                               break;
+
+                       case INT|PTR:
+                       case UNSIGNED|PTR:
+                       case LONG|PTR:
+                       case ULONG|PTR:
+                       case FLOAT|PTR:
+                               o = 4;
+                               break;
+
+                       case DOUBLE|PTR:
+                               o = 8;
+                               break;
+
+                       default:
+                               if ( ISPTR(p->left->type) ) {
+                                       o = 4;
+                                       break;
+                                       }
+                               else return(0);
+                       }
+               return( p->right->lval == o ? STARREG : 0);
+               }
+
+       return( 0 );
+       }
+
+adrcon( val ) CONSZ val; {
+       printf( "$" );
+       printf( CONFMT, val );
+       }
+
+conput( p ) register NODE *p; {
+       switch( p->op ){
+
+       case ICON:
+               acon( p );
+               return;
+
+       case REG:
+               printf( "%s", rnames[p->rval] );
+               return;
+
+       default:
+               cerror( "illegal conput" );
+               }
+       }
+
+insput( p ) register NODE *p; {
+       cerror( "insput" );
+       }
+
+upput( p ) register NODE *p; {
+       cerror( "upput" );
+       }
+
+adrput( p ) register NODE *p; {
+       register int r;
+       /* output an address, with offsets, from p */
+
+       if( p->op == FLD ){
+               p = p->left;
+               }
+       switch( p->op ){
+
+       case NAME:
+               acon( p );
+               return;
+
+       case ICON:
+               /* addressable value of the constant */
+               printf( "$" );
+               acon( p );
+               return;
+
+       case REG:
+               printf( "%s", rnames[p->rval] );
+               return;
+
+       case OREG:
+               r = p->rval;
+               if( R2TEST(r) ){ /* double indexing */
+                       register int flags;
+
+                       flags = R2UPK3(r);
+                       if( flags & 1 ) printf("*");
+                       if( flags & 4 ) printf("-");
+                       if( p->lval != 0 || p->name[0] != '\0' ) acon(p);
+                       if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] );
+                       if( flags & 2 ) printf("+");
+                       printf( "[%s]", rnames[R2UPK2(r)] );
+                       return;
+                       }
+               if( r == AP ){  /* in the argument region */
+                       if( p->lval <= 0 || p->name[0] != '\0' ) werror( "bad arg temp" );
+                       printf( CONFMT, p->lval );
+                       printf( "(ap)" );
+                       return;
+                       }
+               if( p->lval != 0 || p->name[0] != '\0') acon( p );
+               printf( "(%s)", rnames[p->rval] );
+               return;
+
+       case UNARY MUL:
+               /* STARNM or STARREG found */
+               if( tshape(p, STARNM) ) {
+                       printf( "*" );
+                       adrput( p->left);
+                       }
+               else {  /* STARREG - really auto inc or dec */
+                       register NODE *q;
+
+/* tbl
+                       p = p->left;
+                       p->left->op = OREG;
+                       if( p->op == INCR ) {
+                               adrput( p->left );
+                               printf( "+" );
+                               }
+                       else {
+                               printf( "-" );
+                               adrput( p->left );
+                               }
+   tbl */
+                       if( p->left->op!=INCR )
+                               printf("-");
+                       printf("(%s)", rnames[p->left->left->rval]); 
+                       if( p->left->op==INCR )
+                               printf("+");
+                       p->op = OREG;
+                       p->rval = p->left->left->rval;
+                       q = p->left;
+                       p->lval = (p->left->op == INCR ? -p->left->right->lval : 0);
+                       p->name[0] = '\0';
+                       tfree(q);
+               }
+               return;
+
+       default:
+               cerror( "illegal address" );
+               return;
+
+               }
+
+       }
+
+acon( p ) register NODE *p; { /* print out a constant */
+
+       if( p->name[0] == '\0' ){
+               printf( CONFMT, p->lval);
+               }
+       else if( p->lval == 0 ) {
+               printf( "%.8s", p->name );
+               }
+       else {
+               printf( "%.8s+", p->name );
+               printf( CONFMT, p->lval );
+               }
+       }
+
+/*
+aacon( p ) register NODE *p; { /* print out a constant */
+/*
+
+       if( p->name[0] == '\0' ){
+               printf( CONFMT, p->lval);
+               return( 0 );
+               }
+       else if( p->lval == 0 ) {
+               printf( "$%.8s", p->name );
+               return( 1 );
+               }
+       else {
+               printf( "$(" );
+               printf( CONFMT, p->lval );
+               printf( "+" );
+               printf( "%.8s)", p->name );
+               return(1);
+               }
+       }
+ */
+
+genscall( p, cookie ) register NODE *p; {
+       /* structure valued call */
+       return( gencall( p, cookie ) );
+       }
+
+/* tbl */
+int gc_numbytes;
+/* tbl */
+
+gencall( p, cookie ) register NODE *p; {
+       /* generate the call given by p */
+       register NODE *p1, *ptemp;
+       register temp, temp1;
+       register m;
+
+       if( p->right ) temp = argsize( p->right );
+       else temp = 0;
+
+       if( p->op == STCALL || p->op == UNARY STCALL ){
+               /* set aside room for structure return */
+
+               if( p->stsize > temp ) temp1 = p->stsize;
+               else temp1 = temp;
+               }
+
+       if( temp > maxargs ) maxargs = temp;
+       SETOFF(temp1,4);
+
+       if( p->right ){ /* make temp node, put offset in, and generate args */
+               ptemp = talloc();
+               ptemp->op = OREG;
+               ptemp->lval = -1;
+               ptemp->rval = SP;
+               ptemp->name[0] = '\0';
+               ptemp->rall = NOPREF;
+               ptemp->su = 0;
+               genargs( p->right, ptemp );
+               ptemp->op = FREE;
+               }
+
+       p1 = p->left;
+       if( p1->op != ICON ){
+               if( p1->op != REG ){
+                       if( p1->op != OREG || R2TEST(p1->rval) ){
+                               if( p1->op != NAME ){
+                                       order( p1, INAREG );
+                                       }
+                               }
+                       }
+               }
+
+/*
+       if( p1->op == REG && p->rval == R5 ){
+               cerror( "call register overwrite" );
+               }
+ */
+/* tbl
+       setup gc_numbytes so reference to ZC works */
+
+       gc_numbytes = temp;
+/* tbl */
+
+       p->op = UNARY CALL;
+       m = match( p, INTAREG|INTBREG );
+/* tbl
+       switch( temp ) {
+       case 0:
+               break;
+       case 2:
+               printf( "       tst     (sp)+\n" );
+               break;
+       case 4:
+               printf( "       cmp     (sp)+,(sp)+\n" );
+               break;
+       default:
+               printf( "       add     $%d,sp\n", temp);
+               }
+   tbl */
+       return(m != MDONE);
+       }
+
+/* tbl */
+char *
+ccbranches[] = {
+       "       jeql    L%d\n",
+       "       jneq    L%d\n",
+       "       jleq    L%d\n",
+       "       jlss    L%d\n",
+       "       jgeq    L%d\n",
+       "       jgtr    L%d\n",
+       "       jlequ   L%d\n",
+       "       jlssu   L%d\n",
+       "       jgequ   L%d\n",
+       "       jgtru   L%d\n",
+       };
+/* tbl */
+
+cbgen( o, lab, mode ) { /*   printf conditional and unconditional branches */
+
+/* tbl */
+       if( o == 0 ) printf( "  jbr     L%d\n", lab );
+/* tbl */
+       else {
+               if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] );
+               printf( ccbranches[o-EQ], lab );
+               }
+       }
+
+nextcook( p, cookie ) NODE *p; {
+       /* we have failed to match p with cookie; try another */
+       if( cookie == FORREW ) return( 0 );  /* hopeless! */
+       if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG );
+       if( !(cookie&INTEMP) && asgop(p->op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG );
+       return( FORREW );
+       }
+
+lastchance( p, cook ) NODE *p; {
+       /* forget it! */
+       return(0);
+       }
+
+optim2( p ) register NODE *p; {
+       /* do local tree transformations and optimizations */
+
+       register NODE *r;
+
+       switch( p->op ) {
+
+       case AND:
+               /* commute L and R to eliminate compliments and constants */
+               if( (p->left->op==ICON&&p->left->name[0]==0) || p->left->op==COMPL ) {
+                       r = p->left;
+                       p->left = p->right;
+                       p->right = r;
+                       }
+       case ASG AND:
+               /* change meaning of AND to ~R&L - bic on pdp11 */
+               r = p->right;
+               if( r->op==ICON && r->name[0]==0 ) { /* compliment constant */
+                       r->lval = ~r->lval;
+                       }
+               else if( r->op==COMPL ) { /* ~~A => A */
+                       r->op = FREE;
+                       p->right = r->left;
+                       }
+               else { /* insert complement node */
+                       p->right = talloc();
+                       p->right->op = COMPL;
+                       p->right->rall = NOPREF;
+                       p->right->type = r->type;
+                       p->right->left = r;
+                       p->right->right = NULL;
+                       }
+               break;
+
+               }
+       }
+
+
+# ifndef ONEPASS
+main( argc, argv ) char *argv[]; {
+       return( mainp2( argc, argv ) );
+       }
+# endif
+
+
+
diff --git a/usr/src/cmd/pcc/local2.c.old b/usr/src/cmd/pcc/local2.c.old
new file mode 100644 (file)
index 0000000..0255039
--- /dev/null
@@ -0,0 +1,895 @@
+# include "mfile2"
+# include "ctype.h"
+/* a lot of the machine dependent parts of the second pass */
+
+# define BITMASK(n) ((1L<<n)-1)
+
+where(c){
+       fprintf( stderr, "%s, line %d: ", filename, lineno );
+       }
+
+lineid( l, fn ) char *fn; {
+       /* identify line l and file fn */
+       printf( "#      line %d, file %s\n", l, fn );
+       }
+
+eobl2(){
+       OFFSZ spoff;    /* offset from stack pointer */
+       extern int ftlab1, ftlab2;
+
+       spoff = maxoff;
+       if( spoff >= AUTOINIT ) spoff -= AUTOINIT;
+       spoff /= SZCHAR;
+       SETOFF(spoff,4);
+       printf( "L%d:\n", ftlab1);
+       if( spoff!=0 )
+               if( spoff < 64 )
+                       printf( "       subl2   $%ld,sp\n", spoff);
+               else
+                       printf( "       movab   -%ld(sp),sp\n", spoff);
+       printf( "       jbr     L%d\n", ftlab2);
+       maxargs = -1;
+       }
+
+struct hoptab { int opmask; char * opstring; } ioptab[] = {
+
+       ASG PLUS, "add",
+       ASG MINUS, "sub",
+       ASG MUL, "mul",
+       ASG DIV, "div",
+       ASG OR, "bis",
+       ASG ER, "xor",
+       ASG AND, "bic",
+       PLUS,   "add",
+       MINUS,  "sub",
+       MUL,    "mul",
+       DIV,    "div",
+       OR,     "bis",
+       ER,     "xor",
+       AND,    "bic",
+       -1, ""    };
+
+hopcode( f, o ){
+       /* output the appropriate string from the above table */
+
+       register struct hoptab *q;
+
+       for( q = ioptab;  q->opmask>=0; ++q ){
+               if( q->opmask == o ){
+                       printf( "%s", q->opstring );
+/* tbl
+                       if( f == 'F' ) printf( "e" );
+                       else if( f == 'D' ) printf( "d" );
+   tbl */
+/* tbl */
+                       switch( f ) {
+                               case 'L':
+                               case 'W':
+                               case 'B':
+                               case 'D':
+                               case 'F':
+                                       printf("%c", tolower(f));
+                                       break;
+
+                               }
+/* tbl */
+                       return;
+                       }
+               }
+       cerror( "no hoptab for %s", opst[o] );
+       }
+
+char *
+rnames[] = {  /* keyed to register number tokens */
+
+       "r0", "r1",
+       "r2", "r3", "r4", "r5",
+       "r6", "r7", "r8", "r9", "r10", "r11",
+       "ap", "fp", "sp", "pc",
+
+       };
+
+int rstatus[] = {
+       SAREG|STAREG, SAREG|STAREG,
+       SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG,
+       SAREG, SAREG, SAREG, SAREG, SAREG, SAREG,
+       SAREG, SAREG, SAREG, SAREG,
+
+       };
+
+tlen(p) NODE *p;
+{
+       switch(p->type) {
+               case CHAR:
+               case UCHAR:
+                       return(1);
+
+               case SHORT:
+               case USHORT:
+                       return(2);
+
+               case DOUBLE:
+                       return(8);
+
+               default:
+                       return(4);
+               }
+}
+
+mixtypes(p, q) NODE *p, *q;
+{
+       register tp, tq;
+
+       tp = p->type;
+       tq = q->type;
+
+       return( (tp==FLOAT || tp==DOUBLE) !=
+               (tq==FLOAT || tq==DOUBLE) );
+}
+
+prtype(n) NODE *n;
+{
+       switch (n->type)
+               {
+               case DOUBLE:
+                       printf("d");
+                       return;
+
+               case FLOAT:
+                       printf("f");
+                       return;
+
+               case LONG:
+               case ULONG:
+               case INT:
+               case UNSIGNED:
+                       printf("l");
+                       return;
+
+               case SHORT:
+               case USHORT:
+                       printf("w");
+                       return;
+
+               case CHAR:
+               case UCHAR:
+                       printf("b");
+                       return;
+
+               default:
+                       if ( !ISPTR( n->type ) ) cerror("zzzcode- bad type");
+                       else {
+                               printf("l");
+                               return;
+                               }
+               }
+}
+
+zzzcode( p, c ) register NODE *p; {
+       register m;
+       CONSZ val;
+       switch( c ){
+
+       case 'N':  /* logical ops, turned into 0-1 */
+               /* use register given by register 1 */
+               cbgen( 0, m=getlab(), 'I' );
+               deflab( p->label );
+               printf( "       clrl    %s\n", rnames[getlr( p, '1' )->rval] );
+               deflab( m );
+               return;
+
+       case 'I':
+       case 'P':
+               cbgen( p->op, p->label, c );
+               return;
+
+       case 'A':
+               {
+               register NODE *l, *r;
+
+               if (xdebug) eprint(p, 0, &val, &val);
+               r = getlr(p, 'R');
+               if (optype(p->op) == LTYPE || p->op == UNARY MUL)
+                       {
+                       l = resc;
+                       l->type = (r->type==FLOAT || r->type==DOUBLE ? DOUBLE : INT);
+                       }
+               else
+                       l = getlr(p, 'L');
+               if (r->op == ICON  && r->name[0] == '\0')
+                       {
+                       if (r->lval == 0)
+                               {
+                               printf("clr");
+                               prtype(l);
+                               printf("        ");
+                               adrput(l);
+                               return;
+                               }
+                       if (r->lval < 0 && r->lval >= -63)
+                               {
+                               printf("mneg");
+                               prtype(l);
+                               r->lval = -r->lval;
+                               goto ops;
+                               }
+                       r->type = (r->lval < 0 ?
+                                       (r->lval >= -128 ? CHAR
+                                       : (r->lval >= -32768 ? SHORT
+                                       : INT )) : r->type);
+                       r->type = (r->lval >= 0 ?
+                                       (r->lval <= 63 ? INT
+                                       : ( r->lval <= 127 ? CHAR
+                                       : (r->lval <= 255 ? UCHAR
+                                       : (r->lval <= 32767 ? SHORT
+                                       : (r->lval <= 65535 ? USHORT
+                                       : INT ))))) : r->type );
+                       }
+               if (l->op == REG && l->type != FLOAT && l->type != DOUBLE)
+                       l->type = INT;
+               if (!mixtypes(l,r))
+                       {
+                       if (tlen(l) == tlen(r))
+                               {
+                               printf("mov");
+                               prtype(l);
+                               goto ops;
+                               }
+                       else if (tlen(l) > tlen(r) && ISUNSIGNED(r->type))
+                               {
+                               printf("movz");
+                               }
+                       else
+                               {
+                               printf("cvt");
+                               }
+                       }
+               else
+                       {
+                       printf("cvt");
+                       }
+               prtype(r);
+               prtype(l);
+       ops:
+               printf("        ");
+               adrput(r);
+               printf(",");
+               adrput(l);
+               return;
+               }
+
+       case 'C':       /* num words pushed on arg stack */
+               {
+               extern int gc_numbytes;
+               extern int xdebug;
+
+               if (xdebug) printf("->%d<-",gc_numbytes);
+
+               printf("$%d", gc_numbytes/(SZLONG/SZCHAR) );
+               return;
+               }
+
+       case 'D':       /* INCR and DECR */
+               zzzcode(p->left, 'A');
+               printf("\n      ");
+
+       case 'E':       /* INCR and DECR, FOREFF */
+               if (p->right->lval == 1)
+                       {
+                       printf("%s", (p->op == INCR ? "inc" : "dec") );
+                       prtype(p->left);
+                       printf("        ");
+                       adrput(p->left);
+                       return;
+                       }
+               printf("%s", (p->op == INCR ? "add" : "sub") );
+               prtype(p->left);
+               printf("2       ");
+               adrput(p->right);
+               printf(",");
+               adrput(p->left);
+               return;
+
+       case 'F':       /* register type of right operand */
+               {
+               register NODE *n;
+               extern int xdebug;
+               register int ty;
+
+               n = getlr( p, 'R' );
+               ty = n->type;
+
+               if (xdebug) printf("->%d<-", ty);
+
+               if ( ty==DOUBLE) printf("d");
+               else if ( ty==FLOAT ) printf("f");
+               else printf("l");
+               return;
+               }
+
+       case 'L':       /* type of left operand */
+       case 'R':       /* type of right operand */
+               {
+               register NODE *n;
+               extern int xdebug;
+
+               n = getlr ( p, c);
+               if (xdebug) printf("->%d<-", n->type);
+
+               prtype(n);
+               return;
+               }
+
+       case 'Z':       /* complement mask for bit instr */
+               printf("$%ld", ~p->right->lval);
+               return;
+
+       case 'U':       /* 32 - n, for unsigned right shifts */
+               printf("$%d", 32 - p->right->lval );
+               return;
+
+       case 'T':       /* rounded structure length for arguments */
+               {
+               int size;
+
+               size = p->stsize;
+               SETOFF( size, 4);
+               printf("$%d", size);
+               return;
+               }
+
+       case 'S':  /* structure assignment */
+               {
+                       register NODE *l, *r;
+                       register size;
+
+                       if( p->op == STASG ){
+                               l = p->left;
+                               r = p->right;
+
+                               }
+                       else if( p->op == STARG ){  /* store an arg into a temporary */
+                               l = getlr( p, '3' );
+                               r = p->left;
+                               }
+                       else cerror( "STASG bad" );
+
+                       if( r->op == ICON ) r->op = NAME;
+                       else if( r->op == REG ) r->op = OREG;
+                       else if( r->op != OREG ) cerror( "STASG-r" );
+
+                       size = p->stsize;
+
+                       if( size <= 0 || size > 65535 )
+                               cerror("structure size <0=0 or >65535");
+
+                       switch(size) {
+                               case 1:
+                                       printf("        movb    ");
+                                       break;
+                               case 2:
+                                       printf("        movw    ");
+                                       break;
+                               case 4:
+                                       printf("        movl    ");
+                                       break;
+                               case 8:
+                                       printf("        movq    ");
+                                       break;
+                               default:
+                                       printf("        movc3   $%d,", size);
+                                       break;
+                       }
+                       adrput(r);
+                       printf(",");
+                       adrput(l);
+                       printf("\n");
+
+                       if( r->op == NAME ) r->op = ICON;
+                       else if( r->op == OREG ) r->op = REG;
+
+                       }
+               break;
+
+       default:
+               cerror( "illegal zzzcode" );
+               }
+       }
+
+rmove( rt, rs, t ){
+       printf( "       %s      %s,%s\n",
+               (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")),
+               rnames[rs], rnames[rt] );
+       }
+
+struct respref
+respref[] = {
+       INTAREG|INTBREG,        INTAREG|INTBREG,
+       INAREG|INBREG,  INAREG|INBREG|SOREG|STARREG|STARNM|SNAME|SCON,
+       INTEMP, INTEMP,
+       FORARG, FORARG,
+       INTEMP, INTAREG|INAREG|INTBREG|INBREG|SOREG|STARREG|STARNM,
+       0,      0 };
+
+setregs(){ /* set up temporary registers */
+       fregs = 6;      /* tbl- 6 free regs on VAX (0-5) */
+       ;
+       }
+
+szty(t){ /* size, in registers, needed to hold thing of type t */
+       return( (t==DOUBLE||t==FLOAT) ? 2 : 1 );
+       }
+
+rewfld( p ) NODE *p; {
+       return(1);
+       }
+
+callreg(p) NODE *p; {
+       return( R0 );
+       }
+
+base( p ) register NODE *p; {
+       register int o = p->op;
+
+       if( (o==ICON && p->name[0] != '\0')) return( 100 ); /* ie no base reg */
+       if( o==REG ) return( p->rval );
+    if( (o==PLUS || o==MINUS) && p->left->op == REG && p->right->op==ICON)
+               return( p->left->rval );
+    if( o==OREG && !R2TEST(p->rval) && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
+               return( p->rval + 0200*1 );
+       if( o==INCR && p->left->op==REG ) return( p->left->rval + 0200*2 );
+       if( o==ASG MINUS && p->left->op==REG) return( p->left->rval + 0200*4 );
+       if( o==UNARY MUL && p->left->op==INCR && p->left->left->op==REG
+         && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
+               return( p->left->left->rval + 0200*(1+2) );
+       return( -1 );
+       }
+
+offset( p, tyl ) register NODE *p; int tyl; {
+
+       if( tyl==1 && p->op==REG && (p->type==INT || p->type==UNSIGNED) ) return( p->rval );
+       if( (p->op==LS && p->left->op==REG && (p->left->type==INT || p->left->type==UNSIGNED) &&
+             (p->right->op==ICON && p->right->name[0]=='\0')
+             && (1<<p->right->lval)==tyl))
+               return( p->left->rval );
+       return( -1 );
+       }
+
+makeor2( p, q, b, o) register NODE *p, *q; register int b, o; {
+       register NODE *t;
+       register int i;
+       NODE *f;
+
+       p->op = OREG;
+       f = p->left;    /* have to free this subtree later */
+
+       /* init base */
+       switch (q->op) {
+               case ICON:
+               case REG:
+               case OREG:
+                       t = q;
+                       break;
+
+               case MINUS:
+                       q->right->lval = -q->right->lval;
+               case PLUS:
+                       t = q->right;
+                       break;
+
+               case INCR:
+               case ASG MINUS:
+                       t = q->left;
+                       break;
+
+               case UNARY MUL:
+                       t = q->left->left;
+                       break;
+
+               default:
+                       cerror("illegal makeor2");
+       }
+
+       p->lval = t->lval;
+       for(i=0; i<NCHNAM; ++i)
+               p->name[i] = t->name[i];
+
+       /* init offset */
+       p->rval = R2PACK( (b & 0177), o, (b>>7) );
+
+       tfree(f);
+       return;
+       }
+
+canaddr( p ) NODE *p; {
+       register int o = p->op;
+
+       if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->left)) ) return(1);
+       return(0);
+       }
+
+shltype( o, p ) register NODE *p; {
+       return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UNARY MUL && shumul(p->left)) );
+       }
+
+flshape( p ) register NODE *p; {
+       return( p->op == REG || p->op == NAME || p->op == ICON ||
+               (p->op == OREG && (!R2TEST(p->rval) || tlen(p) == 1)) );
+       }
+
+shtemp( p ) register NODE *p; {
+       if( p->op == STARG ) p = p->left;
+       return( p->op==NAME || p->op ==ICON || p->op == OREG || (p->op==UNARY MUL && shumul(p->left)) );
+       }
+
+shumul( p ) register NODE *p; {
+       register o;
+       extern int xdebug;
+
+       if (xdebug) {
+                printf("\nshumul:op=%d,lop=%d,rop=%d", p->op, p->left->op, p->right->op);
+               printf(" prname=%s,plty=%d, prlval=%D\n", p->right->name, p->left->type, p->right->lval);
+               }
+
+
+       o = p->op;
+       if( o == NAME || (o == OREG && !R2TEST(p->rval)) || o == ICON ) return( STARNM );
+
+       if( ( o == INCR || o == ASG MINUS ) &&
+           ( p->left->op == REG && p->right->op == ICON ) &&
+           p->right->name[0] == '\0' )
+               {
+               switch (p->left->type)
+                       {
+                       case CHAR|PTR:
+                       case UCHAR|PTR:
+                               o = 1;
+                               break;
+
+                       case SHORT|PTR:
+                       case USHORT|PTR:
+                               o = 2;
+                               break;
+
+                       case INT|PTR:
+                       case UNSIGNED|PTR:
+                       case LONG|PTR:
+                       case ULONG|PTR:
+                       case FLOAT|PTR:
+                               o = 4;
+                               break;
+
+                       case DOUBLE|PTR:
+                               o = 8;
+                               break;
+
+                       default:
+                               if ( ISPTR(p->left->type) ) {
+                                       o = 4;
+                                       break;
+                                       }
+                               else return(0);
+                       }
+               return( p->right->lval == o ? STARREG : 0);
+               }
+
+       return( 0 );
+       }
+
+adrcon( val ) CONSZ val; {
+       printf( "$" );
+       printf( CONFMT, val );
+       }
+
+conput( p ) register NODE *p; {
+       switch( p->op ){
+
+       case ICON:
+               acon( p );
+               return;
+
+       case REG:
+               printf( "%s", rnames[p->rval] );
+               return;
+
+       default:
+               cerror( "illegal conput" );
+               }
+       }
+
+insput( p ) register NODE *p; {
+       cerror( "insput" );
+       }
+
+upput( p ) register NODE *p; {
+       cerror( "upput" );
+       }
+
+adrput( p ) register NODE *p; {
+       register int r;
+       /* output an address, with offsets, from p */
+
+       if( p->op == FLD ){
+               p = p->left;
+               }
+       switch( p->op ){
+
+       case NAME:
+               acon( p );
+               return;
+
+       case ICON:
+               /* addressable value of the constant */
+               printf( "$" );
+               acon( p );
+               return;
+
+       case REG:
+               printf( "%s", rnames[p->rval] );
+               return;
+
+       case OREG:
+               r = p->rval;
+               if( R2TEST(r) ){ /* double indexing */
+                       register int flags;
+
+                       flags = R2UPK3(r);
+                       if( flags & 1 ) printf("*");
+                       if( flags & 4 ) printf("-");
+                       if( p->lval != 0 || p->name[0] != '\0' ) acon(p);
+                       if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] );
+                       if( flags & 2 ) printf("+");
+                       printf( "[%s]", rnames[R2UPK2(r)] );
+                       return;
+                       }
+               if( r == AP ){  /* in the argument region */
+                       if( p->lval <= 0 || p->name[0] != '\0' ) werror( "bad arg temp" );
+                       printf( CONFMT, p->lval );
+                       printf( "(ap)" );
+                       return;
+                       }
+               if( p->lval != 0 || p->name[0] != '\0') acon( p );
+               printf( "(%s)", rnames[p->rval] );
+               return;
+
+       case UNARY MUL:
+               /* STARNM or STARREG found */
+               if( tshape(p, STARNM) ) {
+                       printf( "*" );
+                       adrput( p->left);
+                       }
+               else {  /* STARREG - really auto inc or dec */
+                       register NODE *q;
+
+/* tbl
+                       p = p->left;
+                       p->left->op = OREG;
+                       if( p->op == INCR ) {
+                               adrput( p->left );
+                               printf( "+" );
+                               }
+                       else {
+                               printf( "-" );
+                               adrput( p->left );
+                               }
+   tbl */
+                       printf("%c(%s)%c", (p->left->op==INCR ? '\0' : '-'),
+                               rnames[p->left->left->rval], 
+                               (p->left->op==INCR ? '+' : '\0') );
+                       p->op = OREG;
+                       p->rval = p->left->left->rval;
+                       q = p->left;
+                       p->lval = (p->left->op == INCR ? -p->left->right->lval : 0);
+                       p->name[0] = '\0';
+                       tfree(q);
+               }
+               return;
+
+       default:
+               cerror( "illegal address" );
+               return;
+
+               }
+
+       }
+
+acon( p ) register NODE *p; { /* print out a constant */
+
+       if( p->name[0] == '\0' ){
+               printf( CONFMT, p->lval);
+               }
+       else if( p->lval == 0 ) {
+               printf( "%.8s", p->name );
+               }
+       else {
+               printf( "%.8s+", p->name );
+               printf( CONFMT, p->lval );
+               }
+       }
+
+/*
+aacon( p ) register NODE *p; { /* print out a constant */
+/*
+
+       if( p->name[0] == '\0' ){
+               printf( CONFMT, p->lval);
+               return( 0 );
+               }
+       else if( p->lval == 0 ) {
+               printf( "$%.8s", p->name );
+               return( 1 );
+               }
+       else {
+               printf( "$(" );
+               printf( CONFMT, p->lval );
+               printf( "+" );
+               printf( "%.8s)", p->name );
+               return(1);
+               }
+       }
+ */
+
+genscall( p, cookie ) register NODE *p; {
+       /* structure valued call */
+       return( gencall( p, cookie ) );
+       }
+
+/* tbl */
+int gc_numbytes;
+/* tbl */
+
+gencall( p, cookie ) register NODE *p; {
+       /* generate the call given by p */
+       register NODE *p1, *ptemp;
+       register temp, temp1;
+       register m;
+
+       if( p->right ) temp = argsize( p->right );
+       else temp = 0;
+
+       if( p->op == STCALL || p->op == UNARY STCALL ){
+               /* set aside room for structure return */
+
+               if( p->stsize > temp ) temp1 = p->stsize;
+               else temp1 = temp;
+               }
+
+       if( temp > maxargs ) maxargs = temp;
+       SETOFF(temp1,4);
+
+       if( p->right ){ /* make temp node, put offset in, and generate args */
+               ptemp = talloc();
+               ptemp->op = OREG;
+               ptemp->lval = -1;
+               ptemp->rval = SP;
+               ptemp->name[0] = '\0';
+               ptemp->rall = NOPREF;
+               ptemp->su = 0;
+               genargs( p->right, ptemp );
+               ptemp->op = FREE;
+               }
+
+       p1 = p->left;
+       if( p1->op != ICON ){
+               if( p1->op != REG ){
+                       if( p1->op != OREG || R2TEST(p1->rval) ){
+                               if( p1->op != NAME ){
+                                       order( p1, INAREG );
+                                       }
+                               }
+                       }
+               }
+
+/*
+       if( p1->op == REG && p->rval == R5 ){
+               cerror( "call register overwrite" );
+               }
+ */
+/* tbl
+       setup gc_numbytes so reference to ZC works */
+
+       gc_numbytes = temp;
+/* tbl */
+
+       p->op = UNARY CALL;
+       m = match( p, INTAREG|INTBREG );
+/* tbl
+       switch( temp ) {
+       case 0:
+               break;
+       case 2:
+               printf( "       tst     (sp)+\n" );
+               break;
+       case 4:
+               printf( "       cmp     (sp)+,(sp)+\n" );
+               break;
+       default:
+               printf( "       add     $%d,sp\n", temp);
+               }
+   tbl */
+       return(m != MDONE);
+       }
+
+/* tbl */
+char *
+ccbranches[] = {
+       "       jeql    L%d\n",
+       "       jneq    L%d\n",
+       "       jleq    L%d\n",
+       "       jlss    L%d\n",
+       "       jgeq    L%d\n",
+       "       jgtr    L%d\n",
+       "       jlequ   L%d\n",
+       "       jlssu   L%d\n",
+       "       jgequ   L%d\n",
+       "       jgtru   L%d\n",
+       };
+/* tbl */
+
+cbgen( o, lab, mode ) { /*   printf conditional and unconditional branches */
+
+/* tbl */
+       if( o == 0 ) printf( "  jbr     L%d\n", lab );
+/* tbl */
+       else {
+               if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] );
+               printf( ccbranches[o-EQ], lab );
+               }
+       }
+
+nextcook( p, cookie ) NODE *p; {
+       /* we have failed to match p with cookie; try another */
+       if( cookie == FORREW ) return( 0 );  /* hopeless! */
+       if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG );
+       if( !(cookie&INTEMP) && asgop(p->op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG );
+       return( FORREW );
+       }
+
+lastchance( p, cook ) NODE *p; {
+       /* forget it! */
+       return(0);
+       }
+
+optim2( p ) register NODE *p; {
+       /* do local tree transformations and optimizations */
+
+       register NODE *r;
+
+       switch( p->op ) {
+
+       case AND:
+               /* commute L and R to eliminate compliments and constants */
+               if( (p->left->op==ICON&&p->left->name[0]==0) || p->left->op==COMPL ) {
+                       r = p->left;
+                       p->left = p->right;
+                       p->right = r;
+                       }
+       case ASG AND:
+               /* change meaning of AND to ~R&L - bic on pdp11 */
+               r = p->right;
+               if( r->op==ICON && r->name[0]==0 ) { /* compliment constant */
+                       r->lval = ~r->lval;
+                       }
+               else if( r->op==COMPL ) { /* ~~A => A */
+                       r->op = FREE;
+                       p->right = r->left;
+                       }
+               else { /* insert complement node */
+                       p->right = talloc();
+                       p->right->op = COMPL;
+                       p->right->rall = NOPREF;
+                       p->right->type = r->type;
+                       p->right->left = r;
+                       p->right->right = NULL;
+                       }
+               break;
+
+               }
+       }
+
+
+# ifndef ONEPASS
+main( argc, argv ) char *argv[]; {
+       return( mainp2( argc, argv ) );
+       }
+# endif
diff --git a/usr/src/cmd/pcc/mac2defs b/usr/src/cmd/pcc/mac2defs
new file mode 100644 (file)
index 0000000..6b75d71
--- /dev/null
@@ -0,0 +1,51 @@
+/*     VAX-11/780 Registers */
+
+       /* scratch registers */
+# define R0 0
+# define R1 1
+# define R2 2
+# define R3 3
+# define R4 4
+# define R5 5
+
+       /* register variables */
+# define R6 6
+# define R7 7
+# define R8 8
+# define R9 9
+# define R10 10
+# define R11 11
+
+       /* special purpose */
+# define AP 12         /* argument pointer */
+# define FP 13         /* frame pointer */
+# define SP 14 /* stack pointer */
+# define PC 15 /* program counter */
+
+       /* floating registers */
+
+       /* there are no floating point registers on the VAX */
+
+extern int fregs;
+extern int maxargs;
+
+# define BYTEOFF(x) ((x)&03)
+# define wdal(k) (BYTEOFF(k)==0)
+# define BITOOR(x) ((x)>>3)  /* bit offset to oreg offset */
+
+# define REGSZ 16
+
+# define TMPREG FP
+
+# define R2REGS   /* permit double indexing */
+
+# define STOARG(p)     /* just evaluate the arguments, and be done with it... */
+# define STOFARG(p)
+# define STOSTARG(p)
+# define genfcall(a,b) gencall(a,b)
+
+# define NESTCALL
+
+# define MYREADER(p) walkf(p, optim2)
+int optim2();
+# define special(a, b) 0
diff --git a/usr/src/cmd/pcc/macdefs b/usr/src/cmd/pcc/macdefs
new file mode 100644 (file)
index 0000000..ef68881
--- /dev/null
@@ -0,0 +1,72 @@
+# define makecc(val,i)  lastcon = (lastcon<<8)|((val<<24)>>24);  
+
+# define  ARGINIT 32 
+# define  AUTOINIT 0 
+# define  SZCHAR 8
+# define  SZINT 32
+# define  SZFLOAT 32
+# define  SZDOUBLE 64
+# define  SZLONG 32
+# define  SZSHORT 16
+# define SZPOINT 32
+# define ALCHAR 8
+# define ALINT 32
+# define ALFLOAT 32
+# define ALDOUBLE 32
+# define ALLONG 32
+# define ALSHORT 16
+# define ALPOINT 32
+# define ALSTRUCT 8
+# define  ALSTACK 32 
+
+/*     size in which constants are converted */
+/*     should be long if feasable */
+
+# define CONSZ long
+# define CONFMT "%ld"
+
+/*     size in which offsets are kept
+/*     should be large enough to cover address space in bits
+*/
+
+# define OFFSZ long
+
+/*     character set macro */
+
+# define  CCTRANS(x) x
+
+/* register cookie for stack poINTer */
+
+# define  STKREG 13
+# define ARGREG 12
+
+/*     maximum and minimum register variables */
+
+# define MAXRVAR 11
+# define MINRVAR 6
+
+       /* various standard pieces of code are used */
+# define STDPRTREE
+# define LABFMT "L%d"
+
+/* show stack grows negatively */
+#define BACKAUTO
+#define BACKTEMP
+
+/* show field hardware support on VAX */
+#define FIELDOPS
+
+/* bytes are numbered from right to left */
+#define RTOLBYTES
+
+/* we want prtree included */
+# define STDPRTREE
+# ifndef FORT
+# define ONEPASS
+#endif
+
+# define ENUMSIZE(high,low) INT
+
+
+
+
diff --git a/usr/src/cmd/pcc/order.c b/usr/src/cmd/pcc/order.c
new file mode 100644 (file)
index 0000000..92f7767
--- /dev/null
@@ -0,0 +1,522 @@
+# include "mfile2"
+
+int maxargs = { -1 };
+
+stoasg( p, o ) register NODE *p; {
+       /* should the assignment op p be stored,
+          given that it lies as the right operand of o
+          (or the left, if o==UNARY MUL) */
+/*
+       if( p->op == INCR || p->op == DECR ) return;
+       if( o==UNARY MUL && p->left->op == REG && !isbreg(p->left->rval) ) SETSTO(p,INAREG);
+ */
+       }
+
+deltest( p ) register NODE *p; {
+       /* should we delay the INCR or DECR operation p */
+       p = p->left;
+       return( p->op == REG || p->op == NAME || p->op == OREG );
+       }
+
+autoincr( p ) NODE *p; {
+       register NODE *q = p->left, *r;
+
+       if( q->op == INCR && (r=q->left)->op == REG &&
+           ISPTR(q->type) && p->type == DECREF(q->type) &&
+           tlen(p) == q->right->lval ) return(1);
+
+       return(0);
+       }
+
+mkadrs(p) register NODE *p; {
+       register o;
+
+       o = p->op;
+
+       if( asgop(o) ){
+               if( p->left->su >= p->right->su ){
+                       if( p->left->op == UNARY MUL ){
+                               SETSTO( p->left->left, INTEMP );
+                               }
+                       else if( p->left->op == FLD && p->left->left->op == UNARY MUL ){
+                               SETSTO( p->left->left->left, INTEMP );
+                               }
+                       else { /* should be only structure assignment */
+                               SETSTO( p->left, INTEMP );
+                               }
+                       }
+               else SETSTO( p->right, INTEMP );
+               }
+       else {
+               if( p->left->su > p->right->su ){
+                       SETSTO( p->left, INTEMP );
+                       }
+               else {
+                       SETSTO( p->right, INTEMP );
+                       }
+               }
+       }
+
+notoff( t, r, off, cp) CONSZ off; char *cp; {
+       /* is it legal to make an OREG or NAME entry which has an
+       /* offset of off, (from a register of r), if the
+       /* resulting thing had type t */
+
+/*     if( r == R0 ) return( 1 );  /* NO */
+       return(0);  /* YES */
+       }
+
+# define max(x,y) ((x)<(y)?(y):(x))
+
+sucomp( p ) register NODE *p; {
+
+       /* set the su field in the node to the sethi-ullman
+          number, or local equivalent */
+
+       register o, ty, sul, sur, r;
+
+       o = p->op;
+       ty = optype( o );
+       p->su = szty( p->type );   /* 2 for float or double, else 1 */;
+
+       if( ty == LTYPE ){
+               if( o == OREG ){
+                       r = p->rval;
+                       /* oreg cost is (worst case) 1 + number of temp registers used */
+                       if( R2TEST(r) ){
+                               if( R2UPK1(r)!=100 && istreg(R2UPK1(r)) ) ++p->su;
+                               if( istreg(R2UPK2(r)) ) ++p->su;
+                               }
+                       else {
+                               if( istreg( r ) ) ++p->su;
+                               }
+                       }
+               if( p->su == szty(p->type) &&
+                  (p->op!=REG || !istreg(p->rval)) &&
+                  (p->type==INT || p->type==UNSIGNED || p->type==DOUBLE) )
+                       p->su = 0;
+               return;
+               }
+
+       else if( ty == UTYPE ){
+               switch( o ) {
+               case UNARY CALL:
+               case UNARY STCALL:
+                       p->su = fregs;  /* all regs needed */
+                       return;
+
+               default:
+                       p->su =  p->left->su + (szty( p->type ) > 1 ? 2 : 0) ;
+                       return;
+                       }
+               }
+
+
+       /* If rhs needs n, lhs needs m, regular su computation */
+
+       sul = p->left->su;
+       sur = p->right->su;
+
+       if( o == ASSIGN ){
+               /* computed by doing right, then left (if not in mem), then doing it */
+               p->su = max(sur,sul+1);
+               return;
+               }
+
+       if( o == CALL || o == STCALL ){
+               /* in effect, takes all free registers */
+               p->su = fregs;
+               return;
+               }
+
+       if( o == STASG ){
+               /* right, then left */
+               p->su = max( max( 1+sul, sur), fregs );
+               return;
+               }
+
+       if( asgop(o) ){
+               /* computed by doing right, doing left address, doing left, op, and store */
+               p->su = max(sur,sul+2);
+/*
+               if( o==ASG MUL || o==ASG DIV || o==ASG MOD) p->su = max(p->su,fregs);
+ */
+               return;
+               }
+
+       switch( o ){
+       case ANDAND:
+       case OROR:
+       case QUEST:
+       case COLON:
+       case COMOP:
+               p->su = max( max(sul,sur), 1);
+               return;
+
+       case PLUS:
+       case OR:
+       case ER:
+               /* commutative ops; put harder on left */
+               if( p->right->su > p->left->su && !istnode(p->left) ){
+                       register NODE *temp;
+                       temp = p->left;
+                       p->left = p->right;
+                       p->right = temp;
+                       }
+               break;
+               }
+
+       /* binary op, computed by left, then right, then do op */
+       p->su = max(sul,szty(p->right->type)+sur);
+/*
+       if( o==MUL||o==DIV||o==MOD) p->su = max(p->su,fregs);
+ */
+
+       }
+
+int radebug = 0;
+
+rallo( p, down ) NODE *p; {
+       /* do register allocation */
+       register o, type, down1, down2, ty;
+
+       if( radebug ) printf( "rallo( %o, %d )\n", p, down );
+
+       down2 = NOPREF;
+       p->rall = down;
+       down1 = ( down &= ~MUSTDO );
+
+       ty = optype( o = p->op );
+       type = p->type;
+
+
+       if( type == DOUBLE || type == FLOAT ){
+               if( o == FORCE ) down1 = R0|MUSTDO;
+               }
+       else switch( o ) {
+       case ASSIGN:    
+               down1 = NOPREF;
+               down2 = down;
+               break;
+
+/*
+       case MUL:
+       case DIV:
+       case MOD:
+               down1 = R3|MUSTDO;
+               down2 = R5|MUSTDO;
+               break;
+
+       case ASG MUL:
+       case ASG DIV:
+       case ASG MOD:
+               p->left->rall = down1 = R3|MUSTDO;
+               if( p->left->op == UNARY MUL ){
+                       rallo( p->left->left, R4|MUSTDO );
+                       }
+               else if( p->left->op == FLD  && p->left->left->op == UNARY MUL ){
+                       rallo( p->left->left->left, R4|MUSTDO );
+                       }
+               else rallo( p->left, R3|MUSTDO );
+               rallo( p->right, R5|MUSTDO );
+               return;
+ */
+
+       case CALL:
+       case STASG:
+       case EQ:
+       case NE:
+       case GT:
+       case GE:
+       case LT:
+       case LE:
+       case NOT:
+       case ANDAND:
+       case OROR:
+               down1 = NOPREF;
+               break;
+
+       case FORCE:     
+               down1 = R0|MUSTDO;
+               break;
+
+               }
+
+       if( ty != LTYPE ) rallo( p->left, down1 );
+       if( ty == BITYPE ) rallo( p->right, down2 );
+
+       }
+
+offstar( p ) register NODE *p; {
+       if( p->op == PLUS ) {
+               if( p->left->su == fregs ) {
+                       order( p->left, INTAREG|INAREG );
+                       return;
+               } else if( p->right->su == fregs ) {
+                       order( p->right, INTAREG|INAREG );
+                       return;
+               }
+               if( p->left->op==LS && 
+                 (p->left->left->op!=REG || tlen(p->left->left)!=sizeof(int) ) ) {
+                       order( p->left->left, INTAREG|INAREG );
+                       return;
+               }
+               if( p->right->op==LS &&
+                 (p->right->left->op!=REG || tlen(p->right->left)!=sizeof(int) ) ) {
+                       order( p->right->left, INTAREG|INAREG );
+                       return;
+               }
+               if( p->type == (PTR|CHAR) || p->type == (PTR|UCHAR) ) {
+                       if( p->left->op!=REG || tlen(p->left)!=sizeof(int) ) {
+                               order( p->left, INTAREG|INAREG );
+                               return;
+                       }
+                       else if( p->right->op!=REG || tlen(p->right)!=sizeof(int) ) {
+                               order(p->right, INTAREG|INAREG);
+                               return;
+                       }
+               }
+       }
+       if( p->op == PLUS || p->op == MINUS ){
+               if( p->right->op == ICON ){
+                       p = p->left;
+                       order( p , INTAREG|INAREG);
+                       return;
+                       }
+               }
+
+       if( p->op == UNARY MUL && !canaddr(p) ) {
+               offstar( p->left );
+               return;
+       }
+
+       order( p, INTAREG|INAREG );
+       }
+
+setincr( p ) NODE *p; {
+       return( 0 );  /* for the moment, don't bother */
+       }
+
+setbin( p ) register NODE *p; {
+       register ro, rt;
+
+       rt = p->right->type;
+       ro = p->right->op;
+
+       if( canaddr( p->left ) && !canaddr( p->right ) ) { /* address rhs */
+               if( ro == UNARY MUL ) {
+                       offstar( p->right->left );
+                       return(1);
+               } else {
+                       order( p->right, INAREG|INTAREG|SOREG );
+                       return(1);
+               }
+       }
+       if( !istnode( p->left) ) { /* try putting LHS into a reg */
+/*             order( p->left, logop(p->op)?(INAREG|INBREG|INTAREG|INTBREG|SOREG):(INTAREG|INTBREG|SOREG) );*/
+               order( p->left, INAREG|INTAREG|INBREG|INTBREG|SOREG );
+               return(1);
+               }
+       else if( ro == UNARY MUL && rt != CHAR && rt != UCHAR ){
+               offstar( p->right->left );
+               return(1);
+               }
+       else if( rt == CHAR || rt == UCHAR || rt == SHORT || rt == USHORT || (ro != REG &&
+                       ro != NAME && ro != OREG && ro != ICON ) ){
+               order( p->right, INAREG|INBREG );
+               return(1);
+               }
+/*
+       else if( logop(p->op) && rt==USHORT ){  /* must get rhs into register */
+/*
+               order( p->right, INAREG );
+               return( 1 );
+               }
+ */
+       return(0);
+       }
+
+setstr( p ) register NODE *p; { /* structure assignment */
+       if( p->right->op != REG ){
+               order( p->right, INTAREG );
+               return(1);
+               }
+       p = p->left;
+       if( p->op != NAME && p->op != OREG ){
+               if( p->op != UNARY MUL ) cerror( "bad setstr" );
+               order( p->left, INTAREG );
+               return( 1 );
+               }
+       return( 0 );
+       }
+
+setasg( p ) register NODE *p; {
+       /* setup for assignment operator */
+
+       if( !canaddr(p->right) ) {
+               if( p->right->op == UNARY MUL )
+                       offstar(p->right->left);
+               else
+                       order( p->right, INAREG|INBREG|SOREG );
+               return(1);
+               }
+       if( p->left->op == UNARY MUL ) {
+               offstar( p->left->left );
+               return(1);
+               }
+       if( p->left->op == FLD && p->left->left->op == UNARY MUL ){
+               offstar( p->left->left->left );
+               return(1);
+               }
+/* FLD patch */
+       if( p->left->op == FLD && !(p->right->type==INT || p->right->type==UNSIGNED)) {
+               order( p->right, INAREG);
+               return(1);
+               }
+/* end of FLD patch */
+       return(0);
+       }
+
+setasop( p ) register NODE *p; {
+       /* setup for =ops */
+       register rt, ro;
+
+       rt = p->right->type;
+       ro = p->right->op;
+
+       if( ro == UNARY MUL && rt != CHAR ){
+               offstar( p->right->left );
+               return(1);
+               }
+       if( ( rt == CHAR || rt == SHORT || rt == UCHAR || rt == USHORT ||
+                       ( ro != REG && ro != ICON && ro != NAME && ro != OREG ) ) ){
+               order( p->right, INAREG|INBREG );
+               return(1);
+               }
+/*
+       if( (p->op == ASG LS || p->op == ASG RS) && ro != ICON && ro != REG ){
+               order( p->right, INAREG );
+               return(1);
+               }
+ */
+
+
+       p = p->left;
+       if( p->op == FLD ) p = p->left;
+
+       switch( p->op ){
+
+       case REG:
+       case ICON:
+       case NAME:
+       case OREG:
+               return(0);
+
+       case UNARY MUL:
+               if( p->left->op==OREG )
+                       return(0);
+               else
+                       offstar( p->left );
+               return(1);
+
+               }
+       cerror( "illegal setasop" );
+       }
+
+int crslab = 9999;  /* Honeywell */
+
+getlab(){
+       return( crslab-- );
+       }
+
+deflab( l ){
+       printf( "L%d:\n", l );
+       }
+
+genargs( p, ptemp ) register NODE *p, *ptemp; {
+       register NODE *pasg;
+       register align;
+       register size;
+       register TWORD type;
+
+       /* generate code for the arguments */
+
+       /*  first, do the arguments on the right */
+       while( p->op == CM ){
+               genargs( p->right, ptemp );
+               p->op = FREE;
+               p = p->left;
+               }
+
+       if( p->op == STARG ){ /* structure valued argument */
+
+               size = p->stsize;
+               align = p->stalign;
+               if( p->left->op == ICON ){
+                       p->op = FREE;
+                       p= p->left;
+                       }
+               else {
+                       /* make it look beautiful... */
+                       p->op = UNARY MUL;
+                       canon( p );  /* turn it into an oreg */
+                       if( p->op != OREG ){
+                               offstar( p->left );
+                               canon( p );
+                               if( p->op != OREG ){
+                                       offstar( p->left );
+                                       canon( p );
+                                       if( p->op != OREG ) cerror( "stuck starg" );
+                                       }
+                               }
+                       }
+
+
+               ptemp->lval = 0;        /* all moves to (sp) */
+
+               pasg = talloc();
+               pasg->op = STASG;
+               pasg->stsize = size;
+               pasg->stalign = align;
+               pasg->right = p;
+               pasg->left = tcopy( ptemp );
+
+               /* the following line is done only with the knowledge
+               that it will be undone by the STASG node, with the
+               offset (lval) field retained */
+
+               if( p->op == OREG ) p->op = REG;  /* only for temporaries */
+
+               order( pasg, FORARG );
+               ptemp->lval += size;
+               return;
+               }
+
+       /* ordinary case */
+
+       order( p, FORARG );
+       }
+
+argsize( p ) register NODE *p; {
+       register t;
+       t = 0;
+       if( p->op == CM ){
+               t = argsize( p->left );
+               p = p->right;
+               }
+       if( p->type == DOUBLE || p->type == FLOAT ){
+               SETOFF( t, 4 );
+               return( t+8 );
+               }
+       else if( p->op == STARG ){
+               SETOFF( t, 4 );  /* alignment */
+               return( t + ((p->stsize+3)/4)*4 );  /* size */
+               }
+       else {
+               SETOFF( t, 4 );
+               return( t+4 );
+               }
+       }
+
+
+
diff --git a/usr/src/cmd/pcc/rodata.c b/usr/src/cmd/pcc/rodata.c
new file mode 100644 (file)
index 0000000..ac63484
--- /dev/null
@@ -0,0 +1,317 @@
+short  yyexca [] ={
+-1, 1,
+       0, -1,
+       2, 23,
+       11, 23,
+       50, 23,
+       57, 23,
+       -2, 0,
+-1, 19,
+       56, 80,
+       57, 80,
+       -2, 7,
+-1, 24,
+       56, 79,
+       57, 79,
+       -2, 77,
+-1, 32,
+       52, 45,
+       -2, 43,
+-1, 34,
+       52, 37,
+       -2, 35,
+-1, 107,
+       33, 18,
+       34, 18,
+       35, 18,
+       49, 18,
+       -2, 13,
+-1, 278,
+       33, 16,
+       34, 16,
+       35, 16,
+       49, 16,
+       -2, 14,
+-1, 295,
+       33, 17,
+       34, 17,
+       35, 17,
+       49, 17,
+       -2, 15,
+       };
+short  yyact []={
+
+ 209,  18, 260,  91,  10,   9,  14, 130, 129, 207,
+ 198,  75,  26, 229,  87,  85,  86,  26, 164,  78,
+  16,  21,  76, 108, 145,  77,  21,  10,   9,  14,
+ 269,  26,  94,  90, 268,  96, 210,  26,  98,  20,
+  21,  80,  79,  16,  57,  64,  21, 219, 220, 224,
+  73, 228, 217, 218, 225, 226, 227, 231, 230,  81,
+  22,  82,  54, 108, 254,  22, 110, 161, 221, 309,
+   6,  50, 278,   8, 308, 131,  36, 295,  24,  22,
+ 302,  28, 289, 146, 150,  22,  17,  26, 138, 139,
+ 140, 141, 142, 143,  72, 264,  21, 263, 101,  99,
+  40,  42, 154, 205, 162,  55, 202,  94,  36,  35,
+  89, 201, 191, 154, 166, 167, 168, 170, 172, 174,
+ 176, 178, 179, 181, 183, 185, 186, 187, 188, 189,
+  97,  92, 105, 131,  93,  22, 193,  19,  68, 160,
+ 156, 192, 158,  69, 159, 146, 296, 134, 284, 136,
+ 282, 248, 153,  41,  43, 112, 147, 109,  84,  87,
+  85,  86, 155,  55,  38, 190,  71, 137,  39, 195,
+ 233, 135, 234,  47, 235,  63, 236,  48, 237, 248,
+ 281, 238, 206, 239,  93, 240,  80,  79, 242, 157,
+  47, 100, 131,  33,  48, 152,  38,  67, 200, 243,
+  39, 204, 252,  46,  81,  31,  82, 253, 247, 304,
+ 250, 251, 287,  47,  66, 275, 261,  48, 147, 246,
+ 266, 256, 257, 258, 259, 200, 262, 106, 244, 196,
+  10, 276,  14, 270, 279,  26, 232, 199, 249,  10,
+   9,  14, 280, 151,  21,  70,  16,  62, 298, 297,
+   4, 286,  45, 274, 273,  16, 285, 272, 247, 271,
+ 151,  51,   9,  52, 199,  30,  95, 222, 277, 119,
+ 267,  27, 290, 291, 261, 293, 292, 194, 229,  87,
+  85,  86,  93,  22,  78,  27, 115,  76,  58,  65,
+  77,  27,   7, 116, 283, 117, 111, 299, 119, 305,
+  34,  29,  32, 261, 223, 306,  80,  79, 107, 104,
+ 103, 132, 219, 220, 224, 115, 228, 217, 218, 225,
+ 226, 227, 231, 230,  81, 116,  82, 117, 108, 208,
+ 119,  49,  25, 221, 229,  87,  85,  86,  59,  44,
+  78,  95, 203,  76,  88, 113,  77, 115, 118,  53,
+  56, 165, 163, 102,  61,  60,  37,   3,   2, 149,
+  83,  11,  80,  79, 100,  12,   5,  23, 219, 220,
+ 224,  13, 228, 217, 218, 225, 226, 227, 231, 230,
+  81,  15,  82, 116, 108, 117, 216, 214, 119, 221,
+ 116, 121, 117, 215, 122, 119, 123, 213, 126, 211,
+ 124, 125, 127, 113, 120, 115, 118, 212,   1,   0,
+ 113, 120, 115, 118,   0,   0,   0,   0,   0, 116,
+   0, 117,   0,   0, 119,   0,   0, 121, 307,   0,
+ 122,   0, 123, 114, 126, 128, 124, 125, 127, 113,
+ 120, 115, 118,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0, 116,   0, 117,   0,   0,
+ 119,   0,   0, 121, 303,   0, 122,   0, 123, 114,
+ 126, 128, 124, 125, 127, 113, 120, 115, 118,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0, 116,   0, 117,   0,   0, 119,   0,   0, 121,
+ 301,   0, 122,   0, 123, 114, 126, 128, 124, 125,
+ 127, 113, 120, 115, 118,   0, 116,   0, 117,   0,
+   0, 119,   0,   0,   0,   0,   0,   0,   0, 116,
+   0, 117, 222,   0, 119,   0, 300, 121, 115, 118,
+ 122, 114, 123, 128, 126, 294, 124, 125, 127, 113,
+ 120, 115, 118, 116,   0, 117,   0,   0, 119,   0,
+   0, 121,   0,   0, 122,   0, 123,   0, 126,   0,
+ 124, 125, 127, 113, 120, 115, 118,   0, 116, 114,
+ 117, 128,   0, 119,   0,   0, 121,   0, 222, 122,
+   0, 123,   0, 126,   0, 124, 125, 127, 113, 120,
+ 115, 118,   0, 114, 288, 128,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0, 114, 255,
+ 128, 116,   0, 117,   0,   0, 119,   0,   0, 121,
+   0,   0, 122,   0, 123,   0, 126,   0, 124, 125,
+ 127, 113, 120, 115, 118, 116,   0, 117,   0,   0,
+ 119,   0,   0, 121,   0,   0, 122,   0, 123,   0,
+ 126, 241, 124, 125, 127, 113, 120, 115, 118,   0,
+ 245, 114,   0, 128,   0,   0,   0,   0,   0,   0,
+   0, 116,   0, 117,   0, 116, 119, 117,   0, 121,
+ 119,   0, 122, 121, 123, 114, 126, 128, 124, 125,
+ 127, 113, 120, 115, 118, 113, 120, 115, 118,   0,
+   0,   0,   0,   0,   0,   0,   0, 116,   0, 117,
+   0,   0, 119,   0,   0, 121, 197,   0, 122,   0,
+ 123, 114, 126, 128, 124, 125, 127, 113, 120, 115,
+ 118, 116,   0, 117,   0,   0, 119,   0,   0, 121,
+   0,   0, 122,   0, 123,   0, 126,   0, 124, 125,
+ 127, 113, 120, 115, 118,   0,   0, 114,   0, 128,
+  84,  87,  85,  86,   0,   0,  78,   0,   0,  76,
+   0,   0,  77,  84,  87,  85,  86,   0,   0,  78,
+   0,   0,  76, 128,   0,  77,   0,   0,  80,  79,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,  80,  79,   0,   0,   0,  81,   0,  82,   0,
+   0,  84,  87,  85,  86,   0, 184,  78,   0,  81,
+  76,  82,   0,  77,  84,  87,  85,  86,   0, 182,
+  78,   0,   0,  76,   0,   0,  77,   0,   0,  80,
+  79,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,  80,  79,   0,   0,   0,  81,   0,  82,
+   0,   0,  84,  87,  85,  86,   0, 180,  78,   0,
+  81,  76,  82,   0,  77,  84,  87,  85,  86,   0,
+ 177,  78,   0,   0,  76,   0,   0,  77,   0,   0,
+  80,  79,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,  80,  79,   0,   0,   0,  81,   0,
+  82,   0,   0,  84,  87,  85,  86,   0, 175,  78,
+   0,  81,  76,  82,   0,  77,  84,  87,  85,  86,
+   0, 173,  78,   0,   0,  76,   0,   0,  77,   0,
+   0,  80,  79,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,  80,  79,   0,   0,   0,  81,
+   0,  82,   0,   0,  84,  87,  85,  86,   0, 171,
+  78,   0,  81,  76,  82,   0,  77,  84,  87,  85,
+  86,   0, 169,  78,   0,   0,  76,   0,   0,  77,
+   0,   0,  80,  79, 116,   0, 117,   0,   0, 119,
+   0,   0, 121,   0,   0,  80,  79, 123,   0,   0,
+  81,   0,  82,   0, 113, 120, 115, 118,   0, 265,
+   0,   0,   0,  81,   0,  82,   0, 133,  84,  87,
+  85,  86,   0,   0,  78,   0,   0,  76,   0,   0,
+  77,  84,  87,  85,  86,   0,   0,  78,   0,   0,
+  76,   0,   0,  77,   0,   0,  80,  79,   0,  10,
+ 116,  14, 117,   0,   0, 119,   0,   0, 121,  80,
+  79, 122,   0, 123,  81,  16,  82, 124,   0,   0,
+ 113, 120, 115, 118,   0,   0,   0,  81,   0,  82,
+   0,  74,  84,  87,  85,  86,   0,   0,  78,   0,
+   0,  76,   0,   0,  77,  84,  87,  85,  86,   0,
+   0,  78,   0,   0,  76,   0,   0,  77,   0,   0,
+  80,  79,   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,  80,  79,   0,   0,   0,  81,   0,
+  82, 148,   0,  84,  87,  85,  86,   0,   0,  78,
+   0,  81,  76,  82,   0,  77,   0,   0,   0,   0,
+   0,   0, 116,   0, 117,   0,   0, 119,   0,   0,
+ 121,  80,  79, 122,   0, 123,   0, 126,   0, 124,
+ 125,   0, 113, 120, 115, 118,   0,   0, 116,  81,
+ 117, 144,   0, 119,   0,   0, 121,   0,   0, 122,
+   0, 123,   0,   0,   0,   0,   0,   0, 113, 120,
+ 115, 118 };
+short  yypact []={
+
+-1000,  -6,-1000,-1000,-1000,  29,-1000, 197, 228,-1000,
+ 232,-1000,-1000, 153, 300, 141, 298,-1000,  52, 114,
+-1000, 233, 233, 201, 123,  13, 211,-1000,-1000,-1000,
+ 230, 197,-1000, 286,-1000,-1000,-1000,-1000, 196, 120,
+ 123, 114, 163, 146,  87,-1000,-1000, 194, 111,1059,
+-1000,-1000,-1000,  53,-1000,  85,  74,-1000, -20,  35,
+-1000, -29,-1000,-1000, 102,1123,-1000,-1000,-1000, 294,
+-1000,-1000, 100, 745, 995, 117,1123,1123,1123,1123,
+1123,1161,1046,1110, 210,-1000,-1000,-1000, 142, 197,
+  57,-1000, 114, 140,-1000,-1000, 136, 286,-1000,-1000,
+ 114,-1000,-1000,-1000,-1000,  10,  47,-1000,-1000,-1000,
+ 745,-1000,-1000,1123,1123, 944, 931, 893, 880, 842,
+1123, 829, 791, 778,1123,1123,1123,1123,1123,  56,
+-1000, 745, 995,-1000,-1000,1123, 275,-1000, 117, 117,
+ 117, 117, 117, 117,1046, 178, 685, 214,-1000,  55,
+ 745,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+  46,-1000,-1000,-1000, 276, 206, 510, 745,-1000,1123,
+ 258,1123, 258,1123, 287,1123,-1000,1123, 319, 384,
+1123,1008,1123, 689,1123,1202,1074, 649, 745, 745,
+ 135, 995,  56, 625,-1000, 168,1123,-1000, 125, 187,
+ 214,1123,-1000,  85,-1000,-1000,  11,-1000,-1000, 572,
+-1000, 332, 332, 332, 332,1123, 332,  40,  38, 982,
+ 268,-1000, -23, 332, 209, 207,-1000, 204, 203, 193,
+1123, 246,  15, 745, 745, 745, 745, 745, 745, 745,
+ 745,1123,-1000,-1000, 127,-1000, 156, 117,  95,-1000,
+  97, 125, 745,-1000,-1000,-1000, 217,-1000,-1000, 208,
+ 161, 721,-1000,-1000,-1000,-1000, 547,  25,-1000,-1000,
+-1000,1123,1123,1123,1123,-1000, 523,-1000,-1000,  20,
+1176,-1000,-1000,  91, 199,-1000, 198, 332,-1000,-1000,
+ 485, 449,  23, 413,-1000,-1000,-1000, 158,1123,-1000,
+-1000,-1000,1123,-1000,-1000, 377,  17,  12,-1000,-1000 };
+short  yypgo []={
+
+   0, 408,  45, 407, 399, 397, 393, 387, 386, 381,
+ 371, 367,   0,   2,  11,  70, 366,  73, 365, 361,
+  24,  10, 360,   3, 131,  78, 359, 358, 357,   1,
+ 356, 355, 354,  36, 353,  18,   9, 352, 351,  33,
+ 292, 350,  35,  44, 349, 344,  62, 342, 339,  39,
+ 338, 332, 331,   8,   7, 311, 310, 309, 308, 304,
+ 289 };
+short  yyr1 []={
+
+   0,   1,   1,  27,  27,  28,  28,  30,  28,  31,
+  32,  32,  35,  35,  37,  37,  38,  38,  38,  34,
+  34,  34,  16,  16,  15,  15,  15,  15,  40,  17,
+  17,  17,  17,  17,  18,  18,   9,   9,  41,  41,
+  43,  43,  19,  19,  10,  10,  44,  44,  46,  46,
+  39,  47,  39,  23,  23,  23,  23,  23,  25,  25,
+  25,  25,  25,  25,  24,  24,  24,  24,  24,  24,
+  24,  11,  48,  48,  29,  50,  29,  51,  51,  49,
+  49,  49,  49,  53,  53,  54,  54,  42,  42,  45,
+  45,  52,  52,  55,  33,  33,  56,  57,  58,  36,
+  36,  36,  36,  36,  36,  36,  36,  36,  36,  36,
+  36,  36,  36,  36,  36,  36,  59,  59,  59,   7,
+   4,   3,   5,   6,   8,  60,   2,  13,  13,  26,
+  26,  12,  12,  12,  12,  12,  12,  12,  12,  12,
+  12,  12,  12,  12,  12,  12,  12,  12,  12,  12,
+  12,  12,  12,  12,  12,  12,  14,  14,  14,  14,
+  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,
+  14,  14,  14,  14,  20,  21,  21,  21,  21,  21,
+  21,  21,  22,  22 };
+short  yyr2 []={
+
+   0,   2,   0,   1,   1,   2,   3,   0,   4,   2,
+   2,   0,   2,   0,   3,   4,   3,   4,   0,   3,
+   2,   2,   1,   0,   2,   2,   1,   1,   1,   1,
+   2,   3,   1,   1,   5,   2,   1,   2,   1,   3,
+   1,   3,   5,   2,   1,   2,   1,   3,   2,   1,
+   1,   0,   4,   1,   1,   3,   2,   1,   2,   3,
+   3,   4,   1,   3,   2,   3,   3,   4,   3,   3,
+   2,   2,   1,   3,   1,   0,   4,   1,   1,   1,
+   1,   3,   6,   1,   3,   1,   4,   0,   1,   0,
+   1,   0,   1,   1,   1,   1,   4,   3,   1,   2,
+   1,   2,   2,   2,   7,   4,   2,   2,   2,   2,
+   3,   3,   1,   2,   2,   2,   2,   3,   2,   1,
+   4,   3,   4,   6,   4,   0,   2,   1,   0,   1,
+   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,
+   3,   3,   3,   3,   4,   4,   4,   4,   4,   4,
+   4,   4,   5,   3,   3,   1,   2,   2,   2,   2,
+   2,   2,   2,   4,   4,   4,   2,   3,   3,   1,
+   1,   1,   1,   3,   2,   0,   2,   5,   2,   3,
+   4,   3,   2,   2 };
+short  yychk []={
+
+-1000,  -1, -27, -28, 256, -16, -15, -40, -17,  34,
+  33, -19, -18, -10,  35,  -9,  49,  57, -29, -24,
+ -49,  11,  50, -11, -25, -51,   2, 256, -17, -40,
+  33,  52,   2,  52,   2,  57,  56, -30,  50,  54,
+ -25, -24, -25, -24, -48,  51,   2,  50,  54, -52,
+  58,  50,  33, -44, -46, -17, -41, -43,   2, -50,
+ -31, -32,  51,  55,  -2, -60,  51,  51,  51,  56,
+  51,  55,  -2, -12,  52, -14,  11,  14,   8,  31,
+  30,  48,  50, -22,   2,   4,   5,   3, -45,  57,
+ -39, -23, -24, -25,  22, 256, -42,  56,  58, -49,
+ -24, -33, -34, -56, -57, -15, 256, -58,  52,  55,
+ -12,   2,  55,  26,  56,  28,   6,   8,  29,  11,
+  27,  14,  17,  19,  23,  24,  21,  25,  58, -53,
+ -54, -12, -55,  52,  30,  54,  32,  50, -14, -14,
+ -14, -14, -14, -14,  50, -20, -12, -17,  51, -26,
+ -12,  50,  53, -46,  56,  22,  -2,  53, -43,  -2,
+ -39,  57,  57, -37, -35, -38, -12, -12, -12,  58,
+ -12,  58, -12,  58, -12,  58, -12,  58, -12, -12,
+  58, -12,  58, -12,  58, -12, -12, -12, -12, -12,
+ -42,  56, -53, -12,   2, -20,  51,  51, -21,  50,
+  11,  56,  51, -47,  -2,  57, -35, -36,  53, -12,
+ -33,  -4,  -3,  -5,  -7,  -6,  -8,  41,  42,  36,
+  37,  57, 256, -59,  38,  43,  44,  45,  40,   2,
+  47,  46, -15, -12, -12, -12, -12, -12, -12, -12,
+ -12,  22,  53, -54, -42,  55,  51, -14,  54,  51,
+ -21, -21, -12, -23,  53,  57, -36, -36, -36, -36,
+ -13, -12, -36,  57,  57,  57, -12,   2,  57,  53,
+ -36,  50,  50,  50,  50,  22, -12,  22,  57, -29,
+ -12,  53,  55,  -2,  51,  39,  43,  51,  57,  57,
+ -12, -12, -13, -12,  22,  57,  55,  50,  50, -36,
+  51,  51,  57,  51,  51, -12, -13,  51,  57,  57 };
+short  yydef []={
+
+   2,  -2,   1,   3,   4,   0,  22,  26,  27,  28,
+  29,  32,  33,   0,  44,   0,  36,   5,   0,  -2,
+  74,   0,   0,   0,  -2,  91,  62,  78,  24,  25,
+  30,   0,  -2,   0,  -2,   6,  75,  11,   0, 125,
+  58,  64,   0,   0,   0,  70,  72,   0, 125,   0,
+  92,  71,  31,  89,  46,  49,  87,  38,  40,   0,
+   8,   0,  65,  66,   0,   0,  63,  68,  69,   0,
+  59,  60,   0,  81,   0, 155,   0,   0,   0,   0,
+   0,   0,   0,   0, 169, 170, 171, 172,   0,  90,
+  48,  50,  53,  54, 125,  57,   0,  88, 125,  76,
+  80,   9,  10,  94,  95,   0,   0,  -2,  98,  67,
+ 126,  73,  61,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,   0,  87,
+  83,  85,   0,  93, 156,   0,   0, 183, 157, 158,
+ 159, 160, 161, 162,   0,   0,   0, 175, 166,   0,
+ 129, 182,  42,  47,  51, 125,  56,  34,  39,  41,
+   0,  20,  21,  13,   0,   0, 131, 132, 133,   0,
+ 134,   0, 135,   0, 136,   0, 137,   0, 138, 139,
+   0, 140,   0, 141,   0, 142, 143,   0, 153, 154,
+   0,  88,  87,   0, 168,   0,   0, 173, 174, 175,
+ 175,   0, 167,   0,  55,  19,   0,  12,  97,   0,
+ 100,   0,   0,   0,   0, 128,   0,   0,   0,   0,
+   0, 112,   0,   0,   0,   0, 119,   0,   0, 169,
+   0,   0,   0, 145, 146, 147, 148, 144, 149, 150,
+ 151,   0,  82,  84,   0, 165, 164, 163, 125, 176,
+   0, 178, 130,  52,  96,  99, 101, 102, 103,   0,
+   0, 127, 106, 107, 108, 109,   0,   0, 113, 114,
+ 115,   0,   0, 128,   0, 116,   0, 118,  -2,   0,
+ 152,  86, 179,   0, 181, 121,   0,   0, 110, 111,
+   0,   0,   0,   0, 117,  -2, 180,   0,   0, 105,
+ 120, 122, 128, 124, 177,   0,   0,   0, 123, 104 };