Annotation of researchv10no/cmd/f77/old/putpcc.c, revision 1.1

1.1     ! root        1: /* INTERMEDIATE CODE GENERATION FOR S. C. JOHNSON C COMPILERS */
        !             2: /* NEW VERSION USING BINARY POLISH POSTFIX INTERMEDIATE */
        !             3: #if FAMILY != PCC
        !             4: WRONG put FILE !!!!
        !             5: #endif
        !             6: 
        !             7: #include "defs"
        !             8: #include "pccdefs"
        !             9: Addrp realpart();
        !            10: LOCAL Addrp intdouble(), putcall(), putch1(), putcx1(), putcxeq();
        !            11: LOCAL putaddr(), putcat(), putchcmp(), putcheq(), putchop(),
        !            12: putcomma(), putct1(), putcxcmp(), putcxop(), putmem(),
        !            13: putmnmx(), putop(), putpower();
        !            14: expptr imagpart();
        !            15: ftnint lencat();
        !            16: 
        !            17: #define FOUR 4
        !            18: extern int ops2[];
        !            19: extern int types2[];
        !            20: 
        !            21: #define P2BUFFMAX 128
        !            22: static long int p2buff[P2BUFFMAX];
        !            23: static long int *p2bufp                = &p2buff[0];
        !            24: static long int *p2bufend      = &p2buff[P2BUFFMAX];
        !            25: 
        !            26: puthead(s, class)
        !            27: char *s;
        !            28: int class;
        !            29: {
        !            30: #if TARGET == VAX
        !            31:        if(s)
        !            32:                p2ps("\t.globl\t_%s", s);
        !            33: #endif
        !            34:        /* put out fake copy of left bracket line, to be redone later */
        !            35:        if( ! headerdone )
        !            36:        {
        !            37: #if FAMILY == PCC
        !            38:                p2flush();
        !            39: #endif
        !            40:                headoffset = ftell(textfile);
        !            41:                prhead(textfile);
        !            42:                headerdone = YES;
        !            43:                p2triple(P2STMT, (strlen(infname)+FOUR-1)/FOUR, 0);
        !            44:                p2str(infname);
        !            45: #if TARGET == PDP11
        !            46:                /* fake jump to start the optimizer */
        !            47:                if(class != CLBLOCK)
        !            48:                        putgoto( fudgelabel = newlabel() );
        !            49: #endif
        !            50: 
        !            51: #if TARGET == VAX
        !            52:                /* jump from top to bottom */
        !            53:                if(s!=CNULL && class!=CLBLOCK)
        !            54:                {
        !            55:                        int proflab = newlabel();
        !            56:                        p2ps("_%s:", s);
        !            57:                        p2pi("\t.word\tLWM%d", procno);
        !            58:                        prsave(proflab);
        !            59:                        p2pi("\tjmp\tL%d", fudgelabel = newlabel());
        !            60:                }
        !            61: #endif
        !            62:        }
        !            63: }
        !            64: 
        !            65: 
        !            66: 
        !            67: 
        !            68: 
        !            69: /* It is necessary to precede each procedure with a "left bracket"
        !            70:  * line that tells pass 2 how many register variables and how
        !            71:  * much automatic space is required for the function.  This compiler
        !            72:  * does not know how much automatic space is needed until the
        !            73:  * entire procedure has been processed.  Therefore, "puthead"
        !            74:  * is called at the begining to record the current location in textfile,
        !            75:  * then to put out a placeholder left bracket line.  This procedure
        !            76:  * repositions the file and rewrites that line, then puts the
        !            77:  * file pointer back to the end of the file.
        !            78:  */
        !            79: 
        !            80: putbracket()
        !            81: {
        !            82:        long int hereoffset;
        !            83: 
        !            84: #if FAMILY == PCC
        !            85:        p2flush();
        !            86: #endif
        !            87:        hereoffset = ftell(textfile);
        !            88:        if(fseek(textfile, headoffset, 0))
        !            89:                fatal("fseek failed");
        !            90:        prhead(textfile);
        !            91:        if(fseek(textfile, hereoffset, 0))
        !            92:                fatal("fseek failed 2");
        !            93: }
        !            94: 
        !            95: 
        !            96: 
        !            97: 
        !            98: putrbrack(k)
        !            99: int k;
        !           100: {
        !           101:        p2op(P2RBRACKET, k);
        !           102: }
        !           103: 
        !           104: 
        !           105: 
        !           106: putnreg()
        !           107: {
        !           108: }
        !           109: 
        !           110: 
        !           111: 
        !           112: 
        !           113: 
        !           114: 
        !           115: puteof()
        !           116: {
        !           117:        p2op(P2EOF, 0);
        !           118:        p2flush();
        !           119: }
        !           120: 
        !           121: 
        !           122: 
        !           123: putstmt()
        !           124: {
        !           125:        p2triple(P2STMT, 0, lineno);
        !           126: }
        !           127: 
        !           128: 
        !           129: 
        !           130: 
        !           131: /* put out code for if( ! p) goto l  */
        !           132: putif(p,l)
        !           133: register expptr p;
        !           134: int l;
        !           135: {
        !           136:        register int k;
        !           137: 
        !           138:        if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL)
        !           139:        {
        !           140:                if(k != TYERROR)
        !           141:                        err("non-logical expression in IF statement");
        !           142:                frexpr(p);
        !           143:        }
        !           144:        else
        !           145:        {
        !           146:                putex1(p);
        !           147:                p2icon( (long int) l , P2INT);
        !           148:                p2op(P2CBRANCH, 0);
        !           149:                putstmt();
        !           150:        }
        !           151: }
        !           152: 
        !           153: 
        !           154: 
        !           155: 
        !           156: 
        !           157: /* put out code for  goto l   */
        !           158: putgoto(label)
        !           159: int label;
        !           160: {
        !           161:        p2triple(P2GOTO, 1, label);
        !           162:        putstmt();
        !           163: }
        !           164: 
        !           165: 
        !           166: /* branch to address constant or integer variable */
        !           167: putbranch(p)
        !           168: register Addrp p;
        !           169: {
        !           170:        putex1(p);
        !           171:        p2op(P2GOTO, P2INT);
        !           172:        putstmt();
        !           173: }
        !           174: 
        !           175: 
        !           176: 
        !           177: /* put out label  l:     */
        !           178: putlabel(label)
        !           179: int label;
        !           180: {
        !           181:        p2op(P2LABEL, label);
        !           182: }
        !           183: 
        !           184: 
        !           185: 
        !           186: 
        !           187: putexpr(p)
        !           188: expptr p;
        !           189: {
        !           190:        putex1(p);
        !           191:        putstmt();
        !           192: }
        !           193: 
        !           194: 
        !           195: 
        !           196: 
        !           197: putcmgo(index, nlab, labs)
        !           198: expptr index;
        !           199: int nlab;
        !           200: struct Labelblock *labs[];
        !           201: {
        !           202:        if(! ISINT(index->headblock.vtype) )
        !           203:        {
        !           204:                execerr("computed goto index must be integer", CNULL);
        !           205:                return;
        !           206:        }
        !           207: 
        !           208: #if TARGET == VAX
        !           209:        /* use special case instruction */
        !           210:        vaxgoto(index, nlab, labs);
        !           211: #else
        !           212:        {
        !           213:        int i, labarray, skiplabel;
        !           214: 
        !           215:        labarray = newlabel();
        !           216:        preven(ALIADDR);
        !           217:        prlabel(asmfile, labarray);
        !           218:        prcona(asmfile, (ftnint) (skiplabel = newlabel()) );
        !           219:        for(i = 0 ; i < nlab ; ++i)
        !           220:                if( labs[i] )
        !           221:                        prcona(asmfile, (ftnint)(labs[i]->labelno) );
        !           222:        prcmgoto(index, nlab, skiplabel, labarray);
        !           223:        putlabel(skiplabel);
        !           224:        }
        !           225: #endif
        !           226: }
        !           227: 
        !           228: putx(p)
        !           229: expptr p;
        !           230: {
        !           231:        char *memname();
        !           232:        int opc;
        !           233:        int ncomma;
        !           234:        int type, k;
        !           235: 
        !           236:        switch(p->tag)
        !           237:        {
        !           238:        case TERROR:
        !           239:                free( (charptr) p );
        !           240:                break;
        !           241: 
        !           242:        case TCONST:
        !           243:                switch(type = p->constblock.vtype)
        !           244:                {
        !           245:                case TYLOGICAL:
        !           246:                        type = tyint;
        !           247:                case TYLONG:
        !           248:                case TYSHORT:
        !           249:                        p2icon(p->constblock.Const.ci, types2[type]);
        !           250:                        free( (charptr) p );
        !           251:                        break;
        !           252: 
        !           253:                case TYADDR:
        !           254:                        p2triple(P2ICON, 1, P2INT|P2PTR);
        !           255:                        p2word(0L);
        !           256:                        p2name(memname(STGCONST,
        !           257:                            (int) p->constblock.Const.ci) );
        !           258:                        free( (charptr) p );
        !           259:                        break;
        !           260: 
        !           261:                default:
        !           262:                        putx( putconst(p) );
        !           263:                        break;
        !           264:                }
        !           265:                break;
        !           266: 
        !           267:        case TEXPR:
        !           268:                switch(opc = p->exprblock.opcode)
        !           269:                {
        !           270:                case OPCALL:
        !           271:                case OPCCALL:
        !           272:                        if( ISCOMPLEX(p->exprblock.vtype) )
        !           273:                                putcxop(p);
        !           274:                        else    putcall(p);
        !           275:                        break;
        !           276: 
        !           277:                case OPMIN:
        !           278:                case OPMAX:
        !           279:                        putmnmx(p);
        !           280:                        break;
        !           281: 
        !           282: 
        !           283:                case OPASSIGN:
        !           284:                        if(ISCOMPLEX(p->exprblock.leftp->headblock.vtype)
        !           285:                            || ISCOMPLEX(p->exprblock.rightp->headblock.vtype) )
        !           286:                                frexpr( putcxeq(p) );
        !           287:                        else if( ISCHAR(p) )
        !           288:                                putcheq(p);
        !           289:                        else
        !           290:                                goto putopp;
        !           291:                        break;
        !           292: 
        !           293:                case OPEQ:
        !           294:                case OPNE:
        !           295:                        if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) ||
        !           296:                            ISCOMPLEX(p->exprblock.rightp->headblock.vtype) )
        !           297:                        {
        !           298:                                putcxcmp(p);
        !           299:                                break;
        !           300:                        }
        !           301:                case OPLT:
        !           302:                case OPLE:
        !           303:                case OPGT:
        !           304:                case OPGE:
        !           305:                        if(ISCHAR(p->exprblock.leftp))
        !           306:                        {
        !           307:                                putchcmp(p);
        !           308:                                break;
        !           309:                        }
        !           310:                        goto putopp;
        !           311: 
        !           312:                case OPPOWER:
        !           313:                        putpower(p);
        !           314:                        break;
        !           315: 
        !           316:                case OPSTAR:
        !           317: #if FAMILY == PCC
        !           318:                        /*   m * (2**k) -> m<<k   */
        !           319:                        if(INT(p->exprblock.leftp->headblock.vtype) &&
        !           320:                            ISICON(p->exprblock.rightp) &&
        !           321:                            ( (k = log2(p->exprblock.rightp->constblock.Const.ci))>0) )
        !           322:                        {
        !           323:                                p->exprblock.opcode = OPLSHIFT;
        !           324:                                frexpr(p->exprblock.rightp);
        !           325:                                p->exprblock.rightp = ICON(k);
        !           326:                                goto putopp;
        !           327:                        }
        !           328: #endif
        !           329: 
        !           330:                case OPMOD:
        !           331:                        goto putopp;
        !           332:                case OPPLUS:
        !           333:                case OPMINUS:
        !           334:                case OPSLASH:
        !           335:                case OPNEG:
        !           336:                        if( ISCOMPLEX(p->exprblock.vtype) )
        !           337:                                putcxop(p);
        !           338:                        else    goto putopp;
        !           339:                        break;
        !           340: 
        !           341:                case OPCONV:
        !           342:                        if( ISCOMPLEX(p->exprblock.vtype) )
        !           343:                                putcxop(p);
        !           344:                        else if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) )
        !           345:                        {
        !           346:                                ncomma = 0;
        !           347:                                putx( mkconv(p->exprblock.vtype,
        !           348:                                    realpart(putcx1(p->exprblock.leftp,
        !           349:                                    &ncomma))));
        !           350:                                putcomma(ncomma, p->exprblock.vtype, NO);
        !           351:                                free( (charptr) p );
        !           352:                        }
        !           353:                        else    goto putopp;
        !           354:                        break;
        !           355: 
        !           356:                case OPNOT:
        !           357:                case OPOR:
        !           358:                case OPAND:
        !           359:                case OPEQV:
        !           360:                case OPNEQV:
        !           361:                case OPADDR:
        !           362:                case OPPLUSEQ:
        !           363:                case OPSTAREQ:
        !           364:                case OPCOMMA:
        !           365:                case OPQUEST:
        !           366:                case OPCOLON:
        !           367:                case OPBITOR:
        !           368:                case OPBITAND:
        !           369:                case OPBITXOR:
        !           370:                case OPBITNOT:
        !           371:                case OPLSHIFT:
        !           372:                case OPRSHIFT:
        !           373: putopp:
        !           374:                        putop(p);
        !           375:                        break;
        !           376: 
        !           377:                default:
        !           378:                        badop("putx", opc);
        !           379:                }
        !           380:                break;
        !           381: 
        !           382:        case TADDR:
        !           383:                putaddr(p, YES);
        !           384:                break;
        !           385: 
        !           386:        default:
        !           387:                badtag("putx", p->tag);
        !           388:        }
        !           389: }
        !           390: 
        !           391: 
        !           392: 
        !           393: LOCAL putop(p)
        !           394: expptr p;
        !           395: {
        !           396:        int k;
        !           397:        expptr lp, tp;
        !           398:        int pt, lt;
        !           399:        int comma;
        !           400: 
        !           401:        switch(p->exprblock.opcode)     /* check for special cases and rewrite */
        !           402:        {
        !           403:        case OPCONV:
        !           404:                pt = p->exprblock.vtype;
        !           405:                lp = p->exprblock.leftp;
        !           406:                lt = lp->headblock.vtype;
        !           407:                while(p->tag==TEXPR && p->exprblock.opcode==OPCONV &&
        !           408:                    ( (ISREAL(pt)&&ISREAL(lt)) ||
        !           409:                    (INT(pt)&&(ONEOF(lt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) ))
        !           410:                {
        !           411: #if SZINT < SZLONG
        !           412:                        if(lp->tag != TEXPR)
        !           413:                        {
        !           414:                                if(pt==TYINT && lt==TYLONG)
        !           415:                                        break;
        !           416:                                if(lt==TYINT && pt==TYLONG)
        !           417:                                        break;
        !           418:                        }
        !           419: #endif
        !           420: 
        !           421: #if TARGET == VAX
        !           422:                        if(pt==TYDREAL && lt==TYREAL)
        !           423:                        {
        !           424:                                if(lp->tag==TEXPR &&
        !           425:                                    lp->exprblock.opcode==OPCONV &&
        !           426:                                    lp->exprblock.leftp->headblock.vtype==TYDREAL)
        !           427:                                {
        !           428:                                        putx(lp->exprblock.leftp);
        !           429:                                        p2op(P2CONV, P2REAL);
        !           430:                                        p2op(P2CONV, P2DREAL);
        !           431:                                        free( (charptr) p );
        !           432:                                        return;
        !           433:                                }
        !           434:                                else break;
        !           435:                        }
        !           436: #endif
        !           437: 
        !           438:                        if(lt==TYCHAR && lp->tag==TEXPR && 
        !           439:                            lp->exprblock.opcode==OPCALL)
        !           440:                        {
        !           441:                                p->exprblock.leftp = (expptr) putcall(lp);
        !           442:                                putop(p);
        !           443:                                putcomma(1, pt, NO);
        !           444:                                free( (charptr) p );
        !           445:                                return;
        !           446:                        }
        !           447:                        free( (charptr) p );
        !           448:                        p = lp;
        !           449:                        pt = lt;
        !           450:                        lp = p->exprblock.leftp;
        !           451:                        lt = lp->headblock.vtype;
        !           452:                }
        !           453:                if(p->tag==TEXPR && p->exprblock.opcode==OPCONV)
        !           454:                        break;
        !           455:                putx(p);
        !           456:                return;
        !           457: 
        !           458:        case OPADDR:
        !           459:                comma = NO;
        !           460:                lp = p->exprblock.leftp;
        !           461:                if(lp->tag != TADDR)
        !           462:                {
        !           463:                        tp = (expptr)
        !           464:                            mktemp(lp->headblock.vtype,lp->headblock.vleng);
        !           465:                        putx( mkexpr(OPASSIGN, cpexpr(tp), lp) );
        !           466:                        lp = tp;
        !           467:                        comma = YES;
        !           468:                }
        !           469:                putaddr(lp, NO);
        !           470:                if(comma)
        !           471:                        putcomma(1, TYINT, NO);
        !           472:                free( (charptr) p );
        !           473:                return;
        !           474: #if TARGET == VAX
        !           475:                /* take advantage of a glitch in the code generator that does not check
        !           476:    the type clash in an assignment or comparison of an integer zero and
        !           477:    a floating left operand, and generates optimal code for the correct
        !           478:    type.  (The PCC has no floating-constant node to encode this correctly.)
        !           479: */
        !           480:        case OPASSIGN:
        !           481:        case OPLT:
        !           482:        case OPLE:
        !           483:        case OPGT:
        !           484:        case OPGE:
        !           485:        case OPEQ:
        !           486:        case OPNE:
        !           487:                if(ISREAL(p->exprblock.leftp->headblock.vtype) &&
        !           488:                    ISREAL(p->exprblock.rightp->headblock.vtype) &&
        !           489:                    ISCONST(p->exprblock.rightp) &&
        !           490:                    p->exprblock.rightp->constblock.Const.cd[0]==0)
        !           491:                {
        !           492:                        p->exprblock.rightp->constblock.vtype = TYINT;
        !           493:                        p->exprblock.rightp->constblock.Const.ci = 0;
        !           494:                }
        !           495: #endif
        !           496:        }
        !           497: 
        !           498:        if( (k = ops2[p->exprblock.opcode]) <= 0)
        !           499:                badop("putop", p->exprblock.opcode);
        !           500:        putx(p->exprblock.leftp);
        !           501:        if(p->exprblock.rightp)
        !           502:                putx(p->exprblock.rightp);
        !           503:        p2op(k, types2[p->exprblock.vtype]);
        !           504: 
        !           505:        if(p->exprblock.vleng)
        !           506:                frexpr(p->exprblock.vleng);
        !           507:        free( (charptr) p );
        !           508: }
        !           509: 
        !           510: putforce(t, p)
        !           511: int t;
        !           512: expptr p;
        !           513: {
        !           514:        p = mkconv(t, fixtype(p));
        !           515:        putx(p);
        !           516:        p2op(P2FORCE,
        !           517:            (t==TYSHORT ? P2SHORT : (t==TYLONG ? P2LONG : P2DREAL)) );
        !           518:        putstmt();
        !           519: }
        !           520: 
        !           521: 
        !           522: 
        !           523: LOCAL putpower(p)
        !           524: expptr p;
        !           525: {
        !           526:        expptr base;
        !           527:        Addrp t1, t2;
        !           528:        ftnint k;
        !           529:        int type;
        !           530:        int ncomma;
        !           531: 
        !           532:        if(!ISICON(p->exprblock.rightp) ||
        !           533:            (k = p->exprblock.rightp->constblock.Const.ci)<2)
        !           534:                fatal("putpower: bad call");
        !           535:        base = p->exprblock.leftp;
        !           536:        type = base->headblock.vtype;
        !           537:        t1 = mktemp(type, PNULL);
        !           538:        t2 = NULL;
        !           539:        ncomma = 1;
        !           540:        putassign(cpexpr(t1), cpexpr(base) );
        !           541: 
        !           542:        for( ; (k&1)==0 && k>2 ; k>>=1 )
        !           543:        {
        !           544:                ++ncomma;
        !           545:                putsteq(t1, t1);
        !           546:        }
        !           547: 
        !           548:        if(k == 2)
        !           549:                putx( mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) );
        !           550:        else
        !           551:        {
        !           552:                t2 = mktemp(type, PNULL);
        !           553:                ++ncomma;
        !           554:                putassign(cpexpr(t2), cpexpr(t1));
        !           555: 
        !           556:                for(k>>=1 ; k>1 ; k>>=1)
        !           557:                {
        !           558:                        ++ncomma;
        !           559:                        putsteq(t1, t1);
        !           560:                        if(k & 1)
        !           561:                        {
        !           562:                                ++ncomma;
        !           563:                                putsteq(t2, t1);
        !           564:                        }
        !           565:                }
        !           566:                putx( mkexpr(OPSTAR, cpexpr(t2),
        !           567:                    mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) ));
        !           568:        }
        !           569:        putcomma(ncomma, type, NO);
        !           570:        frexpr(t1);
        !           571:        if(t2)
        !           572:                frexpr(t2);
        !           573:        frexpr(p);
        !           574: }
        !           575: 
        !           576: 
        !           577: 
        !           578: 
        !           579: LOCAL Addrp intdouble(p, ncommap)
        !           580: Addrp p;
        !           581: int *ncommap;
        !           582: {
        !           583:        register Addrp t;
        !           584: 
        !           585:        t = mktemp(TYDREAL, PNULL);
        !           586:        ++*ncommap;
        !           587:        putassign(cpexpr(t), p);
        !           588:        return(t);
        !           589: }
        !           590: 
        !           591: 
        !           592: 
        !           593: 
        !           594: 
        !           595: LOCAL Addrp putcxeq(p)
        !           596: register expptr p;
        !           597: {
        !           598:        register Addrp lp, rp;
        !           599:        int ncomma;
        !           600: 
        !           601:        if(p->tag != TEXPR)
        !           602:                badtag("putcxeq", p->tag);
        !           603: 
        !           604:        ncomma = 0;
        !           605:        lp = putcx1(p->exprblock.leftp, &ncomma);
        !           606:        rp = putcx1(p->exprblock.rightp, &ncomma);
        !           607:        putassign(realpart(lp), realpart(rp));
        !           608:        if( ISCOMPLEX(p->exprblock.vtype) )
        !           609:        {
        !           610:                ++ncomma;
        !           611:                putassign(imagpart(lp), imagpart(rp));
        !           612:        }
        !           613:        putcomma(ncomma, TYREAL, NO);
        !           614:        frexpr(rp);
        !           615:        free( (charptr) p );
        !           616:        return(lp);
        !           617: }
        !           618: 
        !           619: 
        !           620: 
        !           621: LOCAL putcxop(p)
        !           622: expptr p;
        !           623: {
        !           624:        int ncomma;
        !           625: 
        !           626:        ncomma = 0;
        !           627:        putaddr( putcx1(p, &ncomma), NO);
        !           628:        putcomma(ncomma, TYINT, NO);
        !           629: }
        !           630: 
        !           631: 
        !           632: 
        !           633: LOCAL Addrp putcx1(p, ncommap)
        !           634: register expptr p;
        !           635: int *ncommap;
        !           636: {
        !           637:        expptr q;
        !           638:        Addrp lp, rp;
        !           639:        register Addrp resp;
        !           640:        int opcode;
        !           641:        int ltype, rtype;
        !           642:        expptr mkrealcon();
        !           643: 
        !           644:        if(p == NULL)
        !           645:                return(NULL);
        !           646: 
        !           647:        switch(p->tag)
        !           648:        {
        !           649:        case TCONST:
        !           650:                if( ISCOMPLEX(p->constblock.vtype) )
        !           651:                        p = (expptr) putconst(p);
        !           652:                return( (Addrp) p );
        !           653: 
        !           654:        case TADDR:
        !           655:                if( ! addressable(p) )
        !           656:                {
        !           657:                        ++*ncommap;
        !           658:                        resp = mktemp(tyint, PNULL);
        !           659:                        putassign( cpexpr(resp), p->addrblock.memoffset );
        !           660:                        p->addrblock.memoffset = (expptr)resp;
        !           661:                }
        !           662:                return( (Addrp) p );
        !           663: 
        !           664:        case TEXPR:
        !           665:                if( ISCOMPLEX(p->exprblock.vtype) )
        !           666:                        break;
        !           667:                ++*ncommap;
        !           668:                resp = mktemp(TYDREAL, NO);
        !           669:                putassign( cpexpr(resp), p);
        !           670:                return(resp);
        !           671: 
        !           672:        default:
        !           673:                badtag("putcx1", p->tag);
        !           674:        }
        !           675: 
        !           676:        opcode = p->exprblock.opcode;
        !           677:        if(opcode==OPCALL || opcode==OPCCALL)
        !           678:        {
        !           679:                ++*ncommap;
        !           680:                return( putcall(p) );
        !           681:        }
        !           682:        else if(opcode == OPASSIGN)
        !           683:        {
        !           684:                ++*ncommap;
        !           685:                return( putcxeq(p) );
        !           686:        }
        !           687:        resp = mktemp(p->exprblock.vtype, PNULL);
        !           688:        if(lp = putcx1(p->exprblock.leftp, ncommap) )
        !           689:                ltype = lp->vtype;
        !           690:        if(rp = putcx1(p->exprblock.rightp, ncommap) )
        !           691:                rtype = rp->vtype;
        !           692: 
        !           693:        switch(opcode)
        !           694:        {
        !           695:        case OPCOMMA:
        !           696:                frexpr(resp);
        !           697:                resp = rp;
        !           698:                rp = NULL;
        !           699:                break;
        !           700: 
        !           701:        case OPNEG:
        !           702:                putassign( realpart(resp), mkexpr(OPNEG, realpart(lp), ENULL) );
        !           703:                putassign( imagpart(resp), mkexpr(OPNEG, imagpart(lp), ENULL) );
        !           704:                *ncommap += 2;
        !           705:                break;
        !           706: 
        !           707:        case OPPLUS:
        !           708:        case OPMINUS:
        !           709:                putassign( realpart(resp),
        !           710:                    mkexpr(opcode, realpart(lp), realpart(rp) ));
        !           711:                if(rtype < TYCOMPLEX)
        !           712:                        putassign( imagpart(resp), imagpart(lp) );
        !           713:                else if(ltype < TYCOMPLEX)
        !           714:                {
        !           715:                        if(opcode == OPPLUS)
        !           716:                                putassign( imagpart(resp), imagpart(rp) );
        !           717:                        else    putassign( imagpart(resp),
        !           718:                            mkexpr(OPNEG, imagpart(rp), ENULL) );
        !           719:                }
        !           720:                else
        !           721:                        putassign( imagpart(resp),
        !           722:                            mkexpr(opcode, imagpart(lp), imagpart(rp) ));
        !           723: 
        !           724:                *ncommap += 2;
        !           725:                break;
        !           726: 
        !           727:        case OPSTAR:
        !           728:                if(ltype < TYCOMPLEX)
        !           729:                {
        !           730:                        if( ISINT(ltype) )
        !           731:                                lp = intdouble(lp, ncommap);
        !           732:                        putassign( realpart(resp),
        !           733:                            mkexpr(OPSTAR, cpexpr(lp), realpart(rp) ));
        !           734:                        putassign( imagpart(resp),
        !           735:                            mkexpr(OPSTAR, cpexpr(lp), imagpart(rp) ));
        !           736:                }
        !           737:                else if(rtype < TYCOMPLEX)
        !           738:                {
        !           739:                        if( ISINT(rtype) )
        !           740:                                rp = intdouble(rp, ncommap);
        !           741:                        putassign( realpart(resp),
        !           742:                            mkexpr(OPSTAR, cpexpr(rp), realpart(lp) ));
        !           743:                        putassign( imagpart(resp),
        !           744:                            mkexpr(OPSTAR, cpexpr(rp), imagpart(lp) ));
        !           745:                }
        !           746:                else    {
        !           747:                        putassign( realpart(resp), mkexpr(OPMINUS,
        !           748:                            mkexpr(OPSTAR, realpart(lp), realpart(rp)),
        !           749:                            mkexpr(OPSTAR, imagpart(lp), imagpart(rp)) ));
        !           750:                        putassign( imagpart(resp), mkexpr(OPPLUS,
        !           751:                            mkexpr(OPSTAR, realpart(lp), imagpart(rp)),
        !           752:                            mkexpr(OPSTAR, imagpart(lp), realpart(rp)) ));
        !           753:                }
        !           754:                *ncommap += 2;
        !           755:                break;
        !           756: 
        !           757:        case OPSLASH:
        !           758:                /* fixexpr has already replaced all divisions
        !           759:                 * by a complex by a function call
        !           760:                 */
        !           761:                if( ISINT(rtype) )
        !           762:                        rp = intdouble(rp, ncommap);
        !           763:                putassign( realpart(resp),
        !           764:                    mkexpr(OPSLASH, realpart(lp), cpexpr(rp)) );
        !           765:                putassign( imagpart(resp),
        !           766:                    mkexpr(OPSLASH, imagpart(lp), cpexpr(rp)) );
        !           767:                *ncommap += 2;
        !           768:                break;
        !           769: 
        !           770:        case OPCONV:
        !           771:                putassign( realpart(resp), realpart(lp) );
        !           772:                if( ISCOMPLEX(lp->vtype) )
        !           773:                        q = imagpart(lp);
        !           774:                else if(rp != NULL)
        !           775:                        q = (expptr) realpart(rp);
        !           776:                else
        !           777:                        q = mkrealcon(TYDREAL, 0.0);
        !           778:                putassign( imagpart(resp), q);
        !           779:                *ncommap += 2;
        !           780:                break;
        !           781: 
        !           782:        default:
        !           783:                badop("putcx1", opcode);
        !           784:        }
        !           785: 
        !           786:        frexpr(lp);
        !           787:        frexpr(rp);
        !           788:        free( (charptr) p );
        !           789:        return(resp);
        !           790: }
        !           791: 
        !           792: 
        !           793: 
        !           794: 
        !           795: LOCAL putcxcmp(p)
        !           796: register expptr p;
        !           797: {
        !           798:        int opcode;
        !           799:        int ncomma;
        !           800:        register Addrp lp, rp;
        !           801:        expptr q;
        !           802: 
        !           803:        if(p->tag != TEXPR)
        !           804:                badtag("putcxcmp", p->tag);
        !           805: 
        !           806:        ncomma = 0;
        !           807:        opcode = p->exprblock.opcode;
        !           808:        lp = putcx1(p->exprblock.leftp, &ncomma);
        !           809:        rp = putcx1(p->exprblock.rightp, &ncomma);
        !           810: 
        !           811:        q = mkexpr( opcode==OPEQ ? OPAND : OPOR ,
        !           812:            mkexpr(opcode, realpart(lp), realpart(rp)),
        !           813:            mkexpr(opcode, imagpart(lp), imagpart(rp)) );
        !           814:        putx( fixexpr(q) );
        !           815:        putcomma(ncomma, TYINT, NO);
        !           816: 
        !           817:        free( (charptr) lp);
        !           818:        free( (charptr) rp);
        !           819:        free( (charptr) p );
        !           820: }
        !           821: 
        !           822: LOCAL Addrp putch1(p, ncommap)
        !           823: register expptr p;
        !           824: int * ncommap;
        !           825: {
        !           826:        register Addrp t;
        !           827:        Addrp mktemp();
        !           828:        Addrp putconst();
        !           829: 
        !           830:        switch(p->tag)
        !           831:        {
        !           832:        case TCONST:
        !           833:                return( putconst(p) );
        !           834: 
        !           835:        case TADDR:
        !           836:                return( (Addrp) p );
        !           837: 
        !           838:        case TEXPR:
        !           839:                ++*ncommap;
        !           840: 
        !           841:                switch(p->exprblock.opcode)
        !           842:                {
        !           843:                        expptr q;
        !           844: 
        !           845:                case OPCALL:
        !           846:                case OPCCALL:
        !           847:                        t = putcall(p);
        !           848:                        break;
        !           849: 
        !           850:                case OPCONCAT:
        !           851:                        t = mktemp(TYCHAR, ICON(lencat(p)) );
        !           852:                        q = (expptr) cpexpr(p->headblock.vleng);
        !           853:                        putcat( cpexpr(t), p );
        !           854:                        /* put the correct length on the block */
        !           855:                        frexpr(t->vleng);
        !           856:                        t->vleng = q;
        !           857: 
        !           858:                        break;
        !           859: 
        !           860:                case OPCONV:
        !           861:                        if(!ISICON(p->exprblock.vleng)
        !           862:                            || p->exprblock.vleng->constblock.Const.ci!=1
        !           863:                            || ! INT(p->exprblock.leftp->headblock.vtype) )
        !           864:                                fatal("putch1: bad character conversion");
        !           865:                        t = mktemp(TYCHAR, ICON(1) );
        !           866:                        putop( mkexpr(OPASSIGN, cpexpr(t), p) );
        !           867:                        break;
        !           868:                default:
        !           869:                        badop("putch1", p->exprblock.opcode);
        !           870:                }
        !           871:                return(t);
        !           872: 
        !           873:        default:
        !           874:                badtag("putch1", p->tag);
        !           875:        }
        !           876:        /* NOTREACHED */
        !           877: }
        !           878: 
        !           879: 
        !           880: 
        !           881: 
        !           882: LOCAL putchop(p)
        !           883: expptr p;
        !           884: {
        !           885:        int ncomma;
        !           886: 
        !           887:        ncomma = 0;
        !           888:        putaddr( putch1(p, &ncomma) , NO );
        !           889:        putcomma(ncomma, TYCHAR, YES);
        !           890: }
        !           891: 
        !           892: 
        !           893: 
        !           894: 
        !           895: LOCAL putcheq(p)
        !           896: register expptr p;
        !           897: {
        !           898:        int ncomma;
        !           899:        expptr lp, rp;
        !           900: 
        !           901:        if(p->tag != TEXPR)
        !           902:                badtag("putcheq", p->tag);
        !           903: 
        !           904:        ncomma = 0;
        !           905:        lp = p->exprblock.leftp;
        !           906:        rp = p->exprblock.rightp;
        !           907:        if( rp->tag==TEXPR && rp->exprblock.opcode==OPCONCAT )
        !           908:                putcat(lp, rp);
        !           909:        else if( ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) )
        !           910:        {
        !           911:                putaddr( putch1(lp, &ncomma) , YES );
        !           912:                putaddr( putch1(rp, &ncomma) , YES );
        !           913:                putcomma(ncomma, TYINT, NO);
        !           914:                p2op(P2ASSIGN, P2CHAR);
        !           915:        }
        !           916:        else
        !           917:        {
        !           918:                putx( call2(TYINT, "s_copy", lp, rp) );
        !           919:                putcomma(ncomma, TYINT, NO);
        !           920:        }
        !           921: 
        !           922:        frexpr(p->exprblock.vleng);
        !           923:        free( (charptr) p );
        !           924: }
        !           925: 
        !           926: 
        !           927: 
        !           928: 
        !           929: LOCAL putchcmp(p)
        !           930: register expptr p;
        !           931: {
        !           932:        int ncomma;
        !           933:        expptr lp, rp;
        !           934: 
        !           935:        if(p->tag != TEXPR)
        !           936:                badtag("putchcmp", p->tag);
        !           937: 
        !           938:        ncomma = 0;
        !           939:        lp = p->exprblock.leftp;
        !           940:        rp = p->exprblock.rightp;
        !           941: 
        !           942:        if(ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) )
        !           943:        {
        !           944:                putaddr( putch1(lp, &ncomma) , YES );
        !           945:                putaddr( putch1(rp, &ncomma) , YES );
        !           946:                p2op(ops2[p->exprblock.opcode], P2CHAR);
        !           947:                free( (charptr) p );
        !           948:                putcomma(ncomma, TYINT, NO);
        !           949:        }
        !           950:        else
        !           951:        {
        !           952:                p->exprblock.leftp = call2(TYINT,"s_cmp", lp, rp);
        !           953:                p->exprblock.rightp = ICON(0);
        !           954:                putop(p);
        !           955:        }
        !           956: }
        !           957: 
        !           958: 
        !           959: 
        !           960: 
        !           961: 
        !           962: LOCAL putcat(lhs, rhs)
        !           963: register Addrp lhs;
        !           964: register expptr rhs;
        !           965: {
        !           966:        int n, ncomma;
        !           967:        Addrp lp, cp;
        !           968: 
        !           969:        ncomma = 0;
        !           970:        n = ncat(rhs);
        !           971:        lp = mktmpn(n, TYLENG, PNULL);
        !           972:        cp = mktmpn(n, TYADDR, PNULL);
        !           973: 
        !           974:        n = 0;
        !           975:        putct1(rhs, lp, cp, &n, &ncomma);
        !           976: 
        !           977:        putx( call4(TYSUBR, "s_cat", lhs, cp, lp, mkconv(TYLONG, ICON(n)) ) );
        !           978:        putcomma(ncomma, TYINT, NO);
        !           979: }
        !           980: 
        !           981: 
        !           982: 
        !           983: 
        !           984: 
        !           985: LOCAL putct1(q, lp, cp, ip, ncommap)
        !           986: register expptr q;
        !           987: register Addrp lp, cp;
        !           988: int *ip, *ncommap;
        !           989: {
        !           990:        int i;
        !           991:        Addrp lp1, cp1;
        !           992: 
        !           993:        if(q->tag==TEXPR && q->exprblock.opcode==OPCONCAT)
        !           994:        {
        !           995:                putct1(q->exprblock.leftp, lp, cp, ip, ncommap);
        !           996:                putct1(q->exprblock.rightp, lp, cp , ip, ncommap);
        !           997:                frexpr(q->exprblock.vleng);
        !           998:                free( (charptr) q );
        !           999:        }
        !          1000:        else
        !          1001:        {
        !          1002:                i = (*ip)++;
        !          1003:                lp1 = (Addrp) cpexpr(lp);
        !          1004:                lp1->memoffset = mkexpr(OPPLUS,lp1->memoffset, ICON(i*SZLENG));
        !          1005:                cp1 = (Addrp) cpexpr(cp);
        !          1006:                cp1->memoffset = mkexpr(OPPLUS, cp1->memoffset, ICON(i*SZADDR));
        !          1007:                putassign( lp1, cpexpr(q->headblock.vleng) );
        !          1008:                putassign( cp1, addrof(putch1(q,ncommap)) );
        !          1009:                *ncommap += 2;
        !          1010:        }
        !          1011: }
        !          1012: 
        !          1013: LOCAL putaddr(p, indir)
        !          1014: register Addrp p;
        !          1015: int indir;
        !          1016: {
        !          1017:        int type, type2, funct;
        !          1018:        ftnint offset, simoffset();
        !          1019:        expptr offp, shorten();
        !          1020: 
        !          1021:        if( p->tag==TERROR || (p->memoffset!=NULL && ISERROR(p->memoffset)) )
        !          1022:        {
        !          1023:                frexpr(p);
        !          1024:                return;
        !          1025:        }
        !          1026: 
        !          1027:        type = p->vtype;
        !          1028:        type2 = types2[type];
        !          1029:        funct = (p->vclass==CLPROC ? P2FUNCT<<2 : 0);
        !          1030: 
        !          1031:        offp = (p->memoffset ? (expptr) cpexpr(p->memoffset) : (expptr)NULL );
        !          1032: 
        !          1033: 
        !          1034: #if (FUDGEOFFSET != 1)
        !          1035:        if(offp)
        !          1036:                offp = mkexpr(OPSTAR, ICON(FUDGEOFFSET), offp);
        !          1037: #endif
        !          1038: 
        !          1039:        offset = simoffset( &offp );
        !          1040: #if SZINT < SZLONG
        !          1041:        if(offp)
        !          1042:                if(shortsubs)
        !          1043:                        offp = shorten(offp);
        !          1044:                else
        !          1045:                        offp = mkconv(TYINT, offp);
        !          1046: #else
        !          1047:        if(offp)
        !          1048:                offp = mkconv(TYINT, offp);
        !          1049: #endif
        !          1050: 
        !          1051:        switch(p->vstg)
        !          1052:        {
        !          1053:        case STGAUTO:
        !          1054:                if(indir && !offp)
        !          1055:                {
        !          1056:                        p2oreg(offset, AUTOREG, type2);
        !          1057:                        break;
        !          1058:                }
        !          1059: 
        !          1060:                if(!indir && !offp && !offset)
        !          1061:                {
        !          1062:                        p2reg(AUTOREG, type2 | P2PTR);
        !          1063:                        break;
        !          1064:                }
        !          1065: 
        !          1066:                p2reg(AUTOREG, type2 | P2PTR);
        !          1067:                if(offp)
        !          1068:                {
        !          1069:                        putx(offp);
        !          1070:                        if(offset)
        !          1071:                                p2icon(offset, P2INT);
        !          1072:                }
        !          1073:                else
        !          1074:                        p2icon(offset, P2INT);
        !          1075:                if(offp && offset)
        !          1076:                        p2op(P2PLUS, type2 | P2PTR);
        !          1077:                p2op(P2PLUS, type2 | P2PTR);
        !          1078:                if(indir)
        !          1079:                        p2op(P2INDIRECT, type2);
        !          1080:                break;
        !          1081: 
        !          1082:        case STGARG:
        !          1083:                p2oreg(
        !          1084: #ifdef ARGOFFSET
        !          1085:                    ARGOFFSET +
        !          1086: #endif
        !          1087:                    (ftnint) (FUDGEOFFSET*p->memno),
        !          1088:                    ARGREG,   type2 | P2PTR | funct );
        !          1089: 
        !          1090: based:
        !          1091:                if(offp)
        !          1092:                        putx(offp);
        !          1093:                if(offset)
        !          1094:                {
        !          1095:                        p2icon(offset, P2INT);
        !          1096:                        p2op(P2PLUS, type2 | P2PTR);
        !          1097:                }
        !          1098:                if(offp)
        !          1099:                        p2op(P2PLUS, type2 | P2PTR);
        !          1100:                if(indir)
        !          1101:                        p2op(P2INDIRECT, type2);
        !          1102:                break;
        !          1103: 
        !          1104:        case STGLENG:
        !          1105:                if(indir)
        !          1106:                {
        !          1107:                        p2oreg(
        !          1108: #ifdef ARGOFFSET
        !          1109:                            ARGOFFSET +
        !          1110: #endif
        !          1111:                            (ftnint) (FUDGEOFFSET*p->memno),
        !          1112:                            ARGREG,   type2 );
        !          1113:                }
        !          1114:                else    {
        !          1115:                        p2reg(ARGREG, type2 | P2PTR );
        !          1116:                        p2icon(
        !          1117: #ifdef ARGOFFSET
        !          1118:                            ARGOFFSET +
        !          1119: #endif
        !          1120:                            (ftnint) (FUDGEOFFSET*p->memno), P2INT);
        !          1121:                        p2op(P2PLUS, type2 | P2PTR );
        !          1122:                }
        !          1123:                break;
        !          1124: 
        !          1125: 
        !          1126:        case STGBSS:
        !          1127:        case STGINIT:
        !          1128:        case STGEXT:
        !          1129:        case STGCOMMON:
        !          1130:        case STGEQUIV:
        !          1131:        case STGCONST:
        !          1132:                if(offp)
        !          1133:                {
        !          1134:                        putx(offp);
        !          1135:                        putmem(p, P2ICON, offset);
        !          1136:                        p2op(P2PLUS, type2 | P2PTR);
        !          1137:                        if(indir)
        !          1138:                                p2op(P2INDIRECT, type2);
        !          1139:                }
        !          1140:                else
        !          1141:                        putmem(p, (indir ? P2NAME : P2ICON), offset);
        !          1142: 
        !          1143:                break;
        !          1144: 
        !          1145:        case STGREG:
        !          1146:                if(indir)
        !          1147:                        p2reg(p->memno, type2);
        !          1148:                else
        !          1149:                        fatal("attempt to take address of a register");
        !          1150:                break;
        !          1151: 
        !          1152:                /* for possible future use -- register based arrays
        !          1153:        case STGPREG:
        !          1154:                if(indir && !offp)
        !          1155:                        p2oreg(offset, p->memno, type2);
        !          1156:                else
        !          1157:                        {
        !          1158:                        p2reg(p->memno, type2 | P2PTR);
        !          1159:                        goto based;
        !          1160:                        }
        !          1161:                break;
        !          1162: */
        !          1163: 
        !          1164:        default:
        !          1165:                badstg("putaddr", p->vstg);
        !          1166:        }
        !          1167:        frexpr(p);
        !          1168: }
        !          1169: 
        !          1170: 
        !          1171: 
        !          1172: 
        !          1173: LOCAL putmem(p, class, offset)
        !          1174: expptr p;
        !          1175: int class;
        !          1176: ftnint offset;
        !          1177: {
        !          1178:        int type2;
        !          1179:        char *name,  *memname();
        !          1180:        /* int funct; */
        !          1181: 
        !          1182:        /* funct = (p->headblock.vclass==CLPROC ? P2FUNCT<<2 : 0); */
        !          1183:        type2 = types2[p->headblock.vtype];
        !          1184:        if(p->headblock.vclass == CLPROC)
        !          1185:                type2 |= (P2FUNCT<<2);
        !          1186:        name = memname(p->addrblock.vstg, p->addrblock.memno);
        !          1187:        if(class == P2ICON)
        !          1188:        {
        !          1189:                p2triple(P2ICON, name[0]!='\0', type2|P2PTR);
        !          1190:                p2word(offset);
        !          1191:                if(name[0])
        !          1192:                        p2name(name);
        !          1193:        }
        !          1194:        else
        !          1195:        {
        !          1196:                p2triple(P2NAME, offset!=0, type2);
        !          1197:                if(offset != 0)
        !          1198:                        p2word(offset);
        !          1199:                p2name(name);
        !          1200:        }
        !          1201: }
        !          1202: 
        !          1203: 
        !          1204: 
        !          1205: LOCAL Addrp putcall(p)
        !          1206: register Exprp p;
        !          1207: {
        !          1208:        chainp arglist, charsp, cp;
        !          1209:        int n, first;
        !          1210:        Addrp t;
        !          1211:        register expptr q;
        !          1212:        Addrp fval;
        !          1213:        int type, type2, ctype, qtype, indir;
        !          1214: 
        !          1215:        type2 = types2[type = p->vtype];
        !          1216:        charsp = NULL;
        !          1217:        indir =  (p->opcode == OPCCALL);
        !          1218:        n = 0;
        !          1219:        first = YES;
        !          1220: 
        !          1221:        if(p->rightp)
        !          1222:        {
        !          1223:                arglist = p->rightp->listblock.listp;
        !          1224:                free( (charptr) (p->rightp) );
        !          1225:        }
        !          1226:        else
        !          1227:                arglist = NULL;
        !          1228: 
        !          1229:        for(cp = arglist ; cp ; cp = cp->nextp)
        !          1230:                if(indir)
        !          1231:                        ++n;
        !          1232:                else    {
        !          1233:                        q = (expptr) (cp->datap);
        !          1234:                        if( ISCONST(q) )
        !          1235:                        {
        !          1236:                                q = (expptr) putconst(q);
        !          1237:                                cp->datap = (tagptr) q;
        !          1238:                        }
        !          1239:                        if( ISCHAR(q) && q->headblock.vclass!=CLPROC )
        !          1240:                        {
        !          1241:                                charsp = hookup(charsp,
        !          1242:                                    mkchain(cpexpr(q->headblock.vleng),
        !          1243:                                    CHNULL));
        !          1244:                                n += 2;
        !          1245:                        }
        !          1246:                        else
        !          1247:                                n += 1;
        !          1248:                }
        !          1249: 
        !          1250:        if(type == TYCHAR)
        !          1251:        {
        !          1252:                if( ISICON(p->vleng) )
        !          1253:                {
        !          1254:                        fval = mktemp(TYCHAR, p->vleng);
        !          1255:                        n += 2;
        !          1256:                }
        !          1257:                else    {
        !          1258:                        err("adjustable character function");
        !          1259:                        return 0;
        !          1260:                }
        !          1261:        }
        !          1262:        else if( ISCOMPLEX(type) )
        !          1263:        {
        !          1264:                fval = mktemp(type, PNULL);
        !          1265:                n += 1;
        !          1266:        }
        !          1267:        else
        !          1268:                fval = NULL;
        !          1269: 
        !          1270:        ctype = (fval ? P2INT : type2);
        !          1271:        putaddr(p->leftp, NO);
        !          1272: 
        !          1273:        if(fval)
        !          1274:        {
        !          1275:                first = NO;
        !          1276:                putaddr( cpexpr(fval), NO);
        !          1277:                if(type==TYCHAR)
        !          1278:                {
        !          1279:                        putx( mkconv(TYLENG,p->vleng) );
        !          1280:                        p2op(P2LISTOP, type2);
        !          1281:                }
        !          1282:        }
        !          1283: 
        !          1284:        for(cp = arglist ; cp ; cp = cp->nextp)
        !          1285:        {
        !          1286:                q = (expptr) (cp->datap);
        !          1287:                if(q->tag==TADDR && (indir || q->addrblock.vstg!=STGREG) )
        !          1288:                        putaddr(q, indir && q->addrblock.vtype!=TYCHAR);
        !          1289:                else if( ISCOMPLEX(q->headblock.vtype) )
        !          1290:                        putcxop(q);
        !          1291:                else if (ISCHAR(q) )
        !          1292:                        putchop(q);
        !          1293:                else if( ! ISERROR(q) )
        !          1294:                {
        !          1295:                        if(indir)
        !          1296:                                putx(q);
        !          1297:                        else    {
        !          1298:                                t = mktemp(qtype = q->headblock.vtype,
        !          1299:                                    q->headblock.vleng);
        !          1300:                                putassign( cpexpr(t), q );
        !          1301:                                putaddr(t, NO);
        !          1302:                                putcomma(1, qtype, YES);
        !          1303:                        }
        !          1304:                }
        !          1305:                if(first)
        !          1306:                        first = NO;
        !          1307:                else
        !          1308:                        p2op(P2LISTOP, type2);
        !          1309:        }
        !          1310: 
        !          1311:        if(arglist)
        !          1312:                frchain(&arglist);
        !          1313:        for(cp = charsp ; cp ; cp = cp->nextp)
        !          1314:        {
        !          1315:                putx( mkconv(TYLENG,cp->datap) );
        !          1316:                p2op(P2LISTOP, type2);
        !          1317:        }
        !          1318:        frchain(&charsp);
        !          1319:        p2op(n>0 ? P2CALL : P2CALL0 , ctype);
        !          1320:        free( (charptr) p );
        !          1321:        return(fval);
        !          1322: }
        !          1323: 
        !          1324: 
        !          1325: 
        !          1326: LOCAL putmnmx(p)
        !          1327: register expptr p;
        !          1328: {
        !          1329:        int op, type;
        !          1330:        int ncomma;
        !          1331:        expptr qp;
        !          1332:        chainp p0, p1;
        !          1333:        Addrp sp, tp;
        !          1334: 
        !          1335:        if(p->tag != TEXPR)
        !          1336:                badtag("putmnmx", p->tag);
        !          1337: 
        !          1338:        type = p->exprblock.vtype;
        !          1339:        op = (p->exprblock.opcode==OPMIN ? OPLT : OPGT );
        !          1340:        p0 = p->exprblock.leftp->listblock.listp;
        !          1341:        free( (charptr) (p->exprblock.leftp) );
        !          1342:        free( (charptr) p );
        !          1343: 
        !          1344:        sp = mktemp(type, PNULL);
        !          1345:        tp = mktemp(type, PNULL);
        !          1346:        qp = mkexpr(OPCOLON, cpexpr(tp), cpexpr(sp));
        !          1347:        qp = mkexpr(OPQUEST, mkexpr(op, cpexpr(tp),cpexpr(sp)), qp);
        !          1348:        qp = fixexpr(qp);
        !          1349: 
        !          1350:        ncomma = 1;
        !          1351:        putassign( cpexpr(sp), p0->datap );
        !          1352: 
        !          1353:        for(p1 = p0->nextp ; p1 ; p1 = p1->nextp)
        !          1354:        {
        !          1355:                ++ncomma;
        !          1356:                putassign( cpexpr(tp), p1->datap );
        !          1357:                if(p1->nextp)
        !          1358:                {
        !          1359:                        ++ncomma;
        !          1360:                        putassign( cpexpr(sp), cpexpr(qp) );
        !          1361:                }
        !          1362:                else
        !          1363:                        putx(qp);
        !          1364:        }
        !          1365: 
        !          1366:        putcomma(ncomma, type, NO);
        !          1367:        frtemp(sp);
        !          1368:        frtemp(tp);
        !          1369:        frchain( &p0 );
        !          1370: }
        !          1371: 
        !          1372: 
        !          1373: 
        !          1374: 
        !          1375: LOCAL putcomma(n, type, indir)
        !          1376: int n, type, indir;
        !          1377: {
        !          1378:        type = types2[type];
        !          1379:        if(indir)
        !          1380:                type |= P2PTR;
        !          1381:        while(--n >= 0)
        !          1382:                p2op(P2COMOP, type);
        !          1383: }
        !          1384: 
        !          1385: 
        !          1386: 
        !          1387: 
        !          1388: ftnint simoffset(p0)
        !          1389: expptr *p0;
        !          1390: {
        !          1391:        ftnint offset, prod;
        !          1392:        register expptr p, lp, rp;
        !          1393: 
        !          1394:        offset = 0;
        !          1395:        p = *p0;
        !          1396:        if(p == NULL)
        !          1397:                return(0);
        !          1398: 
        !          1399:        if( ! ISINT(p->headblock.vtype) )
        !          1400:                return(0);
        !          1401: 
        !          1402:        if(p->tag==TEXPR && p->exprblock.opcode==OPSTAR)
        !          1403:        {
        !          1404:                lp = p->exprblock.leftp;
        !          1405:                rp = p->exprblock.rightp;
        !          1406:                if(ISICON(rp) && lp->tag==TEXPR &&
        !          1407:                    lp->exprblock.opcode==OPPLUS && ISICON(lp->exprblock.rightp))
        !          1408:                {
        !          1409:                        p->exprblock.opcode = OPPLUS;
        !          1410:                        lp->exprblock.opcode = OPSTAR;
        !          1411:                        prod = rp->constblock.Const.ci *
        !          1412:                            lp->exprblock.rightp->constblock.Const.ci;
        !          1413:                        lp->exprblock.rightp->constblock.Const.ci = rp->constblock.Const.ci;
        !          1414:                        rp->constblock.Const.ci = prod;
        !          1415:                }
        !          1416:        }
        !          1417: 
        !          1418:        if(p->tag==TEXPR && p->exprblock.opcode==OPPLUS &&
        !          1419:            ISICON(p->exprblock.rightp))
        !          1420:        {
        !          1421:                rp = p->exprblock.rightp;
        !          1422:                lp = p->exprblock.leftp;
        !          1423:                offset += rp->constblock.Const.ci;
        !          1424:                frexpr(rp);
        !          1425:                free( (charptr) p );
        !          1426:                *p0 = lp;
        !          1427:        }
        !          1428: 
        !          1429:        if( ISCONST(p) )
        !          1430:        {
        !          1431:                offset += p->constblock.Const.ci;
        !          1432:                frexpr(p);
        !          1433:                *p0 = NULL;
        !          1434:        }
        !          1435: 
        !          1436:        return(offset);
        !          1437: }
        !          1438: 
        !          1439: 
        !          1440: 
        !          1441: 
        !          1442: 
        !          1443: p2op(op, type)
        !          1444: int op, type;
        !          1445: {
        !          1446:        p2triple(op, 0, type);
        !          1447: }
        !          1448: 
        !          1449: p2icon(offset, type)
        !          1450: ftnint offset;
        !          1451: int type;
        !          1452: {
        !          1453:        p2triple(P2ICON, 0, type);
        !          1454:        p2word(offset);
        !          1455: }
        !          1456: 
        !          1457: 
        !          1458: 
        !          1459: 
        !          1460: p2oreg(offset, reg, type)
        !          1461: ftnint offset;
        !          1462: int reg, type;
        !          1463: {
        !          1464:        p2triple(P2OREG, reg, type);
        !          1465:        p2word(offset);
        !          1466:        p2name("");
        !          1467: }
        !          1468: 
        !          1469: 
        !          1470: 
        !          1471: 
        !          1472: p2reg(reg, type)
        !          1473: int reg, type;
        !          1474: {
        !          1475:        p2triple(P2REG, reg, type);
        !          1476: }
        !          1477: 
        !          1478: 
        !          1479: 
        !          1480: p2pi(s, i)
        !          1481: char *s;
        !          1482: int i;
        !          1483: {
        !          1484:        char buff[100];
        !          1485:        sprintf(buff, s, i);
        !          1486:        p2pass(buff);
        !          1487: }
        !          1488: 
        !          1489: 
        !          1490: 
        !          1491: p2pij(s, i, j)
        !          1492: char *s;
        !          1493: int i, j;
        !          1494: {
        !          1495:        char buff[100];
        !          1496:        sprintf(buff, s, i, j);
        !          1497:        p2pass(buff);
        !          1498: }
        !          1499: 
        !          1500: 
        !          1501: 
        !          1502: 
        !          1503: p2ps(s, t)
        !          1504: char *s, *t;
        !          1505: {
        !          1506:        char buff[100];
        !          1507:        sprintf(buff, s, t);
        !          1508:        p2pass(buff);
        !          1509: }
        !          1510: 
        !          1511: 
        !          1512: 
        !          1513: 
        !          1514: p2pass(s)
        !          1515: char *s;
        !          1516: {
        !          1517:        p2triple(P2PASS, (strlen(s) + FOUR-1)/FOUR, 0);
        !          1518:        p2str(s);
        !          1519: }
        !          1520: 
        !          1521: 
        !          1522: 
        !          1523: 
        !          1524: p2str(s)
        !          1525: register char *s;
        !          1526: {
        !          1527:        union { 
        !          1528:                long int word; 
        !          1529:                char str[FOUR]; 
        !          1530:        } u;
        !          1531:        register int i;
        !          1532: 
        !          1533:        i = 0;
        !          1534:        u.word = 0;
        !          1535:        while(*s)
        !          1536:        {
        !          1537:                u.str[i++] = *s++;
        !          1538:                if(i == FOUR)
        !          1539:                {
        !          1540:                        p2word(u.word);
        !          1541:                        u.word = 0;
        !          1542:                        i = 0;
        !          1543:                }
        !          1544:        }
        !          1545:        if(i > 0)
        !          1546:                p2word(u.word);
        !          1547: }
        !          1548: 
        !          1549: 
        !          1550: 
        !          1551: 
        !          1552: p2triple(op, var, type)
        !          1553: int op, var, type;
        !          1554: {
        !          1555:        register long word;
        !          1556:        word = op | (var<<8);
        !          1557:        word |= ( (long int) type) <<16;
        !          1558:        p2word(word);
        !          1559: }
        !          1560: 
        !          1561: 
        !          1562: 
        !          1563: 
        !          1564: 
        !          1565: p2name(s)
        !          1566: register char *s;
        !          1567: {
        !          1568:        register int i;
        !          1569: 
        !          1570: #ifdef UCBPASS2
        !          1571:        /* arbitrary length names, terminated by a null,
        !          1572:           padded to a full word */
        !          1573: 
        !          1574: #      define WL   sizeof(long int)
        !          1575:        union { 
        !          1576:                long int word; 
        !          1577:                char str[WL]; 
        !          1578:        } w;
        !          1579: 
        !          1580:        w.word = 0;
        !          1581:        i = 0;
        !          1582:        while(w.str[i++] = *s++)
        !          1583:                if(i == WL)
        !          1584:                {
        !          1585:                        p2word(w.word);
        !          1586:                        w.word = 0;
        !          1587:                        i = 0;
        !          1588:                }
        !          1589:        if(i > 0)
        !          1590:                p2word(w.word);
        !          1591: #else
        !          1592:        /* standard intermediate, names are 8 characters long */
        !          1593: 
        !          1594:        union  { 
        !          1595:                long int word[2];  
        !          1596:                char str[8]; 
        !          1597:        } u;
        !          1598: 
        !          1599:        u.word[0] = u.word[1] = 0;
        !          1600:        for(i = 0 ; i<8 && *s ; ++i)
        !          1601:                u.str[i] = *s++;
        !          1602:        p2word(u.word[0]);
        !          1603:        p2word(u.word[1]);
        !          1604: 
        !          1605: #endif
        !          1606: 
        !          1607: }
        !          1608: 
        !          1609: 
        !          1610: 
        !          1611: 
        !          1612: p2word(w)
        !          1613: long int w;
        !          1614: {
        !          1615:        *p2bufp++ = w;
        !          1616:        if(p2bufp >= p2bufend)
        !          1617:                p2flush();
        !          1618: }
        !          1619: 
        !          1620: 
        !          1621: 
        !          1622: p2flush()
        !          1623: {
        !          1624:        if(p2bufp > p2buff)
        !          1625:                write(fileno(textfile), p2buff, (p2bufp-p2buff)*sizeof(long int));
        !          1626:        p2bufp = p2buff;
        !          1627: }

unix.superglobalmegacorp.com

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