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

unix.superglobalmegacorp.com

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