xref: /csrg-svn/usr.bin/f77/pass1.tahoe/exec.c (revision 47951)
1*47951Sbostic /*-
2*47951Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*47951Sbostic  * All rights reserved.
4*47951Sbostic  *
5*47951Sbostic  * %sccs.include.proprietary.c%
643208Sbostic  */
743208Sbostic 
843208Sbostic #ifndef lint
9*47951Sbostic static char sccsid[] = "@(#)exec.c	5.3 (Berkeley) 04/12/91";
10*47951Sbostic #endif /* not lint */
1143208Sbostic 
1243208Sbostic /*
1343208Sbostic  * exec.c
1443208Sbostic  *
1543208Sbostic  * Routines for handling the semantics of control structures.
1643208Sbostic  * F77 compiler, pass 1.
1743208Sbostic  *
1843208Sbostic  * University of Utah CS Dept modification history:
1943208Sbostic  *
2043208Sbostic  * Revision 2.3  85/03/18  08:03:31  donn
2143208Sbostic  * Hacks for conversions from type address to numeric type -- prevent addresses
2243208Sbostic  * from being stored in shorts and prevent warnings about implicit conversions.
2343208Sbostic  *
2443208Sbostic  * Revision 2.2  84/09/03  23:18:30  donn
2543208Sbostic  * When a DO loop had the same variable as its loop variable and its limit,
2643208Sbostic  * the limit temporary was assigned to AFTER the original value of the variable
2743208Sbostic  * was destroyed by assigning the initial value to the loop variable.  I
2843208Sbostic  * swapped the operands of a comparison and changed the direction of the
2943208Sbostic  * operator...  This only affected programs when optimizing.  (This may not
3043208Sbostic  * be enough if something alters the order of evaluation of side effects
3143208Sbostic  * later on... sigh.)
3243208Sbostic  *
3343208Sbostic  * Revision 2.1  84/07/19  12:02:53  donn
3443208Sbostic  * Changed comment headers for UofU.
3543208Sbostic  *
3643208Sbostic  * Revision 1.3  84/07/12  18:35:12  donn
3743208Sbostic  * Added change to enddo() to detect open 'if' blocks at the ends of loops.
3843208Sbostic  *
3943208Sbostic  * Revision 1.2  84/06/08  11:22:53  donn
4043208Sbostic  * Fixed bug in exdo() -- if a loop parameter contained an instance of the loop
4143208Sbostic  * variable and the optimizer was off, the loop variable got converted to
4243208Sbostic  * register before the parameters were processed and so the loop parameters
4343208Sbostic  * were initialized from garbage in the register instead of the memory version
4443208Sbostic  * of the loop variable.
4543208Sbostic  *
4643208Sbostic  */
4743208Sbostic 
4843208Sbostic #include "defs.h"
4943208Sbostic #include "optim.h"
5043208Sbostic 
5143208Sbostic 
5243208Sbostic /*   Logical IF codes
5343208Sbostic */
5443208Sbostic 
5543208Sbostic 
exif(p)5643208Sbostic exif(p)
5743208Sbostic expptr p;
5843208Sbostic {
5943208Sbostic register int k;
6043208Sbostic pushctl(CTLIF);
6143208Sbostic ctlstack->elselabel = newlabel();
6243208Sbostic 
6343208Sbostic if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL)
6443208Sbostic 	{
6543208Sbostic 	if(k != TYERROR)
6643208Sbostic 		err("non-logical expression in IF statement");
6743208Sbostic 	frexpr(p);
6843208Sbostic 	}
6943208Sbostic else if (optimflag)
7043208Sbostic 	optbuff (SKIFN, p, ctlstack->elselabel, 0);
7143208Sbostic else
7243208Sbostic 	putif (p, ctlstack->elselabel);
7343208Sbostic }
7443208Sbostic 
7543208Sbostic 
7643208Sbostic 
exelif(p)7743208Sbostic exelif(p)
7843208Sbostic expptr p;
7943208Sbostic {
8043208Sbostic int k,oldelse;
8143208Sbostic 
8243208Sbostic if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL)
8343208Sbostic 	{
8443208Sbostic 	if(k != TYERROR)
8543208Sbostic 		err("non-logical expression in IF statement");
8643208Sbostic 	frexpr(p);
8743208Sbostic 	}
8843208Sbostic else    {
8943208Sbostic         if(ctlstack->ctltype == CTLIF)
9043208Sbostic 		{
9143208Sbostic 		if(ctlstack->endlabel == 0) ctlstack->endlabel = newlabel();
9243208Sbostic         	oldelse=ctlstack->elselabel;
9343208Sbostic 		ctlstack->elselabel = newlabel();
9443208Sbostic 		if (optimflag)
9543208Sbostic 			{
9643208Sbostic 			optbuff (SKGOTO, 0, ctlstack->endlabel, 0);
9743208Sbostic 			optbuff (SKLABEL, 0, oldelse, 0);
9843208Sbostic 			optbuff (SKIFN, p, ctlstack->elselabel, 0);
9943208Sbostic 			}
10043208Sbostic 		else
10143208Sbostic 			{
10243208Sbostic 			putgoto (ctlstack->endlabel);
10343208Sbostic 			putlabel (oldelse);
10443208Sbostic 			putif (p, ctlstack->elselabel);
10543208Sbostic 			}
10643208Sbostic 		}
10743208Sbostic         else	execerr("elseif out of place", CNULL);
10843208Sbostic         }
10943208Sbostic }
11043208Sbostic 
11143208Sbostic 
11243208Sbostic 
11343208Sbostic 
11443208Sbostic 
exelse()11543208Sbostic exelse()
11643208Sbostic {
11743208Sbostic if(ctlstack->ctltype==CTLIF)
11843208Sbostic 	{
11943208Sbostic 	if(ctlstack->endlabel == 0)
12043208Sbostic 		ctlstack->endlabel = newlabel();
12143208Sbostic 	ctlstack->ctltype = CTLELSE;
12243208Sbostic 	if (optimflag)
12343208Sbostic 		{
12443208Sbostic 		optbuff (SKGOTO, 0, ctlstack->endlabel, 0);
12543208Sbostic 		optbuff (SKLABEL, 0, ctlstack->elselabel, 0);
12643208Sbostic 		}
12743208Sbostic 	else
12843208Sbostic 		{
12943208Sbostic 		putgoto (ctlstack->endlabel);
13043208Sbostic 		putlabel (ctlstack->elselabel);
13143208Sbostic 		}
13243208Sbostic 	}
13343208Sbostic 
13443208Sbostic else	execerr("else out of place", CNULL);
13543208Sbostic }
13643208Sbostic 
13743208Sbostic 
exendif()13843208Sbostic exendif()
13943208Sbostic {
14043208Sbostic if (ctlstack->ctltype == CTLIF)
14143208Sbostic 	{
14243208Sbostic 	if (optimflag)
14343208Sbostic 		{
14443208Sbostic 		optbuff (SKLABEL, 0, ctlstack->elselabel, 0);
14543208Sbostic 		if (ctlstack->endlabel)
14643208Sbostic 			optbuff (SKLABEL, 0, ctlstack->endlabel, 0);
14743208Sbostic 		}
14843208Sbostic 	else
14943208Sbostic 		{
15043208Sbostic 		putlabel (ctlstack->elselabel);
15143208Sbostic 		if (ctlstack->endlabel)
15243208Sbostic 			putlabel (ctlstack->endlabel);
15343208Sbostic 		}
15443208Sbostic 	popctl ();
15543208Sbostic 	}
15643208Sbostic else if (ctlstack->ctltype == CTLELSE)
15743208Sbostic 	{
15843208Sbostic 	if (optimflag)
15943208Sbostic 		optbuff (SKLABEL, 0, ctlstack->endlabel, 0);
16043208Sbostic 	else
16143208Sbostic 		putlabel (ctlstack->endlabel);
16243208Sbostic 	popctl ();
16343208Sbostic 	}
16443208Sbostic else
16543208Sbostic 	execerr("endif out of place", CNULL);
16643208Sbostic }
16743208Sbostic 
16843208Sbostic 
16943208Sbostic 
pushctl(code)17043208Sbostic LOCAL pushctl(code)
17143208Sbostic int code;
17243208Sbostic {
17343208Sbostic register int i;
17443208Sbostic 
17543208Sbostic /* fprintf(diagfile,"old blklevel %d \n",blklevel); dmpframe(ctlstack); */
17643208Sbostic if(++ctlstack >= lastctl)
17743208Sbostic 	many("loops or if-then-elses", 'c');
17843208Sbostic ctlstack->ctltype = code;
17943208Sbostic for(i = 0 ; i < 4 ; ++i)
18043208Sbostic 	ctlstack->ctlabels[i] = 0;
18143208Sbostic ++blklevel;
18243208Sbostic }
18343208Sbostic 
18443208Sbostic 
popctl()18543208Sbostic LOCAL popctl()
18643208Sbostic {
18743208Sbostic if( ctlstack-- < ctls )
18843208Sbostic 	fatal("control stack empty");
18943208Sbostic --blklevel;
19043208Sbostic }
19143208Sbostic 
19243208Sbostic 
19343208Sbostic 
poplab()19443208Sbostic LOCAL poplab()
19543208Sbostic {
19643208Sbostic register struct Labelblock  *lp;
19743208Sbostic 
19843208Sbostic for(lp = labeltab ; lp < highlabtab ; ++lp)
19943208Sbostic 	if(lp->labdefined)
20043208Sbostic 		{
20143208Sbostic 		/* mark all labels in inner blocks unreachable */
20243208Sbostic 		if(lp->blklevel > blklevel)
20343208Sbostic 			lp->labinacc = YES;
20443208Sbostic 		}
20543208Sbostic 	else if(lp->blklevel > blklevel)
20643208Sbostic 		{
20743208Sbostic 		/* move all labels referred to in inner blocks out a level */
20843208Sbostic 		lp->blklevel = blklevel;
20943208Sbostic 		}
21043208Sbostic }
21143208Sbostic 
21243208Sbostic 
21343208Sbostic 
21443208Sbostic /*  BRANCHING CODE
21543208Sbostic */
21643208Sbostic 
21743208Sbostic exgoto(lab)
21843208Sbostic struct Labelblock *lab;
21943208Sbostic {
22043208Sbostic if (optimflag)
22143208Sbostic 	optbuff (SKGOTO, 0, lab->labelno, 0);
22243208Sbostic else
22343208Sbostic 	putgoto (lab->labelno);
22443208Sbostic }
22543208Sbostic 
22643208Sbostic 
22743208Sbostic 
22843208Sbostic 
22943208Sbostic 
23043208Sbostic 
23143208Sbostic 
exequals(lp,rp)23243208Sbostic exequals(lp, rp)
23343208Sbostic register struct Primblock *lp;
23443208Sbostic register expptr rp;
23543208Sbostic {
23643208Sbostic register Namep np;
23743208Sbostic 
23843208Sbostic if(lp->tag != TPRIM)
23943208Sbostic 	{
24043208Sbostic 	err("assignment to a non-variable");
24143208Sbostic 	frexpr(lp);
24243208Sbostic 	frexpr(rp);
24343208Sbostic 	}
24443208Sbostic else if(lp->namep->vclass!=CLVAR && lp->argsp)
24543208Sbostic 	{
24643208Sbostic 	if(parstate >= INEXEC)
24743208Sbostic 		err("assignment to an undimemsioned array");
24843208Sbostic 	else
24943208Sbostic 		mkstfunct(lp, rp);
25043208Sbostic 	}
25143208Sbostic else
25243208Sbostic 	{
25343208Sbostic 	np = (Namep) lp->namep;
25443208Sbostic 	if (np->vclass == CLPROC && np->vprocclass == PTHISPROC
25543208Sbostic 		&& proctype == TYSUBR)
25643208Sbostic 		{
25743208Sbostic 		err("assignment to a subroutine name");
25843208Sbostic 		return;
25943208Sbostic 		}
26043208Sbostic 	if(parstate < INDATA)
26143208Sbostic 		enddcl();
26243208Sbostic 	if (optimflag)
26343208Sbostic 		optbuff (SKEQ, mkexpr(OPASSIGN, mklhs(lp), fixtype(rp)), 0, 0);
26443208Sbostic 	else
26543208Sbostic 		puteq (mklhs(lp), fixtype(rp));
26643208Sbostic 	}
26743208Sbostic }
26843208Sbostic 
26943208Sbostic 
27043208Sbostic 
27143208Sbostic mkstfunct(lp, rp)
27243208Sbostic struct Primblock *lp;
27343208Sbostic expptr rp;
27443208Sbostic {
27543208Sbostic register struct Primblock *p;
27643208Sbostic register Namep np;
27743208Sbostic chainp args;
27843208Sbostic 
27943208Sbostic if(parstate < INDATA)
28043208Sbostic 	{
28143208Sbostic 	enddcl();
28243208Sbostic 	parstate = INDATA;
28343208Sbostic 	}
28443208Sbostic 
28543208Sbostic np = lp->namep;
28643208Sbostic if(np->vclass == CLUNKNOWN)
28743208Sbostic 	np->vclass = CLPROC;
28843208Sbostic else
28943208Sbostic 	{
29043208Sbostic 	dclerr("redeclaration of statement function", np);
29143208Sbostic 	return;
29243208Sbostic 	}
29343208Sbostic np->vprocclass = PSTFUNCT;
29443208Sbostic np->vstg = STGSTFUNCT;
29543208Sbostic impldcl(np);
29643208Sbostic args = (lp->argsp ? lp->argsp->listp : CHNULL);
29743208Sbostic np->varxptr.vstfdesc = mkchain(args , rp );
29843208Sbostic 
29943208Sbostic for( ; args ; args = args->nextp)
30043208Sbostic 	if( args->datap->tag!=TPRIM ||
30143208Sbostic 		(p = (struct Primblock *) (args->datap) )->argsp ||
30243208Sbostic 		p->fcharp || p->lcharp )
30343208Sbostic 		err("non-variable argument in statement function definition");
30443208Sbostic 	else
30543208Sbostic 		{
30643208Sbostic 		args->datap = (tagptr) (p->namep);
30743208Sbostic 		vardcl(p->namep);
30843208Sbostic 		free(p);
30943208Sbostic 		}
31043208Sbostic }
31143208Sbostic 
31243208Sbostic 
31343208Sbostic 
excall(name,args,nstars,labels)31443208Sbostic excall(name, args, nstars, labels)
31543208Sbostic Namep name;
31643208Sbostic struct Listblock *args;
31743208Sbostic int nstars;
31843208Sbostic struct Labelblock *labels[ ];
31943208Sbostic {
32043208Sbostic register expptr p;
32143208Sbostic 
32243208Sbostic settype(name, TYSUBR, ENULL);
32343208Sbostic p = mkfunct( mkprim(name, args, CHNULL) );
32443208Sbostic p->exprblock.vtype = p->exprblock.leftp->headblock.vtype = TYINT;
32543208Sbostic if (nstars > 0)
32643208Sbostic 	if (optimflag)
32743208Sbostic 		optbuff (SKCMGOTO, p, nstars, labels);
32843208Sbostic 	else
32943208Sbostic 		putcmgo (p, nstars, labels);
33043208Sbostic else
33143208Sbostic 	if (optimflag)
33243208Sbostic 		optbuff (SKCALL, p, 0, 0);
33343208Sbostic 	else
33443208Sbostic 		putexpr (p);
33543208Sbostic }
33643208Sbostic 
33743208Sbostic 
33843208Sbostic 
exstop(stop,p)33943208Sbostic exstop(stop, p)
34043208Sbostic int stop;
34143208Sbostic register expptr p;
34243208Sbostic {
34343208Sbostic char *q;
34443208Sbostic int n;
34543208Sbostic expptr mkstrcon();
34643208Sbostic 
34743208Sbostic if(p)
34843208Sbostic 	{
34943208Sbostic 	if( ! ISCONST(p) )
35043208Sbostic 		{
35143208Sbostic 		execerr("pause/stop argument must be constant", CNULL);
35243208Sbostic 		frexpr(p);
35343208Sbostic 		p = mkstrcon(0, CNULL);
35443208Sbostic 		}
35543208Sbostic 	else if( ISINT(p->constblock.vtype) )
35643208Sbostic 		{
35746303Sbostic 		q = convic(p->constblock.constant.ci);
35843208Sbostic 		n = strlen(q);
35943208Sbostic 		if(n > 0)
36043208Sbostic 			{
36146303Sbostic 			p->constblock.constant.ccp = copyn(n, q);
36243208Sbostic 			p->constblock.vtype = TYCHAR;
36343208Sbostic 			p->constblock.vleng = (expptr) ICON(n);
36443208Sbostic 			}
36543208Sbostic 		else
36643208Sbostic 			p = (expptr) mkstrcon(0, CNULL);
36743208Sbostic 		}
36843208Sbostic 	else if(p->constblock.vtype != TYCHAR)
36943208Sbostic 		{
37043208Sbostic 		execerr("pause/stop argument must be integer or string", CNULL);
37143208Sbostic 		p = (expptr) mkstrcon(0, CNULL);
37243208Sbostic 		}
37343208Sbostic 	}
37443208Sbostic else	p = (expptr) mkstrcon(0, CNULL);
37543208Sbostic 
37643208Sbostic if (optimflag)
37743208Sbostic 	optbuff ((stop ? SKSTOP : SKPAUSE), p, 0, 0);
37843208Sbostic else
37943208Sbostic 	putexpr (call1(TYSUBR, (stop ? "s_stop" : "s_paus"), p));
38043208Sbostic }
38143208Sbostic 
38243208Sbostic 
38343208Sbostic /* UCB DO LOOP CODE */
38443208Sbostic 
38543208Sbostic #define DOINIT	par[0]
38643208Sbostic #define DOLIMIT	par[1]
38743208Sbostic #define DOINCR	par[2]
38843208Sbostic 
38946303Sbostic #define CONSTINIT  constant[0]
39046303Sbostic #define CONSTLIMIT constant[1]
39146303Sbostic #define CONSTINCR  constant[2]
39243208Sbostic 
39343208Sbostic #define VARSTEP	0
39443208Sbostic #define POSSTEP	1
39543208Sbostic #define NEGSTEP	2
39643208Sbostic 
39743208Sbostic 
exdo(range,spec)39843208Sbostic exdo(range, spec)
39943208Sbostic int range;
40043208Sbostic chainp spec;
40143208Sbostic 
40243208Sbostic {
40343208Sbostic   register expptr p, q;
40443208Sbostic   expptr q1;
40543208Sbostic   register Namep np;
40643208Sbostic   chainp cp;
40743208Sbostic   register int i;
40843208Sbostic   int dotype, incsign;
40943208Sbostic   Addrp dovarp, dostgp;
41043208Sbostic   expptr par[3];
41146303Sbostic   expptr constant[3];
41243208Sbostic   Slotp doslot;
41343208Sbostic 
41443208Sbostic   pushctl(CTLDO);
41543208Sbostic   dorange = ctlstack->dolabel = range;
41643208Sbostic   np = (Namep) (spec->datap);
41743208Sbostic   ctlstack->donamep = NULL;
41843208Sbostic   if(np->vdovar)
41943208Sbostic     {
42043208Sbostic       errstr("nested loops with variable %s", varstr(VL,np->varname));
42143208Sbostic       return;
42243208Sbostic     }
42343208Sbostic 
42443208Sbostic   dovarp = mkplace(np);
42543208Sbostic   dotype = dovarp->vtype;
42643208Sbostic 
42743208Sbostic   if( ! ONEOF(dotype, MSKINT|MSKREAL) )
42843208Sbostic     {
42943208Sbostic       err("bad type on DO variable");
43043208Sbostic       return;
43143208Sbostic     }
43243208Sbostic 
43343208Sbostic 
43443208Sbostic   for(i=0 , cp = spec->nextp ; cp!=NULL && i<3 ; cp = cp->nextp)
43543208Sbostic     {
43643208Sbostic       p = fixtype((expptr) cpexpr((tagptr) q = cp->datap));
43743208Sbostic       if(!ONEOF(p->headblock.vtype, MSKINT|MSKREAL) )
43843208Sbostic 	{
43943208Sbostic 	  err("bad type on DO parameter");
44043208Sbostic 	  return;
44143208Sbostic 	}
44243208Sbostic 
44343208Sbostic 
44443208Sbostic       if (ISCONST(q))
44546303Sbostic 	constant[i] = mkconv(dotype, q);
44643208Sbostic       else
44743208Sbostic 	{
44843208Sbostic 	  frexpr(q);
44946303Sbostic 	  constant[i] = NULL;
45043208Sbostic 	}
45143208Sbostic 
45243208Sbostic       par[i++] = mkconv(dotype, p);
45343208Sbostic     }
45443208Sbostic 
45543208Sbostic   frchain(&spec);
45643208Sbostic   switch(i)
45743208Sbostic     {
45843208Sbostic     case 0:
45943208Sbostic     case 1:
46043208Sbostic       err("too few DO parameters");
46143208Sbostic       return;
46243208Sbostic 
46343208Sbostic     case 2:
46443208Sbostic       DOINCR = (expptr) ICON(1);
46543208Sbostic       CONSTINCR = ICON(1);
46643208Sbostic 
46743208Sbostic     case 3:
46843208Sbostic       break;
46943208Sbostic 
47043208Sbostic     default:
47143208Sbostic       err("too many DO parameters");
47243208Sbostic       return;
47343208Sbostic     }
47443208Sbostic 
47543208Sbostic   ctlstack->donamep = np;
47643208Sbostic 
47743208Sbostic   np->vdovar = YES;
47843208Sbostic   if( !optimflag && enregister(np) )
47943208Sbostic     {
48043208Sbostic       /* stgp points to a storage version, varp to a register version */
48143208Sbostic       dostgp = dovarp;
48243208Sbostic       dovarp = mkplace(np);
48343208Sbostic     }
48443208Sbostic   else
48543208Sbostic     dostgp = NULL;
48643208Sbostic 
48743208Sbostic   for (i = 0; i < 4; i++)
48843208Sbostic     ctlstack->ctlabels[i] = newlabel();
48943208Sbostic 
49043208Sbostic   if( CONSTLIMIT )
49143208Sbostic     ctlstack->domax = DOLIMIT;
49243208Sbostic   else
49343208Sbostic     ctlstack->domax = (expptr) mktemp(dotype, PNULL);
49443208Sbostic 
49543208Sbostic   if( CONSTINCR )
49643208Sbostic     {
49743208Sbostic       ctlstack->dostep = DOINCR;
49843208Sbostic       if( (incsign = conssgn(CONSTINCR)) == 0)
49943208Sbostic 	err("zero DO increment");
50043208Sbostic       ctlstack->dostepsign = (incsign > 0 ? POSSTEP : NEGSTEP);
50143208Sbostic     }
50243208Sbostic   else
50343208Sbostic     {
50443208Sbostic       ctlstack->dostep = (expptr) mktemp(dotype, PNULL);
50543208Sbostic       ctlstack->dostepsign = VARSTEP;
50643208Sbostic     }
50743208Sbostic 
50843208Sbostic if (optimflag)
50943208Sbostic 	doslot = optbuff (SKDOHEAD,0,0,ctlstack);
51043208Sbostic 
51143208Sbostic if( CONSTLIMIT && CONSTINIT && ctlstack->dostepsign!=VARSTEP)
51243208Sbostic 	{
51343208Sbostic 	if (optimflag)
51443208Sbostic 		optbuff (SKEQ,mkexpr(OPASSIGN,cpexpr(dovarp),cpexpr(DOINIT)),
51543208Sbostic 			0,0);
51643208Sbostic 	else
51743208Sbostic 		puteq (cpexpr(dovarp), cpexpr(DOINIT));
51843208Sbostic 	if( ! onetripflag )
51943208Sbostic 		{
52043208Sbostic 		q = mkexpr(OPMINUS, cpexpr(CONSTLIMIT), cpexpr(CONSTINIT));
52143208Sbostic 		if((incsign * conssgn(q)) == -1)
52243208Sbostic 			{
52343208Sbostic 			warn("DO range never executed");
52443208Sbostic 			if (optimflag)
52543208Sbostic 				optbuff (SKGOTO,0,ctlstack->endlabel,0);
52643208Sbostic 			else
52743208Sbostic 				putgoto (ctlstack->endlabel);
52843208Sbostic 			}
52943208Sbostic 		frexpr(q);
53043208Sbostic 		}
53143208Sbostic 	}
53243208Sbostic 
53343208Sbostic 
53443208Sbostic else if (ctlstack->dostepsign != VARSTEP && !onetripflag)
53543208Sbostic 	{
53643208Sbostic 	if (CONSTLIMIT)
53743208Sbostic 		q = (expptr) cpexpr(ctlstack->domax);
53843208Sbostic 	else
53943208Sbostic 		q = mkexpr(OPASSIGN, cpexpr(ctlstack->domax), DOLIMIT);
54043208Sbostic 	q1 = mkexpr(OPASSIGN, cpexpr(dovarp), DOINIT);
54143208Sbostic 	q = mkexpr( (ctlstack->dostepsign == POSSTEP ? OPGE : OPLE),
54243208Sbostic 		   q, q1);
54343208Sbostic 	if (optimflag)
54443208Sbostic 		optbuff (SKIFN,q, ctlstack->endlabel,0);
54543208Sbostic 	else
54643208Sbostic 		putif (q, ctlstack->endlabel);
54743208Sbostic 	}
54843208Sbostic else
54943208Sbostic 	{
55043208Sbostic 	if (!CONSTLIMIT)
55143208Sbostic 	    if (optimflag)
55243208Sbostic 		optbuff (SKEQ,
55343208Sbostic 			mkexpr(OPASSIGN,cpexpr(ctlstack->domax),DOLIMIT),0,0);
55443208Sbostic 	    else
55543208Sbostic 		puteq (cpexpr(ctlstack->domax), DOLIMIT);
55643208Sbostic 	q = DOINIT;
55743208Sbostic 	if (!onetripflag)
55843208Sbostic 		q = mkexpr(OPMINUS, q,
55943208Sbostic 			mkexpr(OPASSIGN, cpexpr(ctlstack->dostep),
56043208Sbostic 			       DOINCR) );
56143208Sbostic 	if (optimflag)
56243208Sbostic 		optbuff (SKEQ,mkexpr(OPASSIGN,cpexpr(dovarp), q),0,0);
56343208Sbostic 	else
56443208Sbostic 		puteq (cpexpr(dovarp), q);
56543208Sbostic 	if (onetripflag && ctlstack->dostepsign == VARSTEP)
56643208Sbostic 	    if (optimflag)
56743208Sbostic 		optbuff (SKEQ,
56843208Sbostic 			mkexpr(OPASSIGN,cpexpr(ctlstack->dostep),DOINCR),0,0);
56943208Sbostic 	    else
57043208Sbostic 		puteq (cpexpr(ctlstack->dostep), DOINCR);
57143208Sbostic 	}
57243208Sbostic 
57343208Sbostic if (ctlstack->dostepsign == VARSTEP)
57443208Sbostic 	{
57543208Sbostic 	expptr incr,test;
57643208Sbostic 	if (onetripflag)
57743208Sbostic 		if (optimflag)
57843208Sbostic 			optbuff (SKGOTO,0,ctlstack->dobodylabel,0);
57943208Sbostic 		else
58043208Sbostic 			putgoto (ctlstack->dobodylabel);
58143208Sbostic 	else
58243208Sbostic 	    if (optimflag)
58343208Sbostic 		optbuff (SKIFN,mkexpr(OPGE, cpexpr(ctlstack->dostep), ICON(0)),
58443208Sbostic 			ctlstack->doneglabel,0);
58543208Sbostic 	    else
58643208Sbostic 		putif (mkexpr(OPGE, cpexpr(ctlstack->dostep), ICON(0)),
58743208Sbostic 			ctlstack->doneglabel);
58843208Sbostic 	if (optimflag)
58943208Sbostic 		optbuff (SKLABEL,0,ctlstack->doposlabel,0);
59043208Sbostic 	else
59143208Sbostic 		putlabel (ctlstack->doposlabel);
59243208Sbostic 	incr = mkexpr(OPPLUSEQ, cpexpr(dovarp), cpexpr(ctlstack->dostep));
59343208Sbostic 	test = mkexpr(OPLE, incr, cpexpr(ctlstack->domax));
59443208Sbostic 	if (optimflag)
59543208Sbostic 		optbuff (SKIFN,test, ctlstack->endlabel,0);
59643208Sbostic 	else
59743208Sbostic 		putif (test, ctlstack->endlabel);
59843208Sbostic 	}
59943208Sbostic 
60043208Sbostic if (optimflag)
60143208Sbostic 	optbuff (SKLABEL,0,ctlstack->dobodylabel,0);
60243208Sbostic else
60343208Sbostic 	putlabel (ctlstack->dobodylabel);
60443208Sbostic if (dostgp)
60543208Sbostic 	{
60643208Sbostic 	if (optimflag)
60743208Sbostic 		optbuff (SKEQ,mkexpr(OPASSIGN,dostgp, dovarp),0,0);
60843208Sbostic 	else
60943208Sbostic 		puteq (dostgp, dovarp);
61043208Sbostic 	}
61143208Sbostic else
61243208Sbostic 	frexpr(dovarp);
61343208Sbostic if (optimflag)
61443208Sbostic 	doslot->nullslot = optbuff (SKNULL,0,0,0);
61543208Sbostic 
61643208Sbostic frexpr(CONSTINIT);
61743208Sbostic frexpr(CONSTLIMIT);
61843208Sbostic frexpr(CONSTINCR);
61943208Sbostic }
62043208Sbostic 
62143208Sbostic 
enddo(here)62243208Sbostic enddo(here)
62343208Sbostic int here;
62443208Sbostic 
62543208Sbostic {
62643208Sbostic   register struct Ctlframe *q;
62743208Sbostic   Namep np;
62843208Sbostic   Addrp ap, rv;
62943208Sbostic   expptr t;
63043208Sbostic   register int i;
63143208Sbostic   Slotp doslot;
63243208Sbostic 
63343208Sbostic   while (here == dorange)
63443208Sbostic     {
63543208Sbostic       while (ctlstack->ctltype == CTLIF || ctlstack->ctltype == CTLELSE)
63643208Sbostic 	{
63743208Sbostic 	  execerr("missing endif", CNULL);
63843208Sbostic 	  exendif();
63943208Sbostic 	}
64043208Sbostic 
64143208Sbostic       if (np = ctlstack->donamep)
64243208Sbostic 	{
64343208Sbostic 	rv = mkplace (np);
64443208Sbostic 
64543208Sbostic 	t = mkexpr(OPPLUSEQ, cpexpr(rv), cpexpr(ctlstack->dostep) );
64643208Sbostic 
64743208Sbostic 	if (optimflag)
64843208Sbostic 		doslot = optbuff (SKENDDO,0,0,ctlstack);
64943208Sbostic 
65043208Sbostic 	if (ctlstack->dostepsign == VARSTEP)
65143208Sbostic 		if (optimflag)
65243208Sbostic 			{
65343208Sbostic 			optbuff (SKIFN,
65443208Sbostic 				mkexpr(OPLE, cpexpr(ctlstack->dostep), ICON(0)),
65543208Sbostic 				ctlstack->doposlabel,0);
65643208Sbostic 			optbuff (SKLABEL,0,ctlstack->doneglabel,0);
65743208Sbostic 			optbuff (SKIFN,mkexpr(OPLT, t, ctlstack->domax),
65843208Sbostic 				ctlstack->dobodylabel,0);
65943208Sbostic 			}
66043208Sbostic 		else
66143208Sbostic 			{
66243208Sbostic 			putif (mkexpr(OPLE, cpexpr(ctlstack->dostep), ICON(0)),
66343208Sbostic 				ctlstack->doposlabel);
66443208Sbostic 			putlabel (ctlstack->doneglabel);
66543208Sbostic 			putif (mkexpr(OPLT, t, ctlstack->domax),
66643208Sbostic 				ctlstack->dobodylabel);
66743208Sbostic 			}
66843208Sbostic 	else
66943208Sbostic 		{
67043208Sbostic 		int op;
67143208Sbostic 		op = (ctlstack->dostepsign == POSSTEP ? OPGT : OPLT);
67243208Sbostic 		if (optimflag)
67343208Sbostic 			optbuff (SKIFN, mkexpr(op,t,ctlstack->domax),
67443208Sbostic 				ctlstack->dobodylabel,0);
67543208Sbostic 		else
67643208Sbostic 			putif (mkexpr(op, t, ctlstack->domax),
67743208Sbostic 				ctlstack->dobodylabel);
67843208Sbostic 		}
67943208Sbostic 	if (optimflag)
68043208Sbostic 		optbuff (SKLABEL,0,ctlstack->endlabel,0);
68143208Sbostic 	else
68243208Sbostic 		putlabel (ctlstack->endlabel);
68343208Sbostic 
68443208Sbostic 	if (ap = memversion(np))
68543208Sbostic 		{
68643208Sbostic 		if (optimflag)
68743208Sbostic 			optbuff (SKEQ,mkexpr(OPASSIGN,ap, rv),0,0);
68843208Sbostic 		else
68943208Sbostic 			puteq (ap, rv);
69043208Sbostic 		}
69143208Sbostic 	else
69243208Sbostic 		frexpr(rv);
69343208Sbostic 	for (i = 0; i < 4; i++)
69443208Sbostic 		ctlstack->ctlabels[i] = 0;
69543208Sbostic 	if (!optimflag)
69643208Sbostic 		deregister(ctlstack->donamep);
69743208Sbostic 	ctlstack->donamep->vdovar = NO;
69843208Sbostic 	if (optimflag)
69943208Sbostic 		doslot->nullslot = optbuff (SKNULL,0,0,0);
70043208Sbostic 	}
70143208Sbostic 
70243208Sbostic       popctl();
70343208Sbostic       poplab();
70443208Sbostic 
70543208Sbostic       dorange = 0;
70643208Sbostic       for (q = ctlstack; q >= ctls; --q)
70743208Sbostic 	if (q->ctltype == CTLDO)
70843208Sbostic 	  {
70943208Sbostic 	    dorange = q->dolabel;
71043208Sbostic 	    break;
71143208Sbostic 	  }
71243208Sbostic     }
71343208Sbostic }
71443208Sbostic 
71543208Sbostic 
exassign(vname,labelval)71643208Sbostic exassign(vname, labelval)
71743208Sbostic Namep vname;
71843208Sbostic struct Labelblock *labelval;
71943208Sbostic {
72043208Sbostic Addrp p;
72143208Sbostic expptr mkaddcon();
72243208Sbostic 
72343208Sbostic p = mkplace(vname);
72443208Sbostic #if SZADDR > SZSHORT
72543208Sbostic if( p->vtype == TYSHORT )
72643208Sbostic 	err("insufficient precision in ASSIGN variable");
72743208Sbostic else
72843208Sbostic #endif
72943208Sbostic if( ! ONEOF(p->vtype, MSKINT|MSKADDR) )
73043208Sbostic 	err("noninteger assign variable");
73143208Sbostic else
73243208Sbostic 	{
73343208Sbostic 	if (optimflag)
73443208Sbostic 		optbuff (SKASSIGN, p, labelval->labelno, 0);
73543208Sbostic 	else
73643208Sbostic 		puteq (p, intrconv(p->vtype, mkaddcon(labelval->labelno)));
73743208Sbostic 	}
73843208Sbostic }
73943208Sbostic 
74043208Sbostic 
74143208Sbostic 
exarif(expr,neglab,zerlab,poslab)74243208Sbostic exarif(expr, neglab, zerlab, poslab)
74343208Sbostic expptr expr;
74443208Sbostic struct Labelblock *neglab, *zerlab, *poslab;
74543208Sbostic {
74643208Sbostic register int lm, lz, lp;
74743208Sbostic struct Labelblock *labels[3];
74843208Sbostic 
74943208Sbostic lm = neglab->labelno;
75043208Sbostic lz = zerlab->labelno;
75143208Sbostic lp = poslab->labelno;
75243208Sbostic expr = fixtype(expr);
75343208Sbostic 
75443208Sbostic if( ! ONEOF(expr->headblock.vtype, MSKINT|MSKREAL) )
75543208Sbostic 	{
75643208Sbostic 	err("invalid type of arithmetic if expression");
75743208Sbostic 	frexpr(expr);
75843208Sbostic 	}
75943208Sbostic else
76043208Sbostic 	{
76143208Sbostic 	if(lm == lz)
76243208Sbostic 		exar2(OPLE, expr, lm, lp);
76343208Sbostic 	else if(lm == lp)
76443208Sbostic 		exar2(OPNE, expr, lm, lz);
76543208Sbostic 	else if(lz == lp)
76643208Sbostic 		exar2(OPGE, expr, lz, lm);
76743208Sbostic 	else
76843208Sbostic 		if (optimflag)
76943208Sbostic 			{
77043208Sbostic 			labels[0] = neglab;
77143208Sbostic 			labels[1] = zerlab;
77243208Sbostic 			labels[2] = poslab;
77343208Sbostic 			optbuff (SKARIF, expr, 0, labels);
77443208Sbostic 			}
77543208Sbostic 		else
77643208Sbostic 			prarif(expr, lm, lz, lp);
77743208Sbostic 	}
77843208Sbostic }
77943208Sbostic 
78043208Sbostic 
78143208Sbostic 
exar2(op,e,l1,l2)78243208Sbostic LOCAL exar2 (op, e, l1, l2)
78343208Sbostic int	op;
78443208Sbostic expptr	e;
78543208Sbostic int	l1,l2;
78643208Sbostic {
78743208Sbostic if (optimflag)
78843208Sbostic 	{
78943208Sbostic 	optbuff (SKIFN, mkexpr(op, e, ICON(0)), l2, 0);
79043208Sbostic 	optbuff (SKGOTO, 0, l1, 0);
79143208Sbostic 	}
79243208Sbostic else
79343208Sbostic 	{
79443208Sbostic 	putif (mkexpr(op, e, ICON(0)), l2);
79543208Sbostic 	putgoto (l1);
79643208Sbostic 	}
79743208Sbostic }
79843208Sbostic 
79943208Sbostic 
exreturn(p)80043208Sbostic exreturn(p)
80143208Sbostic register expptr p;
80243208Sbostic {
80343208Sbostic if(procclass != CLPROC)
80443208Sbostic 	warn("RETURN statement in main or block data");
80543208Sbostic if(p && (proctype!=TYSUBR || procclass!=CLPROC) )
80643208Sbostic 	{
80743208Sbostic 	err("alternate return in nonsubroutine");
80843208Sbostic 	p = 0;
80943208Sbostic 	}
81043208Sbostic 
81143208Sbostic if(p)
81243208Sbostic 	if (optimflag)
81343208Sbostic 		optbuff (SKRETURN, p, retlabel, 0);
81443208Sbostic 	else
81543208Sbostic 		{
81643208Sbostic 		putforce (TYINT, p);
81743208Sbostic 		putgoto (retlabel);
81843208Sbostic 		}
81943208Sbostic else
82043208Sbostic 	if (optimflag)
82143208Sbostic 		optbuff (SKRETURN, p,
82243208Sbostic 			 (proctype==TYSUBR ? ret0label : retlabel), 0);
82343208Sbostic 	else
82443208Sbostic 		putgoto (proctype==TYSUBR ? ret0label : retlabel);
82543208Sbostic }
82643208Sbostic 
82743208Sbostic 
82843208Sbostic 
82943208Sbostic exasgoto(labvar)
83043208Sbostic struct Hashentry *labvar;
83143208Sbostic {
83243208Sbostic register Addrp p;
83343208Sbostic 
83443208Sbostic p = mkplace(labvar);
83543208Sbostic if( ! ISINT(p->vtype) )
83643208Sbostic 	err("assigned goto variable must be integer");
83743208Sbostic else
83843208Sbostic 	if (optimflag)
83943208Sbostic 		optbuff (SKASGOTO, p, 0, 0);
84043208Sbostic 	else
84143208Sbostic 		putbranch (p);
84243208Sbostic }
843