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