Annotation of researchv9/cmd/sun/pcc/su.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)su.c 1.1 86/02/03 Copyr 1985 Sun Micro";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Copyright (c) 1985 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: # include "cpass2.h"
                     10: 
                     11: /*
                     12:  * from order.c
                     13:  */
                     14: 
                     15: 
                     16: extern int mina, maxa, minb, maxb; /* imported from allo.c */
                     17: int failsafe;
                     18: extern toff, maxtoff;
                     19: 
                     20: # define iscnode(p) (p->in.op==REG && iscreg(p->tn.rval))
                     21: 
                     22: # define max(x,y) ((x)<(y)?(y):(x))
                     23: # define min(x,y) ((x)<(y)?(x):(y))
                     24: 
                     25: 
                     26: sucomp( p ) register NODE *p; 
                     27: {
                     28: 
                     29:        /* set the su field in the node to the sethi-ullman
                     30:           number, or local equivalent */
                     31: 
                     32:        register o, t;
                     33:        register nr;
                     34:        register u, tt;
                     35:        register NODE *r, *l;
                     36:        SUTYPE sul, sur;
                     37:        SUTYPE tempsu;
                     38:        static SUTYPE zed = { 0,0,0,0 };
                     39: 
                     40:        p->in.su = zed;
                     41:        switch(t = optype( o=p->in.op)) {
                     42:        case LTYPE:
                     43:                return;
                     44:        case UTYPE:
                     45:                sucomp(p->in.left);
                     46:                break;
                     47:        case BITYPE:
                     48:                sucomp(p->in.left);
                     49:                sucomp(p->in.right);
                     50:                r = p->in.right;
                     51:                sur = r->in.su ;
                     52:                break;
                     53:        }
                     54:        l = p->in.left;
                     55:        sul = l->in.su;
                     56:        nr = szty( tt = p->in.type );
                     57: 
                     58:        switch ( o ){
                     59:        case ASG ER:
                     60:                /* exclusive-or -- not generally computable to-memory */
                     61:                if ( r->tn.op != ICON ) goto reg_reg_asg;
                     62:                /* fall through */
                     63: 
                     64:        case ASG PLUS:
                     65:        case ASG MINUS:
                     66:        case ASG AND:
                     67:        case ASG OR:
                     68:                /* these may be done directly at memory -- looks like = */
                     69:                if ( tt == FLOAT || tt == DOUBLE ) {
                     70:                        goto float_asop;
                     71:                }
                     72:                /* fall through */
                     73:        
                     74:        case ASSIGN:
                     75:                /* usually, compute rhs into a register, compute lhs, store */
                     76:                /* could do it backwards if lhs is hairier                  */
                     77:                if (SUSUM( sur ) > SUSUM( sul )){
                     78: /*                 p->in.su = max( sur, sul+nr); */
                     79:                    sur.d = max( sur.d, sul.d+nr );
                     80:                    sur.a = max( sur.a, sul.a );
                     81:                }else{
                     82: /*                 p->in.su = max( sur+1, sul); */
                     83:                    if(l->in.op == FLD) {
                     84:                        sur.d = max(max(sur.d, sul.d),2);
                     85:                    } else {
                     86:                        sur.d = max(sur.d, sul.d);
                     87:                    }
                     88:                    sur.a = max( sur.a+1, sul.a);
                     89:                }
                     90:                sur.f = max( sur.f, sul.f);
                     91:                p->in.su = sur;
                     92:                return;
                     93: 
                     94:        case STASG:
                     95:                /* compute two addresses, then use up to three more registrers */
                     96: /*             p->in.su = max( 3, 1+max(sul,sur)); */
                     97:                sur.d = 1+max( sur.d, sul.d );
                     98:                t = max( sur.a, sul.a );
                     99:                sur.a = max( 2, t );
                    100:                p->in.su = sur;
                    101:                return;
                    102: 
                    103:        case UNARY MUL:
                    104:                if (shumul(p->in.left))
                    105:                        return;
                    106:                /* most other unary ops handled in default case */
                    107:                sul.a = max( sul.a, 1); /* 1 address register to * through */
                    108:                p->in.su = sul;
                    109:                return;
                    110: 
                    111:        case CALL:
                    112:        case UNARY CALL:
                    113:        case STCALL:
                    114:        case UNARY STCALL:
                    115:                p->in.su = fregs;
                    116:                return;
                    117: 
                    118:        case ASG RS:
                    119:        case ASG LS:
                    120:                /* if the rhs is not a small contant, this is a reg-reg op */
                    121:                if ( r->tn.op == ICON && r->tn.lval >0 && r->tn.lval <= 8 ){
                    122:                        /* looks like a unary op */
                    123:                        sul.d += nr;
                    124:                        p->in.su = sul;
                    125:                        return;
                    126:                }
                    127:                /* fall through */
                    128:        case ASG MUL:
                    129:        case ASG DIV:
                    130:        case ASG MOD:
                    131:        /* compute rhs, compute lhs (or vice versa), get lhs value, op */
                    132:                if ( tt == FLOAT || tt == DOUBLE ) {
                    133:                        goto float_asop;
                    134:                }
                    135: reg_reg_asg:
                    136:                t = SUSUM(sul)?1:0; /* number regs needed to store lhs address */
                    137:                /* want at least 2 regs + lhs address */
                    138:                /* if lhs is complicated, will always compute it into a reg FIRST */
                    139:                /* p->in.su = max( t+2*nr, min(t+sur, nr+sul)); */
                    140: /*             if (sul)
                    141: /*                 u = max( sul, t+sur );
                    142: /*             else
                    143: /*                 u = sur;
                    144: /*             p->in.su = max( u, t+2*nr);
                    145: */
                    146:                if (SUSUM(sul)){
                    147:                    sur.d = max( sur.d, sul.d );
                    148:                    sur.a = max( sur.a+t, sul.a );
                    149:                } 
                    150:                sur.d = max( sur.d , 2*nr );
                    151:                sur.a = max( sur.a , t );
                    152:                sur.f = 0;
                    153:                p->in.su = sur;
                    154:                return;
                    155: 
                    156:        case PLUS:
                    157:        case AND:
                    158:        case OR:
                    159:        case ER:
                    160:                /* commutable memory-register ops */
                    161:                if ( tt == FLOAT || tt == DOUBLE ) {
                    162:                        goto float_asop;
                    163:                }
                    164:                if (l->in.op != REG && SUSUM(sul) < SUSUM(sur)){
                    165:                        p->in.right = l;
                    166:                        p->in.left = r;
                    167:                        l = r;
                    168:                        r = p->in.right;
                    169:                        sul = sur;
                    170:                        sur = r->in.su ;
                    171:                }
                    172:                goto reg_mem_op;
                    173: 
                    174:        case EQ:
                    175:        case NE:
                    176:        case LE:
                    177:        case GE:
                    178:        case GT:
                    179:        case LT:
                    180:        case UGT:
                    181:        case UGE:
                    182:        case ULT:
                    183:        case ULE:
                    184:                    tt = l->in.type;
                    185:                    nr = szty( tt );
                    186:                    /* fall through */
                    187:        case MINUS:
                    188:        case INCR:
                    189:        case DECR:
                    190:                if ( tt == FLOAT || tt == DOUBLE ) {
                    191: float_asop:
                    192:                        if (use68881) {
                    193:                            nr = 1;
                    194:                            if (!SUTEST(sur)
                    195:                              && (r->in.op != REG || !isbreg(r->tn.rval))){
                    196:                                /* rhs is cheap */
                    197:                                sul.f = max( sul.f, nr );
                    198:                                p->in.su = sul;
                    199:                                return;
                    200:                            }
                    201:                            /* compute rhs, lhs (or vice versa) do op */
                    202:                            if (SUGT(sur, sul)){
                    203:                                /*
                    204:                                 * value of rhs, value of lhs,
                    205:                                 * reg-reg op
                    206:                                 */
                    207: /*                             p->in.su = max( sur, sul+nr ); */
                    208:                                if (commuteop(o) && !SUTEST(sul)
                    209:                                  && (l->in.op != REG || !isbreg(l->tn.rval))){
                    210:                                    u = max( sul.f, nr );
                    211:                                } else {
                    212:                                    u = nr + max( sul.f, nr );
                    213:                                }
                    214:                                sur.d = max( sur.d, sul.d );
                    215:                                sur.a = max( sur.a, sul.a );
                    216:                                sur.f = max( sur.f, u );
                    217:                            } else {
                    218: /*                             p->in.su = max( sul, sur+1 ); */
                    219:                                if (r->in.op == UNARY MUL){
                    220:                                    /*
                    221:                                     * address of rhs, value of lhs,
                    222:                                     * op from memory
                    223:                                     */
                    224:                                    sur.d = max( sur.d, sul.d   );
                    225:                                    sur.a = max( sur.a, sul.a+1 );
                    226:                                    sur.f = max( sul.f, sur.f+1 );
                    227:                                } else {
                    228:                                    /*
                    229:                                     * value of lhs, value of rhs,
                    230:                                     * reg-reg-op
                    231:                                     */
                    232:                                    sur.d = max( sul.d, sur.d );
                    233:                                    sur.a = max( sul.a, sur.a );
                    234:                                    sur.f = max( sul.f+1, sur.f+1 );
                    235:                                }
                    236:                            }
                    237:                            p->in.su = sur;
                    238:                            return;
                    239:                        }
                    240:                        /*
                    241:                         * floating operations are calls.
                    242:                         * They always take ALL the registers.
                    243:                         * SIMPLE FIRST APPROXIMATION HERE.
                    244:                         * evaluate rhs first: if lhs 
                    245:                         * costs, then may need an extra temp.
                    246:                         */
                    247:                        if (SUTEST(sur) && SUTEST(sul) )
                    248:                            u = max( sur.d, sul.d+nr);
                    249:                        else
                    250:                            u = max( sur.d, sul.d );
                    251:                        tempsu.d = max( u, fregs.d );
                    252: 
                    253:                        u = max( sur.a, sul.a );
                    254:                        tempsu.a = max( u, fregs.a );
                    255:                        tempsu.f = 0;
                    256:                        p->in.su = tempsu;
                    257:                        return;
                    258:                }
                    259: reg_mem_op:
                    260:                /* memory-register ops */
                    261: 
                    262:                /*
                    263:                 * if rhs is direct, then the op is very cheap.
                    264:                 * But if rhs is an address register, only integer
                    265:                 * addition and subtraction are cheap.
                    266:                 */
                    267:                if (SUSUM(sur) == 0) {
                    268:                    int cheap = 1;
                    269:                    if (r->in.op == REG && isbreg(r->tn.rval)) {
                    270:                        switch(o) {
                    271:                        case PLUS:
                    272:                        case MINUS:
                    273:                        case ASG PLUS:
                    274:                        case ASG MINUS:
                    275:                            if (tt == CHAR || tt == UCHAR) {
                    276:                                /* can't use addr regs in byte adds and subs */
                    277:                                cheap = 0;
                    278:                            }
                    279:                            break;
                    280:                        default:
                    281:                            /* can't use addr regs for other ops, period */
                    282:                            cheap = 0;
                    283:                            break;
                    284:                        }
                    285:                    }
                    286:                    if (cheap) {
                    287:                        sul.d = max(sul.d, nr);
                    288:                        p->in.su = sul;
                    289:                        return;
                    290:                    }
                    291:                }
                    292:                /* else must compute rhs, lhs (or vice versa) do op */
                    293:                if (SUGT(sul, sur)) {
                    294:                        /* lhs, rhs, reg-reg op */
                    295: /*                     p->in.su = max( sul, sur+nr ); */
                    296:                        u = nr + max( sur.d , nr );
                    297:                        sur.d = max( sul.d, u );
                    298:                        sur.a = max( sur.a, sul.a );
                    299:                } else {
                    300: /*                     p->in.su = max( sul, sur+1 ); */
                    301:                        if (r->in.op == UNARY MUL){
                    302:                            /* address of rhs, value of lhs, op from memory */
                    303:                            sur.d = max( sur.d, sul.d   );
                    304:                            sur.a = max( sur.a, sul.a+1 );
                    305:                        } else if (SUGT(sur,sul)) {
                    306:                            /* value of rhs, value of lhs, reg-reg-op */
                    307:                            sur.d = max( sur.d, sul.d+nr );
                    308:                            sur.a = max( sur.a, sul.a    );
                    309:                        } else {
                    310:                            /* value of lhs, value of rhs, reg-reg-op */
                    311:                            sur.d = max( sul.d, sur.d+nr );
                    312:                            sur.a = max( sul.a, sur.a    );
                    313:                        }
                    314:                }
                    315:                sur.f = 0;
                    316:                p->in.su = sur;
                    317:                /* is there an easier way to do this? */
                    318:                return;
                    319: 
                    320:        case RS:
                    321:        case LS:
                    322:                /* looks like a unary op if rhs is small */
                    323:                if ( r->tn.op == ICON && r->tn.lval >0 && r->tn.lval <= 8 ){
                    324:                        /* looks like a unary op */
                    325:                        sul.d = max( sul.d, nr);
                    326:                        p->in.su = sul;
                    327:                        return;
                    328:                }
                    329:                /* fall through */
                    330:        case MUL:
                    331:        case DIV:
                    332:        case MOD:
                    333:                if ( tt == FLOAT || tt == DOUBLE ) {
                    334:                        goto float_asop;
                    335:                }
                    336: reg_reg_op:
                    337:                /* register-register ops */
                    338:                /* must do one and then the other */
                    339:                /* commutability not an issue here */
                    340:                /* need at least two register sets */
                    341:                if ( SUGT( sul, sur ) ){
                    342:                    t = max( sul.d, sur.d+nr );
                    343:                } else {
                    344:                    t = max( sul.d+nr, sur.d );
                    345:                }
                    346:                sul.d = max( 2*nr, t);
                    347:                sul.a = max( sul.a, sur.a );
                    348:                sul.f = max( sul.f, sur.f );
                    349:                p->in.su = sul;
                    350:                return;
                    351: 
                    352:        case NAME:
                    353:        case REG:
                    354:        case OREG:
                    355:        case ICON:
                    356:        case FCON:
                    357:                return; /* su is zero */
                    358: 
                    359:        case SCONV:
                    360:                if (!ezsconv(p)){
                    361:                        sul.d = max( sul.d, fregs.d);
                    362:                        sul.a = max( sul.a, fregs.a);
                    363:                } else if (use68881
                    364:                    && (ISFLOATING(tt) || ISFLOATING(l->in.type))) {
                    365:                        sul.f = max( sul.f, 1 );
                    366:                        sul.d = max( sul.d, 1 );
                    367:                } else {
                    368:                        sul.d = max( sul.d, nr); /* normal unary */
                    369:                }
                    370:                p->in.su = sul;
                    371:                break;
                    372:        
                    373:        case FAINT:
                    374:        case FANINT:
                    375:        case FNINT:
                    376:                /* float=>integer conversion */
                    377:                if (use68881) {
                    378:                        sul.d = max(sul.d, 1);
                    379:                        sul.f = max(sul.f, 1);
                    380:                } else {
                    381:                        /* must do subroutine call */
                    382:                        sul.d = max(sul.d, fregs.d);
                    383:                        sul.a = max(sul.a, fregs.a);
                    384:                }
                    385:                p->in.su = sul;
                    386:                break;
                    387: 
                    388:        case CHK:
                    389:                /*
                    390:                 * this is actually a ternary operation: 
                    391:                 * the expression to be checked,
                    392:                 *     the lower bound,
                    393:                 *     the upper bound.
                    394:                 * if the upper and lower bounds are constant, then
                    395:                 * cost is the cost of the expression, which must
                    396:                 * always be evaluated into a data register. We
                    397:                 * may have to evaluate the bounds, too, and this 
                    398:                 * costs more.
                    399:                 * we will try to use the 68010's chk instruction.
                    400:                 * failing that, we will use the 68020's chk2 instruction.
                    401:                 * lacking that, use compare-and-branch code.
                    402:                 */
                    403:                if (chk_ovfl){
                    404:                    /*
                    405:                     * assume we have to evaluate each of the bounds &
                    406:                     * at the same time hold the expression.
                    407:                     */
                    408:                    sur.d = max( r->in.left->in.su.d, r->in.right->in.su.d);
                    409:                    sur.a = max( r->in.left->in.su.a, r->in.right->in.su.a);
                    410:                    sur.f = max( r->in.left->in.su.f, r->in.right->in.su.f);
                    411:                    p->in.su.d = max( sul.d, nr+sur.d );
                    412:                    p->in.su.a = max( sul.a, sur.a );
                    413:                    p->in.su.f = max( sul.f, sur.f );
                    414:                } else {
                    415:                    p->in.su = sul;
                    416:                }
                    417:                break;
                    418: 
                    419:        default:
                    420:                if ( t == BITYPE ){
                    421:                        /* random binary operators */
                    422:                        /* choose largest */
                    423:                        t = max( sur.d, sul.d );
                    424:                        sur.d = max( t, nr );
                    425:                        sur.a = max( sur.a, sul.a );
                    426:                        sur.f = max( sur.f, sul.f );
                    427:                        p->in.su = sur;
                    428:                        return;
                    429:                }
                    430:                /* must be unary */
                    431:                if (dope[o]&INTRFLG) {
                    432:                        /* fortran intrinsics */
                    433:                        if (use68881) {
                    434:                                sul.f = max(sul.f, 1);
                    435:                        } else {
                    436:                                /* must do subroutine call */
                    437:                                sul.d = max(sul.d, fregs.d);
                    438:                                sul.a = max(sul.a, fregs.a);
                    439:                        }
                    440:                } else {
                    441:                        /* random unary op */
                    442:                        sul.d = max( sul.d, nr);
                    443:                        if (use68881 && ISFLOATING(tt)) {
                    444:                                sul.f = max( sul.f, 1 );
                    445:                        }
                    446:                }
                    447:                p->in.su = sul;
                    448:        }
                    449: }
                    450: 
                    451: int radebug = 0;
                    452: 
                    453: mkrall( p, r ) register NODE *p; 
                    454: {
                    455:        /* insure that the use of p gets done with register r; in effect, */
                    456:        /* simulate offstar */
                    457: 
                    458:        if( p->in.op == FLD ){
                    459:                p->in.left->in.rall = p->in.rall;
                    460:                p = p->in.left;
                    461:        }
                    462: 
                    463:        if( p->in.op != UNARY MUL ) return;  /* no more to do */
                    464:        p = p->in.left;
                    465:        if( p->in.op == UNARY MUL ){
                    466:                p->in.rall = r;
                    467:                p = p->in.left;
                    468:        }
                    469:        if( p->in.op == PLUS && p->in.right->in.op == ICON ){
                    470:                p->in.rall = r;
                    471:                p = p->in.left;
                    472:        }
                    473:        rallo( p, r );
                    474: }
                    475: 
                    476: rallo( p, down ) NODE *p; 
                    477: {
                    478:        /* do register allocation */
                    479:        register o, type, down1, down2, ty;
                    480:        NODE *p2;
                    481: 
                    482: again:
                    483:        if( radebug ) printf( "rallo( %o, %d )\n", p, down );
                    484: 
                    485:        down2 = NOPREF;
                    486:        p->in.rall = down;
                    487:        down1 = ( down &= ~MUSTDO );
                    488: 
                    489:        ty = optype( o = p->in.op );
                    490:        type = p->in.type;
                    491: 
                    492: 
                    493:        switch( o ) {
                    494:        case UNARY MUL:
                    495:                down1 = NOPREF;
                    496:                break;
                    497: 
                    498:        case ASSIGN:    
                    499:                down1 = NOPREF;
                    500:                down2 = down;
                    501:                break;
                    502: 
                    503:        case ASG MUL:
                    504:        case ASG DIV:
                    505:        case ASG MOD:
                    506: 
                    507:        case MUL:
                    508:        case DIV:
                    509:        case MOD:
                    510:                switch(type){
                    511:                case FLOAT:
                    512:                    if (use68881 || usesky) break;
                    513:                    down1 = D0|MUSTDO;
                    514:                    down2 = D1|MUSTDO;
                    515:                    break;
                    516:                case INT:
                    517:                case UNSIGNED:
                    518:                    if (use68020) break;
                    519:                    down1 = D0|MUSTDO;
                    520:                    down2 = D1|MUSTDO;
                    521:                    break;
                    522:                case DOUBLE:
                    523:                    if (use68881 || usesky) break;
                    524:                    down1 = D0|MUSTDO;
                    525:                    break;
                    526:                default:
                    527:                    if (ISPTR(type)){
                    528:                        /* this is the result of (char *)(a*b) */
                    529:                        /* treat as an unsigned or int         */
                    530:                        if (use68020) break;
                    531:                        down1 = D0|MUSTDO;
                    532:                        down2 = D1|MUSTDO;
                    533:                    }
                    534:                    break;
                    535:                }
                    536:                break;
                    537: 
                    538:        case EQ:
                    539:        case NE:
                    540:        case GT:
                    541:        case GE:
                    542:        case LT:
                    543:        case LE:
                    544:                type = p->in.left->in.type;
                    545:                /* fall through */
                    546:        case PLUS:
                    547:        case MINUS:
                    548:        case ASG PLUS:
                    549:        case ASG MINUS:
                    550:                if (use68881 || usesky) break;
                    551:                switch (type){
                    552:                case FLOAT:
                    553:                    down1 = D0|MUSTDO;
                    554:                    down2 = D1|MUSTDO;
                    555:                    break;
                    556:                case DOUBLE:
                    557:                    down1 = D0|MUSTDO;
                    558:                    break;
                    559:                }
                    560:                break;
                    561: 
                    562:        case NOT:
                    563:        case ANDAND:
                    564:        case OROR:
                    565:                down1 = NOPREF;
                    566:                break;
                    567: 
                    568:        case SCONV: /* float, fix, single, or double */
                    569:                if (use68881 || usesky) break;
                    570:                if (ezsconv(p)) break;
                    571:                down1 = D0|MUSTDO;
                    572:                break;
                    573: 
                    574:        case FORCE:     
                    575:                down1 = D0|MUSTDO;
                    576:                break;
                    577: 
                    578:        case FNINT:     /* float=>int conversion, use biased rounding */
                    579:                if (use68881) break;
                    580:                down1 = D0|MUSTDO;
                    581:                break;
                    582: 
                    583:        default:
                    584:                if ((dope[o]&INTRFLG) && !use68881) {
                    585:                        /* fortran intrinsics */
                    586:                        down1 = D0|MUSTDO;
                    587:                }
                    588:        }
                    589: 
                    590: recur:
                    591:        if( ty == BITYPE ) rallo( p->in.right, down2 );
                    592:        else if( ty == LTYPE )  return;
                    593:        /* else do tail-recursion */
                    594:        p =  p->in.left;
                    595:        down = down1;
                    596:        goto again;
                    597: 
                    598: }
                    599: 
                    600: stoasg( p, o ) register NODE *p; 
                    601: {
                    602:        /* should the assignment op p be stored,
                    603:           given that it lies as the right operand of o
                    604:           (or the left, if o==UNARY MUL) */
                    605: /*
                    606:        if( p->in.op == INCR || p->in.op == DECR ) return;
                    607:        if( o==UNARY MUL && p->in.left->in.op == REG && !isbreg(p->in.left->tn.rval) ) SETSTO(p,INAREG);
                    608:  */
                    609:        return( shltype(p->in.left->in.op, p->in.left ) );
                    610: }
                    611: 
                    612: deltest( p ) register NODE *p; 
                    613: {
                    614:        /* should we delay the INCR or DECR operation p */
                    615: # ifndef MULTILEVEL
                    616:        if( p->in.op == INCR && p->in.left->in.op == REG && spsz( p->in.left->in.type, p->in.right->tn.lval ) ){
                    617:                /* STARREG */
                    618:                return( 0 );
                    619:                }
                    620: # else
                    621:        if( mlmatch(p,DEFINCDEC,INCR) && spsz( p->in.left->in.type, p->in.right->tn.lval ) ){
                    622:                /* STARREG */
                    623:                return( 0 );
                    624:                }
                    625: #endif
                    626:        p = p->in.left;
                    627:        return( p->in.op == REG || p->in.op == NAME || p->in.op == OREG );
                    628: }
                    629: mkadrs(p) register NODE *p; 
                    630: {
                    631:        register o;
                    632: 
                    633:        o = p->in.op;
                    634: 
                    635:        if( asgop(o) ){
                    636:                if( !SUGT( p->in.right->in.su , p->in.left->in.su )){
                    637:                        if( p->in.left->in.op == UNARY MUL ){
                    638:                                if( SUTEST( p->in.left->in.su ) )
                    639:                                        SETSTO( p->in.left->in.left, INTEMP );
                    640:                                else {
                    641:                                        if (SUTEST( p->in.right->in.su ) )
                    642:                                            SETSTO( p->in.right, INTEMP );
                    643:                                        else 
                    644:                                            cerror( "store finds both sides trivial" );
                    645:                                }
                    646:                        }
                    647:                        else if( p->in.left->in.op == FLD 
                    648:                            && p->in.left->in.left->in.op == UNARY MUL ){
                    649:                                SETSTO( p->in.left->in.left->in.left, INTEMP );
                    650:                        } else { 
                    651:                                /* should be only structure assignment */
                    652:                                SETSTO( p->in.left, INTEMP );
                    653:                        }
                    654:                }
                    655:                else SETSTO( p->in.right, INTEMP );
                    656:        } else {
                    657:                if( SUGT( p->in.left->in.su , p->in.right->in.su )){
                    658:                        SETSTO( p->in.left, INTEMP );
                    659:                } else {
                    660:                        SETSTO( p->in.right, INTEMP );
                    661:                }
                    662:        }
                    663: }
                    664: 
                    665: 
                    666: notoff( t, r, off, cp) CONSZ off; char *cp; 
                    667: {
                    668:        /* is it legal to make an OREG or NAME entry which has an
                    669:        /* offset of off, (from a register of r), if the
                    670:        /* resulting thing had type t */
                    671: 
                    672:        /* yes */
                    673:        if (use68020 && isbreg(r))
                    674:                return(0);
                    675:        if ( off>=-32768 && off<=32767
                    676:            && (cp == NULL || *cp=='\0') && r>=A0 && r<=SP )
                    677:                return(0); 
                    678:        return(1); /* NO */
                    679: }
                    680: 
                    681: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
                    682: 
                    683: #define nncon(p)\
                    684:     ((p)->in.op == ICON && ((p)->tn.name == NULL || (p)->tn.name[0] == '\0'))
                    685: 
                    686: /*
                    687:  * Compile an array index expression, exploiting
                    688:  * scaled indexing if possible.  Assume an index
                    689:  * register is known to be available.
                    690:  */
                    691: do_index(p)
                    692:        register NODE *p;
                    693: {
                    694:        register NODE *rp,*lp;
                    695:        int count;
                    696: 
                    697:        switch(p->in.op) {
                    698:        case REG:
                    699:                return;
                    700:        case MUL:
                    701:                /*
                    702:                 * at least one front-end doesn't do this...
                    703:                 */
                    704:                rp = p->in.right;
                    705:                if (nncon(rp)) {
                    706:                        count = -1;
                    707:                        switch(rp->tn.lval) {
                    708:                        case 1:
                    709:                                count = 0;
                    710:                                break;
                    711:                        case 2:
                    712:                                count = 1;
                    713:                                break;
                    714:                        case 4:
                    715:                                count = 2;
                    716:                                break;
                    717:                        case 8:
                    718:                                count = 3;
                    719:                                break;
                    720:                        }
                    721:                        if (count >= 0) {
                    722:                                p->in.op = LS;
                    723:                                rp->tn.lval = count;
                    724:                                /*
                    725:                                 * reset type, because MULS
                    726:                                 * changes shorts to longs, but
                    727:                                 * ASL doesn't!
                    728:                                 */
                    729:                                p->in.type = p->in.left->in.type;
                    730:                                goto leftshift;
                    731:                        }
                    732:                }
                    733:                break;
                    734:        case LS:
                    735:        leftshift:
                    736:                rp = p->in.right;
                    737:                lp = p->in.left;
                    738:                if ( lp->in.op == SCONV && lp->in.type == INT ) {
                    739:                        if ( lp->in.left->in.type == CHAR ) {
                    740:                                /*
                    741:                                 * we only need convert bytes to shorts.
                    742:                                 */
                    743:                                lp->in.type = SHORT;
                    744:                                p->in.type = SHORT;
                    745:                        }
                    746:                        else if ( use68020 && lp->in.left->in.type == SHORT
                    747:                            && lp->in.rall == NOPREF ) {
                    748:                                /*
                    749:                                 * on the 68020, a conversion from short
                    750:                                 * to int below a scale by 2,4, or 8 is
                    751:                                 * subsumed into the addressing modes
                    752:                                 */
                    753:                                p->in.left = lp->in.left;
                    754:                                lp->in.op = FREE;
                    755:                                lp = p->in.left;
                    756:                                p->in.type = lp->in.type;
                    757:                        }
                    758:                } /* lp->in.op == SCONV */
                    759:                if (use68020 && nncon(rp) && rp->tn.lval >= 0
                    760:                        && rp->tn.lval <= 3){
                    761:                        /*
                    762:                         * on the 68020, scaling by 2, 4, or 8 is also free
                    763:                         */
                    764:                        if (lp->in.op != REG || p->in.rall != NOPREF) {
                    765:                                lp->in.rall = p->in.rall;
                    766:                                order(lp,INTAREG|INAREG|INTBREG|INBREG);
                    767:                        }
                    768:                        return;
                    769:                }
                    770:                break;
                    771:        case SCONV:
                    772:                if (p->in.type == INT) {
                    773:                        lp = p->in.left;
                    774:                        if (lp->in.type == CHAR) {
                    775:                                /*
                    776:                                 * we only need convert bytes to shorts.
                    777:                                 */
                    778:                                p->in.type = SHORT;
                    779:                        } /* char */
                    780:                        else if (lp->in.type == SHORT && p->in.rall == NOPREF) {
                    781:                                /*
                    782:                                 * conversions from short to int
                    783:                                 * are done by the addressing modes
                    784:                                 */
                    785:                                *p = *lp;
                    786:                                lp->in.op = FREE;
                    787:                        } /* short */
                    788:                } /* type == INT */
                    789:                break;
                    790:        } /* switch */
                    791:        order(p, INTAREG|INAREG|INTBREG|INBREG);
                    792: } /* do_index */
                    793: 
                    794: /*
                    795:  * is this expression a register or a
                    796:  * sign-extending conversion of one?
                    797:  */
                    798: static int
                    799: regsconv(p)
                    800:        NODE *p;
                    801: {
                    802:        NODE *lp;
                    803: 
                    804:        if (p->in.op == REG)
                    805:                return(1);
                    806:        if (p->in.op == SCONV && p->in.type == INT) {
                    807:                lp = p->in.left;
                    808:                if ( (lp->in.type == SHORT || lp->in.type == CHAR)
                    809:                        && lp->in.op == REG )
                    810:                        return(1);
                    811:        }
                    812:        return(0);
                    813: }
                    814: 
                    815: /*
                    816:  * is this already a legal index?
                    817:  */
                    818: int
                    819: isindex(p)
                    820:        register NODE *p;
                    821: {
                    822:        register rval;
                    823:        NODE *rp;
                    824: 
                    825:        if (use68020) {
                    826:                if (p->in.op == MUL) {
                    827:                        rp = p->in.right;
                    828:                        if (nncon(rp)) {
                    829:                                switch(rp->tn.lval) {
                    830:                                case 1:
                    831:                                case 2:
                    832:                                case 4:
                    833:                                case 8:
                    834:                                        return(regsconv(p->in.left));
                    835:                                } /* switch */
                    836:                        } /* nncon */
                    837:                        return(0);
                    838:                } /* MUL */
                    839:                if (p->in.op == LS) {
                    840:                        rp = p->in.right;
                    841:                        if (nncon(rp)
                    842:                            && (rp->tn.lval >= 0 && rp->tn.lval <= 3))
                    843:                                return(regsconv(p->in.left));
                    844:                        return(0);
                    845:                } /* LS */
                    846:        } /* use68020 */
                    847:        return(regsconv(p));
                    848: }
                    849: 
                    850: /*
                    851:  * is p a signed byte constant ? This really asks whether p is
                    852:  * permissible in a (base+disp+index) expression.  On the 68020,
                    853:  * anything is permissible, including relocatables.
                    854:  */
                    855: 
                    856: static int
                    857: isbcon(p, t)
                    858:        register NODE *p;
                    859:        TWORD t;
                    860: {
                    861:        int maxoff;
                    862:        if (p == NIL)
                    863:                return 0;
                    864:        if (p->in.op == ICON) {
                    865:                if (use68020)
                    866:                        return(1);
                    867:                maxoff = ((BTYPE(t) == DOUBLE) ? 123 : 127);
                    868:                if (nncon(p) && p->tn.lval <= maxoff && p->tn.lval >= -maxoff)
                    869:                        return(1);
                    870:        }
                    871:        return(0);
                    872: }
                    873: 
                    874: /*
                    875:  * Is p a signed short constant ? This really asks whether p
                    876:  * is permissible in a (base+disp) expression.  On the 68020,
                    877:  * anything is permissible, including relocatables.
                    878:  */
                    879: 
                    880: static int
                    881: isscon(p, t)
                    882:        register NODE *p;
                    883:        TWORD t;
                    884: {
                    885:        int maxoff;
                    886:        if (p == NIL)
                    887:                return 0;
                    888:        if (p->in.op == ICON) {
                    889:                if (use68020)
                    890:                        return(1);
                    891:                maxoff = ((BTYPE(t) == DOUBLE) ? 32763 : 32767);
                    892:                if (nncon(p) && p->tn.lval <= maxoff && p->tn.lval >= -maxoff)
                    893:                        return(1);
                    894:        }
                    895:        return(0);
                    896: }
                    897: 
                    898: #define isbregnode(p) ((p)->in.op == REG && isbreg((p)->tn.rval))
                    899: 
                    900: /*
                    901:  * Is a register available for indexing? This depends
                    902:  * on context larger than the immediate expression,
                    903:  * represented by the 'failsafe' flag. (cf., order.c)
                    904:  * Note that we should not ask this unless it we are
                    905:  * fairly sure we WANT to use double indexing.
                    906:  */
                    907: static int
                    908: can_index(p, base, index)
                    909:        NODE *p, *base, *index;
                    910: {
                    911:        if (isindex(index))     /* already got one */
                    912:                return(1);
                    913:        failsafe |= ((p->in.rall == D0) || (p->in.rall == D1));
                    914:        if (failsafe) {
                    915:                /*
                    916:                 * We need d0, d1, or both for something; don't tie
                    917:                 * either one up.
                    918:                 */
                    919:                if (!isbregnode(base) || istreg(base->tn.rval)) {
                    920:                        /*
                    921:                         * need a scratch register for the base, too.
                    922:                         */
                    923:                        return(0);      /* forget it! */
                    924:                }
                    925:                if(!rewrite_rall(index,1)) {
                    926:                        return(0);
                    927:                }
                    928:        }
                    929:        return(1);
                    930: }
                    931: 
                    932: /*
                    933:  * Compile memory reference expressions, attempting to make the best
                    934:  * use of the target machine's addressing modes.  The overall plan
                    935:  * is to put the expression into a canonical form, then select and
                    936:  * compile a suitable subtree based on availability of registers,
                    937:  * offset limitations, and support from the architecture.  A goal
                    938:  * is not to evaluate any more of the tree than is necessary.
                    939:  *
                    940:  * On entry, we assume we have been given the left branch of a UNARY MUL,
                    941:  * not the UNARY MUL itself.
                    942:  *
                    943:  * When done, we must guarantee that the resulting tree can be turned
                    944:  * into an OREG.
                    945:  */
                    946: 
                    947: offstar( p )
                    948:        register NODE *p; 
                    949: {
                    950:        register NODE *lp, *rp;
                    951: 
                    952:        if ( (p->in.rall&MUSTDO)
                    953:            || (p->in.op != PLUS && p->in.op != MINUS ) ) {
                    954:                /* No chance to index */
                    955:                if ( p->in.op != REG || !isbreg(p->tn.rval) ) {
                    956:                        failsafe = 0;
                    957:                        order(p, INTBREG|INBREG);
                    958:                }
                    959:                return;
                    960:        }
                    961:        /*
                    962:         * exp is (<exp> [+-] <exp>)
                    963:         */
                    964:        lp = p->in.left;
                    965:        rp = p->in.right;
                    966:        if (!ISPTR(lp->in.type)) {
                    967:                /*
                    968:                 * put the pointer on the left
                    969:                 */
                    970:                p->in.right = lp;
                    971:                p->in.left = rp;
                    972:                lp = p->in.left;
                    973:                rp = p->in.right;
                    974:        }
                    975:        /*
                    976:         * u-page hack, for the kernel boys: for example,
                    977:         * (*((struct u *) 0x4000)).u_dent.d_name[i++] = *cp;
                    978:         */
                    979:        if (nncon(lp) && isscon(lp) && tlen(rp) == (SZINT/SZCHAR)) {
                    980:                /*
                    981:                 * swap base part and index part,
                    982:                 * then diddle the types
                    983:                 */
                    984:                TWORD temp;
                    985:                p->in.right = lp;
                    986:                p->in.left = rp;
                    987:                lp = p->in.left;
                    988:                rp = p->in.right;
                    989:                temp = lp->in.type;
                    990:                lp->in.type = rp->in.type;
                    991:                rp->in.type = temp;
                    992:        }
                    993:        /*
                    994:         * map (<exp> - <icon>) to (<exp> + <-icon>)
                    995:         */
                    996:        if (p->in.op == MINUS && nncon(rp)) {
                    997:                p->in.op = PLUS;
                    998:                rp->tn.lval = -(rp->tn.lval);
                    999:        }
                   1000:        /*
                   1001:         * map ( (<exp> - <icon> ) [+-] <exp> )
                   1002:         * to  ( (<exp> + <-icon>) [+-] <exp> )
                   1003:         */
                   1004:        if (lp->in.op == MINUS && nncon(lp->in.right)) {
                   1005:                lp->in.op = PLUS;
                   1006:                lp->in.right->tn.lval = -(lp->in.right->tn.lval);
                   1007:        }
                   1008:        /*
                   1009:         * At this point, any subtractions must be done explicitly.
                   1010:         */
                   1011:        if ( p->in.op == MINUS ) {
                   1012:                failsafe = 0;
                   1013:                order(p, INTBREG|INBREG);
                   1014:                return;
                   1015:        }
                   1016:        if ( lp->in.op == PLUS ) {
                   1017: 
                   1018:                /*
                   1019:                 * map (<index> + <base>) + <exp>
                   1020:                 * to  (<base> + <index>) + <exp>
                   1021:                 */
                   1022:                if ( !ISPTR(lp->in.left->in.type) ) {
                   1023:                        NODE *q = lp->in.left;
                   1024:                        lp->in.left = lp->in.right;
                   1025:                        lp->in.right = q;
                   1026:                }
                   1027: 
                   1028:                /*
                   1029:                 * map (<base> + <index>) + <bcon>
                   1030:                 * to  (<base> + <bcon>) + <index>
                   1031:                 */
                   1032:                if ( isbcon(rp) && !isbcon(lp->in.right) ) {
                   1033:                        NODE *q = lp->in.right;
                   1034:                        lp->in.right = rp;
                   1035:                        rp = p->in.right = q;
                   1036:                }
                   1037: 
                   1038:                /*
                   1039:                 * Now we evaluate the expression, or enough of it so
                   1040:                 * that the remainder can be handled by an addressing mode.
                   1041:                 */
                   1042:                if (isbcon(lp->in.right, p->in.type)) {
                   1043:                        /*
                   1044:                         * pattern is ( <base exp> + <bcon> ) + <index>
                   1045:                         * where <bcon> is in [-127..127] for the 68010,
                   1046:                         * or any integral constant on the 68020.
                   1047:                         */
                   1048:                        NODE *llp = lp->in.left;
                   1049:                        if (SUTEST(llp->in.su) && SUTEST(rp->in.su)) {
                   1050:                                /*
                   1051:                                 * don't bother;
                   1052:                                 * both <base> and <index> are messy.
                   1053:                                 */
                   1054:                                goto punt;
                   1055:                        }
                   1056:                        if (SUGT(rp->in.su, llp->in.su)){
                   1057:                                /*
                   1058:                                 * Index is more expensive than base.
                   1059:                                 * Do it first, unless you have to bend
                   1060:                                 * over backwards to do it.
                   1061:                                 */
                   1062:                                if (can_index(p,llp,rp)) {
                   1063:                                        do_index(rp);   /* breg@(disp,index) */
                   1064:                                        if (!isbregnode(llp)) {
                   1065:                                                order(llp, INTBREG|INBREG);
                   1066:                                        }
                   1067:                                        return;
                   1068:                                }
                   1069:                                goto punt;
                   1070:                        }
                   1071:                        /*
                   1072:                         * try for index
                   1073:                         */
                   1074:                        if (can_index(p,llp,rp)) {
                   1075:                                /*
                   1076:                                 * evaluate base into a <breg>
                   1077:                                 */
                   1078:                                if (!isbregnode(llp)) {
                   1079:                                        order(llp, INTBREG|INBREG);
                   1080:                                }
                   1081:                                /*
                   1082:                                 * evaluate <index> into a register
                   1083:                                 */
                   1084:                                do_index(rp);   /* breg@(disp, index) */
                   1085:                                return;
                   1086:                        }
                   1087:                        /*
                   1088:                         * can't index; instead,
                   1089:                         * rewrite as ( <base>+<index> ) + <bcon>
                   1090:                         */
                   1091:                punt:   llp = lp->in.right;
                   1092:                        lp->in.right = rp;
                   1093:                        p->in.right = llp;
                   1094:                        failsafe = 0;
                   1095:                        order(lp, INTBREG|INBREG);  /* breg@(disp) */
                   1096:                        return;
                   1097:                } /* (<base> + <bcon>) + <index> */
                   1098:        } /* lp == PLUS */
                   1099: 
                   1100:        /*
                   1101:         * At this point, the expression is of the form
                   1102:         *      <base part> + <index part>
                   1103:         */
                   1104:        if (SUTEST(lp->in.su) && SUTEST(rp->in.su)) {
                   1105:                /*
                   1106:                 * both <base> and <index> are messy.
                   1107:                 */
                   1108:                failsafe = 0;
                   1109:                order(p, INTBREG|INBREG);       /* breg@ */
                   1110:                return;
                   1111:        }
                   1112:        if ( SUGT(rp->in.su, lp->in.su) ) {
                   1113:                /*
                   1114:                 * index is more expensive than base.
                   1115:                 * Do it first, unless you have to bend
                   1116:                 * over backwards to do it.
                   1117:                 */
                   1118:                if (can_index(p,lp,rp)) {
                   1119:                        do_index(rp);
                   1120:                        if (!isbregnode(lp)){
                   1121:                                order(lp, INTBREG|INBREG);
                   1122:                        }
                   1123:                        return;            /* base@(index)*/
                   1124:                }
                   1125:                failsafe = 0;
                   1126:                order(p, INTBREG|INBREG);       /* base@ */
                   1127:                return;
                   1128:        }
                   1129:        /*
                   1130:         * try to make a breg@(disp) operand
                   1131:         */
                   1132:        if ( isscon(rp) ) {
                   1133:                failsafe = 0;
                   1134:                if (!isbregnode(lp)) {
                   1135:                        order(lp, INTBREG|INBREG);
                   1136:                }
                   1137:                return;                         /* breg@(disp) */
                   1138:        }
                   1139:        /*
                   1140:         * Do base first.
                   1141:         */
                   1142:        if ( !isbregnode(lp) ) {
                   1143:                order(lp, INTBREG|INBREG);
                   1144:        }
                   1145:        if ( istnode(lp) && tshape(rp, SCON|SNAME|SOREG|STARNM) ) {
                   1146:                /*
                   1147:                 * pattern is <temp reg> + <mem operand>
                   1148:                 * indexing doesn't buy us anything.
                   1149:                 */
                   1150:                failsafe = 0;
                   1151:                order(p, INTBREG|INBREG);       /* base@ */
                   1152:                return;
                   1153:        }
                   1154:        if ( can_index(p,lp,rp) ) {
                   1155:                do_index(rp);                   /* base@(index) */
                   1156:                return;
                   1157:        }
                   1158:        /*
                   1159:         * "Either this man is dead, or my watch has stopped."
                   1160:         */
                   1161:        failsafe = 0;
                   1162:        order(p, INTBREG|INBREG);       /* base@ */
                   1163: }
                   1164: 
                   1165: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
                   1166: 
                   1167: int crslab = 2000000;  /* 68k */
                   1168: 
                   1169: getlab()
                   1170: {
                   1171:        return( crslab++ );
                   1172: }
                   1173: 
                   1174: deflab( l )
                   1175: {
                   1176:        print_label(l);
                   1177: }
                   1178: 
                   1179: #define mkmask(reg,mask) (busy[reg] ? ((mask) | (1<<(reg))) : (mask))
                   1180: 
                   1181: genargs( p ) register NODE *p; 
                   1182: {
                   1183:        register NODE *pasg;
                   1184:        register inc;
                   1185:        register align;
                   1186:        register size;
                   1187:        register TWORD type;
                   1188:        int padflag;
                   1189: 
                   1190:        /* generate code for the arguments */
                   1191: 
                   1192:        /*  first, do the arguments on the right */
                   1193:        while( p->in.op == CM ){
                   1194:                genargs( p->in.right );
                   1195:                p->in.op = FREE;
                   1196:                p = p->in.left;
                   1197:        }
                   1198: 
                   1199:        if( p->in.op == STARG ){ /* structure valued argument */
                   1200:                /*
                   1201:                 * We are stacking arguments in anticipation of a 
                   1202:                 * call.
                   1203:                 * The strategy will be to push words on the
                   1204:                 * stack (being careful of alignment problems)
                   1205:                 * in open code. A dbra loop is too hard here.
                   1206:                 */
                   1207:                size = p->stn.stsize;
                   1208:                if( p->in.left->in.op == ICON ){
                   1209:                        p->in.op = FREE;
                   1210:                        p= p->in.left;
                   1211:                        p->in.op = NAME;
                   1212:                }
                   1213:                else {
                   1214:                        /* make it look beautiful... */
                   1215:                        p->in.op = UNARY MUL;
                   1216:                        canon( p );  /* turn it into an oreg */
                   1217:                        if( p->in.op != OREG ){
                   1218:                                offstar( p->in.left );
                   1219:                                canon( p );
                   1220:                                if( p->in.op != OREG ){
                   1221:                                        offstar( p->in.left );
                   1222:                                        canon( p );
                   1223:                                        if( p->in.op != OREG ) cerror( "stuck starg" );
                   1224:                                }
                   1225:                        }
                   1226:                }
                   1227: 
                   1228:                if (size > 16) {
                   1229:                        /*
                   1230:                         * big structure argument.  In its infinite wisdom,
                   1231:                         * Pascal passes array value parameters like this.
                   1232:                         * Twenty-two on the vomit meter.
                   1233:                         */
                   1234:                        int count;
                   1235:                        int residue;
                   1236:                        short regmask;
                   1237:                        int savetemp;
                   1238: 
                   1239:                        if (size&1) size++; /* assumes ALSTACK = 16 */
                   1240:                        toff += size;
                   1241:                        if (toff > maxtoff) maxtoff = toff;
                   1242:                        count = size / sizeof(long);
                   1243:                        residue = size % sizeof(long);
                   1244:                        /*
                   1245:                         * a0 = &(actual argument);
                   1246:                         */
                   1247:                        if (p->in.op == OREG && !R2TEST(p->tn.rval)
                   1248:                            && (p->tn.name == NULL || p->tn.name[0] == '\0')
                   1249:                            && p->tn.lval == 0) {
                   1250:                                p->in.op = REG;
                   1251:                        }
                   1252:                        if (p->in.op == REG) {
                   1253:                            if (p->tn.rval != A0)
                   1254:                                expand(p, RNOP, "       movl    AR,a0\n");
                   1255:                        } else {
                   1256:                                expand(p, RNOP, "       lea     AR,a0\n");
                   1257:                        }
                   1258:                        /*
                   1259:                         * allocate and copy to top of stack
                   1260:                         */
                   1261:                        if (size > 0x7fff) {
                   1262:                                printf("        subl    #%d,sp\n", size);
                   1263:                        } else {
                   1264:                                printf("        lea     sp@(-%d),sp\n", size);
                   1265:                        }
                   1266:                        print_str("     movl    sp,a1\n");
                   1267:                        if (count > 0x7fff) {
                   1268:                                printf("        movl    #%d,d0\n", count-1);
                   1269:                                print_str("1:   movl    a0@+,a1@+\n");
                   1270:                                print_str("     dbra    d0,1b\n");
                   1271:                                print_str("     clrw    d0\n");
                   1272:                                print_str("     subql   #1,d0\n");
                   1273:                                print_str("     jcc     1b\n");
                   1274:                        } else {
                   1275:                                printf("        movw    #%d,d0\n", count-1);
                   1276:                                print_str("1:   movl    a0@+,a1@+\n");
                   1277:                                print_str("     dbra    d0,1b\n");
                   1278:                        }
                   1279:                        switch(residue) {
                   1280:                        case 1:
                   1281:                                print_str("     movb    a0@+,a1@+\n");
                   1282:                                break;
                   1283:                        case 2:
                   1284:                                print_str("     movw    a0@+,a1@+\n");
                   1285:                                break;
                   1286:                        case 3:
                   1287:                                print_str("     movw    a0@+,a1@+\n");
                   1288:                                print_str("     movb    a0@+,a1@+\n");
                   1289:                                break;
                   1290:                        default:
                   1291:                                break;
                   1292:                        }
                   1293:                        reclaim(p,RNULL,0);
                   1294:                        return;
                   1295:                } /* big structure */
                   1296: 
                   1297:                p->tn.lval += size;
                   1298:                /*
                   1299:                 * arguments must be at least sizeof(int) big around here.
                   1300:                 * force size up to it.
                   1301:                 */
                   1302:                padflag = (size <= 2 ) ;
                   1303: #ifdef FORT
                   1304:                /* PASCAL ONLY */
                   1305:                if (size & 1){
                   1306:                        /*
                   1307:                         * size is odd: last byte is peculiar.
                   1308:                         * movb to stack is magic.
                   1309:                         */
                   1310:                        size -= 1;
                   1311:                        p->tn.lval -=1;
                   1312:                        expand( p, RNOP,"\tmovb\tAR,sp@-\n" );
                   1313:                        toff += 2;
                   1314:                        if (toff > maxtoff) maxtoff = toff;
                   1315:                }
                   1316: #endif FORT
                   1317:                toff += size;
                   1318:                if (toff > maxtoff) maxtoff = toff;
                   1319:                for( ; size>0; size -= inc ){
                   1320:                        inc = (size>2) ? 4 : 2;
                   1321:                        p->tn.lval -= inc;
                   1322:                        expand( p, RNOP,(inc==4)?"\tmovl\tAR,sp@-\n":"\tmovw\tAR,sp@-\n" );
                   1323:                }
                   1324:                if (padflag){
                   1325:                    print_str(" subql   #2,sp\n");
                   1326:                    toff += 2;
                   1327:                    if (toff > maxtoff) maxtoff = toff;
                   1328:                }
                   1329:                reclaim(p,RNULL,0);
                   1330:                return;
                   1331:        }
                   1332: 
                   1333:        /* ordinary case */
                   1334:        order( p, FORARG );
                   1335: }
                   1336: 
                   1337: argsize( p ) register NODE *p; 
                   1338: {
                   1339:        register t, s;
                   1340:        t = 0;
                   1341:        if( p->in.op == CM ){
                   1342:                t = argsize( p->in.left );
                   1343:                p = p->in.right;
                   1344:        }
                   1345:        switch (p->in.type){
                   1346:        case FLOAT:
                   1347: #ifdef FLOATMATH
                   1348:                if (FLOATMATH>1){
                   1349:                    SETOFF( t, ALFLOAT/SZCHAR );
                   1350:                    return( t+(SZFLOAT/SZCHAR) );
                   1351:                }
                   1352: #endif FLOATMATH
                   1353:                /* else fall through */
                   1354:        case DOUBLE:
                   1355:                SETOFF( t, ALDOUBLE/SZCHAR );
                   1356:                return( t+(SZDOUBLE/SZCHAR) );
                   1357:        }
                   1358:        if( p->in.op == STARG ){
                   1359:                SETOFF( t, ALSTRUCT/SZCHAR );  /* alignment */
                   1360:                s = p->stn.stsize;            /* size */
                   1361:                s += (s & 1); /* PASCAL ONLY */
                   1362:                if (s < SZINT/SZCHAR)
                   1363:                    s = SZINT/SZCHAR;
                   1364:                return( s+t );
                   1365:        } else {
                   1366:                SETOFF( t, ALSTACK/SZCHAR );
                   1367:                return( t+(SZINT/SZCHAR) );
                   1368:        }
                   1369: }

unix.superglobalmegacorp.com

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