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