122861Smckusick /* 222861Smckusick * Copyright (c) 1980 Regents of the University of California. 322861Smckusick * All rights reserved. The Berkeley software License Agreement 422861Smckusick * specifies the terms and conditions for redistribution. 522861Smckusick */ 622861Smckusick 722861Smckusick #ifndef lint 8*25744Sdonn static char sccsid[] = "@(#)proc.c 5.5 (Berkeley) 01/07/86"; 922861Smckusick #endif not lint 1022861Smckusick 1122861Smckusick /* 1222861Smckusick * proc.c 1322861Smckusick * 1422861Smckusick * Routines for handling procedures, f77 compiler, pass 1. 1522861Smckusick * 1622861Smckusick * University of Utah CS Dept modification history: 1722861Smckusick * 1822861Smckusick * $Log: proc.c,v $ 19*25744Sdonn * Revision 5.6 86/01/06 16:28:06 donn 20*25744Sdonn * Sigh. We can't commit to defining a symbol as a variable instead of a 21*25744Sdonn * function based only on what we have seen through the declaration section; 22*25744Sdonn * this was properly handled for normal variables but not for arguments. 23*25744Sdonn * 24*25744Sdonn * Revision 5.5 86/01/01 21:59:17 donn 25*25744Sdonn * Pick up CHARACTER*(*) declarations for variables which aren't dummy 26*25744Sdonn * arguments, and complain about them. 27*25744Sdonn * 28*25744Sdonn * Revision 5.4 85/12/20 19:18:35 donn 29*25744Sdonn * Don't assume that dummy procedures of unknown type are functions of type 30*25744Sdonn * undefined until the user (mis-)uses them that way -- they may also be 31*25744Sdonn * subroutines. 32*25744Sdonn * 3325103Sdonn * Revision 5.3 85/09/30 23:21:07 donn 3425103Sdonn * Print space with prspace() in outlocvars() so that alignment is preserved. 3525103Sdonn * 3624484Sdonn * Revision 5.2 85/08/10 05:03:34 donn 3724484Sdonn * Support for NAMELIST i/o from Jerry Berkman. 3824484Sdonn * 3924484Sdonn * Revision 5.1 85/08/10 03:49:14 donn 4024484Sdonn * 4.3 alpha 4124484Sdonn * 4223477Smckusick * Revision 3.11 85/06/04 03:45:29 donn 4323477Smckusick * Changed retval() to recognize that a function declaration might have 4423477Smckusick * bombed out earlier, leaving an error node behind... 4523477Smckusick * 4622861Smckusick * Revision 3.10 85/03/08 23:13:06 donn 4722861Smckusick * Finally figured out why function calls and array elements are not legal 4822861Smckusick * dummy array dimension declarator elements. Hacked safedim() to stop 'em. 4922861Smckusick * 5022861Smckusick * Revision 3.9 85/02/02 00:26:10 donn 5122861Smckusick * Removed the call to entrystab() in enddcl() -- this was redundant (it was 5222861Smckusick * also done in startproc()) and confusing to dbx to boot. 5322861Smckusick * 5422861Smckusick * Revision 3.8 85/01/14 04:21:53 donn 5522861Smckusick * Added changes to implement Jerry's '-q' option. 5622861Smckusick * 5722861Smckusick * Revision 3.7 85/01/11 21:10:35 donn 5822861Smckusick * In conjunction with other changes to implement SAVE statements, function 5922861Smckusick * nameblocks were changed to make it appear that they are 'saved' too -- 6022861Smckusick * this arranges things so that function return values are forced out of 6122861Smckusick * register before a return. 6222861Smckusick * 6322861Smckusick * Revision 3.6 84/12/10 19:27:20 donn 6422861Smckusick * comblock() signals an illegal common block name by returning a null pointer, 6522861Smckusick * but incomm() wasn't able to handle it, leading to core dumps. I put the 6622861Smckusick * fix in incomm() to pick up null common blocks. 6722861Smckusick * 6822861Smckusick * Revision 3.5 84/11/21 20:33:31 donn 6922861Smckusick * It seems that I/O elements are treated as character strings so that their 7022861Smckusick * length can be passed to the I/O routines... Unfortunately the compiler 7122861Smckusick * assumes that no temporaries can be of type CHARACTER and casually tosses 7222861Smckusick * length and type info away when removing TEMP blocks. This has been fixed... 7322861Smckusick * 7422861Smckusick * Revision 3.4 84/11/05 22:19:30 donn 7522861Smckusick * Fixed a silly bug in the last fix. 7622861Smckusick * 7722861Smckusick * Revision 3.3 84/10/29 08:15:23 donn 7822861Smckusick * Added code to check the type and shape of subscript declarations, 7922861Smckusick * per Jerry Berkman's suggestion. 8022861Smckusick * 8122861Smckusick * Revision 3.2 84/10/29 05:52:07 donn 8222861Smckusick * Added change suggested by Jerry Berkman to report an error when an array 8322861Smckusick * is redimensioned. 8422861Smckusick * 8522861Smckusick * Revision 3.1 84/10/13 02:12:31 donn 8622861Smckusick * Merged Jerry Berkman's version into mine. 8722861Smckusick * 8822861Smckusick * Revision 2.1 84/07/19 12:04:09 donn 8922861Smckusick * Changed comment headers for UofU. 9022861Smckusick * 9122861Smckusick * Revision 1.6 84/07/19 11:32:15 donn 9222861Smckusick * Incorporated fix to setbound() to detect backward array subscript limits. 9322861Smckusick * The fix is by Bob Corbett, donated by Jerry Berkman. 9422861Smckusick * 9522861Smckusick * Revision 1.5 84/07/18 18:25:50 donn 9622861Smckusick * Fixed problem with doentry() where a placeholder for a return value 9722861Smckusick * was not allocated if the first entry didn't require one but a later 9822861Smckusick * entry did. 9922861Smckusick * 10022861Smckusick * Revision 1.4 84/05/24 20:52:09 donn 10122861Smckusick * Installed firewall #ifdef around the code that recycles stack temporaries, 10222861Smckusick * since it seems to be broken and lacks a good fix for the time being. 10322861Smckusick * 10422861Smckusick * Revision 1.3 84/04/16 09:50:46 donn 10522861Smckusick * Fixed mkargtemp() so that it only passes back a copy of a temporary, keeping 10622861Smckusick * the original for its own use. This fixes a set of bugs that are caused by 10722861Smckusick * elements in the argtemplist getting stomped on. 10822861Smckusick * 10922861Smckusick * Revision 1.2 84/02/28 21:12:58 donn 11022861Smckusick * Added Berkeley changes for subroutine call argument temporaries fix. 11122861Smckusick * 11222861Smckusick */ 11322861Smckusick 11422861Smckusick #include "defs.h" 11522861Smckusick 11622861Smckusick #ifdef SDB 11722861Smckusick # include <a.out.h> 11822861Smckusick # ifndef N_SO 11922861Smckusick # include <stab.h> 12022861Smckusick # endif 12122861Smckusick #endif 12222861Smckusick 12322861Smckusick extern flag namesflag; 12422861Smckusick 12522861Smckusick typedef 12622861Smckusick struct SizeList 12722861Smckusick { 12822861Smckusick struct SizeList *next; 12922861Smckusick ftnint size; 13022861Smckusick struct VarList *vars; 13122861Smckusick } 13222861Smckusick sizelist; 13322861Smckusick 13422861Smckusick 13522861Smckusick typedef 13622861Smckusick struct VarList 13722861Smckusick { 13822861Smckusick struct VarList *next; 13922861Smckusick Namep np; 14022861Smckusick struct Equivblock *ep; 14122861Smckusick } 14222861Smckusick varlist; 14322861Smckusick 14422861Smckusick 14522861Smckusick LOCAL sizelist *varsizes; 14622861Smckusick 14722861Smckusick 14822861Smckusick /* start a new procedure */ 14922861Smckusick 15022861Smckusick newproc() 15122861Smckusick { 15222861Smckusick if(parstate != OUTSIDE) 15322861Smckusick { 15422861Smckusick execerr("missing end statement", CNULL); 15522861Smckusick endproc(); 15622861Smckusick } 15722861Smckusick 15822861Smckusick parstate = INSIDE; 15922861Smckusick procclass = CLMAIN; /* default */ 16022861Smckusick } 16122861Smckusick 16222861Smckusick 16322861Smckusick 16422861Smckusick /* end of procedure. generate variables, epilogs, and prologs */ 16522861Smckusick 16622861Smckusick endproc() 16722861Smckusick { 16822861Smckusick struct Labelblock *lp; 16922861Smckusick 17022861Smckusick if(parstate < INDATA) 17122861Smckusick enddcl(); 17222861Smckusick if(ctlstack >= ctls) 17322861Smckusick err("DO loop or BLOCK IF not closed"); 17422861Smckusick for(lp = labeltab ; lp < labtabend ; ++lp) 17522861Smckusick if(lp->stateno!=0 && lp->labdefined==NO) 17622861Smckusick errstr("missing statement number %s", convic(lp->stateno) ); 17722861Smckusick 17822861Smckusick if (optimflag) 17922861Smckusick optimize(); 18022861Smckusick 18122861Smckusick outiodata(); 18222861Smckusick epicode(); 18322861Smckusick procode(); 18422861Smckusick donmlist(); 18522861Smckusick dobss(); 18622861Smckusick 18722861Smckusick #if FAMILY == PCC 18822861Smckusick putbracket(); 18922861Smckusick #endif 19022861Smckusick fixlwm(); 19122861Smckusick procinit(); /* clean up for next procedure */ 19222861Smckusick } 19322861Smckusick 19422861Smckusick 19522861Smckusick 19622861Smckusick /* End of declaration section of procedure. Allocate storage. */ 19722861Smckusick 19822861Smckusick enddcl() 19922861Smckusick { 20022861Smckusick register struct Entrypoint *ep; 20122861Smckusick 20222861Smckusick parstate = INEXEC; 20322861Smckusick docommon(); 20422861Smckusick doequiv(); 20522861Smckusick docomleng(); 20622861Smckusick for(ep = entries ; ep ; ep = ep->entnextp) { 20722861Smckusick doentry(ep); 20822861Smckusick } 20922861Smckusick } 21022861Smckusick 21122861Smckusick /* ROUTINES CALLED WHEN ENCOUNTERING ENTRY POINTS */ 21222861Smckusick 21322861Smckusick /* Main program or Block data */ 21422861Smckusick 21522861Smckusick startproc(prgname, class) 21622861Smckusick Namep prgname; 21722861Smckusick int class; 21822861Smckusick { 21922861Smckusick struct Extsym *progname; 22022861Smckusick register struct Entrypoint *p; 22122861Smckusick 22222861Smckusick if(prgname) 22322861Smckusick procname = prgname->varname; 22422861Smckusick if(namesflag == YES) { 22522861Smckusick fprintf(diagfile, " %s", (class==CLMAIN ? "MAIN" : "BLOCK DATA") ); 22622861Smckusick if(prgname) 22722861Smckusick fprintf(diagfile, " %s", varstr(XL, procname) ); 22822861Smckusick fprintf(diagfile, ":\n"); 22922861Smckusick } 23022861Smckusick 23122861Smckusick if( prgname ) 23222861Smckusick progname = newentry( prgname ); 23322861Smckusick else 23422861Smckusick progname = NULL; 23522861Smckusick 23622861Smckusick p = ALLOC(Entrypoint); 23722861Smckusick if(class == CLMAIN) 23822861Smckusick puthead("MAIN_", CLMAIN); 23922861Smckusick else 24022861Smckusick puthead(CNULL, CLBLOCK); 24122861Smckusick if(class == CLMAIN) 24222861Smckusick newentry( mkname(5, "MAIN") ); 24322861Smckusick p->entryname = progname; 24422861Smckusick p->entrylabel = newlabel(); 24522861Smckusick entries = p; 24622861Smckusick 24722861Smckusick procclass = class; 24822861Smckusick retlabel = newlabel(); 24922861Smckusick #ifdef SDB 25022861Smckusick if(sdbflag) { 25122861Smckusick entrystab(p,class); 25222861Smckusick } 25322861Smckusick #endif 25422861Smckusick } 25522861Smckusick 25622861Smckusick /* subroutine or function statement */ 25722861Smckusick 25822861Smckusick struct Extsym *newentry(v) 25922861Smckusick register Namep v; 26022861Smckusick { 26122861Smckusick register struct Extsym *p; 26222861Smckusick 26322861Smckusick p = mkext( varunder(VL, v->varname) ); 26422861Smckusick 26522861Smckusick if(p==NULL || p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) ) 26622861Smckusick { 26722861Smckusick if(p == 0) 26822861Smckusick dclerr("invalid entry name", v); 26922861Smckusick else dclerr("external name already used", v); 27022861Smckusick return(0); 27122861Smckusick } 27222861Smckusick v->vstg = STGAUTO; 27322861Smckusick v->vprocclass = PTHISPROC; 27422861Smckusick v->vclass = CLPROC; 27522861Smckusick p->extstg = STGEXT; 27622861Smckusick p->extinit = YES; 27722861Smckusick return(p); 27822861Smckusick } 27922861Smckusick 28022861Smckusick 28122861Smckusick entrypt(class, type, length, entname, args) 28222861Smckusick int class, type; 28322861Smckusick ftnint length; 28422861Smckusick Namep entname; 28522861Smckusick chainp args; 28622861Smckusick { 28722861Smckusick struct Extsym *entry; 28822861Smckusick register Namep q; 28922861Smckusick register struct Entrypoint *p, *ep; 29022861Smckusick 29122861Smckusick if(namesflag == YES) { 29222861Smckusick if(class == CLENTRY) 29322861Smckusick fprintf(diagfile, " entry "); 29422861Smckusick if(entname) 29522861Smckusick fprintf(diagfile, " %s", varstr(XL, entname->varname) ); 29622861Smckusick fprintf(diagfile, ":\n"); 29722861Smckusick } 29822861Smckusick 29922861Smckusick if( entname->vclass == CLPARAM ) { 30022861Smckusick errstr("entry name %s used in 'parameter' statement", 30122861Smckusick varstr(XL, entname->varname) ); 30222861Smckusick return; 30322861Smckusick } 30422861Smckusick if( ((type == TYSUBR) || (class == CLENTRY && proctype == TYSUBR)) 30522861Smckusick && (entname->vtype != TYUNKNOWN && entname->vtype != TYSUBR) ) { 30622861Smckusick errstr("subroutine entry %s previously declared", 30722861Smckusick varstr(XL, entname->varname) ); 30822861Smckusick return; 30922861Smckusick } 31022861Smckusick if( (entname->vstg != STGEXT && entname->vstg != STGUNKNOWN) 31122861Smckusick || (entname->vdim != NULL) ) { 31222861Smckusick errstr("subroutine or function entry %s previously declared", 31322861Smckusick varstr(XL, entname->varname) ); 31422861Smckusick return; 31522861Smckusick } 31622861Smckusick 31722861Smckusick if( (class == CLPROC || class == CLENTRY) && type != TYSUBR ) 31822861Smckusick /* arrange to save function return values */ 31922861Smckusick entname->vsave = YES; 32022861Smckusick 32122861Smckusick entry = newentry( entname ); 32222861Smckusick 32322861Smckusick if(class != CLENTRY) 32422861Smckusick puthead( varstr(XL, procname = entry->extname), class); 32522861Smckusick q = mkname(VL, nounder(XL,entry->extname) ); 32622861Smckusick 32722861Smckusick if( (type = lengtype(type, (int) length)) != TYCHAR) 32822861Smckusick length = 0; 32922861Smckusick if(class == CLPROC) 33022861Smckusick { 33122861Smckusick procclass = CLPROC; 33222861Smckusick proctype = type; 33322861Smckusick procleng = length; 33422861Smckusick 33522861Smckusick retlabel = newlabel(); 33622861Smckusick if(type == TYSUBR) 33722861Smckusick ret0label = newlabel(); 33822861Smckusick } 33922861Smckusick 34022861Smckusick p = ALLOC(Entrypoint); 34122861Smckusick if(entries) /* put new block at end of entries list */ 34222861Smckusick { 34322861Smckusick for(ep = entries; ep->entnextp; ep = ep->entnextp) 34422861Smckusick ; 34522861Smckusick ep->entnextp = p; 34622861Smckusick } 34722861Smckusick else 34822861Smckusick entries = p; 34922861Smckusick 35022861Smckusick p->entryname = entry; 35122861Smckusick p->arglist = args; 35222861Smckusick p->entrylabel = newlabel(); 35322861Smckusick p->enamep = q; 35422861Smckusick 35522861Smckusick if(class == CLENTRY) 35622861Smckusick { 35722861Smckusick class = CLPROC; 35822861Smckusick if(proctype == TYSUBR) 35922861Smckusick type = TYSUBR; 36022861Smckusick } 36122861Smckusick 36222861Smckusick q->vclass = class; 36322861Smckusick q->vprocclass = PTHISPROC; 36422861Smckusick settype(q, type, (int) length); 36522861Smckusick /* hold all initial entry points till end of declarations */ 36622861Smckusick if(parstate >= INDATA) { 36722861Smckusick doentry(p); 36822861Smckusick } 36922861Smckusick #ifdef SDB 37022861Smckusick if(sdbflag) 37122861Smckusick { /* may need to preserve CLENTRY here */ 37222861Smckusick entrystab(p,class); 37322861Smckusick } 37422861Smckusick #endif 37522861Smckusick } 37622861Smckusick 37722861Smckusick /* generate epilogs */ 37822861Smckusick 37922861Smckusick LOCAL epicode() 38022861Smckusick { 38122861Smckusick register int i; 38222861Smckusick 38322861Smckusick if(procclass==CLPROC) 38422861Smckusick { 38522861Smckusick if(proctype==TYSUBR) 38622861Smckusick { 38722861Smckusick putlabel(ret0label); 38822861Smckusick if(substars) 38922861Smckusick putforce(TYINT, ICON(0) ); 39022861Smckusick putlabel(retlabel); 39122861Smckusick goret(TYSUBR); 39222861Smckusick } 39322861Smckusick else { 39422861Smckusick putlabel(retlabel); 39522861Smckusick if(multitype) 39622861Smckusick { 39722861Smckusick typeaddr = autovar(1, TYADDR, PNULL); 39822861Smckusick putbranch( cpexpr(typeaddr) ); 39922861Smckusick for(i = 0; i < NTYPES ; ++i) 40022861Smckusick if(rtvlabel[i] != 0) 40122861Smckusick { 40222861Smckusick putlabel(rtvlabel[i]); 40322861Smckusick retval(i); 40422861Smckusick } 40522861Smckusick } 40622861Smckusick else 40722861Smckusick retval(proctype); 40822861Smckusick } 40922861Smckusick } 41022861Smckusick 41122861Smckusick else if(procclass != CLBLOCK) 41222861Smckusick { 41322861Smckusick putlabel(retlabel); 41422861Smckusick goret(TYSUBR); 41522861Smckusick } 41622861Smckusick } 41722861Smckusick 41822861Smckusick 41922861Smckusick /* generate code to return value of type t */ 42022861Smckusick 42122861Smckusick LOCAL retval(t) 42222861Smckusick register int t; 42322861Smckusick { 42422861Smckusick register Addrp p; 42522861Smckusick 42622861Smckusick switch(t) 42722861Smckusick { 42822861Smckusick case TYCHAR: 42922861Smckusick case TYCOMPLEX: 43022861Smckusick case TYDCOMPLEX: 43122861Smckusick break; 43222861Smckusick 43322861Smckusick case TYLOGICAL: 43422861Smckusick t = tylogical; 43522861Smckusick case TYADDR: 43622861Smckusick case TYSHORT: 43722861Smckusick case TYLONG: 43822861Smckusick p = (Addrp) cpexpr(retslot); 43922861Smckusick p->vtype = t; 44022861Smckusick putforce(t, p); 44122861Smckusick break; 44222861Smckusick 44322861Smckusick case TYREAL: 44422861Smckusick case TYDREAL: 44522861Smckusick p = (Addrp) cpexpr(retslot); 44622861Smckusick p->vtype = t; 44722861Smckusick putforce(t, p); 44822861Smckusick break; 44922861Smckusick 45023477Smckusick case TYERROR: 45123477Smckusick return; /* someone else already complained */ 45223477Smckusick 45322861Smckusick default: 45422861Smckusick badtype("retval", t); 45522861Smckusick } 45622861Smckusick goret(t); 45722861Smckusick } 45822861Smckusick 45922861Smckusick 46022861Smckusick /* Allocate extra argument array if needed. Generate prologs. */ 46122861Smckusick 46222861Smckusick LOCAL procode() 46322861Smckusick { 46422861Smckusick register struct Entrypoint *p; 46522861Smckusick Addrp argvec; 46622861Smckusick 46722861Smckusick #if TARGET==GCOS 46822861Smckusick argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL); 46922861Smckusick #else 47022861Smckusick if(lastargslot>0 && nentry>1) 47122861Smckusick #if TARGET == VAX 47222861Smckusick argvec = autovar(1 + lastargslot/SZADDR, TYADDR, PNULL); 47322861Smckusick #else 47422861Smckusick argvec = autovar(lastargslot/SZADDR, TYADDR, PNULL); 47522861Smckusick #endif 47622861Smckusick else 47722861Smckusick argvec = NULL; 47822861Smckusick #endif 47922861Smckusick 48022861Smckusick 48122861Smckusick #if TARGET == PDP11 48222861Smckusick /* for the optimizer */ 48322861Smckusick if(fudgelabel) 48422861Smckusick putlabel(fudgelabel); 48522861Smckusick #endif 48622861Smckusick 48722861Smckusick for(p = entries ; p ; p = p->entnextp) 48822861Smckusick prolog(p, argvec); 48922861Smckusick 49022861Smckusick #if FAMILY == PCC 49122861Smckusick putrbrack(procno); 49222861Smckusick #endif 49322861Smckusick 49422861Smckusick prendproc(); 49522861Smckusick } 49622861Smckusick 49722861Smckusick 49822861Smckusick /* 499*25744Sdonn * manipulate argument lists (allocate argument slot positions) 50022861Smckusick * keep track of return types and labels 50122861Smckusick */ 50222861Smckusick 50322861Smckusick LOCAL doentry(ep) 50422861Smckusick struct Entrypoint *ep; 50522861Smckusick { 50622861Smckusick register int type; 50722861Smckusick register Namep np; 50822861Smckusick chainp p; 50922861Smckusick register Namep q; 51022861Smckusick Addrp mkarg(); 51122861Smckusick 51222861Smckusick ++nentry; 51322861Smckusick if(procclass == CLMAIN) 51422861Smckusick { 51522861Smckusick if (optimflag) 51622861Smckusick optbuff (SKLABEL, 0, ep->entrylabel, 0); 51722861Smckusick else 51822861Smckusick putlabel(ep->entrylabel); 51922861Smckusick return; 52022861Smckusick } 52122861Smckusick else if(procclass == CLBLOCK) 52222861Smckusick return; 52322861Smckusick 52422861Smckusick impldcl( np = mkname(VL, nounder(XL, ep->entryname->extname) ) ); 52522861Smckusick type = np->vtype; 52622861Smckusick if(proctype == TYUNKNOWN) 52722861Smckusick if( (proctype = type) == TYCHAR) 52822861Smckusick procleng = (np->vleng ? np->vleng->constblock.const.ci : (ftnint) (-1)); 52922861Smckusick 53022861Smckusick if(proctype == TYCHAR) 53122861Smckusick { 53222861Smckusick if(type != TYCHAR) 53322861Smckusick err("noncharacter entry of character function"); 53422861Smckusick else if( (np->vleng ? np->vleng->constblock.const.ci : (ftnint) (-1)) != procleng) 53522861Smckusick err("mismatched character entry lengths"); 53622861Smckusick } 53722861Smckusick else if(type == TYCHAR) 53822861Smckusick err("character entry of noncharacter function"); 53922861Smckusick else if(type != proctype) 54022861Smckusick multitype = YES; 54122861Smckusick if(rtvlabel[type] == 0) 54222861Smckusick rtvlabel[type] = newlabel(); 54322861Smckusick ep->typelabel = rtvlabel[type]; 54422861Smckusick 54522861Smckusick if(type == TYCHAR) 54622861Smckusick { 54722861Smckusick if(chslot < 0) 54822861Smckusick { 54922861Smckusick chslot = nextarg(TYADDR); 55022861Smckusick chlgslot = nextarg(TYLENG); 55122861Smckusick } 55222861Smckusick np->vstg = STGARG; 55322861Smckusick np->vardesc.varno = chslot; 55422861Smckusick if(procleng < 0) 55522861Smckusick np->vleng = (expptr) mkarg(TYLENG, chlgslot); 55622861Smckusick } 55722861Smckusick else if( ISCOMPLEX(type) ) 55822861Smckusick { 55922861Smckusick np->vstg = STGARG; 56022861Smckusick if(cxslot < 0) 56122861Smckusick cxslot = nextarg(TYADDR); 56222861Smckusick np->vardesc.varno = cxslot; 56322861Smckusick } 56422861Smckusick else if(type != TYSUBR) 56522861Smckusick { 56622861Smckusick if(retslot == NULL) 56722861Smckusick retslot = autovar(1, TYDREAL, PNULL); 56822861Smckusick np->vstg = STGAUTO; 56922861Smckusick np->voffset = retslot->memoffset->constblock.const.ci; 57022861Smckusick } 57122861Smckusick 57222861Smckusick for(p = ep->arglist ; p ; p = p->nextp) 57322861Smckusick if(! (( q = (Namep) (p->datap) )->vdcldone) ) 57422861Smckusick q->vardesc.varno = nextarg(TYADDR); 57522861Smckusick 57622861Smckusick for(p = ep->arglist ; p ; p = p->nextp) 57722861Smckusick if(! (( q = (Namep) (p->datap) )->vdcldone) ) 57822861Smckusick { 579*25744Sdonn if(q->vclass == CLPROC && q->vtype == TYUNKNOWN) 580*25744Sdonn continue; 58122861Smckusick impldcl(q); 58222861Smckusick if(q->vtype == TYCHAR) 58322861Smckusick { 58422861Smckusick if(q->vleng == NULL) /* character*(*) */ 58522861Smckusick q->vleng = (expptr) 58622861Smckusick mkarg(TYLENG, nextarg(TYLENG) ); 58722861Smckusick else if(nentry == 1) 58822861Smckusick nextarg(TYLENG); 58922861Smckusick } 59022861Smckusick else if(q->vclass==CLPROC && nentry==1) 59122861Smckusick nextarg(TYLENG) ; 59222861Smckusick #ifdef SDB 59322861Smckusick if(sdbflag) { 59422861Smckusick namestab(q); 59522861Smckusick } 59622861Smckusick #endif 59722861Smckusick } 59822861Smckusick 59922861Smckusick if (optimflag) 60022861Smckusick optbuff (SKLABEL, 0, ep->entrylabel, 0); 60122861Smckusick else 60222861Smckusick putlabel(ep->entrylabel); 60322861Smckusick } 60422861Smckusick 60522861Smckusick 60622861Smckusick 60722861Smckusick LOCAL nextarg(type) 60822861Smckusick int type; 60922861Smckusick { 61022861Smckusick int k; 61122861Smckusick k = lastargslot; 61222861Smckusick lastargslot += typesize[type]; 61322861Smckusick return(k); 61422861Smckusick } 61522861Smckusick 61622861Smckusick /* generate variable references */ 61722861Smckusick 61822861Smckusick LOCAL dobss() 61922861Smckusick { 62022861Smckusick register struct Hashentry *p; 62122861Smckusick register Namep q; 62222861Smckusick register int i; 62322861Smckusick int align; 62422861Smckusick ftnint leng, iarrl; 62522861Smckusick char *memname(); 62622861Smckusick int qstg, qclass, qtype; 62722861Smckusick 62822861Smckusick pruse(asmfile, USEBSS); 62922861Smckusick varsizes = NULL; 63022861Smckusick 63122861Smckusick for(p = hashtab ; p<lasthash ; ++p) 63222861Smckusick if(q = p->varp) 63322861Smckusick { 63422861Smckusick qstg = q->vstg; 63522861Smckusick qtype = q->vtype; 63622861Smckusick qclass = q->vclass; 63722861Smckusick 63822861Smckusick if( (qclass==CLUNKNOWN && qstg!=STGARG) || 63922861Smckusick (qclass==CLVAR && qstg==STGUNKNOWN) ) 64022861Smckusick warn1("local variable %s never used", varstr(VL,q->varname) ); 64122861Smckusick else if(qclass==CLPROC && q->vprocclass==PEXTERNAL && qstg!=STGARG) 64222861Smckusick mkext(varunder(VL, q->varname)) ->extstg = STGEXT; 64322861Smckusick 64422861Smckusick if (qclass == CLVAR && qstg == STGBSS) 64522861Smckusick { 64622861Smckusick if (SMALLVAR(q->varsize)) 64722861Smckusick { 64822861Smckusick enlist(q->varsize, q, NULL); 64922861Smckusick q->inlcomm = NO; 65022861Smckusick } 65122861Smckusick else 65222861Smckusick { 65322861Smckusick if (q->init == NO) 65422861Smckusick { 65522861Smckusick preven(ALIDOUBLE); 65622861Smckusick prlocvar(memname(qstg, q->vardesc.varno), q->varsize); 65722861Smckusick q->inlcomm = YES; 65822861Smckusick } 65922861Smckusick else 66022861Smckusick prlocdata(memname(qstg, q->vardesc.varno), q->varsize, 66122861Smckusick q->vtype, q->initoffset, &(q->inlcomm)); 66222861Smckusick } 66322861Smckusick } 66422861Smckusick else if(qclass==CLVAR && qstg!=STGARG) 66522861Smckusick { 66622861Smckusick if(q->vdim && !ISICON(q->vdim->nelt) ) 66722861Smckusick dclerr("adjustable dimension on non-argument", q); 66822861Smckusick if(qtype==TYCHAR && (q->vleng==NULL || !ISICON(q->vleng))) 66922861Smckusick dclerr("adjustable leng on nonargument", q); 67022861Smckusick } 67122861Smckusick 67222861Smckusick chkdim(q); 67322861Smckusick } 67422861Smckusick 67522861Smckusick for (i = 0 ; i < nequiv ; ++i) 67622861Smckusick if ( (leng = eqvclass[i].eqvleng) != 0 ) 67722861Smckusick { 67822861Smckusick if (SMALLVAR(leng)) 67922861Smckusick enlist(leng, NULL, eqvclass + i); 68022861Smckusick else if (eqvclass[i].init == NO) 68122861Smckusick { 68222861Smckusick preven(ALIDOUBLE); 68322861Smckusick prlocvar(memname(STGEQUIV, i), leng); 68422861Smckusick eqvclass[i].inlcomm = YES; 68522861Smckusick } 68622861Smckusick else 68722861Smckusick prlocdata(memname(STGEQUIV, i), leng, TYDREAL, 68822861Smckusick eqvclass[i].initoffset, &(eqvclass[i].inlcomm)); 68922861Smckusick } 69022861Smckusick 69122861Smckusick outlocvars(); 69222861Smckusick #ifdef SDB 69322861Smckusick if(sdbflag) { 69422861Smckusick for(p = hashtab ; p<lasthash ; ++p) if(q = p->varp) { 69522861Smckusick qstg = q->vstg; 69622861Smckusick qclass = q->vclass; 69722861Smckusick if( ONEOF(qclass, M(CLVAR))) { 69822861Smckusick if (! ONEOF(qstg,M(STGCOMMON)|M(STGARG) ) ) namestab(q); 69922861Smckusick } 70022861Smckusick } 70122861Smckusick } 70222861Smckusick #endif 70322861Smckusick 70422861Smckusick close(vdatafile); 70522861Smckusick close(vchkfile); 70622861Smckusick unlink(vdatafname); 70722861Smckusick unlink(vchkfname); 70822861Smckusick vdatahwm = 0; 70922861Smckusick } 71022861Smckusick 71122861Smckusick 71222861Smckusick 71322861Smckusick donmlist() 71422861Smckusick { 71522861Smckusick register struct Hashentry *p; 71622861Smckusick register Namep q; 71722861Smckusick 71822861Smckusick pruse(asmfile, USEINIT); 71922861Smckusick 72022861Smckusick for(p=hashtab; p<lasthash; ++p) 72122861Smckusick if( (q = p->varp) && q->vclass==CLNAMELIST) 72222861Smckusick namelist(q); 72322861Smckusick } 72422861Smckusick 72522861Smckusick 72622861Smckusick doext() 72722861Smckusick { 72822861Smckusick struct Extsym *p; 72922861Smckusick 73022861Smckusick for(p = extsymtab ; p<nextext ; ++p) 73122861Smckusick prext(p); 73222861Smckusick } 73322861Smckusick 73422861Smckusick 73522861Smckusick 73622861Smckusick 73722861Smckusick ftnint iarrlen(q) 73822861Smckusick register Namep q; 73922861Smckusick { 74022861Smckusick ftnint leng; 74122861Smckusick 74222861Smckusick leng = typesize[q->vtype]; 74322861Smckusick if(leng <= 0) 74422861Smckusick return(-1); 74522861Smckusick if(q->vdim) 74622861Smckusick if( ISICON(q->vdim->nelt) ) 74722861Smckusick leng *= q->vdim->nelt->constblock.const.ci; 74822861Smckusick else return(-1); 74922861Smckusick if(q->vleng) 75022861Smckusick if( ISICON(q->vleng) ) 75122861Smckusick leng *= q->vleng->constblock.const.ci; 75222861Smckusick else return(-1); 75322861Smckusick return(leng); 75422861Smckusick } 75522861Smckusick 75622861Smckusick /* This routine creates a static block representing the namelist. 75722861Smckusick An equivalent declaration of the structure produced is: 75822861Smckusick struct namelist 75922861Smckusick { 76022861Smckusick char namelistname[16]; 76122861Smckusick struct namelistentry 76222861Smckusick { 76324484Sdonn char varname[16]; # 16 plus null padding -> 20 76422861Smckusick char *varaddr; 76524484Sdonn short int type; 76624484Sdonn short int len; # length of type 76722861Smckusick struct dimensions *dimp; # null means scalar 76822861Smckusick } names[]; 76922861Smckusick }; 77022861Smckusick 77122861Smckusick struct dimensions 77222861Smckusick { 77322861Smckusick int numberofdimensions; 77422861Smckusick int numberofelements 77522861Smckusick int baseoffset; 77622861Smckusick int span[numberofdimensions]; 77722861Smckusick }; 77822861Smckusick where the namelistentry list terminates with a null varname 77922861Smckusick If dimp is not null, then the corner element of the array is at 78022861Smckusick varaddr. However, the element with subscripts (i1,...,in) is at 78122861Smckusick varaddr - dimp->baseoffset + sizeoftype * (i1+span[0]*(i2+span[1]*...) 78222861Smckusick */ 78322861Smckusick 78422861Smckusick namelist(np) 78522861Smckusick Namep np; 78622861Smckusick { 78722861Smckusick register chainp q; 78822861Smckusick register Namep v; 78922861Smckusick register struct Dimblock *dp; 79022861Smckusick char *memname(); 79122861Smckusick int type, dimno, dimoffset; 79222861Smckusick flag bad; 79322861Smckusick 79422861Smckusick 79522861Smckusick preven(ALILONG); 79622861Smckusick fprintf(asmfile, LABELFMT, memname(STGINIT, np->vardesc.varno)); 79722861Smckusick putstr(asmfile, varstr(VL, np->varname), 16); 79822861Smckusick dimno = ++lastvarno; 79922861Smckusick dimoffset = 0; 80022861Smckusick bad = NO; 80122861Smckusick 80222861Smckusick for(q = np->varxptr.namelist ; q ; q = q->nextp) 80322861Smckusick { 80422861Smckusick vardcl( v = (Namep) (q->datap) ); 80522861Smckusick type = v->vtype; 80622861Smckusick if( ONEOF(v->vstg, MSKSTATIC) ) 80722861Smckusick { 80822861Smckusick preven(ALILONG); 80922861Smckusick putstr(asmfile, varstr(VL,v->varname), 16); 81022861Smckusick praddr(asmfile, v->vstg, v->vardesc.varno, v->voffset); 81124484Sdonn prconi(asmfile, TYSHORT, type ); 81224484Sdonn prconi(asmfile, TYSHORT, 81322861Smckusick type==TYCHAR ? 81424484Sdonn (v->vleng->constblock.const.ci) : 81524484Sdonn (ftnint) typesize[type]); 81622861Smckusick if(v->vdim) 81722861Smckusick { 81822861Smckusick praddr(asmfile, STGINIT, dimno, (ftnint)dimoffset); 81924484Sdonn dimoffset += (3 + v->vdim->ndim) * SZINT; 82022861Smckusick } 82122861Smckusick else 82222861Smckusick praddr(asmfile, STGNULL,0,(ftnint) 0); 82322861Smckusick } 82422861Smckusick else 82522861Smckusick { 82622861Smckusick dclerr("may not appear in namelist", v); 82722861Smckusick bad = YES; 82822861Smckusick } 82922861Smckusick } 83022861Smckusick 83122861Smckusick if(bad) 83222861Smckusick return; 83322861Smckusick 83422861Smckusick putstr(asmfile, "", 16); 83522861Smckusick 83622861Smckusick if(dimoffset > 0) 83722861Smckusick { 83822861Smckusick fprintf(asmfile, LABELFMT, memname(STGINIT,dimno)); 83922861Smckusick for(q = np->varxptr.namelist ; q ; q = q->nextp) 84022861Smckusick if(dp = q->datap->nameblock.vdim) 84122861Smckusick { 84222861Smckusick int i; 84322861Smckusick prconi(asmfile, TYINT, (ftnint) (dp->ndim) ); 84422861Smckusick prconi(asmfile, TYINT, 84522861Smckusick (ftnint) (dp->nelt->constblock.const.ci) ); 84622861Smckusick prconi(asmfile, TYINT, 84722861Smckusick (ftnint) (dp->baseoffset->constblock.const.ci)); 84822861Smckusick for(i=0; i<dp->ndim ; ++i) 84922861Smckusick prconi(asmfile, TYINT, 85022861Smckusick dp->dims[i].dimsize->constblock.const.ci); 85122861Smckusick } 85222861Smckusick } 85322861Smckusick 85422861Smckusick } 85522861Smckusick 85622861Smckusick LOCAL docommon() 85722861Smckusick { 85822861Smckusick register struct Extsym *p; 85922861Smckusick register chainp q; 86022861Smckusick struct Dimblock *t; 86122861Smckusick expptr neltp; 86222861Smckusick register Namep v; 86322861Smckusick ftnint size; 86422861Smckusick int type; 86522861Smckusick 86622861Smckusick for(p = extsymtab ; p<nextext ; ++p) 86722861Smckusick if(p->extstg==STGCOMMON) 86822861Smckusick { 86922861Smckusick #ifdef SDB 87022861Smckusick if(sdbflag) 87122861Smckusick prstab(varstr(XL,p->extname), N_BCOMM, 0, 0); 87222861Smckusick #endif 87322861Smckusick for(q = p->extp ; q ; q = q->nextp) 87422861Smckusick { 87522861Smckusick v = (Namep) (q->datap); 87622861Smckusick if(v->vdcldone == NO) 87722861Smckusick vardcl(v); 87822861Smckusick type = v->vtype; 87922861Smckusick if(p->extleng % typealign[type] != 0) 88022861Smckusick { 88122861Smckusick dclerr("common alignment", v); 88222861Smckusick p->extleng = roundup(p->extleng, typealign[type]); 88322861Smckusick } 88422861Smckusick v->voffset = p->extleng; 88522861Smckusick v->vardesc.varno = p - extsymtab; 88622861Smckusick if(type == TYCHAR) 88722861Smckusick size = v->vleng->constblock.const.ci; 88822861Smckusick else size = typesize[type]; 88922861Smckusick if(t = v->vdim) 89022861Smckusick if( (neltp = t->nelt) && ISCONST(neltp) ) 89122861Smckusick size *= neltp->constblock.const.ci; 89222861Smckusick else 89322861Smckusick dclerr("adjustable array in common", v); 89422861Smckusick p->extleng += size; 89522861Smckusick #ifdef SDB 89622861Smckusick if(sdbflag) 89722861Smckusick { 89822861Smckusick namestab(v); 89922861Smckusick } 90022861Smckusick #endif 90122861Smckusick } 90222861Smckusick 90322861Smckusick frchain( &(p->extp) ); 90422861Smckusick #ifdef SDB 90522861Smckusick if(sdbflag) 90622861Smckusick prstab(varstr(XL,p->extname), N_ECOMM, 0, 0); 90722861Smckusick #endif 90822861Smckusick } 90922861Smckusick } 91022861Smckusick 91122861Smckusick 91222861Smckusick 91322861Smckusick 91422861Smckusick 91522861Smckusick LOCAL docomleng() 91622861Smckusick { 91722861Smckusick register struct Extsym *p; 91822861Smckusick 91922861Smckusick for(p = extsymtab ; p < nextext ; ++p) 92022861Smckusick if(p->extstg == STGCOMMON) 92122861Smckusick { 92222861Smckusick if(p->maxleng!=0 && p->extleng!=0 && p->maxleng!=p->extleng 92322861Smckusick && !eqn(XL,"_BLNK__ ",p->extname) ) 92422861Smckusick warn1("incompatible lengths for common block %s", 92522861Smckusick nounder(XL, p->extname) ); 92622861Smckusick if(p->maxleng < p->extleng) 92722861Smckusick p->maxleng = p->extleng; 92822861Smckusick p->extleng = 0; 92922861Smckusick } 93022861Smckusick } 93122861Smckusick 93222861Smckusick 93322861Smckusick 93422861Smckusick 93522861Smckusick /* ROUTINES DEALING WITH AUTOMATIC AND TEMPORARY STORAGE */ 93622861Smckusick 93722861Smckusick /* frees a temporary block */ 93822861Smckusick 93922861Smckusick frtemp(p) 94022861Smckusick Tempp p; 94122861Smckusick { 94222861Smckusick Addrp t; 94322861Smckusick 94422861Smckusick if (optimflag) 94522861Smckusick { 94622861Smckusick if (p->tag != TTEMP) 94722861Smckusick badtag ("frtemp",p->tag); 94822861Smckusick t = p->memalloc; 94922861Smckusick } 95022861Smckusick else 95122861Smckusick t = (Addrp) p; 95222861Smckusick 95322861Smckusick /* restore clobbered character string lengths */ 95422861Smckusick if(t->vtype==TYCHAR && t->varleng!=0) 95522861Smckusick { 95622861Smckusick frexpr(t->vleng); 95722861Smckusick t->vleng = ICON(t->varleng); 95822861Smckusick } 95922861Smckusick 96022861Smckusick /* put block on chain of temps to be reclaimed */ 96122861Smckusick holdtemps = mkchain(t, holdtemps); 96222861Smckusick } 96322861Smckusick 96422861Smckusick 96522861Smckusick 96622861Smckusick /* allocate an automatic variable slot */ 96722861Smckusick 96822861Smckusick Addrp autovar(nelt, t, lengp) 96922861Smckusick register int nelt, t; 97022861Smckusick expptr lengp; 97122861Smckusick { 97222861Smckusick ftnint leng; 97322861Smckusick register Addrp q; 97422861Smckusick 97522861Smckusick if(lengp) 97622861Smckusick if( ISICON(lengp) ) 97722861Smckusick leng = lengp->constblock.const.ci; 97822861Smckusick else { 97922861Smckusick fatal("automatic variable of nonconstant length"); 98022861Smckusick } 98122861Smckusick else 98222861Smckusick leng = typesize[t]; 98322861Smckusick autoleng = roundup( autoleng, typealign[t]); 98422861Smckusick 98522861Smckusick q = ALLOC(Addrblock); 98622861Smckusick q->tag = TADDR; 98722861Smckusick q->vtype = t; 98822861Smckusick if(lengp) 98922861Smckusick { 99022861Smckusick q->vleng = ICON(leng); 99122861Smckusick q->varleng = leng; 99222861Smckusick } 99322861Smckusick q->vstg = STGAUTO; 99422861Smckusick q->memno = newlabel(); 99522861Smckusick q->ntempelt = nelt; 99622861Smckusick #if TARGET==PDP11 || TARGET==VAX 99722861Smckusick /* stack grows downward */ 99822861Smckusick autoleng += nelt*leng; 99922861Smckusick q->memoffset = ICON( - autoleng ); 100022861Smckusick #else 100122861Smckusick q->memoffset = ICON( autoleng ); 100222861Smckusick autoleng += nelt*leng; 100322861Smckusick #endif 100422861Smckusick 100522861Smckusick return(q); 100622861Smckusick } 100722861Smckusick 100822861Smckusick 100922861Smckusick 101022861Smckusick /* 101122861Smckusick * create a temporary block (TTEMP) when optimizing, 101222861Smckusick * an ordinary TADDR block when not optimizing 101322861Smckusick */ 101422861Smckusick 101522861Smckusick Tempp mktmpn(nelt, type, lengp) 101622861Smckusick int nelt; 101722861Smckusick register int type; 101822861Smckusick expptr lengp; 101922861Smckusick { 102022861Smckusick ftnint leng; 102122861Smckusick chainp p, oldp; 102222861Smckusick register Tempp q; 102322861Smckusick Addrp altemp; 102422861Smckusick 102522861Smckusick if (! optimflag) 102622861Smckusick return ( (Tempp) mkaltmpn(nelt,type,lengp) ); 102722861Smckusick if(type==TYUNKNOWN || type==TYERROR) 102822861Smckusick badtype("mktmpn", type); 102922861Smckusick 103022861Smckusick if(type==TYCHAR) 103122861Smckusick if( ISICON(lengp) ) 103222861Smckusick leng = lengp->constblock.const.ci; 103322861Smckusick else { 103422861Smckusick err("adjustable length"); 103522861Smckusick return( (Tempp) errnode() ); 103622861Smckusick } 103722861Smckusick else 103822861Smckusick leng = typesize[type]; 103922861Smckusick 104022861Smckusick q = ALLOC(Tempblock); 104122861Smckusick q->tag = TTEMP; 104222861Smckusick q->vtype = type; 104322861Smckusick if(type == TYCHAR) 104422861Smckusick { 104522861Smckusick q->vleng = ICON(leng); 104622861Smckusick q->varleng = leng; 104722861Smckusick } 104822861Smckusick 104922861Smckusick altemp = ALLOC(Addrblock); 105022861Smckusick altemp->tag = TADDR; 105122861Smckusick altemp->vstg = STGUNKNOWN; 105222861Smckusick q->memalloc = altemp; 105322861Smckusick 105422861Smckusick q->ntempelt = nelt; 105522861Smckusick q->istemp = YES; 105622861Smckusick return(q); 105722861Smckusick } 105822861Smckusick 105922861Smckusick 106022861Smckusick 106122861Smckusick Addrp mktemp(type, lengp) 106222861Smckusick int type; 106322861Smckusick expptr lengp; 106422861Smckusick { 106522861Smckusick return( (Addrp) mktmpn(1,type,lengp) ); 106622861Smckusick } 106722861Smckusick 106822861Smckusick 106922861Smckusick 107022861Smckusick /* allocate a temporary location for the given temporary block; 107122861Smckusick if already allocated, return its location */ 107222861Smckusick 107322861Smckusick Addrp altmpn(tp) 107422861Smckusick Tempp tp; 107522861Smckusick 107622861Smckusick { 107722861Smckusick Addrp t, q; 107822861Smckusick 107922861Smckusick if (tp->tag != TTEMP) 108022861Smckusick badtag ("altmpn",tp->tag); 108122861Smckusick 108222861Smckusick t = tp->memalloc; 108322861Smckusick if (t->vstg != STGUNKNOWN) 108422861Smckusick { 108522861Smckusick if (tp->vtype == TYCHAR) 108622861Smckusick { 108722861Smckusick /* 108822861Smckusick * Unformatted I/O parameters are treated like character 108922861Smckusick * strings (sigh) -- propagate type and length. 109022861Smckusick */ 109122861Smckusick t = (Addrp) cpexpr(t); 109222861Smckusick t->vtype = tp->vtype; 109322861Smckusick t->vleng = tp->vleng; 109422861Smckusick t->varleng = tp->varleng; 109522861Smckusick } 109622861Smckusick return (t); 109722861Smckusick } 109822861Smckusick 109922861Smckusick q = mkaltmpn (tp->ntempelt, tp->vtype, tp->vleng); 110022861Smckusick cpn (sizeof(struct Addrblock), (char*)q, (char*)t); 110122861Smckusick free ( (charptr) q); 110222861Smckusick return(t); 110322861Smckusick } 110422861Smckusick 110522861Smckusick 110622861Smckusick 110722861Smckusick /* create and allocate space immediately for a temporary */ 110822861Smckusick 110922861Smckusick Addrp mkaltemp(type,lengp) 111022861Smckusick int type; 111122861Smckusick expptr lengp; 111222861Smckusick { 111322861Smckusick return (mkaltmpn(1,type,lengp)); 111422861Smckusick } 111522861Smckusick 111622861Smckusick 111722861Smckusick 111822861Smckusick Addrp mkaltmpn(nelt,type,lengp) 111922861Smckusick int nelt; 112022861Smckusick register int type; 112122861Smckusick expptr lengp; 112222861Smckusick { 112322861Smckusick ftnint leng; 112422861Smckusick chainp p, oldp; 112522861Smckusick register Addrp q; 112622861Smckusick 112722861Smckusick if(type==TYUNKNOWN || type==TYERROR) 112822861Smckusick badtype("mkaltmpn", type); 112922861Smckusick 113022861Smckusick if(type==TYCHAR) 113122861Smckusick if( ISICON(lengp) ) 113222861Smckusick leng = lengp->constblock.const.ci; 113322861Smckusick else { 113422861Smckusick err("adjustable length"); 113522861Smckusick return( (Addrp) errnode() ); 113622861Smckusick } 113722861Smckusick 113822861Smckusick /* 113922861Smckusick * if a temporary of appropriate shape is on the templist, 114022861Smckusick * remove it from the list and return it 114122861Smckusick */ 114222861Smckusick 114322861Smckusick #ifdef notdef 114422861Smckusick /* 114522861Smckusick * This code is broken until SKFRTEMP slots can be processed in putopt() 114622861Smckusick * instead of in optimize() -- all kinds of things in putpcc.c can 114722861Smckusick * bomb because of this. Sigh. 114822861Smckusick */ 114922861Smckusick for(oldp=CHNULL, p=templist ; p ; oldp=p, p=p->nextp) 115022861Smckusick { 115122861Smckusick q = (Addrp) (p->datap); 115222861Smckusick if(q->vtype==type && q->ntempelt==nelt && 115322861Smckusick (type!=TYCHAR || q->vleng->constblock.const.ci==leng) ) 115422861Smckusick { 115522861Smckusick if(oldp) 115622861Smckusick oldp->nextp = p->nextp; 115722861Smckusick else 115822861Smckusick templist = p->nextp; 115922861Smckusick free( (charptr) p); 116022861Smckusick 116122861Smckusick if (debugflag[14]) 116222861Smckusick fprintf(diagfile,"mkaltmpn reusing offset %d\n", 116322861Smckusick q->memoffset->constblock.const.ci); 116422861Smckusick return(q); 116522861Smckusick } 116622861Smckusick } 116722861Smckusick #endif notdef 116822861Smckusick q = autovar(nelt, type, lengp); 116922861Smckusick q->istemp = YES; 117022861Smckusick 117122861Smckusick if (debugflag[14]) 117222861Smckusick fprintf(diagfile,"mkaltmpn new offset %d\n", 117322861Smckusick q->memoffset->constblock.const.ci); 117422861Smckusick return(q); 117522861Smckusick } 117622861Smckusick 117722861Smckusick 117822861Smckusick 117922861Smckusick /* The following routine is a patch which is only needed because the */ 118022861Smckusick /* code for processing actual arguments for calls does not allocate */ 118122861Smckusick /* the temps it needs before optimization takes place. A better */ 118222861Smckusick /* solution is possible, but I do not have the time to implement it */ 118322861Smckusick /* now. */ 118422861Smckusick /* */ 118522861Smckusick /* Robert P. Corbett */ 118622861Smckusick 118722861Smckusick Addrp 118822861Smckusick mkargtemp(type, lengp) 118922861Smckusick int type; 119022861Smckusick expptr lengp; 119122861Smckusick { 119222861Smckusick ftnint leng; 119322861Smckusick chainp oldp, p; 119422861Smckusick Addrp q; 119522861Smckusick 119622861Smckusick if (type == TYUNKNOWN || type == TYERROR) 119722861Smckusick badtype("mkargtemp", type); 119822861Smckusick 119922861Smckusick if (type == TYCHAR) 120022861Smckusick { 120122861Smckusick if (ISICON(lengp)) 120222861Smckusick leng = lengp->constblock.const.ci; 120322861Smckusick else 120422861Smckusick { 120522861Smckusick err("adjustable length"); 120622861Smckusick return ((Addrp) errnode()); 120722861Smckusick } 120822861Smckusick } 120922861Smckusick 121022861Smckusick oldp = CHNULL; 121122861Smckusick p = argtemplist; 121222861Smckusick 121322861Smckusick while (p) 121422861Smckusick { 121522861Smckusick q = (Addrp) (p->datap); 121622861Smckusick if (q->vtype == type 121722861Smckusick && (type != TYCHAR || q->vleng->constblock.const.ci == leng)) 121822861Smckusick { 121922861Smckusick if (oldp) 122022861Smckusick oldp->nextp = p->nextp; 122122861Smckusick else 122222861Smckusick argtemplist = p->nextp; 122322861Smckusick 122422861Smckusick p->nextp = activearglist; 122522861Smckusick activearglist = p; 122622861Smckusick 122722861Smckusick return ((Addrp) cpexpr(q)); 122822861Smckusick } 122922861Smckusick 123022861Smckusick oldp = p; 123122861Smckusick p = p->nextp; 123222861Smckusick } 123322861Smckusick 123422861Smckusick q = autovar(1, type, lengp); 123522861Smckusick activearglist = mkchain(q, activearglist); 123622861Smckusick return ((Addrp) cpexpr(q)); 123722861Smckusick } 123822861Smckusick 123922861Smckusick /* VARIOUS ROUTINES FOR PROCESSING DECLARATIONS */ 124022861Smckusick 124122861Smckusick struct Extsym *comblock(len, s) 124222861Smckusick register int len; 124322861Smckusick register char *s; 124422861Smckusick { 124522861Smckusick struct Extsym *p; 124622861Smckusick 124722861Smckusick if(len == 0) 124822861Smckusick { 124922861Smckusick s = BLANKCOMMON; 125022861Smckusick len = strlen(s); 125122861Smckusick } 125222861Smckusick p = mkext( varunder(len, s) ); 125322861Smckusick if(p->extstg == STGUNKNOWN) 125422861Smckusick p->extstg = STGCOMMON; 125522861Smckusick else if(p->extstg != STGCOMMON) 125622861Smckusick { 125722861Smckusick errstr("%s cannot be a common block name", s); 125822861Smckusick return(0); 125922861Smckusick } 126022861Smckusick 126122861Smckusick return( p ); 126222861Smckusick } 126322861Smckusick 126422861Smckusick 126522861Smckusick incomm(c, v) 126622861Smckusick struct Extsym *c; 126722861Smckusick Namep v; 126822861Smckusick { 126922861Smckusick if(v->vstg != STGUNKNOWN) 127022861Smckusick dclerr("incompatible common declaration", v); 127122861Smckusick else 127222861Smckusick { 127322861Smckusick if(c == (struct Extsym *) 0) 127422861Smckusick return; /* Illegal common block name upstream */ 127522861Smckusick v->vstg = STGCOMMON; 127622861Smckusick c->extp = hookup(c->extp, mkchain(v,CHNULL) ); 127722861Smckusick } 127822861Smckusick } 127922861Smckusick 128022861Smckusick 128122861Smckusick 128222861Smckusick 128322861Smckusick settype(v, type, length) 128422861Smckusick register Namep v; 128522861Smckusick register int type; 128622861Smckusick register int length; 128722861Smckusick { 128822861Smckusick if(type == TYUNKNOWN) 128922861Smckusick return; 129022861Smckusick 129122861Smckusick if(type==TYSUBR && v->vtype!=TYUNKNOWN && v->vstg==STGARG) 129222861Smckusick { 129322861Smckusick v->vtype = TYSUBR; 129422861Smckusick frexpr(v->vleng); 129522861Smckusick } 129622861Smckusick else if(type < 0) /* storage class set */ 129722861Smckusick { 129822861Smckusick if(v->vstg == STGUNKNOWN) 129922861Smckusick v->vstg = - type; 130022861Smckusick else if(v->vstg != -type) 130122861Smckusick dclerr("incompatible storage declarations", v); 130222861Smckusick } 130322861Smckusick else if(v->vtype == TYUNKNOWN) 130422861Smckusick { 1305*25744Sdonn if( (v->vtype = lengtype(type, length))==TYCHAR ) 1306*25744Sdonn { 1307*25744Sdonn if(length >= 0) 1308*25744Sdonn v->vleng = ICON(length); 1309*25744Sdonn else if(v->vstg != STGARG) 1310*25744Sdonn dclerr("adjustable length character variable that is not a dummy argument", v); 1311*25744Sdonn } 131222861Smckusick } 131322861Smckusick else if(v->vtype!=type || (type==TYCHAR && v->vleng->constblock.const.ci!=length) ) 131422861Smckusick dclerr("incompatible type declarations", v); 131522861Smckusick } 131622861Smckusick 131722861Smckusick 131822861Smckusick 131922861Smckusick 132022861Smckusick 132122861Smckusick lengtype(type, length) 132222861Smckusick register int type; 132322861Smckusick register int length; 132422861Smckusick { 132522861Smckusick switch(type) 132622861Smckusick { 132722861Smckusick case TYREAL: 132822861Smckusick if(length == 8) 132922861Smckusick return(TYDREAL); 133022861Smckusick if(length == 4) 133122861Smckusick goto ret; 133222861Smckusick break; 133322861Smckusick 133422861Smckusick case TYCOMPLEX: 133522861Smckusick if(length == 16) 133622861Smckusick return(TYDCOMPLEX); 133722861Smckusick if(length == 8) 133822861Smckusick goto ret; 133922861Smckusick break; 134022861Smckusick 134122861Smckusick case TYSHORT: 134222861Smckusick case TYDREAL: 134322861Smckusick case TYDCOMPLEX: 134422861Smckusick case TYCHAR: 134522861Smckusick case TYUNKNOWN: 134622861Smckusick case TYSUBR: 134722861Smckusick case TYERROR: 134822861Smckusick goto ret; 134922861Smckusick 135022861Smckusick case TYLOGICAL: 135122861Smckusick if(length == typesize[TYLOGICAL]) 135222861Smckusick goto ret; 135322861Smckusick break; 135422861Smckusick 135522861Smckusick case TYLONG: 135622861Smckusick if(length == 0) 135722861Smckusick return(tyint); 135822861Smckusick if(length == 2) 135922861Smckusick return(TYSHORT); 136022861Smckusick if(length == 4) 136122861Smckusick goto ret; 136222861Smckusick break; 136322861Smckusick default: 136422861Smckusick badtype("lengtype", type); 136522861Smckusick } 136622861Smckusick 136722861Smckusick if(length != 0) 136822861Smckusick err("incompatible type-length combination"); 136922861Smckusick 137022861Smckusick ret: 137122861Smckusick return(type); 137222861Smckusick } 137322861Smckusick 137422861Smckusick 137522861Smckusick 137622861Smckusick 137722861Smckusick 137822861Smckusick setintr(v) 137922861Smckusick register Namep v; 138022861Smckusick { 138122861Smckusick register int k; 138222861Smckusick 138322861Smckusick if(v->vstg == STGUNKNOWN) 138422861Smckusick v->vstg = STGINTR; 138522861Smckusick else if(v->vstg!=STGINTR) 138622861Smckusick dclerr("incompatible use of intrinsic function", v); 138722861Smckusick if(v->vclass==CLUNKNOWN) 138822861Smckusick v->vclass = CLPROC; 138922861Smckusick if(v->vprocclass == PUNKNOWN) 139022861Smckusick v->vprocclass = PINTRINSIC; 139122861Smckusick else if(v->vprocclass != PINTRINSIC) 139222861Smckusick dclerr("invalid intrinsic declaration", v); 139322861Smckusick if(k = intrfunct(v->varname)) 139422861Smckusick v->vardesc.varno = k; 139522861Smckusick else 139622861Smckusick dclerr("unknown intrinsic function", v); 139722861Smckusick } 139822861Smckusick 139922861Smckusick 140022861Smckusick 140122861Smckusick setext(v) 140222861Smckusick register Namep v; 140322861Smckusick { 140422861Smckusick if(v->vclass == CLUNKNOWN) 140522861Smckusick v->vclass = CLPROC; 140622861Smckusick else if(v->vclass != CLPROC) 140722861Smckusick dclerr("conflicting declarations", v); 140822861Smckusick 140922861Smckusick if(v->vprocclass == PUNKNOWN) 141022861Smckusick v->vprocclass = PEXTERNAL; 141122861Smckusick else if(v->vprocclass != PEXTERNAL) 141222861Smckusick dclerr("conflicting declarations", v); 141322861Smckusick } 141422861Smckusick 141522861Smckusick 141622861Smckusick 141722861Smckusick 141822861Smckusick /* create dimensions block for array variable */ 141922861Smckusick 142022861Smckusick setbound(v, nd, dims) 142122861Smckusick register Namep v; 142222861Smckusick int nd; 142322861Smckusick struct { expptr lb, ub; } dims[ ]; 142422861Smckusick { 142522861Smckusick register expptr q, t; 142622861Smckusick register struct Dimblock *p; 142722861Smckusick int i; 142822861Smckusick 142922861Smckusick if(v->vclass == CLUNKNOWN) 143022861Smckusick v->vclass = CLVAR; 143122861Smckusick else if(v->vclass != CLVAR) 143222861Smckusick { 143322861Smckusick dclerr("only variables may be arrays", v); 143422861Smckusick return; 143522861Smckusick } 143622861Smckusick if(v->vdim) 143722861Smckusick { 143822861Smckusick dclerr("redimensioned array", v); 143922861Smckusick return; 144022861Smckusick } 144122861Smckusick 144222861Smckusick v->vdim = p = (struct Dimblock *) 144322861Smckusick ckalloc( sizeof(int) + (3+6*nd)*sizeof(expptr) ); 144422861Smckusick p->ndim = nd; 144522861Smckusick p->nelt = ICON(1); 144622861Smckusick 144722861Smckusick for(i=0 ; i<nd ; ++i) 144822861Smckusick { 144922861Smckusick #ifdef SDB 145022861Smckusick if(sdbflag) { 145122861Smckusick /* Save the bounds trees built up by the grammar routines for use in stabs */ 145222861Smckusick 145322861Smckusick if(dims[i].lb == NULL) p->dims[i].lb=ICON(1); 145422861Smckusick else p->dims[i].lb= (expptr) cpexpr(dims[i].lb); 145522861Smckusick if(ISCONST(p->dims[i].lb)) p->dims[i].lbaddr = (expptr) PNULL; 145622861Smckusick else p->dims[i].lbaddr = (expptr) autovar(1, tyint, PNULL); 145722861Smckusick 145822861Smckusick if(dims[i].ub == NULL) p->dims[i].ub=ICON(1); 145922861Smckusick else p->dims[i].ub = (expptr) cpexpr(dims[i].ub); 146022861Smckusick if(ISCONST(p->dims[i].ub)) p->dims[i].ubaddr = (expptr) PNULL; 146122861Smckusick else p->dims[i].ubaddr = (expptr) autovar(1, tyint, PNULL); 146222861Smckusick } 146322861Smckusick #endif 146422861Smckusick if( (q = dims[i].ub) == NULL) 146522861Smckusick { 146622861Smckusick if(i == nd-1) 146722861Smckusick { 146822861Smckusick frexpr(p->nelt); 146922861Smckusick p->nelt = NULL; 147022861Smckusick } 147122861Smckusick else 147222861Smckusick err("only last bound may be asterisk"); 147322861Smckusick p->dims[i].dimsize = ICON(1);; 147422861Smckusick p->dims[i].dimexpr = NULL; 147522861Smckusick } 147622861Smckusick else 147722861Smckusick { 147822861Smckusick if(dims[i].lb) 147922861Smckusick { 148022861Smckusick q = mkexpr(OPMINUS, q, cpexpr(dims[i].lb)); 148122861Smckusick q = mkexpr(OPPLUS, q, ICON(1) ); 148222861Smckusick } 148322861Smckusick if( ISCONST(q) ) 148422861Smckusick { 148522861Smckusick if (!ISINT(q->headblock.vtype)) { 148622861Smckusick dclerr("dimension bounds must be integer expression", v); 148722861Smckusick frexpr(q); 148822861Smckusick q = ICON(0); 148922861Smckusick } 149022861Smckusick if ( q->constblock.const.ci <= 0) 149122861Smckusick { 149222861Smckusick dclerr("array bounds out of sequence", v); 149322861Smckusick frexpr(q); 149422861Smckusick q = ICON(0); 149522861Smckusick } 149622861Smckusick p->dims[i].dimsize = q; 149722861Smckusick p->dims[i].dimexpr = (expptr) PNULL; 149822861Smckusick } 149922861Smckusick else { 150022861Smckusick p->dims[i].dimsize = (expptr) autovar(1, tyint, PNULL); 150122861Smckusick p->dims[i].dimexpr = q; 150222861Smckusick } 150322861Smckusick if(p->nelt) 150422861Smckusick p->nelt = mkexpr(OPSTAR, p->nelt, 150522861Smckusick cpexpr(p->dims[i].dimsize) ); 150622861Smckusick } 150722861Smckusick } 150822861Smckusick 150922861Smckusick q = dims[nd-1].lb; 151022861Smckusick if(q == NULL) 151122861Smckusick q = ICON(1); 151222861Smckusick 151322861Smckusick for(i = nd-2 ; i>=0 ; --i) 151422861Smckusick { 151522861Smckusick t = dims[i].lb; 151622861Smckusick if(t == NULL) 151722861Smckusick t = ICON(1); 151822861Smckusick if(p->dims[i].dimsize) 151922861Smckusick q = mkexpr(OPPLUS, t, mkexpr(OPSTAR, cpexpr(p->dims[i].dimsize), q) ); 152022861Smckusick } 152122861Smckusick 152222861Smckusick if( ISCONST(q) ) 152322861Smckusick { 152422861Smckusick p->baseoffset = q; 152522861Smckusick p->basexpr = NULL; 152622861Smckusick } 152722861Smckusick else 152822861Smckusick { 152922861Smckusick p->baseoffset = (expptr) autovar(1, tyint, PNULL); 153022861Smckusick p->basexpr = q; 153122861Smckusick } 153222861Smckusick } 153322861Smckusick 153422861Smckusick 153522861Smckusick 153622861Smckusick /* 153722861Smckusick * Check the dimensions of q to ensure that they are appropriately defined. 153822861Smckusick */ 153922861Smckusick LOCAL chkdim(q) 154022861Smckusick register Namep q; 154122861Smckusick { 154222861Smckusick register struct Dimblock *p; 154322861Smckusick register int i; 154422861Smckusick expptr e; 154522861Smckusick 154622861Smckusick if (q == NULL) 154722861Smckusick return; 154822861Smckusick if (q->vclass != CLVAR) 154922861Smckusick return; 155022861Smckusick if (q->vdim == NULL) 155122861Smckusick return; 155222861Smckusick p = q->vdim; 155322861Smckusick for (i = 0; i < p->ndim; ++i) 155422861Smckusick { 155522861Smckusick #ifdef SDB 155622861Smckusick if (sdbflag) 155722861Smckusick { 155822861Smckusick if (e = p->dims[i].lb) 155922861Smckusick chkdime(e, q); 156022861Smckusick if (e = p->dims[i].ub) 156122861Smckusick chkdime(e, q); 156222861Smckusick } 156322861Smckusick else 156422861Smckusick #endif SDB 156522861Smckusick if (e = p->dims[i].dimexpr) 156622861Smckusick chkdime(e, q); 156722861Smckusick } 156822861Smckusick } 156922861Smckusick 157022861Smckusick 157122861Smckusick 157222861Smckusick /* 157322861Smckusick * The actual checking for chkdim() -- examines each expression. 157422861Smckusick */ 157522861Smckusick LOCAL chkdime(expr, q) 157622861Smckusick expptr expr; 157722861Smckusick Namep q; 157822861Smckusick { 157922861Smckusick register expptr e; 158022861Smckusick 158122861Smckusick e = fixtype(cpexpr(expr)); 158222861Smckusick if (!ISINT(e->exprblock.vtype)) 158322861Smckusick dclerr("non-integer dimension", q); 158422861Smckusick else if (!safedim(e)) 158522861Smckusick dclerr("undefined dimension", q); 158622861Smckusick frexpr(e); 158722861Smckusick return; 158822861Smckusick } 158922861Smckusick 159022861Smckusick 159122861Smckusick 159222861Smckusick /* 159322861Smckusick * A recursive routine to find undefined variables in dimension expressions. 159422861Smckusick */ 159522861Smckusick LOCAL safedim(e) 159622861Smckusick expptr e; 159722861Smckusick { 159822861Smckusick chainp cp; 159922861Smckusick 160022861Smckusick if (e == NULL) 160122861Smckusick return 1; 160222861Smckusick switch (e->tag) 160322861Smckusick { 160422861Smckusick case TEXPR: 160522861Smckusick if (e->exprblock.opcode == OPCALL || e->exprblock.opcode == OPCCALL) 160622861Smckusick return 0; 160722861Smckusick return safedim(e->exprblock.leftp) && safedim(e->exprblock.rightp); 160822861Smckusick case TADDR: 160922861Smckusick switch (e->addrblock.vstg) 161022861Smckusick { 161122861Smckusick case STGCOMMON: 161222861Smckusick case STGARG: 161322861Smckusick case STGCONST: 161422861Smckusick case STGEQUIV: 161522861Smckusick if (e->addrblock.isarray) 161622861Smckusick return 0; 161722861Smckusick return safedim(e->addrblock.memoffset); 161822861Smckusick default: 161922861Smckusick return 0; 162022861Smckusick } 162122861Smckusick case TCONST: 162222861Smckusick case TTEMP: 162322861Smckusick return 1; 162422861Smckusick } 162522861Smckusick return 0; 162622861Smckusick } 162722861Smckusick 162822861Smckusick 162922861Smckusick 163022861Smckusick LOCAL enlist(size, np, ep) 163122861Smckusick ftnint size; 163222861Smckusick Namep np; 163322861Smckusick struct Equivblock *ep; 163422861Smckusick { 163522861Smckusick register sizelist *sp; 163622861Smckusick register sizelist *t; 163722861Smckusick register varlist *p; 163822861Smckusick 163922861Smckusick sp = varsizes; 164022861Smckusick 164122861Smckusick if (sp == NULL) 164222861Smckusick { 164322861Smckusick sp = ALLOC(SizeList); 164422861Smckusick sp->size = size; 164522861Smckusick varsizes = sp; 164622861Smckusick } 164722861Smckusick else 164822861Smckusick { 164922861Smckusick while (sp->size != size) 165022861Smckusick { 165122861Smckusick if (sp->next != NULL && sp->next->size <= size) 165222861Smckusick sp = sp->next; 165322861Smckusick else 165422861Smckusick { 165522861Smckusick t = sp; 165622861Smckusick sp = ALLOC(SizeList); 165722861Smckusick sp->size = size; 165822861Smckusick sp->next = t->next; 165922861Smckusick t->next = sp; 166022861Smckusick } 166122861Smckusick } 166222861Smckusick } 166322861Smckusick 166422861Smckusick p = ALLOC(VarList); 166522861Smckusick p->next = sp->vars; 166622861Smckusick p->np = np; 166722861Smckusick p->ep = ep; 166822861Smckusick 166922861Smckusick sp->vars = p; 167022861Smckusick 167122861Smckusick return; 167222861Smckusick } 167322861Smckusick 167422861Smckusick 167522861Smckusick 167622861Smckusick outlocvars() 167722861Smckusick { 167822861Smckusick 167922861Smckusick register varlist *first, *last; 168022861Smckusick register varlist *vp, *t; 168122861Smckusick register sizelist *sp, *sp1; 168222861Smckusick register Namep np; 168322861Smckusick register struct Equivblock *ep; 168422861Smckusick register int i; 168522861Smckusick register int alt; 168622861Smckusick register int type; 168722861Smckusick char sname[100]; 168822861Smckusick char setbuff[100]; 168922861Smckusick 169022861Smckusick sp = varsizes; 169122861Smckusick if (sp == NULL) 169222861Smckusick return; 169322861Smckusick 169422861Smckusick vp = sp->vars; 169522861Smckusick if (vp->np != NULL) 169622861Smckusick { 169722861Smckusick np = vp->np; 169822861Smckusick sprintf(setbuff, "\t.set\tv.%d,v.%d\n", bsslabel, 169922861Smckusick np->vardesc.varno); 170022861Smckusick } 170122861Smckusick else 170222861Smckusick { 170322861Smckusick i = vp->ep - eqvclass; 170422861Smckusick sprintf(setbuff, "\t.set\tv.%d,q.%d\n", bsslabel, i + eqvstart); 170522861Smckusick } 170622861Smckusick 170722861Smckusick first = last = NULL; 170822861Smckusick alt = NO; 170922861Smckusick 171022861Smckusick while (sp != NULL) 171122861Smckusick { 171222861Smckusick vp = sp->vars; 171322861Smckusick while (vp != NULL) 171422861Smckusick { 171522861Smckusick t = vp->next; 171622861Smckusick if (alt == YES) 171722861Smckusick { 171822861Smckusick alt = NO; 171922861Smckusick vp->next = first; 172022861Smckusick first = vp; 172122861Smckusick } 172222861Smckusick else 172322861Smckusick { 172422861Smckusick alt = YES; 172522861Smckusick if (last != NULL) 172622861Smckusick last->next = vp; 172722861Smckusick else 172822861Smckusick first = vp; 172922861Smckusick vp->next = NULL; 173022861Smckusick last = vp; 173122861Smckusick } 173222861Smckusick vp = t; 173322861Smckusick } 173422861Smckusick sp1 = sp; 173522861Smckusick sp = sp->next; 173622861Smckusick free((char *) sp1); 173722861Smckusick } 173822861Smckusick 173922861Smckusick vp = first; 174022861Smckusick while(vp != NULL) 174122861Smckusick { 174222861Smckusick if (vp->np != NULL) 174322861Smckusick { 174422861Smckusick np = vp->np; 174522861Smckusick sprintf(sname, "v.%d", np->vardesc.varno); 174622861Smckusick if (np->init) 174722861Smckusick prlocdata(sname, np->varsize, np->vtype, np->initoffset, 174822861Smckusick &(np->inlcomm)); 174922861Smckusick else 175022861Smckusick { 175122861Smckusick pralign(typealign[np->vtype]); 175225103Sdonn fprintf(initfile, "%s:\n", sname); 175325103Sdonn prspace(np->varsize); 175422861Smckusick } 175522861Smckusick np->inlcomm = NO; 175622861Smckusick } 175722861Smckusick else 175822861Smckusick { 175922861Smckusick ep = vp->ep; 176022861Smckusick i = ep - eqvclass; 176122861Smckusick if (ep->eqvleng >= 8) 176222861Smckusick type = TYDREAL; 176322861Smckusick else if (ep->eqvleng >= 4) 176422861Smckusick type = TYLONG; 176522861Smckusick else if (ep->eqvleng >= 2) 176622861Smckusick type = TYSHORT; 176722861Smckusick else 176822861Smckusick type = TYCHAR; 176922861Smckusick sprintf(sname, "q.%d", i + eqvstart); 177022861Smckusick if (ep->init) 177122861Smckusick prlocdata(sname, ep->eqvleng, type, ep->initoffset, 177222861Smckusick &(ep->inlcomm)); 177322861Smckusick else 177422861Smckusick { 177522861Smckusick pralign(typealign[type]); 177625103Sdonn fprintf(initfile, "%s:\n", sname); 177725103Sdonn prspace(ep->eqvleng); 177822861Smckusick } 177922861Smckusick ep->inlcomm = NO; 178022861Smckusick } 178122861Smckusick t = vp; 178222861Smckusick vp = vp->next; 178322861Smckusick free((char *) t); 178422861Smckusick } 178522861Smckusick fprintf(initfile, "%s\n", setbuff); 178622861Smckusick return; 178722861Smckusick } 1788