xref: /original-bsd/usr.bin/f77/pass1.tahoe/exec.c (revision b8be84b8)
1*b8be84b8Sbostic /*-
2*b8be84b8Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*b8be84b8Sbostic  * All rights reserved.
4*b8be84b8Sbostic  *
5*b8be84b8Sbostic  * %sccs.include.proprietary.c%
6ec6500d3Sbostic  */
7ec6500d3Sbostic 
8ec6500d3Sbostic #ifndef lint
9*b8be84b8Sbostic static char sccsid[] = "@(#)exec.c	5.3 (Berkeley) 04/12/91";
10*b8be84b8Sbostic #endif /* not lint */
11ec6500d3Sbostic 
12ec6500d3Sbostic /*
13ec6500d3Sbostic  * exec.c
14ec6500d3Sbostic  *
15ec6500d3Sbostic  * Routines for handling the semantics of control structures.
16ec6500d3Sbostic  * F77 compiler, pass 1.
17ec6500d3Sbostic  *
18ec6500d3Sbostic  * University of Utah CS Dept modification history:
19ec6500d3Sbostic  *
20ec6500d3Sbostic  * Revision 2.3  85/03/18  08:03:31  donn
21ec6500d3Sbostic  * Hacks for conversions from type address to numeric type -- prevent addresses
22ec6500d3Sbostic  * from being stored in shorts and prevent warnings about implicit conversions.
23ec6500d3Sbostic  *
24ec6500d3Sbostic  * Revision 2.2  84/09/03  23:18:30  donn
25ec6500d3Sbostic  * When a DO loop had the same variable as its loop variable and its limit,
26ec6500d3Sbostic  * the limit temporary was assigned to AFTER the original value of the variable
27ec6500d3Sbostic  * was destroyed by assigning the initial value to the loop variable.  I
28ec6500d3Sbostic  * swapped the operands of a comparison and changed the direction of the
29ec6500d3Sbostic  * operator...  This only affected programs when optimizing.  (This may not
30ec6500d3Sbostic  * be enough if something alters the order of evaluation of side effects
31ec6500d3Sbostic  * later on... sigh.)
32ec6500d3Sbostic  *
33ec6500d3Sbostic  * Revision 2.1  84/07/19  12:02:53  donn
34ec6500d3Sbostic  * Changed comment headers for UofU.
35ec6500d3Sbostic  *
36ec6500d3Sbostic  * Revision 1.3  84/07/12  18:35:12  donn
37ec6500d3Sbostic  * Added change to enddo() to detect open 'if' blocks at the ends of loops.
38ec6500d3Sbostic  *
39ec6500d3Sbostic  * Revision 1.2  84/06/08  11:22:53  donn
40ec6500d3Sbostic  * Fixed bug in exdo() -- if a loop parameter contained an instance of the loop
41ec6500d3Sbostic  * variable and the optimizer was off, the loop variable got converted to
42ec6500d3Sbostic  * register before the parameters were processed and so the loop parameters
43ec6500d3Sbostic  * were initialized from garbage in the register instead of the memory version
44ec6500d3Sbostic  * of the loop variable.
45ec6500d3Sbostic  *
46ec6500d3Sbostic  */
47ec6500d3Sbostic 
48ec6500d3Sbostic #include "defs.h"
49ec6500d3Sbostic #include "optim.h"
50ec6500d3Sbostic 
51ec6500d3Sbostic 
52ec6500d3Sbostic /*   Logical IF codes
53ec6500d3Sbostic */
54ec6500d3Sbostic 
55ec6500d3Sbostic 
exif(p)56ec6500d3Sbostic exif(p)
57ec6500d3Sbostic expptr p;
58ec6500d3Sbostic {
59ec6500d3Sbostic register int k;
60ec6500d3Sbostic pushctl(CTLIF);
61ec6500d3Sbostic ctlstack->elselabel = newlabel();
62ec6500d3Sbostic 
63ec6500d3Sbostic if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL)
64ec6500d3Sbostic 	{
65ec6500d3Sbostic 	if(k != TYERROR)
66ec6500d3Sbostic 		err("non-logical expression in IF statement");
67ec6500d3Sbostic 	frexpr(p);
68ec6500d3Sbostic 	}
69ec6500d3Sbostic else if (optimflag)
70ec6500d3Sbostic 	optbuff (SKIFN, p, ctlstack->elselabel, 0);
71ec6500d3Sbostic else
72ec6500d3Sbostic 	putif (p, ctlstack->elselabel);
73ec6500d3Sbostic }
74ec6500d3Sbostic 
75ec6500d3Sbostic 
76ec6500d3Sbostic 
exelif(p)77ec6500d3Sbostic exelif(p)
78ec6500d3Sbostic expptr p;
79ec6500d3Sbostic {
80ec6500d3Sbostic int k,oldelse;
81ec6500d3Sbostic 
82ec6500d3Sbostic if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL)
83ec6500d3Sbostic 	{
84ec6500d3Sbostic 	if(k != TYERROR)
85ec6500d3Sbostic 		err("non-logical expression in IF statement");
86ec6500d3Sbostic 	frexpr(p);
87ec6500d3Sbostic 	}
88ec6500d3Sbostic else    {
89ec6500d3Sbostic         if(ctlstack->ctltype == CTLIF)
90ec6500d3Sbostic 		{
91ec6500d3Sbostic 		if(ctlstack->endlabel == 0) ctlstack->endlabel = newlabel();
92ec6500d3Sbostic         	oldelse=ctlstack->elselabel;
93ec6500d3Sbostic 		ctlstack->elselabel = newlabel();
94ec6500d3Sbostic 		if (optimflag)
95ec6500d3Sbostic 			{
96ec6500d3Sbostic 			optbuff (SKGOTO, 0, ctlstack->endlabel, 0);
97ec6500d3Sbostic 			optbuff (SKLABEL, 0, oldelse, 0);
98ec6500d3Sbostic 			optbuff (SKIFN, p, ctlstack->elselabel, 0);
99ec6500d3Sbostic 			}
100ec6500d3Sbostic 		else
101ec6500d3Sbostic 			{
102ec6500d3Sbostic 			putgoto (ctlstack->endlabel);
103ec6500d3Sbostic 			putlabel (oldelse);
104ec6500d3Sbostic 			putif (p, ctlstack->elselabel);
105ec6500d3Sbostic 			}
106ec6500d3Sbostic 		}
107ec6500d3Sbostic         else	execerr("elseif out of place", CNULL);
108ec6500d3Sbostic         }
109ec6500d3Sbostic }
110ec6500d3Sbostic 
111ec6500d3Sbostic 
112ec6500d3Sbostic 
113ec6500d3Sbostic 
114ec6500d3Sbostic 
exelse()115ec6500d3Sbostic exelse()
116ec6500d3Sbostic {
117ec6500d3Sbostic if(ctlstack->ctltype==CTLIF)
118ec6500d3Sbostic 	{
119ec6500d3Sbostic 	if(ctlstack->endlabel == 0)
120ec6500d3Sbostic 		ctlstack->endlabel = newlabel();
121ec6500d3Sbostic 	ctlstack->ctltype = CTLELSE;
122ec6500d3Sbostic 	if (optimflag)
123ec6500d3Sbostic 		{
124ec6500d3Sbostic 		optbuff (SKGOTO, 0, ctlstack->endlabel, 0);
125ec6500d3Sbostic 		optbuff (SKLABEL, 0, ctlstack->elselabel, 0);
126ec6500d3Sbostic 		}
127ec6500d3Sbostic 	else
128ec6500d3Sbostic 		{
129ec6500d3Sbostic 		putgoto (ctlstack->endlabel);
130ec6500d3Sbostic 		putlabel (ctlstack->elselabel);
131ec6500d3Sbostic 		}
132ec6500d3Sbostic 	}
133ec6500d3Sbostic 
134ec6500d3Sbostic else	execerr("else out of place", CNULL);
135ec6500d3Sbostic }
136ec6500d3Sbostic 
137ec6500d3Sbostic 
exendif()138ec6500d3Sbostic exendif()
139ec6500d3Sbostic {
140ec6500d3Sbostic if (ctlstack->ctltype == CTLIF)
141ec6500d3Sbostic 	{
142ec6500d3Sbostic 	if (optimflag)
143ec6500d3Sbostic 		{
144ec6500d3Sbostic 		optbuff (SKLABEL, 0, ctlstack->elselabel, 0);
145ec6500d3Sbostic 		if (ctlstack->endlabel)
146ec6500d3Sbostic 			optbuff (SKLABEL, 0, ctlstack->endlabel, 0);
147ec6500d3Sbostic 		}
148ec6500d3Sbostic 	else
149ec6500d3Sbostic 		{
150ec6500d3Sbostic 		putlabel (ctlstack->elselabel);
151ec6500d3Sbostic 		if (ctlstack->endlabel)
152ec6500d3Sbostic 			putlabel (ctlstack->endlabel);
153ec6500d3Sbostic 		}
154ec6500d3Sbostic 	popctl ();
155ec6500d3Sbostic 	}
156ec6500d3Sbostic else if (ctlstack->ctltype == CTLELSE)
157ec6500d3Sbostic 	{
158ec6500d3Sbostic 	if (optimflag)
159ec6500d3Sbostic 		optbuff (SKLABEL, 0, ctlstack->endlabel, 0);
160ec6500d3Sbostic 	else
161ec6500d3Sbostic 		putlabel (ctlstack->endlabel);
162ec6500d3Sbostic 	popctl ();
163ec6500d3Sbostic 	}
164ec6500d3Sbostic else
165ec6500d3Sbostic 	execerr("endif out of place", CNULL);
166ec6500d3Sbostic }
167ec6500d3Sbostic 
168ec6500d3Sbostic 
169ec6500d3Sbostic 
pushctl(code)170ec6500d3Sbostic LOCAL pushctl(code)
171ec6500d3Sbostic int code;
172ec6500d3Sbostic {
173ec6500d3Sbostic register int i;
174ec6500d3Sbostic 
175ec6500d3Sbostic /* fprintf(diagfile,"old blklevel %d \n",blklevel); dmpframe(ctlstack); */
176ec6500d3Sbostic if(++ctlstack >= lastctl)
177ec6500d3Sbostic 	many("loops or if-then-elses", 'c');
178ec6500d3Sbostic ctlstack->ctltype = code;
179ec6500d3Sbostic for(i = 0 ; i < 4 ; ++i)
180ec6500d3Sbostic 	ctlstack->ctlabels[i] = 0;
181ec6500d3Sbostic ++blklevel;
182ec6500d3Sbostic }
183ec6500d3Sbostic 
184ec6500d3Sbostic 
popctl()185ec6500d3Sbostic LOCAL popctl()
186ec6500d3Sbostic {
187ec6500d3Sbostic if( ctlstack-- < ctls )
188ec6500d3Sbostic 	fatal("control stack empty");
189ec6500d3Sbostic --blklevel;
190ec6500d3Sbostic }
191ec6500d3Sbostic 
192ec6500d3Sbostic 
193ec6500d3Sbostic 
poplab()194ec6500d3Sbostic LOCAL poplab()
195ec6500d3Sbostic {
196ec6500d3Sbostic register struct Labelblock  *lp;
197ec6500d3Sbostic 
198ec6500d3Sbostic for(lp = labeltab ; lp < highlabtab ; ++lp)
199ec6500d3Sbostic 	if(lp->labdefined)
200ec6500d3Sbostic 		{
201ec6500d3Sbostic 		/* mark all labels in inner blocks unreachable */
202ec6500d3Sbostic 		if(lp->blklevel > blklevel)
203ec6500d3Sbostic 			lp->labinacc = YES;
204ec6500d3Sbostic 		}
205ec6500d3Sbostic 	else if(lp->blklevel > blklevel)
206ec6500d3Sbostic 		{
207ec6500d3Sbostic 		/* move all labels referred to in inner blocks out a level */
208ec6500d3Sbostic 		lp->blklevel = blklevel;
209ec6500d3Sbostic 		}
210ec6500d3Sbostic }
211ec6500d3Sbostic 
212ec6500d3Sbostic 
213ec6500d3Sbostic 
214ec6500d3Sbostic /*  BRANCHING CODE
215ec6500d3Sbostic */
216ec6500d3Sbostic 
217ec6500d3Sbostic exgoto(lab)
218ec6500d3Sbostic struct Labelblock *lab;
219ec6500d3Sbostic {
220ec6500d3Sbostic if (optimflag)
221ec6500d3Sbostic 	optbuff (SKGOTO, 0, lab->labelno, 0);
222ec6500d3Sbostic else
223ec6500d3Sbostic 	putgoto (lab->labelno);
224ec6500d3Sbostic }
225ec6500d3Sbostic 
226ec6500d3Sbostic 
227ec6500d3Sbostic 
228ec6500d3Sbostic 
229ec6500d3Sbostic 
230ec6500d3Sbostic 
231ec6500d3Sbostic 
exequals(lp,rp)232ec6500d3Sbostic exequals(lp, rp)
233ec6500d3Sbostic register struct Primblock *lp;
234ec6500d3Sbostic register expptr rp;
235ec6500d3Sbostic {
236ec6500d3Sbostic register Namep np;
237ec6500d3Sbostic 
238ec6500d3Sbostic if(lp->tag != TPRIM)
239ec6500d3Sbostic 	{
240ec6500d3Sbostic 	err("assignment to a non-variable");
241ec6500d3Sbostic 	frexpr(lp);
242ec6500d3Sbostic 	frexpr(rp);
243ec6500d3Sbostic 	}
244ec6500d3Sbostic else if(lp->namep->vclass!=CLVAR && lp->argsp)
245ec6500d3Sbostic 	{
246ec6500d3Sbostic 	if(parstate >= INEXEC)
247ec6500d3Sbostic 		err("assignment to an undimemsioned array");
248ec6500d3Sbostic 	else
249ec6500d3Sbostic 		mkstfunct(lp, rp);
250ec6500d3Sbostic 	}
251ec6500d3Sbostic else
252ec6500d3Sbostic 	{
253ec6500d3Sbostic 	np = (Namep) lp->namep;
254ec6500d3Sbostic 	if (np->vclass == CLPROC && np->vprocclass == PTHISPROC
255ec6500d3Sbostic 		&& proctype == TYSUBR)
256ec6500d3Sbostic 		{
257ec6500d3Sbostic 		err("assignment to a subroutine name");
258ec6500d3Sbostic 		return;
259ec6500d3Sbostic 		}
260ec6500d3Sbostic 	if(parstate < INDATA)
261ec6500d3Sbostic 		enddcl();
262ec6500d3Sbostic 	if (optimflag)
263ec6500d3Sbostic 		optbuff (SKEQ, mkexpr(OPASSIGN, mklhs(lp), fixtype(rp)), 0, 0);
264ec6500d3Sbostic 	else
265ec6500d3Sbostic 		puteq (mklhs(lp), fixtype(rp));
266ec6500d3Sbostic 	}
267ec6500d3Sbostic }
268ec6500d3Sbostic 
269ec6500d3Sbostic 
270ec6500d3Sbostic 
271ec6500d3Sbostic mkstfunct(lp, rp)
272ec6500d3Sbostic struct Primblock *lp;
273ec6500d3Sbostic expptr rp;
274ec6500d3Sbostic {
275ec6500d3Sbostic register struct Primblock *p;
276ec6500d3Sbostic register Namep np;
277ec6500d3Sbostic chainp args;
278ec6500d3Sbostic 
279ec6500d3Sbostic if(parstate < INDATA)
280ec6500d3Sbostic 	{
281ec6500d3Sbostic 	enddcl();
282ec6500d3Sbostic 	parstate = INDATA;
283ec6500d3Sbostic 	}
284ec6500d3Sbostic 
285ec6500d3Sbostic np = lp->namep;
286ec6500d3Sbostic if(np->vclass == CLUNKNOWN)
287ec6500d3Sbostic 	np->vclass = CLPROC;
288ec6500d3Sbostic else
289ec6500d3Sbostic 	{
290ec6500d3Sbostic 	dclerr("redeclaration of statement function", np);
291ec6500d3Sbostic 	return;
292ec6500d3Sbostic 	}
293ec6500d3Sbostic np->vprocclass = PSTFUNCT;
294ec6500d3Sbostic np->vstg = STGSTFUNCT;
295ec6500d3Sbostic impldcl(np);
296ec6500d3Sbostic args = (lp->argsp ? lp->argsp->listp : CHNULL);
297ec6500d3Sbostic np->varxptr.vstfdesc = mkchain(args , rp );
298ec6500d3Sbostic 
299ec6500d3Sbostic for( ; args ; args = args->nextp)
300ec6500d3Sbostic 	if( args->datap->tag!=TPRIM ||
301ec6500d3Sbostic 		(p = (struct Primblock *) (args->datap) )->argsp ||
302ec6500d3Sbostic 		p->fcharp || p->lcharp )
303ec6500d3Sbostic 		err("non-variable argument in statement function definition");
304ec6500d3Sbostic 	else
305ec6500d3Sbostic 		{
306ec6500d3Sbostic 		args->datap = (tagptr) (p->namep);
307ec6500d3Sbostic 		vardcl(p->namep);
308ec6500d3Sbostic 		free(p);
309ec6500d3Sbostic 		}
310ec6500d3Sbostic }
311ec6500d3Sbostic 
312ec6500d3Sbostic 
313ec6500d3Sbostic 
excall(name,args,nstars,labels)314ec6500d3Sbostic excall(name, args, nstars, labels)
315ec6500d3Sbostic Namep name;
316ec6500d3Sbostic struct Listblock *args;
317ec6500d3Sbostic int nstars;
318ec6500d3Sbostic struct Labelblock *labels[ ];
319ec6500d3Sbostic {
320ec6500d3Sbostic register expptr p;
321ec6500d3Sbostic 
322ec6500d3Sbostic settype(name, TYSUBR, ENULL);
323ec6500d3Sbostic p = mkfunct( mkprim(name, args, CHNULL) );
324ec6500d3Sbostic p->exprblock.vtype = p->exprblock.leftp->headblock.vtype = TYINT;
325ec6500d3Sbostic if (nstars > 0)
326ec6500d3Sbostic 	if (optimflag)
327ec6500d3Sbostic 		optbuff (SKCMGOTO, p, nstars, labels);
328ec6500d3Sbostic 	else
329ec6500d3Sbostic 		putcmgo (p, nstars, labels);
330ec6500d3Sbostic else
331ec6500d3Sbostic 	if (optimflag)
332ec6500d3Sbostic 		optbuff (SKCALL, p, 0, 0);
333ec6500d3Sbostic 	else
334ec6500d3Sbostic 		putexpr (p);
335ec6500d3Sbostic }
336ec6500d3Sbostic 
337ec6500d3Sbostic 
338ec6500d3Sbostic 
exstop(stop,p)339ec6500d3Sbostic exstop(stop, p)
340ec6500d3Sbostic int stop;
341ec6500d3Sbostic register expptr p;
342ec6500d3Sbostic {
343ec6500d3Sbostic char *q;
344ec6500d3Sbostic int n;
345ec6500d3Sbostic expptr mkstrcon();
346ec6500d3Sbostic 
347ec6500d3Sbostic if(p)
348ec6500d3Sbostic 	{
349ec6500d3Sbostic 	if( ! ISCONST(p) )
350ec6500d3Sbostic 		{
351ec6500d3Sbostic 		execerr("pause/stop argument must be constant", CNULL);
352ec6500d3Sbostic 		frexpr(p);
353ec6500d3Sbostic 		p = mkstrcon(0, CNULL);
354ec6500d3Sbostic 		}
355ec6500d3Sbostic 	else if( ISINT(p->constblock.vtype) )
356ec6500d3Sbostic 		{
35776ad5316Sbostic 		q = convic(p->constblock.constant.ci);
358ec6500d3Sbostic 		n = strlen(q);
359ec6500d3Sbostic 		if(n > 0)
360ec6500d3Sbostic 			{
36176ad5316Sbostic 			p->constblock.constant.ccp = copyn(n, q);
362ec6500d3Sbostic 			p->constblock.vtype = TYCHAR;
363ec6500d3Sbostic 			p->constblock.vleng = (expptr) ICON(n);
364ec6500d3Sbostic 			}
365ec6500d3Sbostic 		else
366ec6500d3Sbostic 			p = (expptr) mkstrcon(0, CNULL);
367ec6500d3Sbostic 		}
368ec6500d3Sbostic 	else if(p->constblock.vtype != TYCHAR)
369ec6500d3Sbostic 		{
370ec6500d3Sbostic 		execerr("pause/stop argument must be integer or string", CNULL);
371ec6500d3Sbostic 		p = (expptr) mkstrcon(0, CNULL);
372ec6500d3Sbostic 		}
373ec6500d3Sbostic 	}
374ec6500d3Sbostic else	p = (expptr) mkstrcon(0, CNULL);
375ec6500d3Sbostic 
376ec6500d3Sbostic if (optimflag)
377ec6500d3Sbostic 	optbuff ((stop ? SKSTOP : SKPAUSE), p, 0, 0);
378ec6500d3Sbostic else
379ec6500d3Sbostic 	putexpr (call1(TYSUBR, (stop ? "s_stop" : "s_paus"), p));
380ec6500d3Sbostic }
381ec6500d3Sbostic 
382ec6500d3Sbostic 
383ec6500d3Sbostic /* UCB DO LOOP CODE */
384ec6500d3Sbostic 
385ec6500d3Sbostic #define DOINIT	par[0]
386ec6500d3Sbostic #define DOLIMIT	par[1]
387ec6500d3Sbostic #define DOINCR	par[2]
388ec6500d3Sbostic 
38976ad5316Sbostic #define CONSTINIT  constant[0]
39076ad5316Sbostic #define CONSTLIMIT constant[1]
39176ad5316Sbostic #define CONSTINCR  constant[2]
392ec6500d3Sbostic 
393ec6500d3Sbostic #define VARSTEP	0
394ec6500d3Sbostic #define POSSTEP	1
395ec6500d3Sbostic #define NEGSTEP	2
396ec6500d3Sbostic 
397ec6500d3Sbostic 
exdo(range,spec)398ec6500d3Sbostic exdo(range, spec)
399ec6500d3Sbostic int range;
400ec6500d3Sbostic chainp spec;
401ec6500d3Sbostic 
402ec6500d3Sbostic {
403ec6500d3Sbostic   register expptr p, q;
404ec6500d3Sbostic   expptr q1;
405ec6500d3Sbostic   register Namep np;
406ec6500d3Sbostic   chainp cp;
407ec6500d3Sbostic   register int i;
408ec6500d3Sbostic   int dotype, incsign;
409ec6500d3Sbostic   Addrp dovarp, dostgp;
410ec6500d3Sbostic   expptr par[3];
41176ad5316Sbostic   expptr constant[3];
412ec6500d3Sbostic   Slotp doslot;
413ec6500d3Sbostic 
414ec6500d3Sbostic   pushctl(CTLDO);
415ec6500d3Sbostic   dorange = ctlstack->dolabel = range;
416ec6500d3Sbostic   np = (Namep) (spec->datap);
417ec6500d3Sbostic   ctlstack->donamep = NULL;
418ec6500d3Sbostic   if(np->vdovar)
419ec6500d3Sbostic     {
420ec6500d3Sbostic       errstr("nested loops with variable %s", varstr(VL,np->varname));
421ec6500d3Sbostic       return;
422ec6500d3Sbostic     }
423ec6500d3Sbostic 
424ec6500d3Sbostic   dovarp = mkplace(np);
425ec6500d3Sbostic   dotype = dovarp->vtype;
426ec6500d3Sbostic 
427ec6500d3Sbostic   if( ! ONEOF(dotype, MSKINT|MSKREAL) )
428ec6500d3Sbostic     {
429ec6500d3Sbostic       err("bad type on DO variable");
430ec6500d3Sbostic       return;
431ec6500d3Sbostic     }
432ec6500d3Sbostic 
433ec6500d3Sbostic 
434ec6500d3Sbostic   for(i=0 , cp = spec->nextp ; cp!=NULL && i<3 ; cp = cp->nextp)
435ec6500d3Sbostic     {
436ec6500d3Sbostic       p = fixtype((expptr) cpexpr((tagptr) q = cp->datap));
437ec6500d3Sbostic       if(!ONEOF(p->headblock.vtype, MSKINT|MSKREAL) )
438ec6500d3Sbostic 	{
439ec6500d3Sbostic 	  err("bad type on DO parameter");
440ec6500d3Sbostic 	  return;
441ec6500d3Sbostic 	}
442ec6500d3Sbostic 
443ec6500d3Sbostic 
444ec6500d3Sbostic       if (ISCONST(q))
44576ad5316Sbostic 	constant[i] = mkconv(dotype, q);
446ec6500d3Sbostic       else
447ec6500d3Sbostic 	{
448ec6500d3Sbostic 	  frexpr(q);
44976ad5316Sbostic 	  constant[i] = NULL;
450ec6500d3Sbostic 	}
451ec6500d3Sbostic 
452ec6500d3Sbostic       par[i++] = mkconv(dotype, p);
453ec6500d3Sbostic     }
454ec6500d3Sbostic 
455ec6500d3Sbostic   frchain(&spec);
456ec6500d3Sbostic   switch(i)
457ec6500d3Sbostic     {
458ec6500d3Sbostic     case 0:
459ec6500d3Sbostic     case 1:
460ec6500d3Sbostic       err("too few DO parameters");
461ec6500d3Sbostic       return;
462ec6500d3Sbostic 
463ec6500d3Sbostic     case 2:
464ec6500d3Sbostic       DOINCR = (expptr) ICON(1);
465ec6500d3Sbostic       CONSTINCR = ICON(1);
466ec6500d3Sbostic 
467ec6500d3Sbostic     case 3:
468ec6500d3Sbostic       break;
469ec6500d3Sbostic 
470ec6500d3Sbostic     default:
471ec6500d3Sbostic       err("too many DO parameters");
472ec6500d3Sbostic       return;
473ec6500d3Sbostic     }
474ec6500d3Sbostic 
475ec6500d3Sbostic   ctlstack->donamep = np;
476ec6500d3Sbostic 
477ec6500d3Sbostic   np->vdovar = YES;
478ec6500d3Sbostic   if( !optimflag && enregister(np) )
479ec6500d3Sbostic     {
480ec6500d3Sbostic       /* stgp points to a storage version, varp to a register version */
481ec6500d3Sbostic       dostgp = dovarp;
482ec6500d3Sbostic       dovarp = mkplace(np);
483ec6500d3Sbostic     }
484ec6500d3Sbostic   else
485ec6500d3Sbostic     dostgp = NULL;
486ec6500d3Sbostic 
487ec6500d3Sbostic   for (i = 0; i < 4; i++)
488ec6500d3Sbostic     ctlstack->ctlabels[i] = newlabel();
489ec6500d3Sbostic 
490ec6500d3Sbostic   if( CONSTLIMIT )
491ec6500d3Sbostic     ctlstack->domax = DOLIMIT;
492ec6500d3Sbostic   else
493ec6500d3Sbostic     ctlstack->domax = (expptr) mktemp(dotype, PNULL);
494ec6500d3Sbostic 
495ec6500d3Sbostic   if( CONSTINCR )
496ec6500d3Sbostic     {
497ec6500d3Sbostic       ctlstack->dostep = DOINCR;
498ec6500d3Sbostic       if( (incsign = conssgn(CONSTINCR)) == 0)
499ec6500d3Sbostic 	err("zero DO increment");
500ec6500d3Sbostic       ctlstack->dostepsign = (incsign > 0 ? POSSTEP : NEGSTEP);
501ec6500d3Sbostic     }
502ec6500d3Sbostic   else
503ec6500d3Sbostic     {
504ec6500d3Sbostic       ctlstack->dostep = (expptr) mktemp(dotype, PNULL);
505ec6500d3Sbostic       ctlstack->dostepsign = VARSTEP;
506ec6500d3Sbostic     }
507ec6500d3Sbostic 
508ec6500d3Sbostic if (optimflag)
509ec6500d3Sbostic 	doslot = optbuff (SKDOHEAD,0,0,ctlstack);
510ec6500d3Sbostic 
511ec6500d3Sbostic if( CONSTLIMIT && CONSTINIT && ctlstack->dostepsign!=VARSTEP)
512ec6500d3Sbostic 	{
513ec6500d3Sbostic 	if (optimflag)
514ec6500d3Sbostic 		optbuff (SKEQ,mkexpr(OPASSIGN,cpexpr(dovarp),cpexpr(DOINIT)),
515ec6500d3Sbostic 			0,0);
516ec6500d3Sbostic 	else
517ec6500d3Sbostic 		puteq (cpexpr(dovarp), cpexpr(DOINIT));
518ec6500d3Sbostic 	if( ! onetripflag )
519ec6500d3Sbostic 		{
520ec6500d3Sbostic 		q = mkexpr(OPMINUS, cpexpr(CONSTLIMIT), cpexpr(CONSTINIT));
521ec6500d3Sbostic 		if((incsign * conssgn(q)) == -1)
522ec6500d3Sbostic 			{
523ec6500d3Sbostic 			warn("DO range never executed");
524ec6500d3Sbostic 			if (optimflag)
525ec6500d3Sbostic 				optbuff (SKGOTO,0,ctlstack->endlabel,0);
526ec6500d3Sbostic 			else
527ec6500d3Sbostic 				putgoto (ctlstack->endlabel);
528ec6500d3Sbostic 			}
529ec6500d3Sbostic 		frexpr(q);
530ec6500d3Sbostic 		}
531ec6500d3Sbostic 	}
532ec6500d3Sbostic 
533ec6500d3Sbostic 
534ec6500d3Sbostic else if (ctlstack->dostepsign != VARSTEP && !onetripflag)
535ec6500d3Sbostic 	{
536ec6500d3Sbostic 	if (CONSTLIMIT)
537ec6500d3Sbostic 		q = (expptr) cpexpr(ctlstack->domax);
538ec6500d3Sbostic 	else
539ec6500d3Sbostic 		q = mkexpr(OPASSIGN, cpexpr(ctlstack->domax), DOLIMIT);
540ec6500d3Sbostic 	q1 = mkexpr(OPASSIGN, cpexpr(dovarp), DOINIT);
541ec6500d3Sbostic 	q = mkexpr( (ctlstack->dostepsign == POSSTEP ? OPGE : OPLE),
542ec6500d3Sbostic 		   q, q1);
543ec6500d3Sbostic 	if (optimflag)
544ec6500d3Sbostic 		optbuff (SKIFN,q, ctlstack->endlabel,0);
545ec6500d3Sbostic 	else
546ec6500d3Sbostic 		putif (q, ctlstack->endlabel);
547ec6500d3Sbostic 	}
548ec6500d3Sbostic else
549ec6500d3Sbostic 	{
550ec6500d3Sbostic 	if (!CONSTLIMIT)
551ec6500d3Sbostic 	    if (optimflag)
552ec6500d3Sbostic 		optbuff (SKEQ,
553ec6500d3Sbostic 			mkexpr(OPASSIGN,cpexpr(ctlstack->domax),DOLIMIT),0,0);
554ec6500d3Sbostic 	    else
555ec6500d3Sbostic 		puteq (cpexpr(ctlstack->domax), DOLIMIT);
556ec6500d3Sbostic 	q = DOINIT;
557ec6500d3Sbostic 	if (!onetripflag)
558ec6500d3Sbostic 		q = mkexpr(OPMINUS, q,
559ec6500d3Sbostic 			mkexpr(OPASSIGN, cpexpr(ctlstack->dostep),
560ec6500d3Sbostic 			       DOINCR) );
561ec6500d3Sbostic 	if (optimflag)
562ec6500d3Sbostic 		optbuff (SKEQ,mkexpr(OPASSIGN,cpexpr(dovarp), q),0,0);
563ec6500d3Sbostic 	else
564ec6500d3Sbostic 		puteq (cpexpr(dovarp), q);
565ec6500d3Sbostic 	if (onetripflag && ctlstack->dostepsign == VARSTEP)
566ec6500d3Sbostic 	    if (optimflag)
567ec6500d3Sbostic 		optbuff (SKEQ,
568ec6500d3Sbostic 			mkexpr(OPASSIGN,cpexpr(ctlstack->dostep),DOINCR),0,0);
569ec6500d3Sbostic 	    else
570ec6500d3Sbostic 		puteq (cpexpr(ctlstack->dostep), DOINCR);
571ec6500d3Sbostic 	}
572ec6500d3Sbostic 
573ec6500d3Sbostic if (ctlstack->dostepsign == VARSTEP)
574ec6500d3Sbostic 	{
575ec6500d3Sbostic 	expptr incr,test;
576ec6500d3Sbostic 	if (onetripflag)
577ec6500d3Sbostic 		if (optimflag)
578ec6500d3Sbostic 			optbuff (SKGOTO,0,ctlstack->dobodylabel,0);
579ec6500d3Sbostic 		else
580ec6500d3Sbostic 			putgoto (ctlstack->dobodylabel);
581ec6500d3Sbostic 	else
582ec6500d3Sbostic 	    if (optimflag)
583ec6500d3Sbostic 		optbuff (SKIFN,mkexpr(OPGE, cpexpr(ctlstack->dostep), ICON(0)),
584ec6500d3Sbostic 			ctlstack->doneglabel,0);
585ec6500d3Sbostic 	    else
586ec6500d3Sbostic 		putif (mkexpr(OPGE, cpexpr(ctlstack->dostep), ICON(0)),
587ec6500d3Sbostic 			ctlstack->doneglabel);
588ec6500d3Sbostic 	if (optimflag)
589ec6500d3Sbostic 		optbuff (SKLABEL,0,ctlstack->doposlabel,0);
590ec6500d3Sbostic 	else
591ec6500d3Sbostic 		putlabel (ctlstack->doposlabel);
592ec6500d3Sbostic 	incr = mkexpr(OPPLUSEQ, cpexpr(dovarp), cpexpr(ctlstack->dostep));
593ec6500d3Sbostic 	test = mkexpr(OPLE, incr, cpexpr(ctlstack->domax));
594ec6500d3Sbostic 	if (optimflag)
595ec6500d3Sbostic 		optbuff (SKIFN,test, ctlstack->endlabel,0);
596ec6500d3Sbostic 	else
597ec6500d3Sbostic 		putif (test, ctlstack->endlabel);
598ec6500d3Sbostic 	}
599ec6500d3Sbostic 
600ec6500d3Sbostic if (optimflag)
601ec6500d3Sbostic 	optbuff (SKLABEL,0,ctlstack->dobodylabel,0);
602ec6500d3Sbostic else
603ec6500d3Sbostic 	putlabel (ctlstack->dobodylabel);
604ec6500d3Sbostic if (dostgp)
605ec6500d3Sbostic 	{
606ec6500d3Sbostic 	if (optimflag)
607ec6500d3Sbostic 		optbuff (SKEQ,mkexpr(OPASSIGN,dostgp, dovarp),0,0);
608ec6500d3Sbostic 	else
609ec6500d3Sbostic 		puteq (dostgp, dovarp);
610ec6500d3Sbostic 	}
611ec6500d3Sbostic else
612ec6500d3Sbostic 	frexpr(dovarp);
613ec6500d3Sbostic if (optimflag)
614ec6500d3Sbostic 	doslot->nullslot = optbuff (SKNULL,0,0,0);
615ec6500d3Sbostic 
616ec6500d3Sbostic frexpr(CONSTINIT);
617ec6500d3Sbostic frexpr(CONSTLIMIT);
618ec6500d3Sbostic frexpr(CONSTINCR);
619ec6500d3Sbostic }
620ec6500d3Sbostic 
621ec6500d3Sbostic 
enddo(here)622ec6500d3Sbostic enddo(here)
623ec6500d3Sbostic int here;
624ec6500d3Sbostic 
625ec6500d3Sbostic {
626ec6500d3Sbostic   register struct Ctlframe *q;
627ec6500d3Sbostic   Namep np;
628ec6500d3Sbostic   Addrp ap, rv;
629ec6500d3Sbostic   expptr t;
630ec6500d3Sbostic   register int i;
631ec6500d3Sbostic   Slotp doslot;
632ec6500d3Sbostic 
633ec6500d3Sbostic   while (here == dorange)
634ec6500d3Sbostic     {
635ec6500d3Sbostic       while (ctlstack->ctltype == CTLIF || ctlstack->ctltype == CTLELSE)
636ec6500d3Sbostic 	{
637ec6500d3Sbostic 	  execerr("missing endif", CNULL);
638ec6500d3Sbostic 	  exendif();
639ec6500d3Sbostic 	}
640ec6500d3Sbostic 
641ec6500d3Sbostic       if (np = ctlstack->donamep)
642ec6500d3Sbostic 	{
643ec6500d3Sbostic 	rv = mkplace (np);
644ec6500d3Sbostic 
645ec6500d3Sbostic 	t = mkexpr(OPPLUSEQ, cpexpr(rv), cpexpr(ctlstack->dostep) );
646ec6500d3Sbostic 
647ec6500d3Sbostic 	if (optimflag)
648ec6500d3Sbostic 		doslot = optbuff (SKENDDO,0,0,ctlstack);
649ec6500d3Sbostic 
650ec6500d3Sbostic 	if (ctlstack->dostepsign == VARSTEP)
651ec6500d3Sbostic 		if (optimflag)
652ec6500d3Sbostic 			{
653ec6500d3Sbostic 			optbuff (SKIFN,
654ec6500d3Sbostic 				mkexpr(OPLE, cpexpr(ctlstack->dostep), ICON(0)),
655ec6500d3Sbostic 				ctlstack->doposlabel,0);
656ec6500d3Sbostic 			optbuff (SKLABEL,0,ctlstack->doneglabel,0);
657ec6500d3Sbostic 			optbuff (SKIFN,mkexpr(OPLT, t, ctlstack->domax),
658ec6500d3Sbostic 				ctlstack->dobodylabel,0);
659ec6500d3Sbostic 			}
660ec6500d3Sbostic 		else
661ec6500d3Sbostic 			{
662ec6500d3Sbostic 			putif (mkexpr(OPLE, cpexpr(ctlstack->dostep), ICON(0)),
663ec6500d3Sbostic 				ctlstack->doposlabel);
664ec6500d3Sbostic 			putlabel (ctlstack->doneglabel);
665ec6500d3Sbostic 			putif (mkexpr(OPLT, t, ctlstack->domax),
666ec6500d3Sbostic 				ctlstack->dobodylabel);
667ec6500d3Sbostic 			}
668ec6500d3Sbostic 	else
669ec6500d3Sbostic 		{
670ec6500d3Sbostic 		int op;
671ec6500d3Sbostic 		op = (ctlstack->dostepsign == POSSTEP ? OPGT : OPLT);
672ec6500d3Sbostic 		if (optimflag)
673ec6500d3Sbostic 			optbuff (SKIFN, mkexpr(op,t,ctlstack->domax),
674ec6500d3Sbostic 				ctlstack->dobodylabel,0);
675ec6500d3Sbostic 		else
676ec6500d3Sbostic 			putif (mkexpr(op, t, ctlstack->domax),
677ec6500d3Sbostic 				ctlstack->dobodylabel);
678ec6500d3Sbostic 		}
679ec6500d3Sbostic 	if (optimflag)
680ec6500d3Sbostic 		optbuff (SKLABEL,0,ctlstack->endlabel,0);
681ec6500d3Sbostic 	else
682ec6500d3Sbostic 		putlabel (ctlstack->endlabel);
683ec6500d3Sbostic 
684ec6500d3Sbostic 	if (ap = memversion(np))
685ec6500d3Sbostic 		{
686ec6500d3Sbostic 		if (optimflag)
687ec6500d3Sbostic 			optbuff (SKEQ,mkexpr(OPASSIGN,ap, rv),0,0);
688ec6500d3Sbostic 		else
689ec6500d3Sbostic 			puteq (ap, rv);
690ec6500d3Sbostic 		}
691ec6500d3Sbostic 	else
692ec6500d3Sbostic 		frexpr(rv);
693ec6500d3Sbostic 	for (i = 0; i < 4; i++)
694ec6500d3Sbostic 		ctlstack->ctlabels[i] = 0;
695ec6500d3Sbostic 	if (!optimflag)
696ec6500d3Sbostic 		deregister(ctlstack->donamep);
697ec6500d3Sbostic 	ctlstack->donamep->vdovar = NO;
698ec6500d3Sbostic 	if (optimflag)
699ec6500d3Sbostic 		doslot->nullslot = optbuff (SKNULL,0,0,0);
700ec6500d3Sbostic 	}
701ec6500d3Sbostic 
702ec6500d3Sbostic       popctl();
703ec6500d3Sbostic       poplab();
704ec6500d3Sbostic 
705ec6500d3Sbostic       dorange = 0;
706ec6500d3Sbostic       for (q = ctlstack; q >= ctls; --q)
707ec6500d3Sbostic 	if (q->ctltype == CTLDO)
708ec6500d3Sbostic 	  {
709ec6500d3Sbostic 	    dorange = q->dolabel;
710ec6500d3Sbostic 	    break;
711ec6500d3Sbostic 	  }
712ec6500d3Sbostic     }
713ec6500d3Sbostic }
714ec6500d3Sbostic 
715ec6500d3Sbostic 
exassign(vname,labelval)716ec6500d3Sbostic exassign(vname, labelval)
717ec6500d3Sbostic Namep vname;
718ec6500d3Sbostic struct Labelblock *labelval;
719ec6500d3Sbostic {
720ec6500d3Sbostic Addrp p;
721ec6500d3Sbostic expptr mkaddcon();
722ec6500d3Sbostic 
723ec6500d3Sbostic p = mkplace(vname);
724ec6500d3Sbostic #if SZADDR > SZSHORT
725ec6500d3Sbostic if( p->vtype == TYSHORT )
726ec6500d3Sbostic 	err("insufficient precision in ASSIGN variable");
727ec6500d3Sbostic else
728ec6500d3Sbostic #endif
729ec6500d3Sbostic if( ! ONEOF(p->vtype, MSKINT|MSKADDR) )
730ec6500d3Sbostic 	err("noninteger assign variable");
731ec6500d3Sbostic else
732ec6500d3Sbostic 	{
733ec6500d3Sbostic 	if (optimflag)
734ec6500d3Sbostic 		optbuff (SKASSIGN, p, labelval->labelno, 0);
735ec6500d3Sbostic 	else
736ec6500d3Sbostic 		puteq (p, intrconv(p->vtype, mkaddcon(labelval->labelno)));
737ec6500d3Sbostic 	}
738ec6500d3Sbostic }
739ec6500d3Sbostic 
740ec6500d3Sbostic 
741ec6500d3Sbostic 
exarif(expr,neglab,zerlab,poslab)742ec6500d3Sbostic exarif(expr, neglab, zerlab, poslab)
743ec6500d3Sbostic expptr expr;
744ec6500d3Sbostic struct Labelblock *neglab, *zerlab, *poslab;
745ec6500d3Sbostic {
746ec6500d3Sbostic register int lm, lz, lp;
747ec6500d3Sbostic struct Labelblock *labels[3];
748ec6500d3Sbostic 
749ec6500d3Sbostic lm = neglab->labelno;
750ec6500d3Sbostic lz = zerlab->labelno;
751ec6500d3Sbostic lp = poslab->labelno;
752ec6500d3Sbostic expr = fixtype(expr);
753ec6500d3Sbostic 
754ec6500d3Sbostic if( ! ONEOF(expr->headblock.vtype, MSKINT|MSKREAL) )
755ec6500d3Sbostic 	{
756ec6500d3Sbostic 	err("invalid type of arithmetic if expression");
757ec6500d3Sbostic 	frexpr(expr);
758ec6500d3Sbostic 	}
759ec6500d3Sbostic else
760ec6500d3Sbostic 	{
761ec6500d3Sbostic 	if(lm == lz)
762ec6500d3Sbostic 		exar2(OPLE, expr, lm, lp);
763ec6500d3Sbostic 	else if(lm == lp)
764ec6500d3Sbostic 		exar2(OPNE, expr, lm, lz);
765ec6500d3Sbostic 	else if(lz == lp)
766ec6500d3Sbostic 		exar2(OPGE, expr, lz, lm);
767ec6500d3Sbostic 	else
768ec6500d3Sbostic 		if (optimflag)
769ec6500d3Sbostic 			{
770ec6500d3Sbostic 			labels[0] = neglab;
771ec6500d3Sbostic 			labels[1] = zerlab;
772ec6500d3Sbostic 			labels[2] = poslab;
773ec6500d3Sbostic 			optbuff (SKARIF, expr, 0, labels);
774ec6500d3Sbostic 			}
775ec6500d3Sbostic 		else
776ec6500d3Sbostic 			prarif(expr, lm, lz, lp);
777ec6500d3Sbostic 	}
778ec6500d3Sbostic }
779ec6500d3Sbostic 
780ec6500d3Sbostic 
781ec6500d3Sbostic 
exar2(op,e,l1,l2)782ec6500d3Sbostic LOCAL exar2 (op, e, l1, l2)
783ec6500d3Sbostic int	op;
784ec6500d3Sbostic expptr	e;
785ec6500d3Sbostic int	l1,l2;
786ec6500d3Sbostic {
787ec6500d3Sbostic if (optimflag)
788ec6500d3Sbostic 	{
789ec6500d3Sbostic 	optbuff (SKIFN, mkexpr(op, e, ICON(0)), l2, 0);
790ec6500d3Sbostic 	optbuff (SKGOTO, 0, l1, 0);
791ec6500d3Sbostic 	}
792ec6500d3Sbostic else
793ec6500d3Sbostic 	{
794ec6500d3Sbostic 	putif (mkexpr(op, e, ICON(0)), l2);
795ec6500d3Sbostic 	putgoto (l1);
796ec6500d3Sbostic 	}
797ec6500d3Sbostic }
798ec6500d3Sbostic 
799ec6500d3Sbostic 
exreturn(p)800ec6500d3Sbostic exreturn(p)
801ec6500d3Sbostic register expptr p;
802ec6500d3Sbostic {
803ec6500d3Sbostic if(procclass != CLPROC)
804ec6500d3Sbostic 	warn("RETURN statement in main or block data");
805ec6500d3Sbostic if(p && (proctype!=TYSUBR || procclass!=CLPROC) )
806ec6500d3Sbostic 	{
807ec6500d3Sbostic 	err("alternate return in nonsubroutine");
808ec6500d3Sbostic 	p = 0;
809ec6500d3Sbostic 	}
810ec6500d3Sbostic 
811ec6500d3Sbostic if(p)
812ec6500d3Sbostic 	if (optimflag)
813ec6500d3Sbostic 		optbuff (SKRETURN, p, retlabel, 0);
814ec6500d3Sbostic 	else
815ec6500d3Sbostic 		{
816ec6500d3Sbostic 		putforce (TYINT, p);
817ec6500d3Sbostic 		putgoto (retlabel);
818ec6500d3Sbostic 		}
819ec6500d3Sbostic else
820ec6500d3Sbostic 	if (optimflag)
821ec6500d3Sbostic 		optbuff (SKRETURN, p,
822ec6500d3Sbostic 			 (proctype==TYSUBR ? ret0label : retlabel), 0);
823ec6500d3Sbostic 	else
824ec6500d3Sbostic 		putgoto (proctype==TYSUBR ? ret0label : retlabel);
825ec6500d3Sbostic }
826ec6500d3Sbostic 
827ec6500d3Sbostic 
828ec6500d3Sbostic 
829ec6500d3Sbostic exasgoto(labvar)
830ec6500d3Sbostic struct Hashentry *labvar;
831ec6500d3Sbostic {
832ec6500d3Sbostic register Addrp p;
833ec6500d3Sbostic 
834ec6500d3Sbostic p = mkplace(labvar);
835ec6500d3Sbostic if( ! ISINT(p->vtype) )
836ec6500d3Sbostic 	err("assigned goto variable must be integer");
837ec6500d3Sbostic else
838ec6500d3Sbostic 	if (optimflag)
839ec6500d3Sbostic 		optbuff (SKASGOTO, p, 0, 0);
840ec6500d3Sbostic 	else
841ec6500d3Sbostic 		putbranch (p);
842ec6500d3Sbostic }
843