1 /* 2 * Copyright (c) 1980 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 static char sccsid[] = "@(#)proc.c 5.2 (Berkeley) 6/9/85"; 9 #endif not lint 10 11 /* 12 * proc.c 13 * 14 * Routines for handling procedures, f77 compiler, pass 1. 15 * 16 * University of Utah CS Dept modification history: 17 * 18 * $Header: proc.c,v 3.11 85/06/04 03:45:29 donn Exp $ 19 * $Log: proc.c,v $ 20 * Revision 3.11 85/06/04 03:45:29 donn 21 * Changed retval() to recognize that a function declaration might have 22 * bombed out earlier, leaving an error node behind... 23 * 24 * Revision 3.10 85/03/08 23:13:06 donn 25 * Finally figured out why function calls and array elements are not legal 26 * dummy array dimension declarator elements. Hacked safedim() to stop 'em. 27 * 28 * Revision 3.9 85/02/02 00:26:10 donn 29 * Removed the call to entrystab() in enddcl() -- this was redundant (it was 30 * also done in startproc()) and confusing to dbx to boot. 31 * 32 * Revision 3.8 85/01/14 04:21:53 donn 33 * Added changes to implement Jerry's '-q' option. 34 * 35 * Revision 3.7 85/01/11 21:10:35 donn 36 * In conjunction with other changes to implement SAVE statements, function 37 * nameblocks were changed to make it appear that they are 'saved' too -- 38 * this arranges things so that function return values are forced out of 39 * register before a return. 40 * 41 * Revision 3.6 84/12/10 19:27:20 donn 42 * comblock() signals an illegal common block name by returning a null pointer, 43 * but incomm() wasn't able to handle it, leading to core dumps. I put the 44 * fix in incomm() to pick up null common blocks. 45 * 46 * Revision 3.5 84/11/21 20:33:31 donn 47 * It seems that I/O elements are treated as character strings so that their 48 * length can be passed to the I/O routines... Unfortunately the compiler 49 * assumes that no temporaries can be of type CHARACTER and casually tosses 50 * length and type info away when removing TEMP blocks. This has been fixed... 51 * 52 * Revision 3.4 84/11/05 22:19:30 donn 53 * Fixed a silly bug in the last fix. 54 * 55 * Revision 3.3 84/10/29 08:15:23 donn 56 * Added code to check the type and shape of subscript declarations, 57 * per Jerry Berkman's suggestion. 58 * 59 * Revision 3.2 84/10/29 05:52:07 donn 60 * Added change suggested by Jerry Berkman to report an error when an array 61 * is redimensioned. 62 * 63 * Revision 3.1 84/10/13 02:12:31 donn 64 * Merged Jerry Berkman's version into mine. 65 * 66 * Revision 2.1 84/07/19 12:04:09 donn 67 * Changed comment headers for UofU. 68 * 69 * Revision 1.6 84/07/19 11:32:15 donn 70 * Incorporated fix to setbound() to detect backward array subscript limits. 71 * The fix is by Bob Corbett, donated by Jerry Berkman. 72 * 73 * Revision 1.5 84/07/18 18:25:50 donn 74 * Fixed problem with doentry() where a placeholder for a return value 75 * was not allocated if the first entry didn't require one but a later 76 * entry did. 77 * 78 * Revision 1.4 84/05/24 20:52:09 donn 79 * Installed firewall #ifdef around the code that recycles stack temporaries, 80 * since it seems to be broken and lacks a good fix for the time being. 81 * 82 * Revision 1.3 84/04/16 09:50:46 donn 83 * Fixed mkargtemp() so that it only passes back a copy of a temporary, keeping 84 * the original for its own use. This fixes a set of bugs that are caused by 85 * elements in the argtemplist getting stomped on. 86 * 87 * Revision 1.2 84/02/28 21:12:58 donn 88 * Added Berkeley changes for subroutine call argument temporaries fix. 89 * 90 */ 91 92 #include "defs.h" 93 94 #ifdef SDB 95 # include <a.out.h> 96 # ifndef N_SO 97 # include <stab.h> 98 # endif 99 #endif 100 101 extern flag namesflag; 102 103 typedef 104 struct SizeList 105 { 106 struct SizeList *next; 107 ftnint size; 108 struct VarList *vars; 109 } 110 sizelist; 111 112 113 typedef 114 struct VarList 115 { 116 struct VarList *next; 117 Namep np; 118 struct Equivblock *ep; 119 } 120 varlist; 121 122 123 LOCAL sizelist *varsizes; 124 125 126 /* start a new procedure */ 127 128 newproc() 129 { 130 if(parstate != OUTSIDE) 131 { 132 execerr("missing end statement", CNULL); 133 endproc(); 134 } 135 136 parstate = INSIDE; 137 procclass = CLMAIN; /* default */ 138 } 139 140 141 142 /* end of procedure. generate variables, epilogs, and prologs */ 143 144 endproc() 145 { 146 struct Labelblock *lp; 147 148 if(parstate < INDATA) 149 enddcl(); 150 if(ctlstack >= ctls) 151 err("DO loop or BLOCK IF not closed"); 152 for(lp = labeltab ; lp < labtabend ; ++lp) 153 if(lp->stateno!=0 && lp->labdefined==NO) 154 errstr("missing statement number %s", convic(lp->stateno) ); 155 156 if (optimflag) 157 optimize(); 158 159 outiodata(); 160 epicode(); 161 procode(); 162 donmlist(); 163 dobss(); 164 165 #if FAMILY == PCC 166 putbracket(); 167 #endif 168 procinit(); /* clean up for next procedure */ 169 } 170 171 172 173 /* End of declaration section of procedure. Allocate storage. */ 174 175 enddcl() 176 { 177 register struct Entrypoint *ep; 178 179 parstate = INEXEC; 180 docommon(); 181 doequiv(); 182 docomleng(); 183 for(ep = entries ; ep ; ep = ep->entnextp) { 184 doentry(ep); 185 } 186 } 187 188 /* ROUTINES CALLED WHEN ENCOUNTERING ENTRY POINTS */ 189 190 /* Main program or Block data */ 191 192 startproc(prgname, class) 193 Namep prgname; 194 int class; 195 { 196 struct Extsym *progname; 197 register struct Entrypoint *p; 198 199 if(prgname) 200 procname = prgname->varname; 201 if(namesflag == YES) { 202 fprintf(diagfile, " %s", (class==CLMAIN ? "MAIN" : "BLOCK DATA") ); 203 if(prgname) 204 fprintf(diagfile, " %s", varstr(XL, procname) ); 205 fprintf(diagfile, ":\n"); 206 } 207 208 if( prgname ) 209 progname = newentry( prgname ); 210 else 211 progname = NULL; 212 213 p = ALLOC(Entrypoint); 214 if(class == CLMAIN) 215 puthead("MAIN_", CLMAIN); 216 else 217 puthead(CNULL, CLBLOCK); 218 if(class == CLMAIN) 219 newentry( mkname(5, "MAIN") ); 220 p->entryname = progname; 221 p->entrylabel = newlabel(); 222 entries = p; 223 224 procclass = class; 225 retlabel = newlabel(); 226 #ifdef SDB 227 if(sdbflag) { 228 entrystab(p,class); 229 } 230 #endif 231 } 232 233 /* subroutine or function statement */ 234 235 struct Extsym *newentry(v) 236 register Namep v; 237 { 238 register struct Extsym *p; 239 240 p = mkext( varunder(VL, v->varname) ); 241 242 if(p==NULL || p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) ) 243 { 244 if(p == 0) 245 dclerr("invalid entry name", v); 246 else dclerr("external name already used", v); 247 return(0); 248 } 249 v->vstg = STGAUTO; 250 v->vprocclass = PTHISPROC; 251 v->vclass = CLPROC; 252 p->extstg = STGEXT; 253 p->extinit = YES; 254 return(p); 255 } 256 257 258 entrypt(class, type, length, entname, args) 259 int class, type; 260 ftnint length; 261 Namep entname; 262 chainp args; 263 { 264 struct Extsym *entry; 265 register Namep q; 266 register struct Entrypoint *p, *ep; 267 268 if(namesflag == YES) { 269 if(class == CLENTRY) 270 fprintf(diagfile, " entry "); 271 if(entname) 272 fprintf(diagfile, " %s", varstr(XL, entname->varname) ); 273 fprintf(diagfile, ":\n"); 274 } 275 276 if( entname->vclass == CLPARAM ) { 277 errstr("entry name %s used in 'parameter' statement", 278 varstr(XL, entname->varname) ); 279 return; 280 } 281 if( ((type == TYSUBR) || (class == CLENTRY && proctype == TYSUBR)) 282 && (entname->vtype != TYUNKNOWN && entname->vtype != TYSUBR) ) { 283 errstr("subroutine entry %s previously declared", 284 varstr(XL, entname->varname) ); 285 return; 286 } 287 if( (entname->vstg != STGEXT && entname->vstg != STGUNKNOWN) 288 || (entname->vdim != NULL) ) { 289 errstr("subroutine or function entry %s previously declared", 290 varstr(XL, entname->varname) ); 291 return; 292 } 293 294 if( (class == CLPROC || class == CLENTRY) && type != TYSUBR ) 295 /* arrange to save function return values */ 296 entname->vsave = YES; 297 298 entry = newentry( entname ); 299 300 if(class != CLENTRY) 301 puthead( varstr(XL, procname = entry->extname), class); 302 q = mkname(VL, nounder(XL,entry->extname) ); 303 304 if( (type = lengtype(type, (int) length)) != TYCHAR) 305 length = 0; 306 if(class == CLPROC) 307 { 308 procclass = CLPROC; 309 proctype = type; 310 procleng = length; 311 312 retlabel = newlabel(); 313 if(type == TYSUBR) 314 ret0label = newlabel(); 315 } 316 317 p = ALLOC(Entrypoint); 318 if(entries) /* put new block at end of entries list */ 319 { 320 for(ep = entries; ep->entnextp; ep = ep->entnextp) 321 ; 322 ep->entnextp = p; 323 } 324 else 325 entries = p; 326 327 p->entryname = entry; 328 p->arglist = args; 329 p->entrylabel = newlabel(); 330 p->enamep = q; 331 332 if(class == CLENTRY) 333 { 334 class = CLPROC; 335 if(proctype == TYSUBR) 336 type = TYSUBR; 337 } 338 339 q->vclass = class; 340 q->vprocclass = PTHISPROC; 341 settype(q, type, (int) length); 342 /* hold all initial entry points till end of declarations */ 343 if(parstate >= INDATA) { 344 doentry(p); 345 } 346 #ifdef SDB 347 if(sdbflag) 348 { /* may need to preserve CLENTRY here */ 349 entrystab(p,class); 350 } 351 #endif 352 } 353 354 /* generate epilogs */ 355 356 LOCAL epicode() 357 { 358 register int i; 359 360 if(procclass==CLPROC) 361 { 362 if(proctype==TYSUBR) 363 { 364 putlabel(ret0label); 365 if(substars) 366 putforce(TYINT, ICON(0) ); 367 putlabel(retlabel); 368 goret(TYSUBR); 369 } 370 else { 371 putlabel(retlabel); 372 if(multitype) 373 { 374 typeaddr = autovar(1, TYADDR, PNULL); 375 putbranch( cpexpr(typeaddr) ); 376 for(i = 0; i < NTYPES ; ++i) 377 if(rtvlabel[i] != 0) 378 { 379 putlabel(rtvlabel[i]); 380 retval(i); 381 } 382 } 383 else 384 retval(proctype); 385 } 386 } 387 388 else if(procclass != CLBLOCK) 389 { 390 putlabel(retlabel); 391 goret(TYSUBR); 392 } 393 } 394 395 396 /* generate code to return value of type t */ 397 398 LOCAL retval(t) 399 register int t; 400 { 401 register Addrp p; 402 403 switch(t) 404 { 405 case TYCHAR: 406 case TYCOMPLEX: 407 case TYDCOMPLEX: 408 break; 409 410 case TYLOGICAL: 411 t = tylogical; 412 case TYADDR: 413 case TYSHORT: 414 case TYLONG: 415 p = (Addrp) cpexpr(retslot); 416 p->vtype = t; 417 putforce(t, p); 418 break; 419 420 case TYREAL: 421 case TYDREAL: 422 p = (Addrp) cpexpr(retslot); 423 p->vtype = t; 424 putforce(t, p); 425 break; 426 427 case TYERROR: 428 return; /* someone else already complained */ 429 430 default: 431 badtype("retval", t); 432 } 433 goret(t); 434 } 435 436 437 /* Allocate extra argument array if needed. Generate prologs. */ 438 439 LOCAL procode() 440 { 441 register struct Entrypoint *p; 442 Addrp argvec; 443 444 #if TARGET==GCOS 445 argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL); 446 #else 447 if(lastargslot>0 && nentry>1) 448 #if TARGET == VAX || TARGET == TAHOE 449 argvec = autovar(1 + lastargslot/SZADDR, TYADDR, PNULL); 450 #else 451 argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL); 452 #endif 453 else 454 argvec = NULL; 455 #endif 456 457 458 #if TARGET == PDP11 459 /* for the optimizer */ 460 if(fudgelabel) 461 putlabel(fudgelabel); 462 #endif 463 464 for(p = entries ; p ; p = p->entnextp) 465 prolog(p, argvec); 466 467 #if FAMILY == PCC 468 putrbrack(procno); 469 #endif 470 471 prendproc(); 472 } 473 474 475 /* 476 manipulate argument lists (allocate argument slot positions) 477 * keep track of return types and labels 478 */ 479 480 LOCAL doentry(ep) 481 struct Entrypoint *ep; 482 { 483 register int type; 484 register Namep np; 485 chainp p; 486 register Namep q; 487 Addrp mkarg(); 488 489 ++nentry; 490 if(procclass == CLMAIN) 491 { 492 if (optimflag) 493 optbuff (SKLABEL, 0, ep->entrylabel, 0); 494 else 495 putlabel(ep->entrylabel); 496 return; 497 } 498 else if(procclass == CLBLOCK) 499 return; 500 501 impldcl( np = mkname(VL, nounder(XL, ep->entryname->extname) ) ); 502 type = np->vtype; 503 if(proctype == TYUNKNOWN) 504 if( (proctype = type) == TYCHAR) 505 procleng = (np->vleng ? np->vleng->constblock.constant.ci : (ftnint) (-1)); 506 507 if(proctype == TYCHAR) 508 { 509 if(type != TYCHAR) 510 err("noncharacter entry of character function"); 511 else if( (np->vleng ? np->vleng->constblock.constant.ci : (ftnint) (-1)) != procleng) 512 err("mismatched character entry lengths"); 513 } 514 else if(type == TYCHAR) 515 err("character entry of noncharacter function"); 516 else if(type != proctype) 517 multitype = YES; 518 if(rtvlabel[type] == 0) 519 rtvlabel[type] = newlabel(); 520 ep->typelabel = rtvlabel[type]; 521 522 if(type == TYCHAR) 523 { 524 if(chslot < 0) 525 { 526 chslot = nextarg(TYADDR); 527 chlgslot = nextarg(TYLENG); 528 } 529 np->vstg = STGARG; 530 np->vardesc.varno = chslot; 531 if(procleng < 0) 532 np->vleng = (expptr) mkarg(TYLENG, chlgslot); 533 } 534 else if( ISCOMPLEX(type) ) 535 { 536 np->vstg = STGARG; 537 if(cxslot < 0) 538 cxslot = nextarg(TYADDR); 539 np->vardesc.varno = cxslot; 540 } 541 else if(type != TYSUBR) 542 { 543 if(retslot == NULL) 544 retslot = autovar(1, TYDREAL, PNULL); 545 np->vstg = STGAUTO; 546 np->voffset = retslot->memoffset->constblock.constant.ci; 547 } 548 549 for(p = ep->arglist ; p ; p = p->nextp) 550 if(! (( q = (Namep) (p->datap) )->vdcldone) ) 551 q->vardesc.varno = nextarg(TYADDR); 552 553 for(p = ep->arglist ; p ; p = p->nextp) 554 if(! (( q = (Namep) (p->datap) )->vdcldone) ) 555 { 556 impldcl(q); 557 q->vdcldone = YES; 558 if(q->vtype == TYCHAR) 559 { 560 if(q->vleng == NULL) /* character*(*) */ 561 q->vleng = (expptr) 562 mkarg(TYLENG, nextarg(TYLENG) ); 563 else if(nentry == 1) 564 nextarg(TYLENG); 565 } 566 else if(q->vclass==CLPROC && nentry==1) 567 nextarg(TYLENG) ; 568 #ifdef SDB 569 if(sdbflag) { 570 namestab(q); 571 } 572 #endif 573 } 574 575 if (optimflag) 576 optbuff (SKLABEL, 0, ep->entrylabel, 0); 577 else 578 putlabel(ep->entrylabel); 579 } 580 581 582 583 LOCAL nextarg(type) 584 int type; 585 { 586 int k; 587 k = lastargslot; 588 lastargslot += typesize[type]; 589 return(k); 590 } 591 592 /* generate variable references */ 593 594 LOCAL dobss() 595 { 596 register struct Hashentry *p; 597 register Namep q; 598 register int i; 599 int align; 600 ftnint leng, iarrl; 601 char *memname(); 602 int qstg, qclass, qtype; 603 604 pruse(asmfile, USEBSS); 605 varsizes = NULL; 606 607 for(p = hashtab ; p<lasthash ; ++p) 608 if(q = p->varp) 609 { 610 qstg = q->vstg; 611 qtype = q->vtype; 612 qclass = q->vclass; 613 614 if( (qclass==CLUNKNOWN && qstg!=STGARG) || 615 (qclass==CLVAR && qstg==STGUNKNOWN) ) 616 warn1("local variable %s never used", varstr(VL,q->varname) ); 617 else if(qclass==CLPROC && q->vprocclass==PEXTERNAL && qstg!=STGARG) 618 mkext(varunder(VL, q->varname)) ->extstg = STGEXT; 619 620 if (qclass == CLVAR && qstg == STGBSS) 621 { 622 if (SMALLVAR(q->varsize)) 623 { 624 enlist(q->varsize, q, NULL); 625 q->inlcomm = NO; 626 } 627 else 628 { 629 if (q->init == NO) 630 { 631 preven(ALIDOUBLE); 632 prlocvar(memname(qstg, q->vardesc.varno), q->varsize); 633 q->inlcomm = YES; 634 } 635 else 636 prlocdata(memname(qstg, q->vardesc.varno), q->varsize, 637 q->vtype, q->initoffset, &(q->inlcomm)); 638 } 639 } 640 else if(qclass==CLVAR && qstg!=STGARG) 641 { 642 if(q->vdim && !ISICON(q->vdim->nelt) ) 643 dclerr("adjustable dimension on non-argument", q); 644 if(qtype==TYCHAR && (q->vleng==NULL || !ISICON(q->vleng))) 645 dclerr("adjustable leng on nonargument", q); 646 } 647 648 chkdim(q); 649 } 650 651 for (i = 0 ; i < nequiv ; ++i) 652 if ( (leng = eqvclass[i].eqvleng) != 0 ) 653 { 654 if (SMALLVAR(leng)) 655 enlist(leng, NULL, eqvclass + i); 656 else if (eqvclass[i].init == NO) 657 { 658 preven(ALIDOUBLE); 659 prlocvar(memname(STGEQUIV, i), leng); 660 eqvclass[i].inlcomm = YES; 661 } 662 else 663 prlocdata(memname(STGEQUIV, i), leng, TYDREAL, 664 eqvclass[i].initoffset, &(eqvclass[i].inlcomm)); 665 } 666 667 outlocvars(); 668 #ifdef SDB 669 if(sdbflag) { 670 for(p = hashtab ; p<lasthash ; ++p) if(q = p->varp) { 671 qstg = q->vstg; 672 qclass = q->vclass; 673 if( ONEOF(qclass, M(CLVAR))) { 674 if (! ONEOF(qstg,M(STGCOMMON)|M(STGARG) ) ) namestab(q); 675 } 676 } 677 } 678 #endif 679 680 close(vdatafile); 681 close(vchkfile); 682 unlink(vdatafname); 683 unlink(vchkfname); 684 vdatahwm = 0; 685 } 686 687 688 689 donmlist() 690 { 691 register struct Hashentry *p; 692 register Namep q; 693 694 pruse(asmfile, USEINIT); 695 696 for(p=hashtab; p<lasthash; ++p) 697 if( (q = p->varp) && q->vclass==CLNAMELIST) 698 namelist(q); 699 } 700 701 702 doext() 703 { 704 struct Extsym *p; 705 706 for(p = extsymtab ; p<nextext ; ++p) 707 prext(p); 708 } 709 710 711 712 713 ftnint iarrlen(q) 714 register Namep q; 715 { 716 ftnint leng; 717 718 leng = typesize[q->vtype]; 719 if(leng <= 0) 720 return(-1); 721 if(q->vdim) 722 if( ISICON(q->vdim->nelt) ) 723 leng *= q->vdim->nelt->constblock.constant.ci; 724 else return(-1); 725 if(q->vleng) 726 if( ISICON(q->vleng) ) 727 leng *= q->vleng->constblock.constant.ci; 728 else return(-1); 729 return(leng); 730 } 731 732 /* This routine creates a static block representing the namelist. 733 An equivalent declaration of the structure produced is: 734 struct namelist 735 { 736 char namelistname[16]; 737 struct namelistentry 738 { 739 char varname[16]; 740 char *varaddr; 741 int type; # negative means -type= number of chars 742 struct dimensions *dimp; # null means scalar 743 } names[]; 744 }; 745 746 struct dimensions 747 { 748 int numberofdimensions; 749 int numberofelements 750 int baseoffset; 751 int span[numberofdimensions]; 752 }; 753 where the namelistentry list terminates with a null varname 754 If dimp is not null, then the corner element of the array is at 755 varaddr. However, the element with subscripts (i1,...,in) is at 756 varaddr - dimp->baseoffset + sizeoftype * (i1+span[0]*(i2+span[1]*...) 757 */ 758 759 namelist(np) 760 Namep np; 761 { 762 register chainp q; 763 register Namep v; 764 register struct Dimblock *dp; 765 char *memname(); 766 int type, dimno, dimoffset; 767 flag bad; 768 769 770 preven(ALILONG); 771 fprintf(asmfile, LABELFMT, memname(STGINIT, np->vardesc.varno)); 772 putstr(asmfile, varstr(VL, np->varname), 16); 773 dimno = ++lastvarno; 774 dimoffset = 0; 775 bad = NO; 776 777 for(q = np->varxptr.namelist ; q ; q = q->nextp) 778 { 779 vardcl( v = (Namep) (q->datap) ); 780 type = v->vtype; 781 if( ONEOF(v->vstg, MSKSTATIC) ) 782 { 783 preven(ALILONG); 784 putstr(asmfile, varstr(VL,v->varname), 16); 785 praddr(asmfile, v->vstg, v->vardesc.varno, v->voffset); 786 prconi(asmfile, TYINT, 787 type==TYCHAR ? 788 -(v->vleng->constblock.constant.ci) : (ftnint) type); 789 if(v->vdim) 790 { 791 praddr(asmfile, STGINIT, dimno, (ftnint)dimoffset); 792 dimoffset += 3 + v->vdim->ndim; 793 } 794 else 795 praddr(asmfile, STGNULL,0,(ftnint) 0); 796 } 797 else 798 { 799 dclerr("may not appear in namelist", v); 800 bad = YES; 801 } 802 } 803 804 if(bad) 805 return; 806 807 putstr(asmfile, "", 16); 808 809 if(dimoffset > 0) 810 { 811 fprintf(asmfile, LABELFMT, memname(STGINIT,dimno)); 812 for(q = np->varxptr.namelist ; q ; q = q->nextp) 813 if(dp = q->datap->nameblock.vdim) 814 { 815 int i; 816 prconi(asmfile, TYINT, (ftnint) (dp->ndim) ); 817 prconi(asmfile, TYINT, 818 (ftnint) (dp->nelt->constblock.constant.ci) ); 819 prconi(asmfile, TYINT, 820 (ftnint) (dp->baseoffset->constblock.constant.ci)); 821 for(i=0; i<dp->ndim ; ++i) 822 prconi(asmfile, TYINT, 823 dp->dims[i].dimsize->constblock.constant.ci); 824 } 825 } 826 827 } 828 829 LOCAL docommon() 830 { 831 register struct Extsym *p; 832 register chainp q; 833 struct Dimblock *t; 834 expptr neltp; 835 register Namep v; 836 ftnint size; 837 int type; 838 839 for(p = extsymtab ; p<nextext ; ++p) 840 if(p->extstg==STGCOMMON) 841 { 842 #ifdef SDB 843 if(sdbflag) 844 prstab(varstr(XL,p->extname), N_BCOMM, 0, 0); 845 #endif 846 for(q = p->extp ; q ; q = q->nextp) 847 { 848 v = (Namep) (q->datap); 849 if(v->vdcldone == NO) 850 vardcl(v); 851 type = v->vtype; 852 if(p->extleng % typealign[type] != 0) 853 { 854 dclerr("common alignment", v); 855 p->extleng = roundup(p->extleng, typealign[type]); 856 } 857 v->voffset = p->extleng; 858 v->vardesc.varno = p - extsymtab; 859 if(type == TYCHAR) 860 size = v->vleng->constblock.constant.ci; 861 else size = typesize[type]; 862 if(t = v->vdim) 863 if( (neltp = t->nelt) && ISCONST(neltp) ) 864 size *= neltp->constblock.constant.ci; 865 else 866 dclerr("adjustable array in common", v); 867 p->extleng += size; 868 #ifdef SDB 869 if(sdbflag) 870 { 871 namestab(v); 872 } 873 #endif 874 } 875 876 frchain( &(p->extp) ); 877 #ifdef SDB 878 if(sdbflag) 879 prstab(varstr(XL,p->extname), N_ECOMM, 0, 0); 880 #endif 881 } 882 } 883 884 885 886 887 888 LOCAL docomleng() 889 { 890 register struct Extsym *p; 891 892 for(p = extsymtab ; p < nextext ; ++p) 893 if(p->extstg == STGCOMMON) 894 { 895 if(p->maxleng!=0 && p->extleng!=0 && p->maxleng!=p->extleng 896 && !eqn(XL,"_BLNK__ ",p->extname) ) 897 warn1("incompatible lengths for common block %s", 898 nounder(XL, p->extname) ); 899 if(p->maxleng < p->extleng) 900 p->maxleng = p->extleng; 901 p->extleng = 0; 902 } 903 } 904 905 906 907 908 /* ROUTINES DEALING WITH AUTOMATIC AND TEMPORARY STORAGE */ 909 910 /* frees a temporary block */ 911 912 frtemp(p) 913 Tempp p; 914 { 915 Addrp t; 916 917 if (optimflag) 918 { 919 if (p->tag != TTEMP) 920 badtag ("frtemp",p->tag); 921 t = p->memalloc; 922 } 923 else 924 t = (Addrp) p; 925 926 /* restore clobbered character string lengths */ 927 if(t->vtype==TYCHAR && t->varleng!=0) 928 { 929 frexpr(t->vleng); 930 t->vleng = ICON(t->varleng); 931 } 932 933 /* put block on chain of temps to be reclaimed */ 934 holdtemps = mkchain(t, holdtemps); 935 } 936 937 938 939 /* allocate an automatic variable slot */ 940 941 Addrp autovar(nelt, t, lengp) 942 register int nelt, t; 943 expptr lengp; 944 { 945 ftnint leng; 946 register Addrp q; 947 948 if(lengp) 949 if( ISICON(lengp) ) 950 leng = lengp->constblock.constant.ci; 951 else { 952 fatal("automatic variable of nonconstant length"); 953 } 954 else 955 leng = typesize[t]; 956 autoleng = roundup( autoleng, typealign[t]); 957 958 q = ALLOC(Addrblock); 959 q->tag = TADDR; 960 q->vtype = t; 961 if(lengp) 962 { 963 q->vleng = ICON(leng); 964 q->varleng = leng; 965 } 966 q->vstg = STGAUTO; 967 q->memno = newlabel(); 968 q->ntempelt = nelt; 969 #if TARGET==PDP11 || TARGET==VAX || TARGET == TAHOE 970 /* stack grows downward */ 971 autoleng += nelt*leng; 972 q->memoffset = ICON( - autoleng ); 973 #else 974 q->memoffset = ICON( autoleng ); 975 autoleng += nelt*leng; 976 #endif 977 978 return(q); 979 } 980 981 982 983 /* 984 * create a temporary block (TTEMP) when optimizing, 985 * an ordinary TADDR block when not optimizing 986 */ 987 988 Tempp mktmpn(nelt, type, lengp) 989 int nelt; 990 register int type; 991 expptr lengp; 992 { 993 ftnint leng; 994 chainp p, oldp; 995 register Tempp q; 996 Addrp altemp; 997 998 if (! optimflag) 999 return ( (Tempp) mkaltmpn(nelt,type,lengp) ); 1000 if(type==TYUNKNOWN || type==TYERROR) 1001 badtype("mktmpn", type); 1002 1003 if(type==TYCHAR) 1004 if( ISICON(lengp) ) 1005 leng = lengp->constblock.constant.ci; 1006 else { 1007 err("adjustable length"); 1008 return( (Tempp) errnode() ); 1009 } 1010 else 1011 leng = typesize[type]; 1012 1013 q = ALLOC(Tempblock); 1014 q->tag = TTEMP; 1015 q->vtype = type; 1016 if(type == TYCHAR) 1017 { 1018 q->vleng = ICON(leng); 1019 q->varleng = leng; 1020 } 1021 1022 altemp = ALLOC(Addrblock); 1023 altemp->tag = TADDR; 1024 altemp->vstg = STGUNKNOWN; 1025 q->memalloc = altemp; 1026 1027 q->ntempelt = nelt; 1028 q->istemp = YES; 1029 return(q); 1030 } 1031 1032 1033 1034 Addrp mktemp(type, lengp) 1035 int type; 1036 expptr lengp; 1037 { 1038 return( (Addrp) mktmpn(1,type,lengp) ); 1039 } 1040 1041 1042 1043 /* allocate a temporary location for the given temporary block; 1044 if already allocated, return its location */ 1045 1046 Addrp altmpn(tp) 1047 Tempp tp; 1048 1049 { 1050 Addrp t, q; 1051 1052 if (tp->tag != TTEMP) 1053 badtag ("altmpn",tp->tag); 1054 1055 t = tp->memalloc; 1056 if (t->vstg != STGUNKNOWN) 1057 { 1058 if (tp->vtype == TYCHAR) 1059 { 1060 /* 1061 * Unformatted I/O parameters are treated like character 1062 * strings (sigh) -- propagate type and length. 1063 */ 1064 t = (Addrp) cpexpr(t); 1065 t->vtype = tp->vtype; 1066 t->vleng = tp->vleng; 1067 t->varleng = tp->varleng; 1068 } 1069 return (t); 1070 } 1071 1072 q = mkaltmpn (tp->ntempelt, tp->vtype, tp->vleng); 1073 cpn (sizeof(struct Addrblock), (char*)q, (char*)t); 1074 free ( (charptr) q); 1075 return(t); 1076 } 1077 1078 1079 1080 /* create and allocate space immediately for a temporary */ 1081 1082 Addrp mkaltemp(type,lengp) 1083 int type; 1084 expptr lengp; 1085 { 1086 return (mkaltmpn(1,type,lengp)); 1087 } 1088 1089 1090 1091 Addrp mkaltmpn(nelt,type,lengp) 1092 int nelt; 1093 register int type; 1094 expptr lengp; 1095 { 1096 ftnint leng; 1097 chainp p, oldp; 1098 register Addrp q; 1099 1100 if(type==TYUNKNOWN || type==TYERROR) 1101 badtype("mkaltmpn", type); 1102 1103 if(type==TYCHAR) 1104 if( ISICON(lengp) ) 1105 leng = lengp->constblock.constant.ci; 1106 else { 1107 err("adjustable length"); 1108 return( (Addrp) errnode() ); 1109 } 1110 1111 /* 1112 * if a temporary of appropriate shape is on the templist, 1113 * remove it from the list and return it 1114 */ 1115 1116 #ifdef notdef 1117 /* 1118 * This code is broken until SKFRTEMP slots can be processed in putopt() 1119 * instead of in optimize() -- all kinds of things in putpcc.c can 1120 * bomb because of this. Sigh. 1121 */ 1122 for(oldp=CHNULL, p=templist ; p ; oldp=p, p=p->nextp) 1123 { 1124 q = (Addrp) (p->datap); 1125 if(q->vtype==type && q->ntempelt==nelt && 1126 (type!=TYCHAR || q->vleng->constblock.constant.ci==leng) ) 1127 { 1128 if(oldp) 1129 oldp->nextp = p->nextp; 1130 else 1131 templist = p->nextp; 1132 free( (charptr) p); 1133 1134 if (debugflag[14]) 1135 fprintf(diagfile,"mkaltmpn reusing offset %d\n", 1136 q->memoffset->constblock.constant.ci); 1137 return(q); 1138 } 1139 } 1140 #endif notdef 1141 q = autovar(nelt, type, lengp); 1142 q->istemp = YES; 1143 1144 if (debugflag[14]) 1145 fprintf(diagfile,"mkaltmpn new offset %d\n", 1146 q->memoffset->constblock.constant.ci); 1147 return(q); 1148 } 1149 1150 1151 1152 /* The following routine is a patch which is only needed because the */ 1153 /* code for processing actual arguments for calls does not allocate */ 1154 /* the temps it needs before optimization takes place. A better */ 1155 /* solution is possible, but I do not have the time to implement it */ 1156 /* now. */ 1157 /* */ 1158 /* Robert P. Corbett */ 1159 1160 Addrp 1161 mkargtemp(type, lengp) 1162 int type; 1163 expptr lengp; 1164 { 1165 ftnint leng; 1166 chainp oldp, p; 1167 Addrp q; 1168 1169 if (type == TYUNKNOWN || type == TYERROR) 1170 badtype("mkargtemp", type); 1171 1172 if (type == TYCHAR) 1173 { 1174 if (ISICON(lengp)) 1175 leng = lengp->constblock.constant.ci; 1176 else 1177 { 1178 err("adjustable length"); 1179 return ((Addrp) errnode()); 1180 } 1181 } 1182 1183 oldp = CHNULL; 1184 p = argtemplist; 1185 1186 while (p) 1187 { 1188 q = (Addrp) (p->datap); 1189 if (q->vtype == type 1190 && (type != TYCHAR || q->vleng->constblock.constant.ci == leng)) 1191 { 1192 if (oldp) 1193 oldp->nextp = p->nextp; 1194 else 1195 argtemplist = p->nextp; 1196 1197 p->nextp = activearglist; 1198 activearglist = p; 1199 1200 return ((Addrp) cpexpr(q)); 1201 } 1202 1203 oldp = p; 1204 p = p->nextp; 1205 } 1206 1207 q = autovar(1, type, lengp); 1208 activearglist = mkchain(q, activearglist); 1209 return ((Addrp) cpexpr(q)); 1210 } 1211 1212 /* VARIOUS ROUTINES FOR PROCESSING DECLARATIONS */ 1213 1214 struct Extsym *comblock(len, s) 1215 register int len; 1216 register char *s; 1217 { 1218 struct Extsym *p; 1219 1220 if(len == 0) 1221 { 1222 s = BLANKCOMMON; 1223 len = strlen(s); 1224 } 1225 p = mkext( varunder(len, s) ); 1226 if(p->extstg == STGUNKNOWN) 1227 p->extstg = STGCOMMON; 1228 else if(p->extstg != STGCOMMON) 1229 { 1230 errstr("%s cannot be a common block name", s); 1231 return(0); 1232 } 1233 1234 return( p ); 1235 } 1236 1237 1238 incomm(c, v) 1239 struct Extsym *c; 1240 Namep v; 1241 { 1242 if(v->vstg != STGUNKNOWN) 1243 dclerr("incompatible common declaration", v); 1244 else 1245 { 1246 if(c == (struct Extsym *) 0) 1247 return; /* Illegal common block name upstream */ 1248 v->vstg = STGCOMMON; 1249 c->extp = hookup(c->extp, mkchain(v,CHNULL) ); 1250 } 1251 } 1252 1253 1254 1255 1256 settype(v, type, length) 1257 register Namep v; 1258 register int type; 1259 register int length; 1260 { 1261 if(type == TYUNKNOWN) 1262 return; 1263 1264 if(type==TYSUBR && v->vtype!=TYUNKNOWN && v->vstg==STGARG) 1265 { 1266 v->vtype = TYSUBR; 1267 frexpr(v->vleng); 1268 } 1269 else if(type < 0) /* storage class set */ 1270 { 1271 if(v->vstg == STGUNKNOWN) 1272 v->vstg = - type; 1273 else if(v->vstg != -type) 1274 dclerr("incompatible storage declarations", v); 1275 } 1276 else if(v->vtype == TYUNKNOWN) 1277 { 1278 if( (v->vtype = lengtype(type, length))==TYCHAR && length>=0) 1279 v->vleng = ICON(length); 1280 } 1281 else if(v->vtype!=type || (type==TYCHAR && v->vleng->constblock.constant.ci!=length) ) 1282 dclerr("incompatible type declarations", v); 1283 } 1284 1285 1286 1287 1288 1289 lengtype(type, length) 1290 register int type; 1291 register int length; 1292 { 1293 switch(type) 1294 { 1295 case TYREAL: 1296 if(length == 8) 1297 return(TYDREAL); 1298 if(length == 4) 1299 goto ret; 1300 break; 1301 1302 case TYCOMPLEX: 1303 if(length == 16) 1304 return(TYDCOMPLEX); 1305 if(length == 8) 1306 goto ret; 1307 break; 1308 1309 case TYSHORT: 1310 case TYDREAL: 1311 case TYDCOMPLEX: 1312 case TYCHAR: 1313 case TYUNKNOWN: 1314 case TYSUBR: 1315 case TYERROR: 1316 goto ret; 1317 1318 case TYLOGICAL: 1319 if(length == typesize[TYLOGICAL]) 1320 goto ret; 1321 break; 1322 1323 case TYLONG: 1324 if(length == 0 ) 1325 return(tyint); 1326 if(length == 2) 1327 return(TYSHORT); 1328 if(length == 4 ) 1329 goto ret; 1330 break; 1331 default: 1332 badtype("lengtype", type); 1333 } 1334 1335 if(length != 0) 1336 err("incompatible type-length combination"); 1337 1338 ret: 1339 return(type); 1340 } 1341 1342 1343 1344 1345 1346 setintr(v) 1347 register Namep v; 1348 { 1349 register int k; 1350 1351 if(v->vstg == STGUNKNOWN) 1352 v->vstg = STGINTR; 1353 else if(v->vstg!=STGINTR) 1354 dclerr("incompatible use of intrinsic function", v); 1355 if(v->vclass==CLUNKNOWN) 1356 v->vclass = CLPROC; 1357 if(v->vprocclass == PUNKNOWN) 1358 v->vprocclass = PINTRINSIC; 1359 else if(v->vprocclass != PINTRINSIC) 1360 dclerr("invalid intrinsic declaration", v); 1361 if(k = intrfunct(v->varname)) 1362 v->vardesc.varno = k; 1363 else 1364 dclerr("unknown intrinsic function", v); 1365 } 1366 1367 1368 1369 setext(v) 1370 register Namep v; 1371 { 1372 if(v->vclass == CLUNKNOWN) 1373 v->vclass = CLPROC; 1374 else if(v->vclass != CLPROC) 1375 dclerr("conflicting declarations", v); 1376 1377 if(v->vprocclass == PUNKNOWN) 1378 v->vprocclass = PEXTERNAL; 1379 else if(v->vprocclass != PEXTERNAL) 1380 dclerr("conflicting declarations", v); 1381 } 1382 1383 1384 1385 1386 /* create dimensions block for array variable */ 1387 1388 setbound(v, nd, dims) 1389 register Namep v; 1390 int nd; 1391 struct { expptr lb, ub; } dims[ ]; 1392 { 1393 register expptr q, t; 1394 register struct Dimblock *p; 1395 int i; 1396 1397 if(v->vclass == CLUNKNOWN) 1398 v->vclass = CLVAR; 1399 else if(v->vclass != CLVAR) 1400 { 1401 dclerr("only variables may be arrays", v); 1402 return; 1403 } 1404 if(v->vdim) 1405 { 1406 dclerr("redimensioned array", v); 1407 return; 1408 } 1409 1410 v->vdim = p = (struct Dimblock *) 1411 ckalloc( sizeof(int) + (3+6*nd)*sizeof(expptr) ); 1412 p->ndim = nd; 1413 p->nelt = ICON(1); 1414 1415 for(i=0 ; i<nd ; ++i) 1416 { 1417 #ifdef SDB 1418 if(sdbflag) { 1419 /* Save the bounds trees built up by the grammar routines for use in stabs */ 1420 1421 if(dims[i].lb == NULL) p->dims[i].lb=ICON(1); 1422 else p->dims[i].lb= (expptr) cpexpr(dims[i].lb); 1423 if(ISCONST(p->dims[i].lb)) p->dims[i].lbaddr = (expptr) PNULL; 1424 else p->dims[i].lbaddr = (expptr) autovar(1, tyint, PNULL); 1425 1426 if(dims[i].ub == NULL) p->dims[i].ub=ICON(1); 1427 else p->dims[i].ub = (expptr) cpexpr(dims[i].ub); 1428 if(ISCONST(p->dims[i].ub)) p->dims[i].ubaddr = (expptr) PNULL; 1429 else p->dims[i].ubaddr = (expptr) autovar(1, tyint, PNULL); 1430 } 1431 #endif 1432 if( (q = dims[i].ub) == NULL) 1433 { 1434 if(i == nd-1) 1435 { 1436 frexpr(p->nelt); 1437 p->nelt = NULL; 1438 } 1439 else 1440 err("only last bound may be asterisk"); 1441 p->dims[i].dimsize = ICON(1);; 1442 p->dims[i].dimexpr = NULL; 1443 } 1444 else 1445 { 1446 if(dims[i].lb) 1447 { 1448 q = mkexpr(OPMINUS, q, cpexpr(dims[i].lb)); 1449 q = mkexpr(OPPLUS, q, ICON(1) ); 1450 } 1451 if( ISCONST(q) ) 1452 { 1453 if (!ISINT(q->headblock.vtype)) { 1454 dclerr("dimension bounds must be integer expression", v); 1455 frexpr(q); 1456 q = ICON(0); 1457 } 1458 if ( q->constblock.constant.ci <= 0) 1459 { 1460 dclerr("array bounds out of sequence", v); 1461 frexpr(q); 1462 q = ICON(0); 1463 } 1464 p->dims[i].dimsize = q; 1465 p->dims[i].dimexpr = (expptr) PNULL; 1466 } 1467 else { 1468 p->dims[i].dimsize = (expptr) autovar(1, tyint, PNULL); 1469 p->dims[i].dimexpr = q; 1470 } 1471 if(p->nelt) 1472 p->nelt = mkexpr(OPSTAR, p->nelt, 1473 cpexpr(p->dims[i].dimsize) ); 1474 } 1475 } 1476 1477 q = dims[nd-1].lb; 1478 if(q == NULL) 1479 q = ICON(1); 1480 1481 for(i = nd-2 ; i>=0 ; --i) 1482 { 1483 t = dims[i].lb; 1484 if(t == NULL) 1485 t = ICON(1); 1486 if(p->dims[i].dimsize) 1487 q = mkexpr(OPPLUS, t, mkexpr(OPSTAR, cpexpr(p->dims[i].dimsize), q) ); 1488 } 1489 1490 if( ISCONST(q) ) 1491 { 1492 p->baseoffset = q; 1493 p->basexpr = NULL; 1494 } 1495 else 1496 { 1497 p->baseoffset = (expptr) autovar(1, tyint, PNULL); 1498 p->basexpr = q; 1499 } 1500 } 1501 1502 1503 1504 /* 1505 * Check the dimensions of q to ensure that they are appropriately defined. 1506 */ 1507 LOCAL chkdim(q) 1508 register Namep q; 1509 { 1510 register struct Dimblock *p; 1511 register int i; 1512 expptr e; 1513 1514 if (q == NULL) 1515 return; 1516 if (q->vclass != CLVAR) 1517 return; 1518 if (q->vdim == NULL) 1519 return; 1520 p = q->vdim; 1521 for (i = 0; i < p->ndim; ++i) 1522 { 1523 #ifdef SDB 1524 if (sdbflag) 1525 { 1526 if (e = p->dims[i].lb) 1527 chkdime(e, q); 1528 if (e = p->dims[i].ub) 1529 chkdime(e, q); 1530 } 1531 else 1532 #endif SDB 1533 if (e = p->dims[i].dimexpr) 1534 chkdime(e, q); 1535 } 1536 } 1537 1538 1539 1540 /* 1541 * The actual checking for chkdim() -- examines each expression. 1542 */ 1543 LOCAL chkdime(expr, q) 1544 expptr expr; 1545 Namep q; 1546 { 1547 register expptr e; 1548 1549 e = fixtype(cpexpr(expr)); 1550 if (!ISINT(e->exprblock.vtype)) 1551 dclerr("non-integer dimension", q); 1552 else if (!safedim(e)) 1553 dclerr("undefined dimension", q); 1554 frexpr(e); 1555 return; 1556 } 1557 1558 1559 1560 /* 1561 * A recursive routine to find undefined variables in dimension expressions. 1562 */ 1563 LOCAL safedim(e) 1564 expptr e; 1565 { 1566 chainp cp; 1567 1568 if (e == NULL) 1569 return 1; 1570 switch (e->tag) 1571 { 1572 case TEXPR: 1573 if (e->exprblock.opcode == OPCALL || e->exprblock.opcode == OPCCALL) 1574 return 0; 1575 return safedim(e->exprblock.leftp) && safedim(e->exprblock.rightp); 1576 case TADDR: 1577 switch (e->addrblock.vstg) 1578 { 1579 case STGCOMMON: 1580 case STGARG: 1581 case STGCONST: 1582 case STGEQUIV: 1583 if (e->addrblock.isarray) 1584 return 0; 1585 return safedim(e->addrblock.memoffset); 1586 default: 1587 return 0; 1588 } 1589 case TCONST: 1590 case TTEMP: 1591 return 1; 1592 } 1593 return 0; 1594 } 1595 1596 1597 1598 LOCAL enlist(size, np, ep) 1599 ftnint size; 1600 Namep np; 1601 struct Equivblock *ep; 1602 { 1603 register sizelist *sp; 1604 register sizelist *t; 1605 register varlist *p; 1606 1607 sp = varsizes; 1608 1609 if (sp == NULL) 1610 { 1611 sp = ALLOC(SizeList); 1612 sp->size = size; 1613 varsizes = sp; 1614 } 1615 else 1616 { 1617 while (sp->size != size) 1618 { 1619 if (sp->next != NULL && sp->next->size <= size) 1620 sp = sp->next; 1621 else 1622 { 1623 t = sp; 1624 sp = ALLOC(SizeList); 1625 sp->size = size; 1626 sp->next = t->next; 1627 t->next = sp; 1628 } 1629 } 1630 } 1631 1632 p = ALLOC(VarList); 1633 p->next = sp->vars; 1634 p->np = np; 1635 p->ep = ep; 1636 1637 sp->vars = p; 1638 1639 return; 1640 } 1641 1642 1643 1644 outlocvars() 1645 { 1646 1647 register varlist *first, *last; 1648 register varlist *vp, *t; 1649 register sizelist *sp, *sp1; 1650 register Namep np; 1651 register struct Equivblock *ep; 1652 register int i; 1653 register int alt; 1654 register int type; 1655 char sname[100]; 1656 char setbuff[100]; 1657 1658 sp = varsizes; 1659 if (sp == NULL) 1660 return; 1661 1662 vp = sp->vars; 1663 if (vp->np != NULL) 1664 { 1665 np = vp->np; 1666 sprintf(setbuff, "\t.set\tv.%d,v.%d\n", bsslabel, 1667 np->vardesc.varno); 1668 } 1669 else 1670 { 1671 i = vp->ep - eqvclass; 1672 sprintf(setbuff, "\t.set\tv.%d,q.%d\n", bsslabel, i + eqvstart); 1673 } 1674 1675 first = last = NULL; 1676 alt = NO; 1677 1678 while (sp != NULL) 1679 { 1680 vp = sp->vars; 1681 while (vp != NULL) 1682 { 1683 t = vp->next; 1684 if (alt == YES) 1685 { 1686 alt = NO; 1687 vp->next = first; 1688 first = vp; 1689 } 1690 else 1691 { 1692 alt = YES; 1693 if (last != NULL) 1694 last->next = vp; 1695 else 1696 first = vp; 1697 vp->next = NULL; 1698 last = vp; 1699 } 1700 vp = t; 1701 } 1702 sp1 = sp; 1703 sp = sp->next; 1704 free((char *) sp1); 1705 } 1706 1707 vp = first; 1708 while(vp != NULL) 1709 { 1710 if (vp->np != NULL) 1711 { 1712 np = vp->np; 1713 sprintf(sname, "v.%d", np->vardesc.varno); 1714 pralign(typealign[np->vtype]); 1715 if (np->init) 1716 prlocdata(sname, np->varsize, np->vtype, np->initoffset, 1717 &(np->inlcomm)); 1718 else 1719 { 1720 if (typealign[np->vtype] == 1) 1721 pralign(3); 1722 fprintf(initfile, "%s:\n\t.space\t%d\n", sname, 1723 np->varsize); 1724 } 1725 np->inlcomm = NO; 1726 } 1727 else 1728 { 1729 ep = vp->ep; 1730 i = ep - eqvclass; 1731 if (ep->eqvleng >= 8) 1732 type = TYDREAL; 1733 else if (ep->eqvleng >= 4) 1734 type = TYLONG; 1735 else if (ep->eqvleng >= 2) 1736 type = TYSHORT; 1737 else 1738 type = TYCHAR; 1739 sprintf(sname, "q.%d", i + eqvstart); 1740 if (ep->init) 1741 prlocdata(sname, ep->eqvleng, type, ep->initoffset, 1742 &(ep->inlcomm)); 1743 else 1744 { 1745 pralign(typealign[type]); 1746 fprintf(initfile, "%s:\n\t.space\t%d\n", sname, ep->eqvleng); 1747 } 1748 ep->inlcomm = NO; 1749 } 1750 t = vp; 1751 vp = vp->next; 1752 free((char *) t); 1753 } 1754 fprintf(initfile, "%s\n", setbuff); 1755 return; 1756 } 1757