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

unix.superglobalmegacorp.com

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