date and time created 88/10/19 11:45:49 by bostic
[unix-history] / usr / src / old / pcc / ccom.vax / order.c
index f745b7f..861a421 100644 (file)
@@ -1,16 +1,16 @@
-static char *sccsid ="@(#)order.c      1.4 (Berkeley) %G%";
-# include "mfile2"
+#ifndef lint
+static char *sccsid ="@(#)order.c      1.20 (Berkeley) %G%";
+#endif lint
+
+# include "pass2.h"
 
 int maxargs = { -1 };
 
 
 int maxargs = { -1 };
 
-stoasg( p, o ) register NODE *p; {
+/*ARGSUSED*/
+stoasg( p, o ) 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) */
        /* 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->in.op == INCR || p->in.op == DECR ) return;
-       if( o==UNARY MUL && p->in.left->in.op == REG && !isbreg(p->in.left->tn.rval) ) SETSTO(p,INAREG);
- */
        }
 
 deltest( p ) register NODE *p; {
        }
 
 deltest( p ) register NODE *p; {
@@ -20,17 +20,28 @@ deltest( p ) register NODE *p; {
        }
 
 autoincr( p ) NODE *p; {
        }
 
 autoincr( p ) NODE *p; {
-       register NODE *q = p->in.left, *r;
+       register NODE *q = p->in.left;
+       register TWORD t;
 
 
-       if( q->in.op == INCR && (r=q->in.left)->in.op == REG &&
-           ISPTR(q->in.type) && p->in.type == DECREF(q->in.type) &&
-           tlen(p) == q->in.right->tn.lval ) return(1);
+       if( q->in.op != INCR ||
+           q->in.left->in.op != REG ||
+           !ISPTR(q->in.type) )
+               return(0);
+       t = q->in.type;
+       q->in.type = DECREF(t);
+       if( tlen(p) != tlen(q) ) { /* side effects okay? */
+               q->in.type = t;
+               return(0);
+               }
+       q->in.type = t;
+       if( tlen(p) != q->in.right->tn.lval )
+               return(0);
 
 
-       return(0);
+       return(1);
        }
 
 mkadrs(p) register NODE *p; {
        }
 
 mkadrs(p) register NODE *p; {
-       register o;
+       register int o;
 
        o = p->in.op;
 
 
        o = p->in.op;
 
@@ -58,12 +69,12 @@ mkadrs(p) register NODE *p; {
                }
        }
 
                }
        }
 
-notoff( t, r, off, cp) CONSZ off; char *cp; {
+/*ARGSUSED*/
+notoff( t, r, off, cp) TWORD t; 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 */
 
        /* 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 */
        }
 
        return(0);  /* YES */
        }
 
