Annotation of researchv10no/cmd/f77/alt/putdmr.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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