|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.