xref: /csrg-svn/usr.bin/f77/pass1.vax/exec.c (revision 47955)
1*47955Sbostic /*-
2*47955Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*47955Sbostic  * All rights reserved.
4*47955Sbostic  *
5*47955Sbostic  * %sccs.include.proprietary.c%
622809Smckusick  */
722809Smckusick 
822809Smckusick #ifndef lint
9*47955Sbostic static char sccsid[] = "@(#)exec.c	5.7 (Berkeley) 04/12/91";
10*47955Sbostic #endif /* not lint */
1122809Smckusick 
1222809Smckusick /*
1322809Smckusick  * exec.c
1422809Smckusick  *
1522809Smckusick  * Routines for handling the semantics of control structures.
1622809Smckusick  * F77 compiler, pass 1.
1722809Smckusick  *
1822809Smckusick  * University of Utah CS Dept modification history:
1922809Smckusick  *
2024476Sdonn  * $Log:	exec.c,v $
2125735Sdonn  * Revision 5.6  85/12/20  19:42:46  donn
2225735Sdonn  * Change style of error reporting in last fix.
2325735Sdonn  *
2425735Sdonn  * Revision 5.5  85/12/20  18:54:10  donn
2525735Sdonn  * Complain about calls to things which aren't subroutines.
2625735Sdonn  *
2725735Sdonn  * Revision 5.4  85/12/18  19:57:58  donn
2825735Sdonn  * Assignment statements are executable statements -- advance the magic
2925735Sdonn  * parser state to forbid DATA statements and statement functions.
3025735Sdonn  *
3125735Sdonn  * Revision 5.3  85/11/25  00:23:49  donn
3225735Sdonn  * 4.3 beta
3325735Sdonn  *
3424476Sdonn  * Revision 5.2  85/08/10  04:07:36  donn
3524476Sdonn  * Changed an error message to correct spelling and be more accurate.
3624476Sdonn  * From Jerry Berkman.
3724476Sdonn  *
3822809Smckusick  * Revision 2.3  85/03/18  08:03:31  donn
3922809Smckusick  * Hacks for conversions from type address to numeric type -- prevent addresses
4022809Smckusick  * from being stored in shorts and prevent warnings about implicit conversions.
4122809Smckusick  *
4222809Smckusick  * Revision 2.2  84/09/03  23:18:30  donn
4322809Smckusick  * When a DO loop had the same variable as its loop variable and its limit,
4422809Smckusick  * the limit temporary was assigned to AFTER the original value of the variable
4522809Smckusick  * was destroyed by assigning the initial value to the loop variable.  I
4622809Smckusick  * swapped the operands of a comparison and changed the direction of the
4722809Smckusick  * operator...  This only affected programs when optimizing.  (This may not
4822809Smckusick  * be enough if something alters the order of evaluation of side effects
4922809Smckusick  * later on... sigh.)
5022809Smckusick  *
5122809Smckusick  * Revision 2.1  84/07/19  12:02:53  donn
5222809Smckusick  * Changed comment headers for UofU.
5322809Smckusick  *
5422809Smckusick  * Revision 1.3  84/07/12  18:35:12  donn
5522809Smckusick  * Added change to enddo() to detect open 'if' blocks at the ends of loops.
5622809Smckusick  *
5722809Smckusick  * Revision 1.2  84/06/08  11:22:53  donn
5822809Smckusick  * Fixed bug in exdo() -- if a loop parameter contained an instance of the loop
5922809Smckusick  * variable and the optimizer was off, the loop variable got converted to
6022809Smckusick  * register before the parameters were processed and so the loop parameters
6122809Smckusick  * were initialized from garbage in the register instead of the memory version
6222809Smckusick  * of the loop variable.
6322809Smckusick  *
6422809Smckusick  */
6522809Smckusick 
6622809Smckusick #include "defs.h"
6722809Smckusick #include "optim.h"
6822809Smckusick 
6922809Smckusick 
7022809Smckusick /*   Logical IF codes
7122809Smckusick */
7222809Smckusick 
7322809Smckusick 
exif(p)7422809Smckusick exif(p)
7522809Smckusick expptr p;
7622809Smckusick {
7722809Smckusick register int k;
7822809Smckusick pushctl(CTLIF);
7922809Smckusick ctlstack->elselabel = newlabel();
8022809Smckusick 
8122809Smckusick if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL)
8222809Smckusick 	{
8322809Smckusick 	if(k != TYERROR)
8422809Smckusick 		err("non-logical expression in IF statement");
8522809Smckusick 	frexpr(p);
8622809Smckusick 	}
8722809Smckusick else if (optimflag)
8822809Smckusick 	optbuff (SKIFN, p, ctlstack->elselabel, 0);
8922809Smckusick else
9022809Smckusick 	putif (p, ctlstack->elselabel);
9122809Smckusick }
9222809Smckusick 
9322809Smckusick 
9422809Smckusick 
exelif(p)9522809Smckusick exelif(p)
9622809Smckusick expptr p;
9722809Smckusick {
9822809Smckusick int k,oldelse;
9922809Smckusick 
10022809Smckusick if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL)
10122809Smckusick 	{
10222809Smckusick 	if(k != TYERROR)
10322809Smckusick 		err("non-logical expression in IF statement");
10422809Smckusick 	frexpr(p);
10522809Smckusick 	}
10622809Smckusick else    {
10722809Smckusick         if(ctlstack->ctltype == CTLIF)
10822809Smckusick 		{
10922809Smckusick 		if(ctlstack->endlabel == 0) ctlstack->endlabel = newlabel();
11022809Smckusick         	oldelse=ctlstack->elselabel;
11122809Smckusick 		ctlstack->elselabel = newlabel();
11222809Smckusick 		if (optimflag)
11322809Smckusick 			{
11422809Smckusick 			optbuff (SKGOTO, 0, ctlstack->endlabel, 0);
11522809Smckusick 			optbuff (SKLABEL, 0, oldelse, 0);
11622809Smckusick 			optbuff (SKIFN, p, ctlstack->elselabel, 0);
11722809Smckusick 			}
11822809Smckusick 		else
11922809Smckusick 			{
12022809Smckusick 			putgoto (ctlstack->endlabel);
12122809Smckusick 			putlabel (oldelse);
12222809Smckusick 			putif (p, ctlstack->elselabel);
12322809Smckusick 			}
12422809Smckusick 		}
12522809Smckusick         else	execerr("elseif out of place", CNULL);
12622809Smckusick         }
12722809Smckusick }
12822809Smckusick 
12922809Smckusick 
13022809Smckusick 
13122809Smckusick 
13222809Smckusick 
exelse()13322809Smckusick exelse()
13422809Smckusick {
13522809Smckusick if(ctlstack->ctltype==CTLIF)
13622809Smckusick 	{
13722809Smckusick 	if(ctlstack->endlabel == 0)
13822809Smckusick 		ctlstack->endlabel = newlabel();
13922809Smckusick 	ctlstack->ctltype = CTLELSE;
14022809Smckusick 	if (optimflag)
14122809Smckusick 		{
14222809Smckusick 		optbuff (SKGOTO, 0, ctlstack->endlabel, 0);
14322809Smckusick 		optbuff (SKLABEL, 0, ctlstack->elselabel, 0);
14422809Smckusick 		}
14522809Smckusick 	else
14622809Smckusick 		{
14722809Smckusick 		putgoto (ctlstack->endlabel);
14822809Smckusick 		putlabel (ctlstack->elselabel);
14922809Smckusick 		}
15022809Smckusick 	}
15122809Smckusick 
15222809Smckusick else	execerr("else out of place", CNULL);
15322809Smckusick }
15422809Smckusick 
15522809Smckusick 
exendif()15622809Smckusick exendif()
15722809Smckusick {
15822809Smckusick if (ctlstack->ctltype == CTLIF)
15922809Smckusick 	{
16022809Smckusick 	if (optimflag)
16122809Smckusick 		{
16222809Smckusick 		optbuff (SKLABEL, 0, ctlstack->elselabel, 0);
16322809Smckusick 		if (ctlstack->endlabel)
16422809Smckusick 			optbuff (SKLABEL, 0, ctlstack->endlabel, 0);
16522809Smckusick 		}
16622809Smckusick 	else
16722809Smckusick 		{
16822809Smckusick 		putlabel (ctlstack->elselabel);
16922809Smckusick 		if (ctlstack->endlabel)
17022809Smckusick 			putlabel (ctlstack->endlabel);
17122809Smckusick 		}
17222809Smckusick 	popctl ();
17322809Smckusick 	}
17422809Smckusick else if (ctlstack->ctltype == CTLELSE)
17522809Smckusick 	{
17622809Smckusick 	if (optimflag)
17722809Smckusick 		optbuff (SKLABEL, 0, ctlstack->endlabel, 0);
17822809Smckusick 	else
17922809Smckusick 		putlabel (ctlstack->endlabel);
18022809Smckusick 	popctl ();
18122809Smckusick 	}
18222809Smckusick else
18322809Smckusick 	execerr("endif out of place", CNULL);
18422809Smckusick }
18522809Smckusick 
18622809Smckusick 
18722809Smckusick 
pushctl(code)18822809Smckusick LOCAL pushctl(code)
18922809Smckusick int code;
19022809Smckusick {
19122809Smckusick register int i;
19222809Smckusick 
19322809Smckusick /* fprintf(diagfile,"old blklevel %d \n",blklevel); dmpframe(ctlstack); */
19422809Smckusick if(++ctlstack >= lastctl)
19522809Smckusick 	many("loops or if-then-elses", 'c');
19622809Smckusick ctlstack->ctltype = code;
19722809Smckusick for(i = 0 ; i < 4 ; ++i)
19822809Smckusick 	ctlstack->ctlabels[i] = 0;
19922809Smckusick ++blklevel;
20022809Smckusick }
20122809Smckusick 
20222809Smckusick 
popctl()20322809Smckusick LOCAL popctl()
20422809Smckusick {
20522809Smckusick if( ctlstack-- < ctls )
20622809Smckusick 	fatal("control stack empty");
20722809Smckusick --blklevel;
20822809Smckusick }
20922809Smckusick 
21022809Smckusick 
21122809Smckusick 
poplab()21222809Smckusick LOCAL poplab()
21322809Smckusick {
21422809Smckusick register struct Labelblock  *lp;
21522809Smckusick 
21622809Smckusick for(lp = labeltab ; lp < highlabtab ; ++lp)
21722809Smckusick 	if(lp->labdefined)
21822809Smckusick 		{
21922809Smckusick 		/* mark all labels in inner blocks unreachable */
22022809Smckusick 		if(lp->blklevel > blklevel)
22122809Smckusick 			lp->labinacc = YES;
22222809Smckusick 		}
22322809Smckusick 	else if(lp->blklevel > blklevel)
22422809Smckusick 		{
22522809Smckusick 		/* move all labels referred to in inner blocks out a level */
22622809Smckusick 		lp->blklevel = blklevel;
22722809Smckusick 		}
22822809Smckusick }
22922809Smckusick 
23022809Smckusick 
23122809Smckusick 
23222809Smckusick /*  BRANCHING CODE
23322809Smckusick */
23422809Smckusick 
23522809Smckusick exgoto(lab)
23622809Smckusick struct Labelblock *lab;
23722809Smckusick {
23822809Smckusick if (optimflag)
23922809Smckusick 	optbuff (SKGOTO, 0, lab->labelno, 0);
24022809Smckusick else
24122809Smckusick 	putgoto (lab->labelno);
24222809Smckusick }
24322809Smckusick 
24422809Smckusick 
24522809Smckusick 
24622809Smckusick 
24722809Smckusick 
24822809Smckusick 
24922809Smckusick 
exequals(lp,rp)25022809Smckusick exequals(lp, rp)
25122809Smckusick register struct Primblock *lp;
25222809Smckusick register expptr rp;
25322809Smckusick {
25422809Smckusick register Namep np;
25522809Smckusick 
25622809Smckusick if(lp->tag != TPRIM)
25722809Smckusick 	{
25822809Smckusick 	err("assignment to a non-variable");
25922809Smckusick 	frexpr(lp);
26022809Smckusick 	frexpr(rp);
26122809Smckusick 	}
26222809Smckusick else if(lp->namep->vclass!=CLVAR && lp->argsp)
26322809Smckusick 	{
26422809Smckusick 	if(parstate >= INEXEC)
26524476Sdonn 		err("undimensioned array or statement function out of order");
26622809Smckusick 	else
26722809Smckusick 		mkstfunct(lp, rp);
26822809Smckusick 	}
26922809Smckusick else
27022809Smckusick 	{
27122809Smckusick 	np = (Namep) lp->namep;
27222809Smckusick 	if (np->vclass == CLPROC && np->vprocclass == PTHISPROC
27322809Smckusick 		&& proctype == TYSUBR)
27422809Smckusick 		{
27522809Smckusick 		err("assignment to a subroutine name");
27622809Smckusick 		return;
27722809Smckusick 		}
27822809Smckusick 	if(parstate < INDATA)
27922809Smckusick 		enddcl();
28025735Sdonn 	parstate = INEXEC;
28122809Smckusick 	if (optimflag)
28222809Smckusick 		optbuff (SKEQ, mkexpr(OPASSIGN, mklhs(lp), fixtype(rp)), 0, 0);
28322809Smckusick 	else
28422809Smckusick 		puteq (mklhs(lp), fixtype(rp));
28522809Smckusick 	}
28622809Smckusick }
28722809Smckusick 
28822809Smckusick 
28922809Smckusick 
29022809Smckusick mkstfunct(lp, rp)
29122809Smckusick struct Primblock *lp;
29222809Smckusick expptr rp;
29322809Smckusick {
29422809Smckusick register struct Primblock *p;
29522809Smckusick register Namep np;
29622809Smckusick chainp args;
29722809Smckusick 
29822809Smckusick if(parstate < INDATA)
29922809Smckusick 	{
30022809Smckusick 	enddcl();
30122809Smckusick 	parstate = INDATA;
30222809Smckusick 	}
30322809Smckusick 
30422809Smckusick np = lp->namep;
30522809Smckusick if(np->vclass == CLUNKNOWN)
30622809Smckusick 	np->vclass = CLPROC;
30722809Smckusick else
30822809Smckusick 	{
30922809Smckusick 	dclerr("redeclaration of statement function", np);
31022809Smckusick 	return;
31122809Smckusick 	}
31222809Smckusick np->vprocclass = PSTFUNCT;
31322809Smckusick np->vstg = STGSTFUNCT;
31422809Smckusick impldcl(np);
31522809Smckusick args = (lp->argsp ? lp->argsp->listp : CHNULL);
31622809Smckusick np->varxptr.vstfdesc = mkchain(args , rp );
31722809Smckusick 
31822809Smckusick for( ; args ; args = args->nextp)
31922809Smckusick 	if( args->datap->tag!=TPRIM ||
32022809Smckusick 		(p = (struct Primblock *) (args->datap) )->argsp ||
32122809Smckusick 		p->fcharp || p->lcharp )
32222809Smckusick 		err("non-variable argument in statement function definition");
32322809Smckusick 	else
32422809Smckusick 		{
32522809Smckusick 		args->datap = (tagptr) (p->namep);
32622809Smckusick 		vardcl(p->namep);
32722809Smckusick 		free(p);
32822809Smckusick 		}
32922809Smckusick }
33022809Smckusick 
33122809Smckusick 
33222809Smckusick 
excall(name,args,nstars,labels)33322809Smckusick excall(name, args, nstars, labels)
33422809Smckusick Namep name;
33522809Smckusick struct Listblock *args;
33622809Smckusick int nstars;
33722809Smckusick struct Labelblock *labels[ ];
33822809Smckusick {
33922809Smckusick register expptr p;
34022809Smckusick 
34125735Sdonn if (name->vdcldone)
34225735Sdonn 	if (name->vclass != CLPROC && name->vclass != CLENTRY)
34325735Sdonn 		{
34425735Sdonn 		dclerr("call to non-subroutine", name);
34525735Sdonn 		return;
34625735Sdonn 		}
34725735Sdonn 	else if (name->vtype != TYSUBR)
34825735Sdonn 		{
34925735Sdonn 		dclerr("subroutine invocation of function", name);
35025735Sdonn 		return;
35125735Sdonn 		}
35222809Smckusick settype(name, TYSUBR, ENULL);
35322809Smckusick p = mkfunct( mkprim(name, args, CHNULL) );
35422809Smckusick p->exprblock.vtype = p->exprblock.leftp->headblock.vtype = TYINT;
35522809Smckusick if (nstars > 0)
35622809Smckusick 	if (optimflag)
35722809Smckusick 		optbuff (SKCMGOTO, p, nstars, labels);
35822809Smckusick 	else
35922809Smckusick 		putcmgo (p, nstars, labels);
36022809Smckusick else
36122809Smckusick 	if (optimflag)
36222809Smckusick 		optbuff (SKCALL, p, 0, 0);
36322809Smckusick 	else
36422809Smckusick 		putexpr (p);
36522809Smckusick }
36622809Smckusick 
36722809Smckusick 
36822809Smckusick 
exstop(stop,p)36922809Smckusick exstop(stop, p)
37022809Smckusick int stop;
37122809Smckusick register expptr p;
37222809Smckusick {
37322809Smckusick char *q;
37422809Smckusick int n;
37522809Smckusick expptr mkstrcon();
37622809Smckusick 
37722809Smckusick if(p)
37822809Smckusick 	{
37922809Smckusick 	if( ! ISCONST(p) )
38022809Smckusick 		{
38122809Smckusick 		execerr("pause/stop argument must be constant", CNULL);
38222809Smckusick 		frexpr(p);
38322809Smckusick 		p = mkstrcon(0, CNULL);
38422809Smckusick 		}
38522809Smckusick 	else if( ISINT(p->constblock.vtype) )
38622809Smckusick 		{
38733256Sbostic 		q = convic(p->constblock.constant.ci);
38822809Smckusick 		n = strlen(q);
38922809Smckusick 		if(n > 0)
39022809Smckusick 			{
39133256Sbostic 			p->constblock.constant.ccp = copyn(n, q);
39222809Smckusick 			p->constblock.vtype = TYCHAR;
39322809Smckusick 			p->constblock.vleng = (expptr) ICON(n);
39422809Smckusick 			}
39522809Smckusick 		else
39622809Smckusick 			p = (expptr) mkstrcon(0, CNULL);
39722809Smckusick 		}
39822809Smckusick 	else if(p->constblock.vtype != TYCHAR)
39922809Smckusick 		{
40022809Smckusick 		execerr("pause/stop argument must be integer or string", CNULL);
40122809Smckusick 		p = (expptr) mkstrcon(0, CNULL);
40222809Smckusick 		}
40322809Smckusick 	}
40422809Smckusick else	p = (expptr) mkstrcon(0, CNULL);
40522809Smckusick 
40622809Smckusick if (optimflag)
40722809Smckusick 	optbuff ((stop ? SKSTOP : SKPAUSE), p, 0, 0);
40822809Smckusick else
40922809Smckusick 	putexpr (call1(TYSUBR, (stop ? "s_stop" : "s_paus"), p));
41022809Smckusick }
41122809Smckusick 
41222809Smckusick 
41322809Smckusick /* UCB DO LOOP CODE */
41422809Smckusick 
41522809Smckusick #define DOINIT	par[0]
41622809Smckusick #define DOLIMIT	par[1]
41722809Smckusick #define DOINCR	par[2]
41822809Smckusick 
41933256Sbostic #define CONSTINIT  constant[0]
42033256Sbostic #define CONSTLIMIT constant[1]
42133256Sbostic #define CONSTINCR  constant[2]
42222809Smckusick 
42322809Smckusick #define VARSTEP	0
42422809Smckusick #define POSSTEP	1
42522809Smckusick #define NEGSTEP	2
42622809Smckusick 
42722809Smckusick 
exdo(range,spec)42822809Smckusick exdo(range, spec)
42922809Smckusick int range;
43022809Smckusick chainp spec;
43122809Smckusick 
43222809Smckusick {
43322809Smckusick   register expptr p, q;
43422809Smckusick   expptr q1;
43522809Smckusick   register Namep np;
43622809Smckusick   chainp cp;
43722809Smckusick   register int i;
43822809Smckusick   int dotype, incsign;
43922809Smckusick   Addrp dovarp, dostgp;
44022809Smckusick   expptr par[3];
44133256Sbostic   expptr constant[3];
44222809Smckusick   Slotp doslot;
44322809Smckusick 
44422809Smckusick   pushctl(CTLDO);
44522809Smckusick   dorange = ctlstack->dolabel = range;
44622809Smckusick   np = (Namep) (spec->datap);
44722809Smckusick   ctlstack->donamep = NULL;
44822809Smckusick   if(np->vdovar)
44922809Smckusick     {
45022809Smckusick       errstr("nested loops with variable %s", varstr(VL,np->varname));
45122809Smckusick       return;
45222809Smckusick     }
45322809Smckusick 
45422809Smckusick   dovarp = mkplace(np);
45522809Smckusick   dotype = dovarp->vtype;
45622809Smckusick 
45722809Smckusick   if( ! ONEOF(dotype, MSKINT|MSKREAL) )
45822809Smckusick     {
45922809Smckusick       err("bad type on DO variable");
46022809Smckusick       return;
46122809Smckusick     }
46222809Smckusick 
46322809Smckusick 
46422809Smckusick   for(i=0 , cp = spec->nextp ; cp!=NULL && i<3 ; cp = cp->nextp)
46522809Smckusick     {
46622809Smckusick       p = fixtype((expptr) cpexpr((tagptr) q = cp->datap));
46722809Smckusick       if(!ONEOF(p->headblock.vtype, MSKINT|MSKREAL) )
46822809Smckusick 	{
46922809Smckusick 	  err("bad type on DO parameter");
47022809Smckusick 	  return;
47122809Smckusick 	}
47222809Smckusick 
47322809Smckusick 
47422809Smckusick       if (ISCONST(q))
47533256Sbostic 	constant[i] = mkconv(dotype, q);
47622809Smckusick       else
47722809Smckusick 	{
47822809Smckusick 	  frexpr(q);
47933256Sbostic 	  constant[i] = NULL;
48022809Smckusick 	}
48122809Smckusick 
48222809Smckusick       par[i++] = mkconv(dotype, p);
48322809Smckusick     }
48422809Smckusick 
48522809Smckusick   frchain(&spec);
48622809Smckusick   switch(i)
48722809Smckusick     {
48822809Smckusick     case 0:
48922809Smckusick     case 1:
49022809Smckusick       err("too few DO parameters");
49122809Smckusick       return;
49222809Smckusick 
49322809Smckusick     case 2:
49422809Smckusick       DOINCR = (expptr) ICON(1);
49522809Smckusick       CONSTINCR = ICON(1);
49622809Smckusick 
49722809Smckusick     case 3:
49822809Smckusick       break;
49922809Smckusick 
50022809Smckusick     default:
50122809Smckusick       err("too many DO parameters");
50222809Smckusick       return;
50322809Smckusick     }
50422809Smckusick 
50522809Smckusick   ctlstack->donamep = np;
50622809Smckusick 
50722809Smckusick   np->vdovar = YES;
50822809Smckusick   if( !optimflag && enregister(np) )
50922809Smckusick     {
51022809Smckusick       /* stgp points to a storage version, varp to a register version */
51122809Smckusick       dostgp = dovarp;
51222809Smckusick       dovarp = mkplace(np);
51322809Smckusick     }
51422809Smckusick   else
51522809Smckusick     dostgp = NULL;
51622809Smckusick 
51722809Smckusick   for (i = 0; i < 4; i++)
51822809Smckusick     ctlstack->ctlabels[i] = newlabel();
51922809Smckusick 
52022809Smckusick   if( CONSTLIMIT )
52122809Smckusick     ctlstack->domax = DOLIMIT;
52222809Smckusick   else
52322809Smckusick     ctlstack->domax = (expptr) mktemp(dotype, PNULL);
52422809Smckusick 
52522809Smckusick   if( CONSTINCR )
52622809Smckusick     {
52722809Smckusick       ctlstack->dostep = DOINCR;
52822809Smckusick       if( (incsign = conssgn(CONSTINCR)) == 0)
52922809Smckusick 	err("zero DO increment");
53022809Smckusick       ctlstack->dostepsign = (incsign > 0 ? POSSTEP : NEGSTEP);
53122809Smckusick     }
53222809Smckusick   else
53322809Smckusick     {
53422809Smckusick       ctlstack->dostep = (expptr) mktemp(dotype, PNULL);
53522809Smckusick       ctlstack->dostepsign = VARSTEP;
53622809Smckusick     }
53722809Smckusick 
53822809Smckusick if (optimflag)
53922809Smckusick 	doslot = optbuff (SKDOHEAD,0,0,ctlstack);
54022809Smckusick 
54122809Smckusick if( CONSTLIMIT && CONSTINIT && ctlstack->dostepsign!=VARSTEP)
54222809Smckusick 	{
54322809Smckusick 	if (optimflag)
54422809Smckusick 		optbuff (SKEQ,mkexpr(OPASSIGN,cpexpr(dovarp),cpexpr(DOINIT)),
54522809Smckusick 			0,0);
54622809Smckusick 	else
54722809Smckusick 		puteq (cpexpr(dovarp), cpexpr(DOINIT));
54822809Smckusick 	if( ! onetripflag )
54922809Smckusick 		{
55022809Smckusick 		q = mkexpr(OPMINUS, cpexpr(CONSTLIMIT), cpexpr(CONSTINIT));
55122809Smckusick 		if((incsign * conssgn(q)) == -1)
55222809Smckusick 			{
55322809Smckusick 			warn("DO range never executed");
55422809Smckusick 			if (optimflag)
55522809Smckusick 				optbuff (SKGOTO,0,ctlstack->endlabel,0);
55622809Smckusick 			else
55722809Smckusick 				putgoto (ctlstack->endlabel);
55822809Smckusick 			}
55922809Smckusick 		frexpr(q);
56022809Smckusick 		}
56122809Smckusick 	}
56222809Smckusick 
56322809Smckusick 
56422809Smckusick else if (ctlstack->dostepsign != VARSTEP && !onetripflag)
56522809Smckusick 	{
56622809Smckusick 	if (CONSTLIMIT)
56722809Smckusick 		q = (expptr) cpexpr(ctlstack->domax);
56822809Smckusick 	else
56922809Smckusick 		q = mkexpr(OPASSIGN, cpexpr(ctlstack->domax), DOLIMIT);
57022809Smckusick 	q1 = mkexpr(OPASSIGN, cpexpr(dovarp), DOINIT);
57122809Smckusick 	q = mkexpr( (ctlstack->dostepsign == POSSTEP ? OPGE : OPLE),
57222809Smckusick 		   q, q1);
57322809Smckusick 	if (optimflag)
57422809Smckusick 		optbuff (SKIFN,q, ctlstack->endlabel,0);
57522809Smckusick 	else
57622809Smckusick 		putif (q, ctlstack->endlabel);
57722809Smckusick 	}
57822809Smckusick else
57922809Smckusick 	{
58022809Smckusick 	if (!CONSTLIMIT)
58122809Smckusick 	    if (optimflag)
58222809Smckusick 		optbuff (SKEQ,
58322809Smckusick 			mkexpr(OPASSIGN,cpexpr(ctlstack->domax),DOLIMIT),0,0);
58422809Smckusick 	    else
58522809Smckusick 		puteq (cpexpr(ctlstack->domax), DOLIMIT);
58622809Smckusick 	q = DOINIT;
58722809Smckusick 	if (!onetripflag)
58822809Smckusick 		q = mkexpr(OPMINUS, q,
58922809Smckusick 			mkexpr(OPASSIGN, cpexpr(ctlstack->dostep),
59022809Smckusick 			       DOINCR) );
59122809Smckusick 	if (optimflag)
59222809Smckusick 		optbuff (SKEQ,mkexpr(OPASSIGN,cpexpr(dovarp), q),0,0);
59322809Smckusick 	else
59422809Smckusick 		puteq (cpexpr(dovarp), q);
59522809Smckusick 	if (onetripflag && ctlstack->dostepsign == VARSTEP)
59622809Smckusick 	    if (optimflag)
59722809Smckusick 		optbuff (SKEQ,
59822809Smckusick 			mkexpr(OPASSIGN,cpexpr(ctlstack->dostep),DOINCR),0,0);
59922809Smckusick 	    else
60022809Smckusick 		puteq (cpexpr(ctlstack->dostep), DOINCR);
60122809Smckusick 	}
60222809Smckusick 
60322809Smckusick if (ctlstack->dostepsign == VARSTEP)
60422809Smckusick 	{
60522809Smckusick 	expptr incr,test;
60622809Smckusick 	if (onetripflag)
60722809Smckusick 		if (optimflag)
60822809Smckusick 			optbuff (SKGOTO,0,ctlstack->dobodylabel,0);
60922809Smckusick 		else
61022809Smckusick 			putgoto (ctlstack->dobodylabel);
61122809Smckusick 	else
61222809Smckusick 	    if (optimflag)
61322809Smckusick 		optbuff (SKIFN,mkexpr(OPGE, cpexpr(ctlstack->dostep), ICON(0)),
61422809Smckusick 			ctlstack->doneglabel,0);
61522809Smckusick 	    else
61622809Smckusick 		putif (mkexpr(OPGE, cpexpr(ctlstack->dostep), ICON(0)),
61722809Smckusick 			ctlstack->doneglabel);
61822809Smckusick 	if (optimflag)
61922809Smckusick 		optbuff (SKLABEL,0,ctlstack->doposlabel,0);
62022809Smckusick 	else
62122809Smckusick 		putlabel (ctlstack->doposlabel);
62222809Smckusick 	incr = mkexpr(OPPLUSEQ, cpexpr(dovarp), cpexpr(ctlstack->dostep));
62322809Smckusick 	test = mkexpr(OPLE, incr, cpexpr(ctlstack->domax));
62422809Smckusick 	if (optimflag)
62522809Smckusick 		optbuff (SKIFN,test, ctlstack->endlabel,0);
62622809Smckusick 	else
62722809Smckusick 		putif (test, ctlstack->endlabel);
62822809Smckusick 	}
62922809Smckusick 
63022809Smckusick if (optimflag)
63122809Smckusick 	optbuff (SKLABEL,0,ctlstack->dobodylabel,0);
63222809Smckusick else
63322809Smckusick 	putlabel (ctlstack->dobodylabel);
63422809Smckusick if (dostgp)
63522809Smckusick 	{
63622809Smckusick 	if (optimflag)
63722809Smckusick 		optbuff (SKEQ,mkexpr(OPASSIGN,dostgp, dovarp),0,0);
63822809Smckusick 	else
63922809Smckusick 		puteq (dostgp, dovarp);
64022809Smckusick 	}
64122809Smckusick else
64222809Smckusick 	frexpr(dovarp);
64322809Smckusick if (optimflag)
64422809Smckusick 	doslot->nullslot = optbuff (SKNULL,0,0,0);
64522809Smckusick 
64622809Smckusick frexpr(CONSTINIT);
64722809Smckusick frexpr(CONSTLIMIT);
64822809Smckusick frexpr(CONSTINCR);
64922809Smckusick }
65022809Smckusick 
65122809Smckusick 
enddo(here)65222809Smckusick enddo(here)
65322809Smckusick int here;
65422809Smckusick 
65522809Smckusick {
65622809Smckusick   register struct Ctlframe *q;
65722809Smckusick   Namep np;
65822809Smckusick   Addrp ap, rv;
65922809Smckusick   expptr t;
66022809Smckusick   register int i;
66122809Smckusick   Slotp doslot;
66222809Smckusick 
66322809Smckusick   while (here == dorange)
66422809Smckusick     {
66522809Smckusick       while (ctlstack->ctltype == CTLIF || ctlstack->ctltype == CTLELSE)
66622809Smckusick 	{
66722809Smckusick 	  execerr("missing endif", CNULL);
66822809Smckusick 	  exendif();
66922809Smckusick 	}
67022809Smckusick 
67122809Smckusick       if (np = ctlstack->donamep)
67222809Smckusick 	{
67322809Smckusick 	rv = mkplace (np);
67422809Smckusick 
67522809Smckusick 	t = mkexpr(OPPLUSEQ, cpexpr(rv), cpexpr(ctlstack->dostep) );
67622809Smckusick 
67722809Smckusick 	if (optimflag)
67822809Smckusick 		doslot = optbuff (SKENDDO,0,0,ctlstack);
67922809Smckusick 
68022809Smckusick 	if (ctlstack->dostepsign == VARSTEP)
68122809Smckusick 		if (optimflag)
68222809Smckusick 			{
68322809Smckusick 			optbuff (SKIFN,
68422809Smckusick 				mkexpr(OPLE, cpexpr(ctlstack->dostep), ICON(0)),
68522809Smckusick 				ctlstack->doposlabel,0);
68622809Smckusick 			optbuff (SKLABEL,0,ctlstack->doneglabel,0);
68722809Smckusick 			optbuff (SKIFN,mkexpr(OPLT, t, ctlstack->domax),
68822809Smckusick 				ctlstack->dobodylabel,0);
68922809Smckusick 			}
69022809Smckusick 		else
69122809Smckusick 			{
69222809Smckusick 			putif (mkexpr(OPLE, cpexpr(ctlstack->dostep), ICON(0)),
69322809Smckusick 				ctlstack->doposlabel);
69422809Smckusick 			putlabel (ctlstack->doneglabel);
69522809Smckusick 			putif (mkexpr(OPLT, t, ctlstack->domax),
69622809Smckusick 				ctlstack->dobodylabel);
69722809Smckusick 			}
69822809Smckusick 	else
69922809Smckusick 		{
70022809Smckusick 		int op;
70122809Smckusick 		op = (ctlstack->dostepsign == POSSTEP ? OPGT : OPLT);
70222809Smckusick 		if (optimflag)
70322809Smckusick 			optbuff (SKIFN, mkexpr(op,t,ctlstack->domax),
70422809Smckusick 				ctlstack->dobodylabel,0);
70522809Smckusick 		else
70622809Smckusick 			putif (mkexpr(op, t, ctlstack->domax),
70722809Smckusick 				ctlstack->dobodylabel);
70822809Smckusick 		}
70922809Smckusick 	if (optimflag)
71022809Smckusick 		optbuff (SKLABEL,0,ctlstack->endlabel,0);
71122809Smckusick 	else
71222809Smckusick 		putlabel (ctlstack->endlabel);
71322809Smckusick 
71422809Smckusick 	if (ap = memversion(np))
71522809Smckusick 		{
71622809Smckusick 		if (optimflag)
71722809Smckusick 			optbuff (SKEQ,mkexpr(OPASSIGN,ap, rv),0,0);
71822809Smckusick 		else
71922809Smckusick 			puteq (ap, rv);
72022809Smckusick 		}
72122809Smckusick 	else
72222809Smckusick 		frexpr(rv);
72322809Smckusick 	for (i = 0; i < 4; i++)
72422809Smckusick 		ctlstack->ctlabels[i] = 0;
72522809Smckusick 	if (!optimflag)
72622809Smckusick 		deregister(ctlstack->donamep);
72722809Smckusick 	ctlstack->donamep->vdovar = NO;
72822809Smckusick 	if (optimflag)
72922809Smckusick 		doslot->nullslot = optbuff (SKNULL,0,0,0);
73022809Smckusick 	}
73122809Smckusick 
73222809Smckusick       popctl();
73322809Smckusick       poplab();
73422809Smckusick 
73522809Smckusick       dorange = 0;
73622809Smckusick       for (q = ctlstack; q >= ctls; --q)
73722809Smckusick 	if (q->ctltype == CTLDO)
73822809Smckusick 	  {
73922809Smckusick 	    dorange = q->dolabel;
74022809Smckusick 	    break;
74122809Smckusick 	  }
74222809Smckusick     }
74322809Smckusick }
74422809Smckusick 
74522809Smckusick 
exassign(vname,labelval)74622809Smckusick exassign(vname, labelval)
74722809Smckusick Namep vname;
74822809Smckusick struct Labelblock *labelval;
74922809Smckusick {
75022809Smckusick Addrp p;
75122809Smckusick expptr mkaddcon();
75222809Smckusick 
75322809Smckusick p = mkplace(vname);
75422809Smckusick #if SZADDR > SZSHORT
75522809Smckusick if( p->vtype == TYSHORT )
75622809Smckusick 	err("insufficient precision in ASSIGN variable");
75722809Smckusick else
75822809Smckusick #endif
75922809Smckusick if( ! ONEOF(p->vtype, MSKINT|MSKADDR) )
76022809Smckusick 	err("noninteger assign variable");
76122809Smckusick else
76222809Smckusick 	{
76322809Smckusick 	if (optimflag)
76422809Smckusick 		optbuff (SKASSIGN, p, labelval->labelno, 0);
76522809Smckusick 	else
76622809Smckusick 		puteq (p, intrconv(p->vtype, mkaddcon(labelval->labelno)));
76722809Smckusick 	}
76822809Smckusick }
76922809Smckusick 
77022809Smckusick 
77122809Smckusick 
exarif(expr,neglab,zerlab,poslab)77222809Smckusick exarif(expr, neglab, zerlab, poslab)
77322809Smckusick expptr expr;
77422809Smckusick struct Labelblock *neglab, *zerlab, *poslab;
77522809Smckusick {
77622809Smckusick register int lm, lz, lp;
77722809Smckusick struct Labelblock *labels[3];
77822809Smckusick 
77922809Smckusick lm = neglab->labelno;
78022809Smckusick lz = zerlab->labelno;
78122809Smckusick lp = poslab->labelno;
78222809Smckusick expr = fixtype(expr);
78322809Smckusick 
78422809Smckusick if( ! ONEOF(expr->headblock.vtype, MSKINT|MSKREAL) )
78522809Smckusick 	{
78622809Smckusick 	err("invalid type of arithmetic if expression");
78722809Smckusick 	frexpr(expr);
78822809Smckusick 	}
78922809Smckusick else
79022809Smckusick 	{
79122809Smckusick 	if(lm == lz)
79222809Smckusick 		exar2(OPLE, expr, lm, lp);
79322809Smckusick 	else if(lm == lp)
79422809Smckusick 		exar2(OPNE, expr, lm, lz);
79522809Smckusick 	else if(lz == lp)
79622809Smckusick 		exar2(OPGE, expr, lz, lm);
79722809Smckusick 	else
79822809Smckusick 		if (optimflag)
79922809Smckusick 			{
80022809Smckusick 			labels[0] = neglab;
80122809Smckusick 			labels[1] = zerlab;
80222809Smckusick 			labels[2] = poslab;
80322809Smckusick 			optbuff (SKARIF, expr, 0, labels);
80422809Smckusick 			}
80522809Smckusick 		else
80622809Smckusick 			prarif(expr, lm, lz, lp);
80722809Smckusick 	}
80822809Smckusick }
80922809Smckusick 
81022809Smckusick 
81122809Smckusick 
exar2(op,e,l1,l2)81222809Smckusick LOCAL exar2 (op, e, l1, l2)
81322809Smckusick int	op;
81422809Smckusick expptr	e;
81522809Smckusick int	l1,l2;
81622809Smckusick {
81722809Smckusick if (optimflag)
81822809Smckusick 	{
81922809Smckusick 	optbuff (SKIFN, mkexpr(op, e, ICON(0)), l2, 0);
82022809Smckusick 	optbuff (SKGOTO, 0, l1, 0);
82122809Smckusick 	}
82222809Smckusick else
82322809Smckusick 	{
82422809Smckusick 	putif (mkexpr(op, e, ICON(0)), l2);
82522809Smckusick 	putgoto (l1);
82622809Smckusick 	}
82722809Smckusick }
82822809Smckusick 
82922809Smckusick 
exreturn(p)83022809Smckusick exreturn(p)
83122809Smckusick register expptr p;
83222809Smckusick {
83322809Smckusick if(procclass != CLPROC)
83422809Smckusick 	warn("RETURN statement in main or block data");
83522809Smckusick if(p && (proctype!=TYSUBR || procclass!=CLPROC) )
83622809Smckusick 	{
83722809Smckusick 	err("alternate return in nonsubroutine");
83822809Smckusick 	p = 0;
83922809Smckusick 	}
84022809Smckusick 
84122809Smckusick if(p)
84222809Smckusick 	if (optimflag)
84322809Smckusick 		optbuff (SKRETURN, p, retlabel, 0);
84422809Smckusick 	else
84522809Smckusick 		{
84622809Smckusick 		putforce (TYINT, p);
84722809Smckusick 		putgoto (retlabel);
84822809Smckusick 		}
84922809Smckusick else
85022809Smckusick 	if (optimflag)
85122809Smckusick 		optbuff (SKRETURN, p,
85222809Smckusick 			 (proctype==TYSUBR ? ret0label : retlabel), 0);
85322809Smckusick 	else
85422809Smckusick 		putgoto (proctype==TYSUBR ? ret0label : retlabel);
85522809Smckusick }
85622809Smckusick 
85722809Smckusick 
85822809Smckusick 
85922809Smckusick exasgoto(labvar)
86022809Smckusick struct Hashentry *labvar;
86122809Smckusick {
86222809Smckusick register Addrp p;
86322809Smckusick 
86422809Smckusick p = mkplace(labvar);
86522809Smckusick if( ! ISINT(p->vtype) )
86622809Smckusick 	err("assigned goto variable must be integer");
86722809Smckusick else
86822809Smckusick 	if (optimflag)
86922809Smckusick 		optbuff (SKASGOTO, p, 0, 0);
87022809Smckusick 	else
87122809Smckusick 		putbranch (p);
87222809Smckusick }
873