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

unix.superglobalmegacorp.com

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