Annotation of researchv9/cmd/sun/pcc/order.c, revision 1.1

1.1     ! root        1: # include "cpass2.h"
        !             2: #ifndef lint
        !             3: static char sccsid[] = "@(#)order.c 1.1 86/02/03 Copyr 1985 Sun Micro";
        !             4: #endif
        !             5: 
        !             6: /*
        !             7:  * Copyright (c) 1985 by Sun Microsystems, Inc.
        !             8:  */
        !             9: 
        !            10: /*
        !            11:  * order.c -- conditionally included 680X0 version
        !            12:  */
        !            13: 
        !            14: 
        !            15: int fltused = 0;
        !            16: int floatmath = 0;
        !            17: 
        !            18: SUTYPE fregs;
        !            19: 
        !            20: extern int mina, maxa, minb, maxb; /* imported from allo.c */
        !            21: extern int toff, maxtoff;
        !            22: 
        !            23: int maxargs = { -1 };
        !            24: 
        !            25: static SUTYPE zed = { 0,0,0,0 };
        !            26: 
        !            27: int failsafe; /* very disgusting: see offstar() for use */
        !            28: 
        !            29: # define SAFETY( a, reg,  b ) \
        !            30:        {if ((reg & MUSTDO) && find_mustdo( a , reg )) {rewrite_rall( b, 1 );} }
        !            31: # define iscnode(p) ((p)->in.op==REG && iscreg((p)->tn.rval))
        !            32: 
        !            33: # define max(x,y) ((x)<(y)?(y):(x))
        !            34: # define min(x,y) ((x)<(y)?(x):(y))
        !            35: 
        !            36: # define divmulop(o) (dope[o]&(DIVFLG|MULFLG))
        !            37: 
        !            38: 
        !            39: NODE *
        !            40: double_conv( p ) register NODE *p;
        !            41: {
        !            42:        NODE *q    = talloc();
        !            43:        q->in.op   = SCONV;
        !            44:        q->in.type = DOUBLE;
        !            45:        q->in.left = p;
        !            46:        q->in.rall = p->in.rall;
        !            47:        if (use68881) {
        !            48:            q->in.su.d = max( p->in.su.d, 1 );
        !            49:            q->in.su.a = 0;
        !            50:            q->in.su.f = max( p->in.su.f, 1 );
        !            51:        } else {
        !            52:            p->in.rall = MUSTDO|D0;
        !            53:            q->in.su.d = max( p->in.su.d, fregs.d );
        !            54:            q->in.su.a = max( p->in.su.a, fregs.a );
        !            55:            q->in.su.f = max( p->in.su.f, fregs.f );
        !            56:        }
        !            57:        return q;
        !            58: }
        !            59: 
        !            60: setincr( p ) register NODE *p; 
        !            61: {
        !            62:        return( 0 );
        !            63: }
        !            64: 
        !            65: niceuty( p ) register NODE *p; 
        !            66: {
        !            67:        return( p->in.op == UNARY MUL && p->in.type != FLOAT &&
        !            68:                shumul( p->in.left) == STARNM );
        !            69: }
        !            70: 
        !            71: setconv( p, cookie )
        !            72:     NODE *p;
        !            73: {
        !            74:     register NODE *lp;
        !            75:     TWORD t;
        !            76:     
        !            77:     lp = p->in.left;
        !            78:     switch(p->in.type) {
        !            79:     case FLOAT:
        !            80:     case DOUBLE:
        !            81:        /* convert from something nice to something icky */
        !            82:        if ( use68881 ) {
        !            83:            if (p->in.type == DOUBLE && iscnode(lp)) {
        !            84:                /*
        !            85:                 * no code necessary -- floating point
        !            86:                 * regs are always in extended format
        !            87:                 */
        !            88:                TWORD t = p->in.type;
        !            89:                *p = *lp;
        !            90:                p->in.type = t;
        !            91:                lp->in.op = FREE;
        !            92:                return(1);
        !            93:            }
        !            94:            if (ISFLOATING(lp->in.type)) {
        !            95:                /*
        !            96:                 * float => double, or vice versa
        !            97:                 */
        !            98:                order(lp, INCREG|INTCREG|INTEMP);
        !            99:                return(1);
        !           100:            }
        !           101:            if (ISUNSIGNED(lp->in.type)) {
        !           102:                /*
        !           103:                 * the 68881 doesn't deal with unsigned types;
        !           104:                 * convert the unsigned operand to INT.
        !           105:                 */
        !           106:                register NODE *q;
        !           107:                q = talloc();
        !           108:                q->in.op   = SCONV;
        !           109:                q->in.type = INT;
        !           110:                q->in.left = lp;
        !           111:                q->in.rall = lp->in.rall;
        !           112:                q->in.su.d = 1;
        !           113:                q->in.su.a = 0;
        !           114:                q->in.su.f = 0;
        !           115:                p->in.left = lp = q;
        !           116:            }
        !           117:            break;
        !           118:        }
        !           119:        failsafe = 1;
        !           120:        break;
        !           121:     default:
        !           122:        /* check for inverse (floating type => fixed type) */
        !           123:        if (lp->in.type == FLOAT || lp->in.type == DOUBLE) {
        !           124:            if (use68881) {
        !           125:                order(lp, INCREG|INTCREG|INTEMP);
        !           126:                return(1);
        !           127:            }
        !           128:            failsafe = 1;
        !           129:        }
        !           130:        break;
        !           131:     }
        !           132:     if (cookie!=(INBREG|INTBREG))
        !           133:        cookie = (INAREG|INTAREG|INBREG|INTBREG);
        !           134:     cookie |= INTEMP;
        !           135:     order( p->in.left, cookie );
        !           136:     return 1;
        !           137: }
        !           138: 
        !           139: /*
        !           140:  * deal properly with the operand of a unary operator.
        !           141:  */
        !           142: int
        !           143: setunary(p, cookie)
        !           144:        NODE *p;
        !           145: {
        !           146:        NODE *lp;
        !           147: 
        !           148:        lp = p->in.left;
        !           149:        if (use68881 && ISFLOATING(lp->in.type)) {
        !           150:                switch(p->in.op) {
        !           151:                case FCOS:
        !           152:                case FSIN:
        !           153:                case FTAN:
        !           154:                case FACOS:
        !           155:                case FASIN:
        !           156:                case FATAN:
        !           157:                case FCOSH:
        !           158:                case FSINH:
        !           159:                case FTANH:
        !           160:                case FEXP:
        !           161:                case F10TOX:
        !           162:                case F2TOX:
        !           163:                case FLOGN:
        !           164:                case FLOG10:
        !           165:                case FLOG2:
        !           166:                case FSQR:
        !           167:                case FSQRT:
        !           168:                case FAINT:
        !           169:                case FANINT:
        !           170:                        floatsrce(lp);
        !           171:                        return(1);
        !           172:                case FNINT:
        !           173:                        order(lp, INCREG|INTCREG);
        !           174:                        return(1);
        !           175:                case UNARY MINUS:
        !           176:                case FABS:
        !           177:                        /* don't use the 81 unless we have to */
        !           178:                        order(lp, INAREG|INCREG);
        !           179:                        return(1);
        !           180:                default:
        !           181:                        break;
        !           182:                }
        !           183:        }
        !           184:        order(lp, INAREG|INBREG|INCREG);
        !           185:        return(1);
        !           186: }
        !           187: 
        !           188: /*
        !           189:  * put p into a form acceptable as a 68881 source operand.
        !           190:  */
        !           191: static
        !           192: floatsrce(p)
        !           193:        register NODE *p;
        !           194: {
        !           195:        if (p->in.op == SCONV) {
        !           196:                /*
        !           197:                 * the 68881 converts signed ints, float, and double
        !           198:                 * to internal (extended) format automatically.
        !           199:                 */
        !           200:                switch(p->in.left->in.type) {
        !           201:                case CHAR:
        !           202:                case SHORT:
        !           203:                case INT:
        !           204:                case LONG:
        !           205:                case FLOAT:
        !           206:                case DOUBLE:
        !           207:                        p = p->in.left;
        !           208:                        break;
        !           209:                default:
        !           210:                        /* must do the conversion explicitly */
        !           211:                        order(p->in.left, INAREG|INTAREG|INTEMP);
        !           212:                        break;
        !           213:                }
        !           214:        }
        !           215:        switch(p->in.op) {
        !           216:        case UNARY MUL:
        !           217:                /* just make it addressable */
        !           218:                offstar(p->in.left);
        !           219:                break;
        !           220:        case REG:
        !           221:                /* coprocessor cannot access address registers */
        !           222:                if (isbreg(p->tn.rval)) {
        !           223:                        order(p, INTAREG|INAREG);
        !           224:                }
        !           225:                break;
        !           226:        default:
        !           227:                /* lacking any better ideas, put it in a register */
        !           228:                if (SUTEST(p->in.su)) {
        !           229:                        if (ISFLOATING(p->in.type)) {
        !           230:                                order(p, INCREG|INTCREG|INTEMP);
        !           231:                        } else {
        !           232:                                order(p, INAREG|INTAREG|INTEMP);
        !           233:                        }
        !           234:                }
        !           235:                break;
        !           236:        }
        !           237: }
        !           238: 
        !           239: setbin( p, cook ) register NODE *p; 
        !           240: {
        !           241:        register NODE *r, *l;
        !           242:        NODE *p2, *q, *t;
        !           243:        SUTYPE sur, sul;
        !           244:        SUTYPE qcost, pcost;
        !           245:        extern short revrel[]; /* for logic ops */
        !           246:        int cookie, i;
        !           247: 
        !           248:        r = p->in.right;
        !           249:        l = p->in.left;
        !           250:        sur = r->in.su;
        !           251:        sul = l->in.su;
        !           252: 
        !           253:        cookie = cook;
        !           254:        if (cookie!=(INBREG|INTBREG))
        !           255:            cookie = (INAREG|INTAREG|INBREG|INTBREG);
        !           256:        cookie |= INTEMP;
        !           257:        /* if this is one of the constrained operators, rewrite as op= */
        !           258:        switch( p->in.op ){
        !           259:            case GT:
        !           260:            case GE:
        !           261:            case LT:
        !           262:            case LE:
        !           263:            case EQ:
        !           264:            case NE:
        !           265:                        if (l->in.type != FLOAT && l->in.type != DOUBLE)
        !           266:                            break;
        !           267:                        if (use68881) {
        !           268:                            /*
        !           269:                             * figure out what, if anything, is
        !           270:                             * already in a coprocessor reg
        !           271:                             */
        !           272:                            int lhs,rhs;
        !           273:                            lhs = iscnode(l);
        !           274:                            rhs = iscnode(r);
        !           275:                            /*
        !           276:                             * logical ops require one operand to
        !           277:                             * be in a coprocessor register. table.c
        !           278:                             * expects the register on the left.
        !           279:                             */
        !           280:                            if ( !lhs ) {
        !           281:                                /* lhs is not in a coprocessor reg */
        !           282:                                if ( !rhs ) {
        !           283:                                    /* rhs isn't either; do harder one */
        !           284:                                    if (SUGT(sur, sul)
        !           285:                                      && !tshape(r, SFLOAT_SRCE)) {
        !           286:                                        order(r, INCREG|INTCREG);
        !           287:                                        rhs = 1;
        !           288:                                    } else {
        !           289:                                        order(l, INCREG|INTCREG);
        !           290:                                        lhs = 1;
        !           291:                                    }
        !           292:                                } 
        !           293:                                if (rhs) {
        !           294:                                    /* rhs is, lhs isn't */
        !           295:                                    int temp;
        !           296:                                    p->in.op = revrel[p->in.op - EQ];
        !           297:                                    p->in.left = r;
        !           298:                                    p->in.right = l;
        !           299:                                    r = l;
        !           300:                                    l = p->in.left;
        !           301:                                    temp = rhs;
        !           302:                                    rhs = lhs;
        !           303:                                    lhs = temp;
        !           304:                                }
        !           305:                            }
        !           306:                            /*
        !           307:                             * lhs is in a coprocessor reg
        !           308:                             */
        !           309:                            if ( !rhs ) {
        !           310:                                /*
        !           311:                                 * rhs isn't, and doesn't need to be
        !           312:                                 */
        !           313:                                floatsrce(r);
        !           314:                            } /* !rhs */
        !           315:                            return(1);
        !           316:                        } /* use68881 */
        !           317: 
        !           318:                        /*
        !           319:                         * evaluate most expensive side first. If 
        !           320:                         * cheaper size has non-zero cost, may have
        !           321:                         * to put first intermediate result in a temp.
        !           322:                         * Actually, this should not be a problem, if
        !           323:                         * the su-stuff worked.
        !           324:                         */
        !           325:                        /* set variable "i" if we do anything here */
        !           326:                        i = 0;
        !           327:                        if( SUGT( sul, sur ) && !(istnode(l)&&l->tn.rval==D0) ){
        !           328:                            /* do lhs first if it is the more expensive */
        !           329:                            l->in.rall = MUSTDO|D0;
        !           330:                            SAFETY( r , MUSTDO|D0, l);
        !           331:                            order( l, INTAREG);
        !           332:                            i++;
        !           333:                        }
        !           334:                        if ( r->in.type == DOUBLE ){
        !           335:                            /* must be addressable */
        !           336:                            if ( !tshape( r, SNAME|SOREG|STARNM)){
        !           337:                                r->in.rall = NOPREF;
        !           338:                                order( r, INTEMP );
        !           339:                                i++;
        !           340:                            }
        !           341:                        } else {
        !           342:                            if( !(istnode(r) && r->tn.rval == D1) ){
        !           343:                                r->in.rall = MUSTDO|D1;
        !           344:                                SAFETY( l , MUSTDO|D1, r);
        !           345:                                order( r, INTAREG);
        !           346:                                i++;
        !           347:                            }
        !           348:                        }
        !           349:                        if( !(istnode(l) && l->tn.rval == D0) ){
        !           350:                            /* do lhs after if it is the less expensive */
        !           351:                            l->in.rall = MUSTDO|D0;
        !           352:                            order( l, INTAREG);
        !           353:                            i++;
        !           354:                        }
        !           355:                        if (i)
        !           356:                            return 1;
        !           357:                        break ; /* didn't accomplish anything -- fall into general case */
        !           358:            case PLUS:
        !           359:            case MINUS:
        !           360:                if( p->in.type == FLOAT || p->in.type == DOUBLE ){
        !           361: float_ops:
        !           362:                        /*
        !           363:                         * evaluate most expensive side first. If 
        !           364:                         * cheaper size has non-zero cost, may have
        !           365:                         * to put first intermediate result in a temp.
        !           366:                         * Actually, this should not be a problem, if
        !           367:                         * the su-stuff worked.
        !           368:                         */
        !           369:                        if (r->in.type==FLOAT && (!FLOATMATH || p->in.type==DOUBLE)){
        !           370:                            r = p->in.right = double_conv(r);
        !           371:                        }
        !           372:                        if (l->in.type==FLOAT && (!FLOATMATH || p->in.type==DOUBLE)){
        !           373:                            l = p->in.left = double_conv(l);
        !           374:                        }
        !           375:                        /*----------------------------*/
        !           376:                        if (use68881) {
        !           377:                            /*
        !           378:                             * figure out what, if anything, is
        !           379:                             * already in a coprocessor reg.  The
        !           380:                             * lhs must be a temporary.
        !           381:                             */
        !           382:                            int lhs,rhs;
        !           383:                            lhs = (istnode(l) && iscreg(l->tn.rval));
        !           384:                            rhs = (iscnode(r));
        !           385:                            /*
        !           386:                             * dyadic ops require one operand to
        !           387:                             * be in a coprocessor register. table.c
        !           388:                             * expects the register on the left.
        !           389:                             */
        !           390:                            if ( !lhs ) {
        !           391:                                /* lhs is not in a temp coprocessor reg */
        !           392:                                if ( !rhs ) {
        !           393:                                    /* rhs isn't either; do harder one */
        !           394:                                    if (SUGT(sur, sul)
        !           395:                                      && !tshape(r, SFLOAT_SRCE)) {
        !           396:                                        floatsrce(r);
        !           397:                                        rhs = iscnode(r);
        !           398:                                    } else {
        !           399:                                        order(l, INTCREG);
        !           400:                                        lhs = 1;
        !           401:                                    }
        !           402:                                } 
        !           403:                                if ( rhs && !lhs && istnode(r)
        !           404:                                  && (p->in.op == PLUS || p->in.op == MUL) ) {
        !           405:                                    /*
        !           406:                                     * rhs is in a writable coprocessor
        !           407:                                     * reg, lhs isn't, and op is commutable
        !           408:                                     */
        !           409:                                    int temp;
        !           410:                                    p->in.left = r;
        !           411:                                    p->in.right = l;
        !           412:                                    r = l;
        !           413:                                    l = p->in.left;
        !           414:                                    temp = rhs;
        !           415:                                    rhs = lhs;
        !           416:                                    lhs = temp;
        !           417:                                }
        !           418:                                if (!lhs) {
        !           419:                                    order(l, INTCREG);
        !           420:                                    lhs = 1;
        !           421:                                }
        !           422:                            }
        !           423:                            /*
        !           424:                             * lhs is in a writable coprocessor reg
        !           425:                             */
        !           426:                            if ( !rhs ) {
        !           427:                                /*
        !           428:                                 * rhs isn't, and doesn't need to be
        !           429:                                 */
        !           430:                                floatsrce(r);
        !           431:                            } 
        !           432:                            p->in.op = ASG p->in.op;
        !           433:                            return(1);
        !           434:                        } /* use68881 */
        !           435: 
        !           436:                        if (usesky) {
        !           437:                            if ( p->in.op == PLUS ) {
        !           438:                                /*
        !           439:                                 * look for expressions of
        !           440:                                 * the form (x + y*z), which the
        !           441:                                 * sky board does in a single
        !           442:                                 * operation.
        !           443:                                 */
        !           444:                                if ( l->in.op == MUL && r->in.op != MUL ) {
        !           445:                                    l = r;
        !           446:                                    r = p->in.left;
        !           447:                                    p->in.left = l;
        !           448:                                    p->in.right = r;
        !           449:                                }
        !           450:                                if (r->in.op == MUL) {
        !           451:                                    /*
        !           452:                                     * Don't even go near it
        !           453:                                     * unless x,y, or z comes for free.
        !           454:                                     */
        !           455:                                    if (!SUTEST(l->in.su)) {
        !           456:                                        l = r->in.left;
        !           457:                                        r = r->in.right;
        !           458:                                    } else if (!SUTEST(r->in.left->in.su)) {
        !           459:                                        r = r->in.right;
        !           460:                                    } else if (!SUTEST(r->in.right->in.su)) {
        !           461:                                        r = r->in.left;
        !           462:                                    }
        !           463:                                }
        !           464:                            }
        !           465:                            for( i=0; i<2; i++ ){
        !           466:                                if (SUGT( l->in.su, r->in.su )){
        !           467:                                    p2 = l; q = r;
        !           468:                                }else if (SUTEST( r->in.su )){
        !           469:                                    p2 = r; q = l;
        !           470:                                }else break;
        !           471:                                if (p2->in.op==UNARY MUL 
        !           472:                                  && rewrite_b_rall(p2->in.left, 1)){
        !           473:                                    /* try to offstar, but not into a1 */
        !           474:                                    failsafe = find_mustdo( q, MUSTDO|D0 );
        !           475:                                    offstar(p2->in.left);
        !           476:                                } else {
        !           477:                                    if ( !find_mustdo( q, MUSTDO|D0) ||
        !           478:                                        rewrite_rall(p2, i) )
        !           479:                                        order( p2, INTAREG| INTBREG| INTEMP );
        !           480:                                    else
        !           481:                                        order( p2, INTEMP );
        !           482:                                }
        !           483:                                /* set su to zero here */
        !           484:                                p2->in.su = zed;
        !           485:                            } /* for */
        !           486:                        } else {
        !           487:                            /*
        !           488:                             * do it in software
        !           489:                             */
        !           490:                            if (p->in.type == FLOAT){
        !           491:                                /* assume rall's set up already */
        !           492:                                for( i=0; i<2; i++ ){
        !           493:                                    if (SUGT( l->in.su, r->in.su )){
        !           494:                                        p2 = l; q = r;
        !           495:                                    }else if (SUTEST( r->in.su )){
        !           496:                                        p2 = r; q = l;
        !           497:                                    }else break;
        !           498:                                    SAFETY( q, D0|MUSTDO, p2 );
        !           499:                                    failsafe = 1;
        !           500:                                    order( p2, INTAREG|INTBREG );
        !           501:                                    p2->in.su = zed;
        !           502:                                }
        !           503:                                /* are no-cost, but may be wrong */
        !           504:                                if (!istnode(l) || l->tn.rval != D0)
        !           505:                                    order( l, INTAREG );
        !           506:                            } else {
        !           507:                                /* this case is the least symmetric */
        !           508:                                /* basically, must rewrite lhs as d0/d1 */
        !           509:                                /* but if rhs is hard, do it first */
        !           510:                                if (!istnode(l) || l->tn.rval != D0){
        !           511:                                    if (SUTEST( sur )){
        !           512:                                        if (r->in.op == UNARY MUL 
        !           513:                                        && ( !SUTEST(sul) || rewrite_b_rall( r->in.left, 0)) ){
        !           514:                                                failsafe = 1;
        !           515:                                                offstar( r->in.left );
        !           516:                                        } else {
        !           517:                                            order( r, INTEMP );
        !           518:                                        }
        !           519:                                    }
        !           520:                                    failsafe = 1;
        !           521:                                    order( l, INTAREG );
        !           522:                                }
        !           523:                            }
        !           524:                            p->in.op = ASG p->in.op ; /* gag */
        !           525:                        }
        !           526:                        /*----------------------------*/
        !           527: #ifdef FLOATMATH
        !           528:                        if (!FLOATMATH)
        !           529: #endif
        !           530:                            p->in.type = DOUBLE;
        !           531:                        return 1; /* order(): try again */
        !           532:                } else if (ISPTR(p->in.type)){
        !           533:                    /*
        !           534:                     * cute hack: we can add a short into an address register
        !           535:                     * without extending it first.
        !           536:                     */
        !           537:                    if ( isconv( l, SHORT, -1) && p->in.op==PLUS ){
        !           538:                        /* un-canonical form -- flip it */
        !           539:                        p->in.left = r;
        !           540:                        p->in.right = r =l;
        !           541:                        l = p->in.left;
        !           542:                    }
        !           543:                    if ( isconv( r, SHORT, -1 ) ){
        !           544:                        /*
        !           545:                         * if this is being evaluated into an address 
        !           546:                         * register or for argument, delete the conversion
        !           547:                         */
        !           548:                        if ( (cook==FORARG || (cook&(INBREG|INTBREG)
        !           549:                                && !(cook&~(INBREG|INTBREG))))
        !           550:                        && l->tn.op==REG
        !           551:                        && tshape( r->in.left, SAREG|STAREG|SBREG|STBREG|SNAME|SOREG|STARREG) ){
        !           552:                            if (cook==FORARG && r->in.left->tn.op != REG){
        !           553:                                order( r->in.left, INAREG|INTAREG|INBREG|INTBREG );
        !           554:                            }
        !           555:                            /* lhs should be in an address register,
        !           556:                               and should be writeable if SCONV operand
        !           557:                               is not a register */
        !           558:                            if (!isbreg(l->tn.rval)
        !           559:                              || !istreg(l->tn.rval) && r->in.left->in.op != REG) {
        !           560:                                order( l, INBREG|INTBREG );
        !           561:                            }
        !           562:                            p->in.right = r->in.left;
        !           563:                            r->in.op = FREE;
        !           564:                            return 1;
        !           565:                        } else if (p->in.op == PLUS) {
        !           566:                            /* otherwise, we were better off the other way */
        !           567:                            /* flip back */
        !           568:                            p->in.left = r;
        !           569:                            p->in.right = r =l;
        !           570:                            l = p->in.left;
        !           571:                        }
        !           572:                    }
        !           573:                }
        !           574:                break;
        !           575:            case MUL:
        !           576:            case DIV:
        !           577:            case MOD:
        !           578:                if( p->in.type == FLOAT || p->in.type == DOUBLE ){
        !           579:                        goto float_ops;
        !           580:                }
        !           581:                if( p->in.type != INT && p->in.type != UNSIGNED && !ISPTR(p->in.type))
        !           582: 
        !           583:                        break;
        !           584:                if(use68020) 
        !           585:                        break;
        !           586: d0_d1:
        !           587:                /* copied from Setasop */
        !           588:                sul = l->in.su;
        !           589:                sur = r->in.su;
        !           590:                /* use q to designate the more expensive side, p2 the cheaper */
        !           591:                if (!SUGT(sur, sul)){
        !           592:                        q = l; p2 = r; pcost = sur;
        !           593:                } else {
        !           594:                        q = r; p2 = l; pcost = sul;
        !           595:                }
        !           596:                if( SUTEST(sul) && SUTEST(sur) ){
        !           597:                    SAFETY( p2, q->in.rall, q );
        !           598:                }
        !           599:                        
        !           600:                /* do code emission, most expensive side first */
        !           601:                if (!istnode( q ) ){
        !           602:                  order( q, INAREG|INTAREG);
        !           603:                }
        !           604:                if ( SUTEST( pcost ) && !istnode( p2 )){
        !           605:                  order( p2 ,INAREG|INTAREG);
        !           606:                }
        !           607:                if ( !istnode( l ) || l->tn.rval != D0 ){
        !           608:                    l->tn.rall = MUSTDO | D0;
        !           609:                    order( l, INTAREG);
        !           610:                }
        !           611:                if (logop(p->in.op)){
        !           612:                    if ( !istnode( r )||r->tn.rval != D1 ){
        !           613:                        r->tn.rall = MUSTDO | D1;
        !           614:                        order( r, INTAREG);
        !           615:                    }
        !           616:                } else {
        !           617:                    if ( SUTEST( sur ) && (!istnode( r )||r->tn.rval != D1)){
        !           618:                        r->tn.rall = MUSTDO | D1;
        !           619:                        order( r, INTAREG);
        !           620:                    }
        !           621:                    p->in.op = ASG p->in.op;
        !           622:                }
        !           623:                return 1; /* go try 'gain */
        !           624:            case CHK:
        !           625:                /*
        !           626:                 * the rhs of a CHK operator is an ordered pair
        !           627:                 * of integers.  We load the lhs first, regardless
        !           628:                 * of what the bounds cost, since both the bounds
        !           629:                 * and the lhs must be in hand simultaneously.
        !           630:                 */
        !           631:                if (!istnode(l) || !isareg(l->tn.lval)) {
        !           632:                    SAFETY(r, MUSTDO|D0, l);
        !           633:                    order(l, INTAREG|INAREG);
        !           634:                    return(1);
        !           635:                }
        !           636:                return(0);
        !           637:        } /* switch */
        !           638: 
        !           639:        if( !SUTEST( r->in.su ) ){
        !           640:                /* rhs is addressable */
        !           641:                if( logop( p->in.op ) ){
        !           642:                        if ( l->in.op==UNARY MUL 
        !           643:                        && l->in.type!=FLOAT && shumul(l->in.left)!=STARREG ) {
        !           644:                            offstar( l->in.left );
        !           645:                        } else  if ( !(l->in.op==REG && isareg(l->tn.rval))) {
        !           646:                            /* lhs is not in a data register */
        !           647:                            switch (l->in.type) {
        !           648:                            case FLOAT:
        !           649:                            case DOUBLE:
        !           650:                                /* lhs must be in d0/d1 */
        !           651:                                if (r->in.op == REG && r->tn.rval == D0) {
        !           652:                                    goto reverse;
        !           653:                                }
        !           654:                                break;
        !           655:                            case CHAR:
        !           656:                            case UCHAR:
        !           657:                                /* bytes cannot be in address registers */
        !           658:                                if (l->in.op == REG && isbreg(l->tn.rval)) {
        !           659:                                    break;
        !           660:                                }
        !           661:                                /* fall through */
        !           662:                            default:
        !           663:                            reverse:
        !           664:                                if ( r->in.op == REG && isareg(r->tn.rval)
        !           665:                                  && !SUTEST(l->in.su) ) {
        !           666:                                    /*
        !           667:                                     * rhs is in a data register, lhs
        !           668:                                     * isn't, and doesn't have to be
        !           669:                                     */
        !           670:                                    p->in.left = r;
        !           671:                                    p->in.right = l;
        !           672:                                    p->in.op = revrel[p->in.op - EQ];
        !           673:                                    return(1);
        !           674:                                }
        !           675:                            }
        !           676:                            order( l, cookie );
        !           677:                        } else {
        !           678:                            /*
        !           679:                             * if here, must be a logical operator for 0-1 value
        !           680:                             * and we don't have 2 registers, as we would prefer
        !           681:                             */
        !           682:                            int m;
        !           683:                            cbranch( p, -1, m=getlab() );
        !           684:                            p->in.op = CCODES;
        !           685:                            p->bn.label = m;
        !           686:                            order( p, INTAREG );
        !           687:                        } 
        !           688:                        return( 1 );
        !           689:                }
        !           690:                if ( !istnode( l ) ){
        !           691:                    if (commuteop(p->in.op) && istnode(r)) {
        !           692:                        /* commutative op - put temp node on the left */
        !           693:                        p->in.right = l;
        !           694:                        p->in.left = r;
        !           695:                    } else {
        !           696:                        order( l, cookie&(INTAREG|INTBREG) );
        !           697:                        return( 1 );
        !           698:                    }
        !           699:                }
        !           700:                if ( divmulop(p->in.op) && r->in.op == REG
        !           701:                  && isbreg(r->tn.rval)) {
        !           702:                    order( r, INAREG|INTAREG );
        !           703:                    return( 1 );
        !           704:                }
        !           705:                /* rewrite */
        !           706:                return( 0 );
        !           707:        }
        !           708:        /* now, rhs is complicated */
        !           709:        /* do the harder side first */
        !           710:        /* be careful of D0, D1 usage */
        !           711: 
        !           712:        if (SUGT(l->in.su, r->in.su)) {
        !           713:                /* lhs first; put into register */
        !           714:                SAFETY(r, MUSTDO|D0, l);
        !           715:                order(l, cookie&(INTAREG|INTBREG));
        !           716:                return( 1 );
        !           717:        }
        !           718:        /* try to make rhs addressable */
        !           719:        if(r->in.op == UNARY MUL) {
        !           720:                failsafe = find_mustdo( l, D0|MUSTDO) ;
        !           721:                if (l->in.su.d >= nfree(STAREG)) {
        !           722:                        /* lhs needs all available d-registers;
        !           723:                           do not use double indexing */
        !           724:                        failsafe |= 1;
        !           725:                }
        !           726:                offstar( r->in.left );
        !           727:                return(1);
        !           728:        }
        !           729:        if (SUGT(r->in.su , l->in.su)){
        !           730:                /* rhs first; put into register */
        !           731:                SAFETY( l, MUSTDO|D0, r);
        !           732:                /* anything goes on rhs */
        !           733:                order( r, INTAREG|INAREG|INTBREG|INBREG|INTEMP ); 
        !           734:                return( 1 );
        !           735:        }
        !           736:        if (!istnode(l)) {
        !           737:                SAFETY(r, MUSTDO|D0, l);
        !           738:                order(l, cookie&(INTAREG|INTBREG));
        !           739:                return( 1 );
        !           740:        }
        !           741:        if (!istnode(r)) {
        !           742:                SAFETY(l, MUSTDO|D0, r);
        !           743:                order(r, INTAREG|INAREG|INTBREG|INBREG|INTEMP);
        !           744:                return( 1 );
        !           745:        }
        !           746:        /* rewrite */
        !           747:        return( 0 );
        !           748: }
        !           749: 
        !           750: setstr( p, cook ) register NODE *p; 
        !           751: { 
        !           752:        /* structure assignment */
        !           753:        if (p->in.right->in.op != REG){
        !           754:                order( p->in.right, INTBREG );
        !           755:                return(1);
        !           756:        }
        !           757:        p = p->in.left;
        !           758:        if ( p->in.op != NAME && p->in.op != OREG ){
        !           759:                if ( p->in.op != UNARY MUL ) cerror( "bad setstr");
        !           760:                order( p->in.left, INTBREG );
        !           761:                return( 1 );
        !           762:        }
        !           763:        if( p->in.op == OREG && !R2TEST(p->tn.rval) && istreg(p->tn.rval)
        !           764:            && p->tn.lval == 0){
        !           765:                /* cheat -- rewrite this as a REG */
        !           766:                p->in.op = REG;
        !           767:                return (1);
        !           768:        }
        !           769: #ifdef FORT
        !           770:        /* Pascal does struct assignment of things that ain't structs!! */
        !           771:        if (ISARY(p->in.type)){
        !           772:            p->in.type = STRTY;
        !           773:            return(1);
        !           774:        }
        !           775: #endif
        !           776:        return( 0 );
        !           777: }
        !           778: 
        !           779: setasg( p , cookie ) 
        !           780:        register NODE *p; 
        !           781: {
        !           782:        /* setup for assignment operator */
        !           783:        register NODE *r, *l;
        !           784:        int failsave = failsafe;
        !           785: 
        !           786:        r = p->in.right;
        !           787:        l = p->in.left;
        !           788: 
        !           789:        if ( !SUGT( r->in.su , l->in.su )) goto do_lhs;
        !           790: /*     if ((p->in.type == DOUBLE || p->in.type == FLOAT) 
        !           791: /*     && iscnode(p->in.right)){
        !           792: /*         order( p->in.right, INAREG|SOREG|SNAME|SCON );
        !           793: /*         return 1;
        !           794: /*     }
        !           795: */
        !           796:        if( SUTEST( r->in.su ) && r->in.op != REG ){
        !           797:            failsafe |=  SUTEST( l->in.su ); /* conservative guess */
        !           798:            if( r->in.op == UNARY MUL ){
        !           799:                offstar( r->in.left );
        !           800:            }else{
        !           801:                if (p->in.type == DOUBLE && r->in.type == FLOAT) 
        !           802:                    p->in.right = r = double_conv( r );
        !           803:                if (!use68020 || !use68881) {
        !           804:                    /*
        !           805:                     * more goddamn complications from register parameters:
        !           806:                     * if the lhs needs D0 for a multiply, for instance,
        !           807:                     * then we must be careful not to
        !           808:                     * evaluate the rhs into D0. 
        !           809:                     */
        !           810:                    SAFETY( l, MUSTDO|D0, r );
        !           811:                }
        !           812:                order( r, INAREG|INBREG|INCREG|SOREG|SNAME|SCON );
        !           813:            }
        !           814:            failsafe = failsave;
        !           815:            return(1);
        !           816:        }
        !           817: do_lhs:
        !           818:        if( l->in.op == UNARY MUL )
        !           819:                if (!tshape( l, STARREG|STARNM ) 
        !           820:                    || p->in.type == DOUBLE){
        !           821:                    /* sorry, we're too feeble to *P++ with double pointers */
        !           822:                        failsafe |=  SUTEST( r->in.su ); /* conservative guess */
        !           823:                        failsafe |=  r->tn.su.d >= fregs.d;
        !           824:                        offstar( l->in.left );
        !           825:                        failsafe = failsave;
        !           826:                        return(1);
        !           827:                }
        !           828:        if (l->in.op==FLD && l->in.left->in.op==UNARY MUL ){
        !           829:                failsafe |=  SUTEST( r->in.su ); /* conservative guess */
        !           830:                offstar( l->in.left->in.left );
        !           831:                failsafe = failsave;
        !           832:                return(1);
        !           833:        }
        !           834:        /* if things are really strange, get rhs into a register */
        !           835:        if( r->in.op != REG ) {
        !           836:                order( r, INAREG|INBREG|INCREG );
        !           837:                failsafe = failsave;
        !           838:                return( 1 );
        !           839:        }
        !           840:        /* for fields, rhs must be in a data register */
        !           841:        if( l->in.op == FLD && r->in.op == REG && isbreg(r->tn.rval) ) {
        !           842:                order( r, INAREG|INTAREG );
        !           843:                failsafe = failsave;
        !           844:                return( 1 );
        !           845:        }
        !           846:        return(0);
        !           847: }
        !           848: 
        !           849: find_mustdo( p, regname ) register NODE *p;
        !           850: {
        !           851:     /* if there are any ops here that require use of reg regname,  return
        !           852:      * 1 else return 0;
        !           853:      */
        !           854: redo:
        !           855:     if (p->in.rall == regname) return 1;
        !           856:     if (p->in.type == DOUBLE && p->in.rall == regname-1) return 1;
        !           857:     switch( optype(p->in.op) ){
        !           858:     case LTYPE: return 0;
        !           859:     case BITYPE:
        !           860:                if (find_mustdo(p->in.right, regname)) return 1;
        !           861:                /* else fall through */
        !           862:     }
        !           863:     p = p->in.left;
        !           864:     goto redo; /* go 'round again */
        !           865: }
        !           866: 
        !           867: int
        !           868: rewrite_rall( n, trybreg ) NODE *n;
        !           869: {
        !           870:        register int i, reg;
        !           871:        register TWORD t = n->in.type;
        !           872: 
        !           873:        /* find a temporary home for n */
        !           874:        reg = -1;
        !           875:        for( i = D2; i <= maxa; i++){
        !           876:            if( istreg(i) && busy[i] == 0){
        !           877:                if (t==DOUBLE && ((i&1) || !( istreg(i+1) && busy[i+1] == 0)))
        !           878:                    continue; /* too bad */
        !           879:                reg = i; break;
        !           880:            }
        !           881:        }
        !           882:        if (reg < 0 && trybreg && t!=CHAR && t!= UCHAR) {
        !           883:            /* we are DESPARATE! */
        !           884:            for( i = minb; i <= maxb; i++){
        !           885:                if( istreg(i) && busy[i] == 0){
        !           886:                    if (t==DOUBLE && ((i&1) || !( istreg(i+1) && busy[i+1] == 0)))
        !           887:                        continue; /* too bad */
        !           888:                    reg = i; break;
        !           889:                }
        !           890:            }
        !           891:        }
        !           892:        if ( reg < 0 ) return 0;
        !           893:        n->in.rall = (MUSTDO | reg);
        !           894:        return 1;
        !           895: }
        !           896: 
        !           897: int
        !           898: rewrite_b_rall( n, a0ok )
        !           899:     NODE *n;
        !           900: {
        !           901:        register int i, reg;
        !           902: 
        !           903:        /* find a temporary home for n in the b-registers */
        !           904:        /* get out of the hair of a0/a1     */
        !           905:        reg = -1;
        !           906:        for( i = minb+2; i <= maxb; i++){
        !           907:            if( istreg(i) && busy[i] == 0){
        !           908:                reg = i; break;
        !           909:            }
        !           910:        }
        !           911:        if (reg<0 && a0ok && busy[minb]==0)
        !           912:            reg = minb;
        !           913:        if ( reg < 0) return 0; /*failure*/
        !           914:        n->in.rall = MUSTDO | reg;
        !           915:        /* if this is a prospective oreg -- keep going */
        !           916:        if (n->in.op == PLUS || n->in.op == MINUS){
        !           917:            n = n->in.left;
        !           918:            if (n->in.op != REG || !isareg( n->tn.rval ) )
        !           919:                n->in.rall = MUSTDO | reg;
        !           920:        }
        !           921:        return 1;
        !           922: }
        !           923: 
        !           924: NODE *
        !           925: hard_rew( p ) register NODE *p;
        !           926: {
        !           927:        register NODE *lp, *p2;
        !           928:        register int i, reg;
        !           929:        /* do rewriting for non-reg lhs of hard op='s */
        !           930: 
        !           931:        lp = p->in.left;
        !           932:        switch(lp->in.op){
        !           933:            default:
        !           934:                return p;
        !           935:            case REG:
        !           936:                if(istreg(lp->tn.rval)) return p;
        !           937:            case NAME:
        !           938:            case OREG:
        !           939:            case UNARY MUL:
        !           940:            case FLD:
        !           941:                break;
        !           942:            }
        !           943: 
        !           944:        if (odebug){
        !           945:            printf("hard_rew( %o ):\n", p);
        !           946:            fwalk( p, eprint, 0);
        !           947:        }
        !           948: 
        !           949:        if( lp->in.op == UNARY MUL ){
        !           950:                NODE *llp = lp->in.left;
        !           951:                offstar( llp );
        !           952:                if ( llp->in.op == PLUS && llp->in.right->in.op != ICON ) {
        !           953:                        /* de-index */
        !           954:                        order(llp, INTBREG|INBREG);
        !           955:                }
        !           956:        }
        !           957:        if( lp->in.op == FLD && lp->in.left->in.op == UNARY MUL ){
        !           958:                NODE *lllp = lp->in.left->in.left;
        !           959:                offstar( lllp );
        !           960:                if ( lllp->in.op == PLUS && lllp->in.right->in.op != ICON ) {
        !           961:                        /* de-index */
        !           962:                        order(lllp, INTBREG|INBREG);
        !           963:                }
        !           964:        }
        !           965:        if( lp->in.op == FLD ) lp = lp->in.left;
        !           966: 
        !           967:        /* mimic code from reader.c */
        !           968:        p2 = tcopy( p );
        !           969:        p->in.op = ASSIGN;
        !           970:        reclaim( p->in.right, RNULL, 0 );
        !           971:        p->in.right = p2;
        !           972:        canon(p);
        !           973:        rallo( p, p->in.rall );
        !           974:        lp = p2->in.left;
        !           975:        /* if we are doing a floating op, we'll let the caller finish it off */
        !           976:        if(p->in.type == DOUBLE || p->in.type == FLOAT)
        !           977:            return p2;
        !           978:        /* if we must, rewrite rhs, too */
        !           979:        if (SUGT( p2->in.right->in.su , lp->in.su )){
        !           980:            SAFETY( lp, p2->in.right->in.rall, p2->in.right );
        !           981:            order( p2->in.right, INTAREG|INTBREG );
        !           982:        }
        !           983:        SAFETY( p2->in.right, lp->in.rall, lp );
        !           984:        order( lp, INTBREG|INTAREG );
        !           985:        
        !           986:        return p->in.right;
        !           987: }
        !           988: 
        !           989: setasop( p, cookie ) register NODE *p; 
        !           990: {
        !           991:        /* setup for =ops */
        !           992:        register SUTYPE sul, sur;
        !           993:        register NODE *r, *l;
        !           994:        register NODE *q, *p2;
        !           995:        SUTYPE pcost;
        !           996: 
        !           997:        r = p->in.right;
        !           998:        l = p->in.left;
        !           999:        sul = l->in.su;
        !          1000:        sur = r->in.su;
        !          1001: 
        !          1002:        switch( p->in.op ){
        !          1003:          case ASG PLUS:
        !          1004:          case ASG MINUS:
        !          1005:          case ASG OR:
        !          1006:          case ASG ER:
        !          1007:          case ASG AND:
        !          1008:                if (p->in.type == FLOAT || p->in.type == DOUBLE ) {
        !          1009: floatops:
        !          1010:                    /*
        !          1011:                     * lhs in dreg or AWD, rhs in dreg or AWD.
        !          1012:                     */
        !          1013: 
        !          1014:                    /*
        !          1015:                     * if the lhs is not a temp node, then we need to let
        !          1016:                     * a op= b ; be rewritten as...
        !          1017:                     * a = (a) op= b;
        !          1018:                     */
        !          1019:                    /* HOWEVER!:
        !          1020:                     * if rhs is expensive, we gotta do it first!
        !          1021:                     */
        !          1022:                    if (r->in.type==FLOAT && p->in.type==DOUBLE){
        !          1023:                        r = p->in.right = double_conv(r);
        !          1024:                    }
        !          1025: 
        !          1026:                    if (use68881) {
        !          1027:                        /*
        !          1028:                         * if lhs is already a coprocessor reg, all
        !          1029:                         * we have to do is clean up the rhs a little.
        !          1030:                         */
        !          1031:                        int rhs = 0;
        !          1032:                        if (iscnode(l)) {
        !          1033:                            floatsrce(r);
        !          1034:                            return(1);
        !          1035:                        }
        !          1036:                        if ( SUGT(sur, sul) ) {
        !          1037:                            /* rhs is hard -- do it first */
        !          1038:                            floatsrce(r);
        !          1039:                            rhs = 1;
        !          1040:                        }
        !          1041:                        p = hard_rew(p);
        !          1042:                        l = p->in.left;
        !          1043:                        r = p->in.right;
        !          1044:                        if ( istnode(r) && iscreg(r->tn.rval)
        !          1045:                          && (p->in.op == ASG PLUS || p->in.op == ASG MUL) ) {
        !          1046:                            /*
        !          1047:                             * commute -- we can do this because hard_rew
        !          1048:                             * assigns the result of p to the lhs
        !          1049:                             */
        !          1050:                            p->in.left = r;
        !          1051:                            p->in.right = l;
        !          1052:                            l = r;
        !          1053:                            r = p->in.right;
        !          1054:                            rhs = 0;
        !          1055:                        } else {
        !          1056:                            /*
        !          1057:                             * put lhs in a coprocessor reg
        !          1058:                             */
        !          1059:                            order(l, INCREG|INTCREG);
        !          1060:                        }
        !          1061:                        /*
        !          1062:                         * if rhs hasn't been dealt with yet, do it
        !          1063:                         */
        !          1064:                        if (!rhs) {
        !          1065:                            floatsrce(r);
        !          1066:                        }
        !          1067:                        return(1);
        !          1068:                    } /* use68881 */
        !          1069: 
        !          1070:                    if (usesky){
        !          1071:                        /*
        !          1072:                         * check for pivot operation ( x += y * z )
        !          1073:                         * only do if one of x,y,z is free
        !          1074:                         */
        !          1075:                        int pivoting = 0;
        !          1076:                        if (p->in.op == ASG PLUS && r->in.op == MUL) {
        !          1077:                            if (!SUTEST(sul)) {
        !          1078:                                setbin(r, INTAREG|INAREG|INTEMP);
        !          1079:                                return(1);
        !          1080:                            }
        !          1081:                            if (!SUTEST(r->in.left->in.su)
        !          1082:                              || !SUTEST(r->in.right->in.su)) {
        !          1083:                                pivoting = 1;
        !          1084:                            }
        !          1085:                        }
        !          1086:                        /*
        !          1087:                         * on the sky board, "op=" ops can be done
        !          1088:                         * with lhs in memory. However, we must stay
        !          1089:                         * away from a0/a1.
        !          1090:                         */
        !          1091:                        if (SUGT(sur,sul)){
        !          1092:                            /* must do rhs first */
        !          1093:                            if (pivoting) {
        !          1094:                                if (SUTEST(r->in.left->in.su)) {
        !          1095:                                    r = r->in.left;
        !          1096:                                } else {
        !          1097:                                    r = r->in.right;
        !          1098:                                }
        !          1099:                                pivoting = 0;
        !          1100:                            }
        !          1101:                            if (r->in.op == UNARY MUL
        !          1102:                              && rewrite_b_rall(r->in.left, 0)) {
        !          1103:                                /* make addressable, avoiding a1 */
        !          1104:                                offstar(r->in.left);
        !          1105:                            } else if (!find_mustdo(l, MUSTDO|D0)
        !          1106:                              || rewrite_rall(r, 0)) {
        !          1107:                                order(r, INAREG|INTAREG|INTEMP);
        !          1108:                            } else {
        !          1109:                                order(r, INTEMP);
        !          1110:                            }
        !          1111:                            r->in.su = zed;
        !          1112:                        }
        !          1113:                        /*
        !          1114:                         * deal with lhs
        !          1115:                         */
        !          1116:                        if (SUTEST(sul)) {
        !          1117:                            if (l->in.op == UNARY MUL
        !          1118:                              && rewrite_b_rall( l->in.left, 0 )) {
        !          1119:                                /* make addressable, avoiding a1 */
        !          1120:                                offstar( l->in.left );
        !          1121:                            } else {
        !          1122:                                /* failing that, try rewriting */
        !          1123:                                p = hard_rew(p);
        !          1124:                                l = p->in.left;
        !          1125:                                r = p->in.right;
        !          1126:                                if (pivoting) {
        !          1127:                                    if (SUTEST(r->in.left->in.su)) {
        !          1128:                                        r = r->in.left;
        !          1129:                                    } else {
        !          1130:                                        r = r->in.right;
        !          1131:                                    }
        !          1132:                                    pivoting = 0;
        !          1133:                                }
        !          1134:                                if (!find_mustdo(r, MUSTDO|D0)
        !          1135:                                  || rewrite_rall(l, 0)) {
        !          1136:                                    order(l, INAREG|INTAREG|INTEMP);
        !          1137:                                } else {
        !          1138:                                    order(l, INTEMP);
        !          1139:                                }
        !          1140:                            }
        !          1141:                        }
        !          1142:                        /*
        !          1143:                         * deal with rhs, if necessary
        !          1144:                         */
        !          1145:                        if (pivoting) {
        !          1146:                            if (SUTEST(r->in.left->in.su)) {
        !          1147:                                r = r->in.left;
        !          1148:                            } else {
        !          1149:                                r = r->in.right;
        !          1150:                            }
        !          1151:                        }
        !          1152:                        if (SUTEST(r->in.su)){
        !          1153:                            if (r->in.op == UNARY MUL
        !          1154:                              && rewrite_b_rall(r->in.left, 0)) {
        !          1155:                                /* make addressable, avoiding a1 */
        !          1156:                                offstar(r->in.left);
        !          1157:                            } else {
        !          1158:                                order(r, INAREG|INTAREG|INTEMP);
        !          1159:                            }
        !          1160:                        }
        !          1161:                        return 1;
        !          1162:                    } else if ( !istnode(l) ){
        !          1163:                        if (SUTEST( sur )){
        !          1164:                            if (!SUTEST(sul) && r->in.type == FLOAT){
        !          1165:                                r->in.rall = MUSTDO|D1;
        !          1166:                                order( r, INAREG );
        !          1167:                            } else {
        !          1168:                                /* may not want it in a register, 
        !          1169:                                in case lhs needs  the register */
        !          1170:                                if (rewrite_rall(r, 0)){
        !          1171:                                    order( r, INAREG|INTAREG|INBREG|INTBREG|INCREG|INTCREG );
        !          1172:                                } else {
        !          1173:                                    r->in.rall = NOPREF;
        !          1174:                                    order( r, INTEMP );
        !          1175:                                }
        !          1176:                            }
        !          1177:                        }
        !          1178:                        /* lhs is either easy or is an address */
        !          1179:                        /*
        !          1180:                         * if its an address, we must, unhappily,
        !          1181:                         * evaluate it AWAY from a0/a1, which will
        !          1182:                         * be clobbered by the operation.
        !          1183:                         */
        !          1184:                        if (l->in.op == UNARY MUL && l->in.left->in.op != REG){
        !          1185:                            failsafe = 1; /* keep away from d0/d1!! */
        !          1186:                            if ( rewrite_b_rall( l->in.left, 0 )  )
        !          1187:                                offstar( l->in.left );
        !          1188:                            else 
        !          1189:                                order( l->in.left, INTEMP );
        !          1190:                        } else 
        !          1191:                            l->in.rall = MUSTDO|D0;
        !          1192:                        /* p->in.op = NOASG p->in.op; */
        !          1193:                        goto rew_lhs;
        !          1194:                    }
        !          1195:                            
        !          1196:                    if (r->in.type == DOUBLE ){
        !          1197:                        if ( !tshape( r, SNAME|SOREG|STARNM)){
        !          1198:                            r->in.rall = NOPREF;
        !          1199:                            order( r, INTEMP );
        !          1200:                        }
        !          1201:                    } else {
        !          1202:                        if( !(istnode(r) && r->tn.rval == D1) ){
        !          1203:                            r->in.rall = MUSTDO|D1;
        !          1204:                            order( r, INTAREG);
        !          1205:                        }
        !          1206:                    }
        !          1207:                    if ( !(istnode(l) && l->tn.rval == D0) ){
        !          1208:                        l->in.rall = MUSTDO|D0;
        !          1209:                        order( l, INTAREG);
        !          1210:                    }
        !          1211: 
        !          1212:                    return 1;
        !          1213:                } else if (ISPTR(p->in.type)
        !          1214:                  && (p->in.op==ASG PLUS || p->in.op==ASG MINUS)
        !          1215:                  && isconv(r, SHORT, -1)
        !          1216:                  && l->in.op== REG && isbreg(l->tn.rval)) {
        !          1217:                    p->in.right = r->in.left;
        !          1218:                    r->in.op = FREE;
        !          1219:                    return 1;
        !          1220:                } else {
        !          1221:                    if ((p->in.right->in.op != REG || 
        !          1222:                    isbreg(p->in.right->tn.rval)) && !SUTEST( sul )) {
        !          1223:                        order(p->in.right,INAREG|INTAREG);
        !          1224:                        return(1);
        !          1225:                    } else break;
        !          1226:                }
        !          1227: 
        !          1228:          case ASG MUL:
        !          1229:          case ASG DIV:
        !          1230:          case ASG MOD:
        !          1231:                /*
        !          1232:                 * This is difficult: These ops require the lhs in d0 and the
        !          1233:                 * rhs in d1. This means that whichever side gets evaluated
        !          1234:                 * first will monopolize one of these strategic registers for
        !          1235:                 * the whole time the other side is being evaluated. This is
        !          1236:                 * not acceptable if the less-expensive side ALSO requires
        !          1237:                 * evaluation of one of these constrained ops. So we must be
        !          1238:                 * very careful here. First, we assume that there are, indeed,
        !          1239:                 * enough registers for us to play with, otherwise off-storing
        !          1240:                 * should already have been taken care of by the wonders of 
        !          1241:                 * portable code generation. So what we'll do is find a free
        !          1242:                 * register NOT in the set {d0,d1}, and force evaluation of the
        !          1243:                 * more expensive side into that register, then rewrite the 
        !          1244:                 * requirements for that side. Hold on.
        !          1245:                 */
        !          1246: 
        !          1247:                if (p->in.type == FLOAT || p->in.type == DOUBLE)
        !          1248:                    goto floatops;
        !          1249:                if( p->in.type != INT && p->in.type != UNSIGNED && !ISPTR(p->in.type))
        !          1250:                        break;
        !          1251:                if(use68020)
        !          1252:                        break;
        !          1253: 
        !          1254:                /* we can only do these into d0 */
        !          1255: d0_d1:
        !          1256:                /* if things already look optimum, we must already have been this way once */
        !          1257:                if (istnode(p->in.left) && !SUTEST( p->in.right->tn.su )){
        !          1258:                    order( p->in.right, INTAREG );
        !          1259:                    return 1;
        !          1260:                }
        !          1261:                p = hard_rew( p );
        !          1262:                sul = p->in.left->in.su;
        !          1263:                /* use q to designate the more expensive side, p2 the cheaper */
        !          1264:                if ( !SUGT( sur, sul )){ q = p->in.left;  p2 = p->in.right; pcost = sur; }
        !          1265:                        else { q = p->in.right; p2 = p->in.left;  pcost = sul; }
        !          1266:                if( SUTEST( sul ) && SUTEST( sur )){
        !          1267:                    SAFETY( p2, q->in.rall, q );
        !          1268:                }
        !          1269:                        
        !          1270:                /* do code emission, most expensive side first */
        !          1271:                if (!istnode( q ) ){
        !          1272:                  order( q, INAREG|INTAREG);
        !          1273:                }
        !          1274:                if ( SUTEST( pcost ) && !istnode( p2 )){
        !          1275:                  order( p2 ,INAREG|INTAREG);
        !          1276:                }
        !          1277:                if ( !istnode( p->in.left ) || p->in.left->tn.rval != D0 ){
        !          1278:                    p->in.left->tn.rall = MUSTDO | D0;
        !          1279:                    order( p->in.left, INTAREG );
        !          1280:                }
        !          1281:                if ( SUTEST(sur) &&(!istnode(p->in.right)||p->in.right->tn.rval!=D1)){
        !          1282:                    p->in.right->tn.rall = MUSTDO | D0;
        !          1283:                    order( p->in.right, INTAREG );
        !          1284:                }
        !          1285: 
        !          1286:                return(1);
        !          1287: 
        !          1288:          case ASG LS:
        !          1289:          case ASG RS:
        !          1290:                if (l->in.op != REG){
        !          1291:                        /* must rewrite as lhs = ((lhs) op= rhs) */
        !          1292:                        /* if we must, rewrite rhs, too */
        !          1293:                        if (SUGT( sur , sul)){
        !          1294:                            SAFETY( l, MUSTDO|D0, r );
        !          1295:                            order( r, INAREG|INBREG );
        !          1296:                        }
        !          1297:                        /* lhs is either easy or is an address */
        !          1298:                        if (SUTEST( sul )){
        !          1299:                            if (l->in.op == UNARY MUL)
        !          1300:                                offstar( l->in.left );
        !          1301:                            else if (l->in.op == FLD &&
        !          1302:                                l->in.left->in.op == UNARY MUL)
        !          1303:                                offstar( l->in.left->in.left);
        !          1304:                        }
        !          1305:                        goto rew_lhs;
        !          1306:                }
        !          1307:                if (r->in.op == REG && isareg(r->tn.rval)
        !          1308:                  || (r->in.op==ICON && r->tn.lval>=1 && r->tn.lval<=8))
        !          1309:                    break;
        !          1310:                order(r,INAREG|INTAREG);
        !          1311:                return(1);
        !          1312: 
        !          1313:        }
        !          1314: 
        !          1315:        /*
        !          1316:         * What we have here is an asop which could POSSIBLY be done to memory
        !          1317:         * if we desire it. Luckily we have the cookie as a parameter to make
        !          1318:         * this decision. If we do it to memory, then we just want to evaluate
        !          1319:         * the lhs to an address. If we do it for a value, we have to evaluate
        !          1320:         * the lhs for a value, then store afterwards.
        !          1321:         */
        !          1322:        if (SUTEST( sul ) && !SUGT( sur,sul )){
        !          1323:            /* since an lhs can only be an address ... */
        !          1324:            if (l->in.op == UNARY MUL){
        !          1325:                failsafe |= SUTEST( sur ); /* conservative guess */
        !          1326:                offstar( l->in.left );
        !          1327:            } else if (l->in.op == FLD){
        !          1328:                if (l->in.left->in.op == UNARY MUL)
        !          1329:                    offstar( l->in.left->in.left);
        !          1330:                return 0; /* rewrite as something sane */
        !          1331:            }
        !          1332:            if (cookie&FOREFF){
        !          1333:                /* for effect only! */
        !          1334:                return 1;
        !          1335:            }
        !          1336:            /* otherwise, rewrite as (lhs1) = ((lhs2) op= rhs) */
        !          1337: rew_lhs:
        !          1338:            ncopy( p2=talloc(), p);
        !          1339:            p->in.op    = ASSIGN;
        !          1340:            p->in.right = p2;
        !          1341:            l = p->in.left  = tcopy( p2->in.left );
        !          1342:            SAFETY( p2->in.right, MUSTDO|D0, p2->in.left );
        !          1343:            if (l->in.op == UNARY MUL && shumul(l->in.left) == STARREG) {
        !          1344:                /*
        !          1345:                 * Beware side effects lurking in lhs.  We now
        !          1346:                 * have two copies -- side effects of one copy must
        !          1347:                 * be eliminated.  Note that (lhs2) will be evaluated first.
        !          1348:                 */
        !          1349:                if (l->in.left->in.op == ASG MINUS) {
        !          1350:                    /* predecrement -- keep side effect in (lhs2),
        !          1351:                       delete side effect in (lhs1) */
        !          1352:                    q = l->in.left;
        !          1353:                } else {
        !          1354:                    /* postincrement -- keep side effect in (lhs1),
        !          1355:                       delete side effect in (lhs2) */
        !          1356:                    q = p2->in.left->in.left;
        !          1357:                }
        !          1358:                l = q->in.left;  /* = REG */
        !          1359:                r = q->in.right; /* = ICON */
        !          1360:                *q = *l;
        !          1361:                l->in.op = FREE;
        !          1362:                r->in.op = FREE;
        !          1363:            }
        !          1364:            order( p2->in.left, INAREG|INBREG );
        !          1365:            return 1;
        !          1366:        }
        !          1367:        if( SUTEST( sur )){
        !          1368:            /* evaluate rhs into a register, then go try again */
        !          1369:            SAFETY( l, MUSTDO|D0, r );
        !          1370:            order( r, INAREG|INBREG );
        !          1371:            return 1;
        !          1372:        }
        !          1373:        if (divmulop(p->in.op) && r->in.op == REG && isbreg(r->tn.rval)) {
        !          1374:            order(r, INAREG|INTAREG);
        !          1375:            return(1);
        !          1376:        }
        !          1377:        if (l->in.op == UNARY MUL && shumul(l->in.left) == STARREG) {
        !          1378:            goto rew_lhs;
        !          1379:        }
        !          1380:        return 0;
        !          1381: }
        !          1382: 
        !          1383: /*
        !          1384:  * returns number of free registers of a given type.  This wouldn't
        !          1385:  * be necessary if the SU-numbers were strictly followed; however,
        !          1386:  * double indexing ties up more registers than sucomp assumes, and
        !          1387:  * should not be attempted unless a spare register exists.
        !          1388:  */
        !          1389: int
        !          1390: nfree(cookie)
        !          1391: {
        !          1392:     register r;
        !          1393:     register n;
        !          1394:     n = 0;
        !          1395:     for (r = 0; r < REGSZ; r++) {
        !          1396:        if ((rstatus[r]&cookie) && !busy[r])
        !          1397:            n++;
        !          1398:     }
        !          1399:     return n;
        !          1400: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.