Annotation of researchv8dc/cmd/f77/proc.c, revision 1.1.1.1

1.1       root        1: #include "defs"
                      2: #include "machdefs"
                      3: 
                      4: #ifdef SDB
                      5: #      include <a.out.h>
                      6: char *stabline();
                      7: #      ifndef N_SO
                      8: #              include <stab.h>
                      9: #      endif
                     10: #endif
                     11: 
                     12: /* start a new procedure */
                     13: 
                     14: newproc()
                     15: {
                     16: if(parstate != OUTSIDE)
                     17:        {
                     18:        execerr("missing end statement", CNULL);
                     19:        endproc();
                     20:        }
                     21: 
                     22: parstate = INSIDE;
                     23: procclass = CLMAIN;    /* default */
                     24: }
                     25: 
                     26: 
                     27: 
                     28: /* end of procedure. generate variables, epilogs, and prologs */
                     29: 
                     30: endproc()
                     31: {
                     32: struct Labelblock *lp;
                     33: #if SDB
                     34: char elab[10];
                     35: int elnum;
                     36: #endif
                     37: 
                     38: if(parstate < INDATA)
                     39:        enddcl();
                     40: if(ctlstack >= ctls)
                     41:        err("DO loop or BLOCK IF not closed");
                     42: for(lp = labeltab ; lp < labtabend ; ++lp)
                     43:        if(lp->stateno!=0 && lp->labdefined==NO)
                     44:                errstr("missing statement number %s", convic(lp->stateno) );
                     45: 
                     46: epicode();
                     47: procode();
                     48: donmlist();
                     49: dobss();
                     50: prdbginfo();
                     51: #if SDB
                     52: if (sdbflag) {
                     53:        sprintf(elab, "L%d", elnum = newlabel());
                     54:        putlabel(elnum);
                     55:        prstab(procclass == CLMAIN ? "MAIN_" : nounder(XL, procname),
                     56:                N_EFUN, lineno, elab);
                     57: }
                     58: #endif
                     59: #if FAMILY == PCC
                     60:        putbracket();
                     61: #endif
                     62: fixlwm();
                     63: procinit();    /* clean up for next procedure */
                     64: }
                     65: 
                     66: 
                     67: 
                     68: /* End of declaration section of procedure.  Allocate storage. */
                     69: 
                     70: enddcl()
                     71: {
                     72: register struct Entrypoint *ep;
                     73: 
                     74: parstate = INEXEC;
                     75: docommon();
                     76: doequiv();
                     77: docomleng();
                     78: for(ep = entries ; ep ; ep = ep->entnextp)
                     79:        doentry(ep);
                     80: }
                     81: 
                     82: /* ROUTINES CALLED WHEN ENCOUNTERING ENTRY POINTS */
                     83: 
                     84: /* Main program or Block data */
                     85: 
                     86: startproc(progname, class)
                     87: struct Extsym * progname;
                     88: int class;
                     89: {
                     90: register struct Entrypoint *p;
                     91: char *ftnname();
                     92: 
                     93: p = ALLOC(Entrypoint);
                     94: if(class == CLMAIN)
                     95:        puthead("MAIN__", CLMAIN);
                     96: else
                     97:        puthead(CNULL, CLBLOCK);
                     98: if(class == CLMAIN)
                     99:        newentry( mkname(5, "MAIN_") );
                    100: p->entryname = progname;
                    101: p->entrylabel = newlabel();
                    102: entries = p;
                    103: 
                    104: procclass = class;
                    105: retlabel = newlabel();
                    106: fprintf(diagfile, "   %s", (class==CLMAIN ? "MAIN" : "BLOCK DATA") );
                    107: if(progname)
                    108:        fprintf(diagfile, " %s", nounder(XL, procname = progname->extname) );
                    109: fprintf(diagfile, ":\n");
                    110: #ifdef SDB
                    111: if(sdbflag && class==CLMAIN)
                    112:        {
                    113:        prstab("MAIN_", N_BFUN, lineno, ftnname(STGEXT, "MAIN__"));
                    114: #if NOTDEF
                    115:        p2pass( stabline("MAIN_", N_FNAME, 0, 0) );
                    116: #endif
                    117:        if(progname)
                    118:                {
                    119:                prstab(nounder(XL,progname->extname), N_ENTRY, lineno,
                    120:                        ftnname(STGEXT, progname->extname));
                    121: /*             p2pass(stabline(nounder(XL,progname->extname),N_FNAME,0,0));    */
                    122:                }
                    123:        }
                    124: #endif
                    125: }
                    126: 
                    127: /* subroutine or function statement */
                    128: 
                    129: struct Extsym *newentry(v)
                    130: register Namep v;
                    131: {
                    132: register struct Extsym *p;
                    133: 
                    134: p = mkext( varunder(VL, v->varname) );
                    135: 
                    136: if(p==NULL || p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) )
                    137:        {
                    138:        if(p == 0)
                    139:                dclerr("invalid entry name", v);
                    140:        else    dclerr("external name already used", v);
                    141:        return(0);
                    142:        }
                    143: v->vstg = STGAUTO;
                    144: v->vprocclass = PTHISPROC;
                    145: v->vclass = CLPROC;
                    146: p->extstg = STGEXT;
                    147: p->extinit = YES;
                    148: return(p);
                    149: }
                    150: 
                    151: 
                    152: entrypt(class, type, length, entry, args)
                    153: int class, type;
                    154: ftnint length;
                    155: struct Extsym *entry;
                    156: chainp args;
                    157: {
                    158: register Namep q;
                    159: register struct Entrypoint *p, *ep;
                    160: 
                    161: if(class != CLENTRY)
                    162:        puthead( varstr(XL, procname = entry->extname), class);
                    163: if(class == CLENTRY)
                    164:        fprintf(diagfile, "       entry ");
                    165: fprintf(diagfile, "   %s:\n", nounder(XL, entry->extname));
                    166: q = mkname(VL, nounder(XL,entry->extname) );
                    167: 
                    168: if( (type = lengtype(type, (int) length)) != TYCHAR)
                    169:        length = 0;
                    170: if(class == CLPROC)
                    171:        {
                    172:        procclass = CLPROC;
                    173:        proctype = type;
                    174:        procleng = length;
                    175: 
                    176:        retlabel = newlabel();
                    177:        if(type == TYSUBR)
                    178:                ret0label = newlabel();
                    179:        }
                    180: 
                    181: p = ALLOC(Entrypoint);
                    182: 
                    183: if(entries)    /* put new block at end of entries list */
                    184:        {
                    185:        for(ep = entries; ep->entnextp; ep = ep->entnextp)
                    186:                ;
                    187:        ep->entnextp = p;
                    188:        }
                    189: else
                    190:        entries = p;
                    191: 
                    192: p->entryname = entry;
                    193: p->arglist = args;
                    194: p->entrylabel = newlabel();
                    195: p->enamep = q;
                    196: 
                    197: #ifdef SDB
                    198: if(sdbflag)
                    199:        {
                    200:        prstab(nounder(XL, entry->extname),
                    201:                (class==CLENTRY ? N_ENTRY : N_BFUN),
                    202:                lineno, ftnname(STGEXT, entry->extname));
                    203:        if(class != CLENTRY) {
                    204: #if NOTDEF
                    205:                p2pass( stabline( nounder(XL,entry->extname), N_FNAME, 0, 0) );
                    206: #endif
                    207:                }
                    208:        }
                    209: #endif
                    210: 
                    211: if(class == CLENTRY)
                    212:        {
                    213:        class = CLPROC;
                    214:        if(proctype == TYSUBR)
                    215:                type = TYSUBR;
                    216:        }
                    217: 
                    218: q->vclass = class;
                    219: q->vprocclass = PTHISPROC;
                    220: settype(q, type, (int) length);
                    221: /* hold all initial entry points till end of declarations */
                    222: if(parstate >= INDATA)
                    223:        doentry(p);
                    224: }
                    225: 
                    226: /* generate epilogs */
                    227: 
                    228: LOCAL epicode()
                    229: {
                    230: register int i;
                    231: 
                    232: if(procclass==CLPROC)
                    233:        {
                    234:        if(proctype==TYSUBR)
                    235:                {
                    236:                putlabel(ret0label);
                    237:                if(substars)
                    238:                        putforce(TYINT, ICON(0) );
                    239:                putlabel(retlabel);
                    240:                goret(TYSUBR);
                    241:                }
                    242:        else    {
                    243:                putlabel(retlabel);
                    244:                if(multitype)
                    245:                        {
                    246:                        typeaddr = autovar(1, TYADDR, PNULL);
                    247:                        putbranch( cpexpr(typeaddr) );
                    248:                        for(i = 0; i < NTYPES ; ++i)
                    249:                                if(rtvlabel[i] != 0)
                    250:                                        {
                    251:                                        putlabel(rtvlabel[i]);
                    252:                                        retval(i);
                    253:                                        }
                    254:                        }
                    255:                else
                    256:                        retval(proctype);
                    257:                }
                    258:        }
                    259: 
                    260: else if(procclass != CLBLOCK)
                    261:        {
                    262:        putlabel(retlabel);
                    263:        goret(TYSUBR);
                    264:        }
                    265: }
                    266: 
                    267: 
                    268: /* generate code to return value of type  t */
                    269: 
                    270: LOCAL retval(t)
                    271: register int t;
                    272: {
                    273: register Addrp p;
                    274: 
                    275: switch(t)
                    276:        {
                    277:        case TYCHAR:
                    278:        case TYCOMPLEX:
                    279:        case TYDCOMPLEX:
                    280:                break;
                    281: 
                    282:        case TYLOGICAL:
                    283:                t = tylogical;
                    284:        case TYADDR:
                    285:        case TYSHORT:
                    286:        case TYLONG:
                    287:                p = (Addrp) cpexpr(retslot);
                    288:                p->vtype = t;
                    289:                putforce(t, p);
                    290:                break;
                    291: 
                    292:        case TYREAL:
                    293:        case TYDREAL:
                    294:                p = (Addrp) cpexpr(retslot);
                    295:                p->vtype = t;
                    296:                putforce(t, p);
                    297:                break;
                    298: 
                    299:        default:
                    300:                badtype("retval", t);
                    301:        }
                    302: goret(t);
                    303: }
                    304: 
                    305: 
                    306: /* Allocate extra argument array if needed. Generate prologs. */
                    307: 
                    308: LOCAL procode()
                    309: {
                    310: register struct Entrypoint *p;
                    311: Addrp argvec;
                    312: 
                    313: #if TARGET==GCOS
                    314:        argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL);
                    315: #else
                    316:        if(lastargslot>0 && nentry>1)
                    317: #if TARGET == VAX
                    318:                argvec = autovar(1 + lastargslot/SZADDR, TYADDR, PNULL);
                    319: #else
                    320:                argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL);
                    321: #endif
                    322:        else
                    323:                argvec = NULL;
                    324: #endif
                    325: 
                    326: 
                    327: #if TARGET == PDP11
                    328:        /* for the optimizer */
                    329:        if(fudgelabel)
                    330:                putlabel(fudgelabel);
                    331: #endif
                    332: 
                    333: for(p = entries ; p ; p = p->entnextp)
                    334:        prolog(p, argvec);
                    335: 
                    336: #if FAMILY == PCC
                    337:        putrbrack(procno);
                    338: #endif
                    339: 
                    340: prendproc();
                    341: }
                    342: 
                    343: /*
                    344:    manipulate argument lists (allocate argument slot positions)
                    345:  * keep track of return types and labels
                    346:  */
                    347: 
                    348: LOCAL doentry(ep)
                    349: struct Entrypoint *ep;
                    350: {
                    351: register int type;
                    352: register Namep np;
                    353: chainp p;
                    354: register Namep q;
                    355: Addrp mkarg();
                    356: 
                    357: ++nentry;
                    358: if(procclass == CLMAIN)
                    359:        {
                    360:        putlabel(ep->entrylabel);
                    361:        return;
                    362:        }
                    363: else if(procclass == CLBLOCK)
                    364:        return;
                    365: 
                    366: impldcl( np = mkname(VL, nounder(XL, ep->entryname->extname) ) );
                    367: type = np->vtype;
                    368: if(proctype == TYUNKNOWN)
                    369:        if( (proctype = type) == TYCHAR)
                    370:                procleng = (np->vleng ? np->vleng->constblock.const.ci : (ftnint) (-1));
                    371: 
                    372: if(proctype == TYCHAR)
                    373:        {
                    374:        if(type != TYCHAR)
                    375:                err("noncharacter entry of character function");
                    376:        else if( (np->vleng ? np->vleng->constblock.const.ci : (ftnint) (-1)) != procleng)
                    377:                err("mismatched character entry lengths");
                    378:        }
                    379: else if(type == TYCHAR)
                    380:        err("character entry of noncharacter function");
                    381: else if(type != proctype)
                    382:        multitype = YES;
                    383: if(rtvlabel[type] == 0)
                    384:        rtvlabel[type] = newlabel();
                    385: ep->typelabel = rtvlabel[type];
                    386: 
                    387: if(type == TYCHAR)
                    388:        {
                    389:        if(chslot < 0)
                    390:                {
                    391:                chslot = nextarg(TYADDR);
                    392:                chlgslot = nextarg(TYLENG);
                    393:                }
                    394:        np->vstg = STGARG;
                    395:        np->vardesc.varno = chslot;
                    396:        if(procleng < 0)
                    397:                np->vleng = (expptr) mkarg(TYLENG, chlgslot);
                    398:        }
                    399: else if( ISCOMPLEX(type) )
                    400:        {
                    401:        np->vstg = STGARG;
                    402:        if(cxslot < 0)
                    403:                cxslot = nextarg(TYADDR);
                    404:        np->vardesc.varno = cxslot;
                    405:        }
                    406: else if(type != TYSUBR)
                    407:        {
                    408:        if(nentry == 1)
                    409:                retslot = autovar(1, TYDREAL, PNULL);
                    410:        np->vstg = STGAUTO;
                    411:        np->voffset = retslot->memoffset->constblock.const.ci;
                    412:        }
                    413: 
                    414: for(p = ep->arglist ; p ; p = p->nextp)
                    415:        if(! (( q = (Namep) (p->datap) )->vdcldone) )
                    416:                q->vardesc.varno = nextarg(TYADDR);
                    417: 
                    418: for(p = ep->arglist ; p ; p = p->nextp)
                    419:        if(! (( q = (Namep) (p->datap) )->vdcldone) )
                    420:                {
                    421:                impldcl(q);
                    422:                q->vdcldone = YES;
                    423: #ifdef SDB
                    424:                if(sdbflag)
                    425:                        prstab(varstr(VL,q->varname), N_PSYM,
                    426:                                stabtype(q),
                    427:                                convic(q->vardesc.varno + ARGOFFSET) );
                    428: #endif
                    429:                if(q->vtype == TYCHAR)
                    430:                        {
                    431:                        if(q->vleng == NULL)    /* character*(*) */
                    432:                                q->vleng = (expptr)
                    433:                                                mkarg(TYLENG, nextarg(TYLENG) );
                    434:                        else if(nentry == 1)
                    435:                                nextarg(TYLENG);
                    436:                        }
                    437:                else if(q->vclass==CLPROC && nentry==1)
                    438:                        nextarg(TYLENG) ;
                    439:                }
                    440: 
                    441: putlabel(ep->entrylabel);
                    442: }
                    443: 
                    444: 
                    445: 
                    446: LOCAL nextarg(type)
                    447: int type;
                    448: {
                    449: int k;
                    450: k = lastargslot;
                    451: lastargslot += typesize[type];
                    452: return(k);
                    453: }
                    454: 
                    455: /* generate variable references */
                    456: 
                    457: LOCAL dobss()
                    458: {
                    459: register struct Hashentry *p;
                    460: register Namep q;
                    461: register int i;
                    462: int align;
                    463: ftnint leng, iarrl;
                    464: char *memname();
                    465: int qstg, qclass, qtype;
                    466: char buf[20];
                    467: 
                    468: pruse(asmfile, USEBSS);
                    469: 
                    470: for(p = hashtab ; p<lasthash ; ++p)
                    471:     if(q = p->varp)
                    472:        {
                    473:        qstg = q->vstg;
                    474:        qtype = q->vtype;
                    475:        qclass = q->vclass;
                    476: 
                    477: #ifdef SDB
                    478:                 if(sdbflag && qclass==CLVAR) switch(qstg)
                    479:                         {
                    480:                         case STGAUTO:
                    481:                                 prstab(varstr(VL,q->varname), N_LSYM,
                    482:                                         stabtype(q),
                    483:                                         convic( - q->voffset)) ;
                    484:                                 prstleng(q, iarrlen(q));
                    485:                                 break;
                    486: 
                    487:                         case STGBSS:
                    488:                                 prstab(varstr(VL,q->varname), N_LCSYM,
                    489:                                         stabtype(q),
                    490:                                         memname(qstg,q->vardesc.varno) );
                    491:                                 prstleng(q, iarrlen(q));
                    492:                                 break;
                    493: 
                    494:                         case STGINIT:
                    495:                                 prstab(varstr(VL,q->varname), N_STSYM,
                    496:                                         stabtype(q),
                    497:                                         memname(qstg,q->vardesc.varno) );
                    498:                                 prstleng(q, iarrlen(q));
                    499:                                 break;
                    500:                         }
                    501: #endif
                    502: 
                    503:        if( (qclass==CLUNKNOWN && qstg!=STGARG) ||
                    504:            (qclass==CLVAR && qstg==STGUNKNOWN) )
                    505:                warn1("local variable %s never used", varstr(VL,q->varname) );
                    506:        else if(qclass==CLVAR && qstg==STGBSS)
                    507:                {
                    508:                align = (qtype==TYCHAR ? ALILONG : typealign[qtype]);
                    509:                if(bssleng % align != 0)
                    510:                        {
                    511:                        bssleng = roundup(bssleng, align);
                    512:                        preven(align);
                    513:                        }
                    514:                prlocvar(memname(STGBSS,q->vardesc.varno), iarrl = iarrlen(q) );
                    515:                bssleng += iarrl;
                    516:                }
                    517:        else if(qclass==CLPROC && q->vprocclass==PEXTERNAL && qstg!=STGARG)
                    518:                mkext(varunder(VL, q->varname)) ->extstg = STGEXT;
                    519: 
                    520:        if(qclass==CLVAR && qstg!=STGARG)
                    521:                {
                    522:                if(q->vdim && !ISICON(q->vdim->nelt) )
                    523:                        dclerr("adjustable dimension on non-argument", q);
                    524:                if(qtype==TYCHAR && (q->vleng==NULL || !ISICON(q->vleng)))
                    525:                        dclerr("adjustable leng on nonargument", q);
                    526:                }
                    527:        }
                    528: 
                    529: for(i = 0 ; i < nequiv ; ++i)
                    530:        if(eqvclass[i].eqvinit==NO && (leng = eqvclass[i].eqvleng)!=0 )
                    531:                {
                    532:                bssleng = roundup(bssleng, ALIDOUBLE);
                    533:                preven(ALIDOUBLE);
                    534:                prlocvar( memname(STGEQUIV, i), leng);
                    535:                bssleng += leng;
                    536:                }
                    537: }
                    538: 
                    539: 
                    540: 
                    541: donmlist()
                    542: {
                    543: register struct Hashentry *p;
                    544: register Namep q;
                    545: 
                    546: pruse(asmfile, USEINIT);
                    547: 
                    548: for(p=hashtab; p<lasthash; ++p)
                    549:        if( (q = p->varp) && q->vclass==CLNAMELIST)
                    550:                namelist(q);
                    551: }
                    552: 
                    553: 
                    554: doext()
                    555: {
                    556: struct Extsym *p;
                    557: 
                    558: for(p = extsymtab ; p<nextext ; ++p)
                    559:        prext( varstr(XL, p->extname), p->maxleng, p->extinit);
                    560: }
                    561: 
                    562: 
                    563: 
                    564: 
                    565: ftnint iarrlen(q)
                    566: register Namep q;
                    567: {
                    568: ftnint leng;
                    569: 
                    570: leng = typesize[q->vtype];
                    571: if(leng <= 0)
                    572:        return(-1);
                    573: if(q->vdim)
                    574:        if( ISICON(q->vdim->nelt) )
                    575:                leng *= q->vdim->nelt->constblock.const.ci;
                    576:        else    return(-1);
                    577: if(q->vleng)
                    578:        if( ISICON(q->vleng) )
                    579:                leng *= q->vleng->constblock.const.ci;
                    580:        else    return(-1);
                    581: return(leng);
                    582: }
                    583: 
                    584: /* This routine creates a static block representing the namelist.
                    585:    An equivalent declaration of the structure produced is:
                    586:        struct namelist
                    587:                {
                    588:                char namelistname[16];
                    589:                struct namelistentry
                    590:                        {
                    591:                        char varname[16];
                    592:                        char *varaddr;
                    593:                        int type; # negative means -type= number of chars
                    594:                        struct dimensions *dimp; # null means scalar
                    595:                        } names[];
                    596:                };
                    597: 
                    598:        struct dimensions
                    599:                {
                    600:                int numberofdimensions;
                    601:                int numberofelements
                    602:                int baseoffset;
                    603:                int span[numberofdimensions];
                    604:                };
                    605:    where the namelistentry list terminates with a null varname
                    606:    If dimp is not null, then the corner element of the array is at
                    607:    varaddr.  However,  the element with subscripts (i1,...,in) is at
                    608:    varaddr - dimp->baseoffset + sizeoftype * (i1+span[0]*(i2+span[1]*...)
                    609: */
                    610: 
                    611: namelist(np)
                    612: Namep np;
                    613: {
                    614: register chainp q;
                    615: register Namep v;
                    616: register struct Dimblock *dp;
                    617: char *memname();
                    618: int type, dimno, dimoffset;
                    619: flag bad;
                    620: 
                    621: 
                    622: preven(ALILONG);
                    623: fprintf(asmfile, LABELFMT, memname(STGINIT, np->vardesc.varno));
                    624: putstr(asmfile, varstr(VL, np->varname), 16);
                    625: dimno = ++lastvarno;
                    626: dimoffset = 0;
                    627: bad = NO;
                    628: 
                    629: for(q = np->varxptr.namelist ; q ; q = q->nextp)
                    630:        {
                    631:        vardcl( v = (Namep) (q->datap) );
                    632:        type = v->vtype;
                    633:        if( ONEOF(v->vstg, MSKSTATIC) )
                    634:                {
                    635:                preven(ALILONG);
                    636:                putstr(asmfile, varstr(VL,v->varname), 16);
                    637:                praddr(asmfile, v->vstg, v->vardesc.varno, v->voffset);
                    638:                prconi(asmfile, TYINT,
                    639:                        type==TYCHAR ?
                    640:                            -(v->vleng->constblock.const.ci) : (ftnint) type);
                    641:                if(v->vdim)
                    642:                        {
                    643:                        praddr(asmfile, STGINIT, dimno, (ftnint)dimoffset);
                    644:                        dimoffset += 3 + v->vdim->ndim;
                    645:                        }
                    646:                else
                    647:                        praddr(asmfile, STGNULL,0,(ftnint) 0);
                    648:                }
                    649:        else
                    650:                {
                    651:                dclerr("may not appear in namelist", v);
                    652:                bad = YES;
                    653:                }
                    654:        }
                    655: 
                    656: if(bad)
                    657:        return;
                    658: 
                    659: putstr(asmfile, "", 16);
                    660: 
                    661: if(dimoffset > 0)
                    662:        {
                    663:        fprintf(asmfile, LABELFMT, memname(STGINIT,dimno));
                    664:        for(q = np->varxptr.namelist ; q ; q = q->nextp)
                    665:                if(dp = q->datap->nameblock.vdim)
                    666:                        {
                    667:                        int i;
                    668:                        prconi(asmfile, TYINT, (ftnint) (dp->ndim) );
                    669:                        prconi(asmfile, TYINT,
                    670:                                (ftnint) (dp->nelt->constblock.const.ci) );
                    671:                        prconi(asmfile, TYINT,
                    672:                                (ftnint) (dp->baseoffset->constblock.const.ci));
                    673:                        for(i=0; i<dp->ndim ; ++i)
                    674:                                prconi(asmfile, TYINT,
                    675:                                        dp->dims[i].dimsize->constblock.const.ci);
                    676:                        }
                    677:        }
                    678: 
                    679: }
                    680: 
                    681: LOCAL docommon()
                    682: {
                    683: register struct Extsym *p;
                    684: register chainp q;
                    685: struct Dimblock *t;
                    686: expptr neltp;
                    687: register Namep v;
                    688: ftnint size;
                    689: int type;
                    690: 
                    691: for(p = extsymtab ; p<nextext ; ++p)
                    692:        if(p->extstg==STGCOMMON)
                    693:                {
                    694: #ifdef SDB
                    695:                if(sdbflag)
                    696:                        prstab(varstr(XL, p->extname), N_BCOMM, 0,
                    697:                                ftnname(STGCOMMON, p->extname));
                    698: #endif
                    699:                for(q = p->extp ; q ; q = q->nextp)
                    700:                        {
                    701:                        v = (Namep) (q->datap);
                    702:                        if(v->vdcldone == NO)
                    703:                                vardcl(v);
                    704:                        type = v->vtype;
                    705:                        if(p->extleng % typealign[type] != 0)
                    706:                                {
                    707:                                dclerr("common alignment", v);
                    708:                                p->extleng = roundup(p->extleng, typealign[type]);
                    709:                                }
                    710:                        v->voffset = p->extleng;
                    711:                        v->vardesc.varno = p - extsymtab;
                    712:                        if(type == TYCHAR)
                    713:                                size = v->vleng->constblock.const.ci;
                    714:                        else    size = typesize[type];
                    715:                        if(t = v->vdim)
                    716:                                if( (neltp = t->nelt) && ISCONST(neltp) )
                    717:                                        size *= neltp->constblock.const.ci;
                    718:                                else
                    719:                                        dclerr("adjustable array in common", v);
                    720:                        p->extleng += size;
                    721: #ifdef SDB
                    722:                        if(sdbflag)
                    723:                                {
                    724:                                prcomssym(v, p);
                    725:                                prstleng(v, size);
                    726:                                }
                    727: #endif
                    728:                        }
                    729: 
                    730:                frchain( &(p->extp) );
                    731: #ifdef SDB
                    732:                if(sdbflag)
                    733:                        prstab(varstr(XL,p->extname), N_ECOMM, 0, ftnname(STGCOMMON, p->extname));
                    734: #endif
                    735:                }
                    736: }
                    737: 
                    738: 
                    739: 
                    740: 
                    741: 
                    742: LOCAL docomleng()
                    743: {
                    744: register struct Extsym *p;
                    745: 
                    746: for(p = extsymtab ; p < nextext ; ++p)
                    747:        if(p->extstg == STGCOMMON)
                    748:                {
                    749:                if(p->maxleng!=0 && p->extleng!=0 && p->maxleng!=p->extleng
                    750:                    && !eqn(XL,"_BLNK__ ",p->extname) )
                    751:                        warn1("incompatible lengths for common block %s",
                    752:                                nounder(XL, p->extname) );
                    753:                if(p->maxleng < p->extleng)
                    754:                        p->maxleng = p->extleng;
                    755:                p->extleng = 0;
                    756:        }
                    757: }
                    758: 
                    759: 
                    760: 
                    761: 
                    762: /* ROUTINES DEALING WITH AUTOMATIC AND TEMPORARY STORAGE */
                    763: 
                    764: frtemp(p)
                    765: Addrp p;
                    766: {
                    767: /* restore clobbered character string lengths */
                    768: if(p->vtype==TYCHAR && p->varleng!=0)
                    769:        {
                    770:        frexpr(p->vleng);
                    771:        p->vleng = ICON(p->varleng);
                    772:        }
                    773: 
                    774: /* put block on chain of temps to be reclaimed */
                    775: holdtemps = mkchain(p, holdtemps);
                    776: }
                    777: 
                    778: 
                    779: 
                    780: 
                    781: /* allocate an automatic variable slot */
                    782: 
                    783: Addrp autovar(nelt, t, lengp)
                    784: register int nelt, t;
                    785: expptr lengp;
                    786: {
                    787: ftnint leng;
                    788: register Addrp q;
                    789: 
                    790: if(t == TYCHAR)
                    791:        if( ISICON(lengp) )
                    792:                leng = lengp->constblock.const.ci;
                    793:        else    {
                    794:                fatal("automatic variable of nonconstant length");
                    795:                }
                    796: else
                    797:        leng = typesize[t];
                    798: autoleng = roundup( autoleng, typealign[t]);
                    799: 
                    800: q = ALLOC(Addrblock);
                    801: q->tag = TADDR;
                    802: q->vtype = t;
                    803: if(t == TYCHAR)
                    804:        {
                    805:        q->vleng = ICON(leng);
                    806:        q->varleng = leng;
                    807:        }
                    808: q->vstg = STGAUTO;
                    809: q->ntempelt = nelt;
                    810: #if TARGET==PDP11 || TARGET==VAX
                    811:        /* stack grows downward */
                    812:        autoleng += nelt*leng;
                    813:        q->memoffset = ICON( - autoleng );
                    814: #else
                    815:        q->memoffset = ICON( autoleng );
                    816:        autoleng += nelt*leng;
                    817: #endif
                    818: 
                    819: return(q);
                    820: }
                    821: 
                    822: 
                    823: Addrp mktmpn(nelt, type, lengp)
                    824: int nelt;
                    825: register int type;
                    826: expptr lengp;
                    827: {
                    828: ftnint leng;
                    829: chainp p, oldp;
                    830: register Addrp q;
                    831: 
                    832: if(type==TYUNKNOWN || type==TYERROR)
                    833:        badtype("mktmpn", type);
                    834: 
                    835: if(type==TYCHAR)
                    836:        if( ISICON(lengp) )
                    837:                leng = lengp->constblock.const.ci;
                    838:        else    {
                    839:                err("adjustable length");
                    840:                return( errnode() );
                    841:                }
                    842: /*
                    843:  * if an temporary of appropriate shape is on the templist,
                    844:  * remove it from the list and return it
                    845:  */
                    846: 
                    847: for(oldp=CHNULL, p=templist  ;  p  ;  oldp=p, p=p->nextp)
                    848:        {
                    849:        q = (Addrp) (p->datap);
                    850:        if(q->vtype==type && q->ntempelt==nelt &&
                    851:            (type!=TYCHAR || q->vleng->constblock.const.ci==leng) )
                    852:                {
                    853:                if(oldp)
                    854:                        oldp->nextp = p->nextp;
                    855:                else
                    856:                        templist = p->nextp;
                    857:                free( (charptr) p);
                    858:                return(q);
                    859:                }
                    860:        }
                    861: q = autovar(nelt, type, lengp);
                    862: q->istemp = YES;
                    863: return(q);
                    864: }
                    865: 
                    866: 
                    867: 
                    868: 
                    869: Addrp mktemp(type, lengp)
                    870: int type;
                    871: expptr lengp;
                    872: {
                    873: return( mktmpn(1,type,lengp) );
                    874: }
                    875: 
                    876: /* VARIOUS ROUTINES FOR PROCESSING DECLARATIONS */
                    877: 
                    878: struct Extsym *comblock(len, s)
                    879: register int len;
                    880: register char *s;
                    881: {
                    882: struct Extsym *p;
                    883: 
                    884: if(len == 0)
                    885:        {
                    886:        s = BLANKCOMMON;
                    887:        len = strlen(s);
                    888:        }
                    889: p = mkext( varunder(len, s) );
                    890: if(p->extstg == STGUNKNOWN)
                    891:        p->extstg = STGCOMMON;
                    892: else if(p->extstg != STGCOMMON)
                    893:        {
                    894:        errstr("%s cannot be a common block name", s);
                    895:        return(0);
                    896:        }
                    897: 
                    898: return( p );
                    899: }
                    900: 
                    901: 
                    902: incomm(c, v)
                    903: struct Extsym *c;
                    904: Namep v;
                    905: {
                    906: if(v->vstg != STGUNKNOWN)
                    907:        dclerr("incompatible common declaration", v);
                    908: else
                    909:        {
                    910:        v->vstg = STGCOMMON;
                    911:        c->extp = hookup(c->extp, mkchain(v,CHNULL) );
                    912:        }
                    913: }
                    914: 
                    915: 
                    916: 
                    917: 
                    918: settype(v, type, length)
                    919: register Namep  v;
                    920: register int type;
                    921: register int length;
                    922: {
                    923: if(type == TYUNKNOWN)
                    924:        return;
                    925: 
                    926: if(type==TYSUBR && v->vtype!=TYUNKNOWN && v->vstg==STGARG)
                    927:        {
                    928:        v->vtype = TYSUBR;
                    929:        frexpr(v->vleng);
                    930:        }
                    931: else if(type < 0)      /* storage class set */
                    932:        {
                    933:        if(v->vstg == STGUNKNOWN)
                    934:                v->vstg = - type;
                    935:        else if(v->vstg != -type)
                    936:                dclerr("incompatible storage declarations", v);
                    937:        }
                    938: else if(v->vtype == TYUNKNOWN)
                    939:        {
                    940:        if( (v->vtype = lengtype(type, length))==TYCHAR && length>=0)
                    941:                v->vleng = ICON(length);
                    942:        }
                    943: else if(v->vtype!=type || (type==TYCHAR && v->vleng->constblock.const.ci!=length) )
                    944:        dclerr("incompatible type declarations", v);
                    945: }
                    946: 
                    947: 
                    948: 
                    949: 
                    950: 
                    951: lengtype(type, length)
                    952: register int type;
                    953: register int length;
                    954: {
                    955: switch(type)
                    956:        {
                    957:        case TYREAL:
                    958:                if(length == 8)
                    959:                        return(TYDREAL);
                    960:                if(length == 4)
                    961:                        goto ret;
                    962:                break;
                    963: 
                    964:        case TYCOMPLEX:
                    965:                if(length == 16)
                    966:                        return(TYDCOMPLEX);
                    967:                if(length == 8)
                    968:                        goto ret;
                    969:                break;
                    970: 
                    971:        case TYSHORT:
                    972:        case TYDREAL:
                    973:        case TYDCOMPLEX:
                    974:        case TYCHAR:
                    975:        case TYUNKNOWN:
                    976:        case TYSUBR:
                    977:        case TYERROR:
                    978:                goto ret;
                    979: 
                    980:        case TYLOGICAL:
                    981:                if(length == typesize[TYLOGICAL])
                    982:                        goto ret;
                    983:                break;
                    984: 
                    985:        case TYLONG:
                    986:                if(length == 0)
                    987:                        return(tyint);
                    988:                if(length == 2)
                    989:                        return(TYSHORT);
                    990:                if(length == 4)
                    991:                        goto ret;
                    992:                break;
                    993:        default:
                    994:                badtype("lengtype", type);
                    995:        }
                    996: 
                    997: if(length != 0)
                    998:        err("incompatible type-length combination");
                    999: 
                   1000: ret:
                   1001:        return(type);
                   1002: }
                   1003: 
                   1004: 
                   1005: 
                   1006: 
                   1007: 
                   1008: setintr(v)
                   1009: register Namep  v;
                   1010: {
                   1011: register int k;
                   1012: 
                   1013: if(v->vstg == STGUNKNOWN)
                   1014:        v->vstg = STGINTR;
                   1015: else if(v->vstg!=STGINTR)
                   1016:        dclerr("incompatible use of intrinsic function", v);
                   1017: if(v->vclass==CLUNKNOWN)
                   1018:        v->vclass = CLPROC;
                   1019: if(v->vprocclass == PUNKNOWN)
                   1020:        v->vprocclass = PINTRINSIC;
                   1021: else if(v->vprocclass != PINTRINSIC)
                   1022:        dclerr("invalid intrinsic declaration", v);
                   1023: if(k = intrfunct(v->varname))
                   1024:        v->vardesc.varno = k;
                   1025: else
                   1026:        dclerr("unknown intrinsic function", v);
                   1027: }
                   1028: 
                   1029: 
                   1030: 
                   1031: setext(v)
                   1032: register Namep  v;
                   1033: {
                   1034: if(v->vclass == CLUNKNOWN)
                   1035:        v->vclass = CLPROC;
                   1036: else if(v->vclass != CLPROC)
                   1037:        dclerr("invalid external declaration", v);
                   1038: 
                   1039: if(v->vprocclass == PUNKNOWN)
                   1040:        v->vprocclass = PEXTERNAL;
                   1041: else if(v->vprocclass != PEXTERNAL)
                   1042:        dclerr("invalid external declaration", v);
                   1043: }
                   1044: 
                   1045: 
                   1046: 
                   1047: 
                   1048: /* create dimensions block for array variable */
                   1049: 
                   1050: setbound(v, nd, dims)
                   1051: register Namep  v;
                   1052: int nd;
                   1053: struct { expptr lb, ub; } dims[ ];
                   1054: {
                   1055: register expptr q, t;
                   1056: register struct Dimblock *p;
                   1057: int i;
                   1058: 
                   1059: if(v->vclass == CLUNKNOWN)
                   1060:        v->vclass = CLVAR;
                   1061: else if(v->vclass != CLVAR)
                   1062:        {
                   1063:        dclerr("only variables may be arrays", v);
                   1064:        return;
                   1065:        }
                   1066: 
                   1067: v->vdim = p = (struct Dimblock *)
                   1068:                ckalloc( sizeof(int) + (3+2*nd)*sizeof(expptr) );
                   1069: p->ndim = nd;
                   1070: p->nelt = ICON(1);
                   1071: 
                   1072: for(i=0 ; i<nd ; ++i)
                   1073:        {
                   1074:        if( (q = dims[i].ub) == NULL)
                   1075:                {
                   1076:                if(i == nd-1)
                   1077:                        {
                   1078:                        frexpr(p->nelt);
                   1079:                        p->nelt = NULL;
                   1080:                        }
                   1081:                else
                   1082:                        err("only last bound may be asterisk");
                   1083:                p->dims[i].dimsize = ICON(1);;
                   1084:                p->dims[i].dimexpr = NULL;
                   1085:                }
                   1086:        else
                   1087:                {
                   1088:                if(dims[i].lb)
                   1089:                        {
                   1090:                        q = mkexpr(OPMINUS, q, cpexpr(dims[i].lb));
                   1091:                        q = mkexpr(OPPLUS, q, ICON(1) );
                   1092:                        }
                   1093:                if( ISCONST(q) )
                   1094:                        {
                   1095:                        p->dims[i].dimsize = q;
                   1096:                        p->dims[i].dimexpr = (expptr) PNULL;
                   1097:                        }
                   1098:                else    {
                   1099:                        p->dims[i].dimsize = (expptr) autovar(1, tyint, PNULL);
                   1100:                        p->dims[i].dimexpr = q;
                   1101:                        }
                   1102:                if(p->nelt)
                   1103:                        p->nelt = mkexpr(OPSTAR, p->nelt,
                   1104:                                        cpexpr(p->dims[i].dimsize) );
                   1105:                }
                   1106:        }
                   1107: 
                   1108: q = dims[nd-1].lb;
                   1109: if(q == NULL)
                   1110:        q = ICON(1);
                   1111: 
                   1112: for(i = nd-2 ; i>=0 ; --i)
                   1113:        {
                   1114:        t = dims[i].lb;
                   1115:        if(t == NULL)
                   1116:                t = ICON(1);
                   1117:        if(p->dims[i].dimsize)
                   1118:                q = mkexpr(OPPLUS, t, mkexpr(OPSTAR, cpexpr(p->dims[i].dimsize), q) );
                   1119:        }
                   1120: 
                   1121: if( ISCONST(q) )
                   1122:        {
                   1123:        p->baseoffset = q;
                   1124:        p->basexpr = NULL;
                   1125:        }
                   1126: else
                   1127:        {
                   1128:        p->baseoffset = (expptr) autovar(1, tyint, PNULL);
                   1129:        p->basexpr = q;
                   1130:        }
                   1131: }

unix.superglobalmegacorp.com

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