@@ -74,11 +85,13 @@ sucomp( p ) register NODE *p; {
        /* set the su field in the node to the sethi-ullman
           number, or local equivalent */
 
        /* set the su field in the node to the sethi-ullman
           number, or local equivalent */
 
-       register o, ty, sul, sur, r;
+       register int o, ty, sul, sur, r;
+       int szr;
+       NODE *temp;
 
        o = p->in.op;
        ty = optype( o );
 
        o = p->in.op;
        ty = optype( o );
-       p->in.su = szty( p->in.type );   /* 2 for float or double, else 1 */;
+       p->in.su = szty( p->in.type );   /* 2 for double, else 1 */;
 
        if( ty == LTYPE ){
                if( o == OREG ){
 
        if( ty == LTYPE ){
                if( o == OREG ){
@@ -94,7 +107,14 @@ sucomp( p ) register NODE *p; {
                        }
                if( p->in.su == szty(p->in.type) &&
                   (p->in.op!=REG || !istreg(p->tn.rval)) &&
                        }
                if( p->in.su == szty(p->in.type) &&
                   (p->in.op!=REG || !istreg(p->tn.rval)) &&
-                  (p->in.type==INT || p->in.type==UNSIGNED || p->in.type==DOUBLE) )
+                  (p->in.type==INT ||
+                   p->in.type==UNSIGNED ||
+#if defined(FORT) || defined(SPRECC)
+                   p->in.type==FLOAT ||
+#endif
+                   p->in.type==DOUBLE ||
+                   ISPTR(p->in.type) ||
+                   ISARY(p->in.type)) )
                        p->in.su = 0;
                return;
                }
                        p->in.su = 0;
                return;
                }
@@ -117,6 +137,12 @@ sucomp( p ) register NODE *p; {
 
        sul = p->in.left->in.su;
        sur = p->in.right->in.su;
 
        sul = p->in.left->in.su;
        sur = p->in.right->in.su;
+       szr = szty( p->in.right->in.type );
+       if( szty( p->in.type ) > szr && szr >= 1 ) {
+               /* implicit conversion in rhs */
+               szr = szty( p->in.type );
+               sur = max( szr, sur );
+       }
 
        if( o == ASSIGN ){
                /* computed by doing right, then left (if not in mem), then doing it */
 
        if( o == ASSIGN ){
                /* computed by doing right, then left (if not in mem), then doing it */
@@ -136,12 +162,25 @@ sucomp( p ) register NODE *p; {
                return;
                }
 
                return;
                }
 
+       switch( o ){
+               case DIV:
+               case ASG DIV:
+               case MOD:
+               case ASG MOD:
+                       /* EDIV instructions require reg pairs */
+                       if( p->in.left->in.type == UNSIGNED &&
+                           p->in.right->in.op == ICON &&
+                           p->in.right->tn.name[0] == '\0' &&
+                           (unsigned) p->in.right->tn.lval < 0x80000000 ) {
+                               p->in.su = sul + 2;
+                               return;
+                               }
+                       break;
+               }
+
        if( asgop(o) ){
                /* computed by doing right, doing left address, doing left, op, and store */
                p->in.su = max(sur,sul+2);
        if( asgop(o) ){
                /* computed by doing right, doing left address, doing left, op, and store */
                p->in.su = max(sur,sul+2);
-/*
-               if( o==ASG MUL || o==ASG DIV || o==ASG MOD) p->in.su = max(p->in.su,fregs);
- */
                return;
                }
 
                return;
                }
 
@@ -155,23 +194,27 @@ sucomp( p ) register NODE *p; {
                return;
 
        case PLUS:
                return;
 
        case PLUS:
+       case MUL:
        case OR:
        case ER:
                /* commutative ops; put harder on left */
                if( p->in.right->in.su > p->in.left->in.su && !istnode(p->in.left) ){
        case OR:
        case ER:
                /* commutative ops; put harder on left */
                if( p->in.right->in.su > p->in.left->in.su && !istnode(p->in.left) ){
-                       register NODE *temp;
                        temp = p->in.left;
                        p->in.left = p->in.right;
                        p->in.right = temp;
                        temp = p->in.left;
                        p->in.left = p->in.right;
                        p->in.right = temp;
+                       sul = p->in.left->in.su;
+                       sur = p->in.right->in.su;
+                       szr = szty( p->in.right->in.type );
+                       if( szty( p->in.type ) > szr && szr >= 1 ) {
+                               /* implicit conversion in rhs */
+                               szr = szty( p->in.type );
+                               sur = max( szr, sur );
+                               }
                        }
                break;
                }
                        }
                break;
                }
-
        /* binary op, computed by left, then right, then do op */
        /* binary op, computed by left, then right, then do op */
-       p->in.su = max(sul,szty(p->in.right->in.type)+sur);
-/*
-       if( o==MUL||o==DIV||o==MOD) p->in.su = max(p->in.su,fregs);
- */
+       p->in.su = max(sul,szr+sur);
 
        }
 
 
        }
 
@@ -179,7 +222,7 @@ int radebug = 0;
 
 rallo( p, down ) NODE *p; {
        /* do register allocation */
 
 rallo( p, down ) NODE *p; {
        /* do register allocation */
-       register o, type, down1, down2, ty;
+       register int o, down1, down2, ty;
 
        if( radebug ) printf( "rallo( %o, %d )\n", p, down );
 
 
        if( radebug ) printf( "rallo( %o, %d )\n", p, down );
 
@@ -188,41 +231,12 @@ rallo( p, down ) NODE *p; {
        down1 = ( down &= ~MUSTDO );
 
        ty = optype( o = p->in.op );
        down1 = ( down &= ~MUSTDO );
 
        ty = optype( o = p->in.op );
-       type = p->in.type;
-
-
-       if( type == DOUBLE || type == FLOAT ){
-               if( o == FORCE ) down1 = R0|MUSTDO;
-               }
-       else switch( o ) {
+       switch( o ) {
        case ASSIGN:    
                down1 = NOPREF;
                down2 = down;
                break;
 
        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->in.left->in.rall = down1 = R3|MUSTDO;
-               if( p->in.left->in.op == UNARY MUL ){
-                       rallo( p->in.left->in.left, R4|MUSTDO );
-                       }
-               else if( p->in.left->in.op == FLD  && p->in.left->in.left->in.op == UNARY MUL ){
-                       rallo( p->in.left->in.left->in.left, R4|MUSTDO );
-                       }
-               else rallo( p->in.left, R3|MUSTDO );
-               rallo( p->in.right, R5|MUSTDO );
-               return;
- */
-
        case CALL:
        case STASG:
        case EQ:
        case CALL:
        case STASG:
        case EQ:
@@ -250,29 +264,41 @@ rallo( p, down ) NODE *p; {
 
 offstar( p ) register NODE *p; {
        if( p->in.op == PLUS ) {
 
 offstar( p ) register NODE *p; {
        if( p->in.op == PLUS ) {
+               /* try to create index expressions */
+               if( p->in.left->in.op==LS && 
+                   p->in.left->in.left->in.op!=REG &&
+                   p->in.left->in.right->in.op==ICON &&
+                   p->in.left->in.right->tn.lval<=3 ){
+                       order( p->in.left->in.left, INTAREG|INAREG );
+                       return;
+               }
                if( p->in.left->in.su == fregs ) {
                        order( p->in.left, INTAREG|INAREG );
                        return;
                if( p->in.left->in.su == fregs ) {
                        order( p->in.left, INTAREG|INAREG );
                        return;
-               } else if( p->in.right->in.su == fregs ) {
-                       order( p->in.right, INTAREG|INAREG );
-                       return;
                }
                }
-               if( p->in.left->in.op==LS && 
-                 (p->in.left->in.left->in.op!=REG || tlen(p->in.left->in.left)!=sizeof(int) ) ) {
-                       order( p->in.left->in.left, INTAREG|INAREG );
+               if( p->in.right->in.op==LS && 
+                   p->in.right->in.left->in.op!=REG &&
+                   p->in.right->in.right->in.op==ICON &&
+                   p->in.right->in.right->tn.lval<=3 ){
+                       order( p->in.right->in.left, INTAREG|INAREG );
                        return;
                }
                        return;
                }
-               if( p->in.right->in.op==LS &&
-                 (p->in.right->in.left->in.op!=REG || tlen(p->in.right->in.left)!=sizeof(int) ) ) {
-                       order( p->in.right->in.left, INTAREG|INAREG );
+               if( p->in.right->in.su == fregs ) {
+                       order( p->in.right, INTAREG|INAREG );
                        return;
                }
                if( p->in.type == (PTR|CHAR) || p->in.type == (PTR|UCHAR) ) {
                        return;
                }
                if( p->in.type == (PTR|CHAR) || p->in.type == (PTR|UCHAR) ) {
-                       if( p->in.left->in.op!=REG || tlen(p->in.left)!=sizeof(int) ) {
+                       if( (p->in.left->in.op == ICON ||
+                            p->in.left->in.op == NAME) &&
+                           p->in.right->in.op != REG ) {
+                               order(p->in.right, INTAREG|INAREG);
+                               return;
+                       }
+                       if( p->in.left->in.op!=REG ) {
                                order( p->in.left, INTAREG|INAREG );
                                return;
                        }
                                order( p->in.left, INTAREG|INAREG );
                                return;
                        }
-                       else if( p->in.right->in.op!=REG || tlen(p->in.right)!=sizeof(int) ) {
+                       if( p->in.right->in.op!=REG ) {
                                order(p->in.right, INTAREG|INAREG);
                                return;
                        }
                                order(p->in.right, INTAREG|INAREG);
                                return;
                        }
@@ -297,14 +323,14 @@ offstar( p ) register NODE *p; {
 setincr( p ) register NODE *p; {
        p = p->in.left;
        if( p->in.op == UNARY MUL ){
 setincr( p ) register NODE *p; {
        p = p->in.left;
        if( p->in.op == UNARY MUL ){
-               offstar( p );
+               offstar( p->in.left );
                return( 1 );
                }
        return( 0 );
        }
 
 setbin( p ) register NODE *p; {
                return( 1 );
                }
        return( 0 );
        }
 
 setbin( p ) register NODE *p; {
-       register ro, rt;
+       register int ro, rt;
 
        rt = p->in.right->in.type;
        ro = p->in.right->in.op;
 
        rt = p->in.right->in.type;
        ro = p->in.right->in.op;
@@ -319,7 +345,6 @@ setbin( p ) register NODE *p; {
                }
        }
        if( !istnode( p->in.left) ) { /* try putting LHS into a reg */
                }
        }
        if( !istnode( p->in.left) ) { /* try putting LHS into a reg */
-/*             order( p->in.left, logop(p->in.op)?(INAREG|INBREG|INTAREG|INTBREG|SOREG):(INTAREG|INTBREG|SOREG) );*/
                order( p->in.left, INAREG|INTAREG|INBREG|INTBREG|SOREG );
                return(1);
                }
                order( p->in.left, INAREG|INTAREG|INBREG|INTBREG|SOREG );
                return(1);
                }
@@ -328,17 +353,13 @@ setbin( p ) register NODE *p; {
                return(1);
                }
        else if( rt == CHAR || rt == UCHAR || rt == SHORT || rt == USHORT ||
                return(1);
                }
        else if( rt == CHAR || rt == UCHAR || rt == SHORT || rt == USHORT ||
-           rt == FLOAT || (ro != REG && ro != NAME && ro != OREG && ro != ICON ) ){
+#ifndef SPRECC
+           rt == FLOAT ||
+#endif
+           (ro != REG && ro != NAME && ro != OREG && ro != ICON ) ){
                order( p->in.right, INAREG|INBREG );
                return(1);
                }
                order( p->in.right, INAREG|INBREG );
                return(1);
                }
-/*
-       else if( logop(p->in.op) && rt==USHORT ){  /* must get rhs into register */
-/*
-               order( p->in.right, INAREG );
-               return( 1 );
-               }
- */
        return(0);
        }
 
        return(0);
        }
 
@@ -385,7 +406,7 @@ setasg( p ) register NODE *p; {
 
 setasop( p ) register NODE *p; {
        /* setup for =ops */
 
 setasop( p ) register NODE *p; {
        /* setup for =ops */
-       register rt, ro;
+       register int rt, ro;
 
        rt = p->in.right->in.type;
        ro = p->in.right->in.op;
 
        rt = p->in.right->in.type;
        ro = p->in.right->in.op;
@@ -395,16 +416,13 @@ setasop( p ) register NODE *p; {
                return(1);
                }
        if( rt == CHAR || rt == SHORT || rt == UCHAR || rt == USHORT ||
                return(1);
                }
        if( rt == CHAR || rt == SHORT || rt == UCHAR || rt == USHORT ||
-           rt == FLOAT || ( ro != REG && ro != ICON && ro != NAME && ro != OREG ) ){
+#ifndef SPRECC
+           rt == FLOAT ||
+#endif
+           ( ro != REG && ro != ICON && ro != NAME && ro != OREG ) ){
                order( p->in.right, INAREG|INBREG );
                return(1);
                }
                order( p->in.right, INAREG|INBREG );
                return(1);
                }
-/*
-       if( (p->in.op == ASG LS || p->in.op == ASG RS) && ro != ICON && ro != REG ){
-               order( p->in.right, INAREG );
-               return(1);
-               }
- */
 
 
        p = p->in.left;
 
 
        p = p->in.left;
@@ -427,23 +445,25 @@ setasop( p ) register NODE *p; {
 
                }
        cerror( "illegal setasop" );
 
                }
        cerror( "illegal setasop" );
+       /*NOTREACHED*/
        }
 
        }
 
-int crslab = 9999;  /* Honeywell */
+int crslab = 99999;  /* VAX */
 
 getlab(){
        return( crslab-- );
        }
 
 deflab( l ){
 
 getlab(){
        return( crslab-- );
        }
 
 deflab( l ){
+       if (nerrors) return;
        printf( "L%d:\n", l );
        }
 
 genargs( p ) register NODE *p; {
        register NODE *pasg;
        printf( "L%d:\n", l );
        }
 
 genargs( p ) register NODE *p; {
        register NODE *pasg;
-       register align;
-       register size;
-       register TWORD type;
+       register int align;
+       register int size;
+       int count;
 
        /* generate code for the arguments */
 
 
        /* generate code for the arguments */
 
@@ -466,15 +486,11 @@ genargs( p ) register NODE *p; {
                        /* make it look beautiful... */
                        p->in.op = UNARY MUL;
                        canon( p );  /* turn it into an oreg */
                        /* make it look beautiful... */
                        p->in.op = UNARY MUL;
                        canon( p );  /* turn it into an oreg */
-                       if( p->in.op != OREG ){
+                       for( count = 0; p->in.op != OREG && count < 10; ++count ){
                                offstar( p->in.left );
                                canon( p );
                                offstar( p->in.left );
                                canon( p );
-                               if( p->in.op != OREG ){
-                                       offstar( p->in.left );
-                                       canon( p );
-                                       if( p->in.op != OREG ) cerror( "stuck starg" );
-                                       }
                                }
                                }
+                       if( p->in.op != OREG ) cerror( "stuck starg" );
                        }
 
                pasg = talloc();
                        }
 
                pasg = talloc();
@@ -494,7 +510,7 @@ genargs( p ) register NODE *p; {
        }
 
 argsize( p ) register NODE *p; {
        }
 
 argsize( p ) register NODE *p; {
-       register t;
+       register int t;
        t = 0;
        if( p->in.op == CM ){
                t = argsize( p->in.left );
        t = 0;
        if( p->in.op == CM ){
                t = argsize( p->in.left );
@@ -513,5 +529,3 @@ argsize( p ) register NODE *p; {
                return( t+4 );
                }
        }
                return( t+4 );
                }
        }
-
-