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

unix.superglobalmegacorp.com

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