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