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