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

unix.superglobalmegacorp.com

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