Annotation of researchv10no/cmd/f77/putpcc.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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