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