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

unix.superglobalmegacorp.com

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