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%
622806Smckusick */
722806Smckusick
822806Smckusick #ifndef lint
9*47955Sbostic static char sccsid[] = "@(#)equiv.c 5.3 (Berkeley) 04/12/91";
10*47955Sbostic #endif /* not lint */
1122806Smckusick
1222806Smckusick /*
1322806Smckusick * equiv.c
1422806Smckusick *
1522806Smckusick * Routines related to equivalence class processing, f77 compiler, 4.2 BSD.
1622806Smckusick *
1722806Smckusick * University of Utah CS Dept modification history:
1822806Smckusick *
1922806Smckusick * Revision 3.2 85/01/14 00:14:12 donn
2022806Smckusick * Fixed bug in eqvcommon that was causing the calculations of multilevel
2122806Smckusick * equivalences to be screwed up.
2222806Smckusick *
2322806Smckusick * Revision 3.1 84/10/13 01:16:08 donn
2422806Smckusick * Installed Jerry Berkman's version; added UofU comment header.
2522806Smckusick *
2622806Smckusick */
2722806Smckusick
2822806Smckusick
2922806Smckusick #include "defs.h"
3022806Smckusick
3122806Smckusick #ifdef SDB
3222806Smckusick # include <a.out.h>
3322806Smckusick # ifndef N_SO
3422806Smckusick # include <stab.h>
3522806Smckusick # endif
3622806Smckusick #endif
3722806Smckusick
3822806Smckusick /* called at end of declarations section to process chains
3922806Smckusick created by EQUIVALENCE statements
4022806Smckusick */
4122806Smckusick
doequiv()4222806Smckusick doequiv()
4322806Smckusick {
4422806Smckusick register int i;
4522806Smckusick int inequiv, comno, ovarno;
4622806Smckusick ftnint comoffset, offset, leng;
4722806Smckusick register struct Equivblock *p;
4822806Smckusick register struct Eqvchain *q;
4922806Smckusick struct Primblock *itemp;
5022806Smckusick register Namep np;
5122806Smckusick expptr offp, suboffset();
5222806Smckusick int ns, nsubs();
5322806Smckusick chainp cp;
5422806Smckusick char *memname();
5522806Smckusick int doeqverr = 0;
5622806Smckusick
5722806Smckusick for(i = 0 ; i < nequiv ; ++i)
5822806Smckusick {
5922806Smckusick p = &eqvclass[i];
6022806Smckusick p->eqvbottom = p->eqvtop = 0;
6122806Smckusick comno = -1;
6222806Smckusick
6322806Smckusick for(q = p->equivs ; q ; q = q->eqvnextp)
6422806Smckusick {
6522806Smckusick offset = 0;
6622806Smckusick itemp = q->eqvitem.eqvlhs;
6722806Smckusick if( itemp == NULL ) fatal("error processing equivalence");
6822806Smckusick equivdcl = YES;
6922806Smckusick vardcl(np = itemp->namep);
7022806Smckusick equivdcl = NO;
7122806Smckusick if(itemp->argsp || itemp->fcharp)
7222806Smckusick {
7322806Smckusick if(np->vdim!=NULL && np->vdim->ndim>1 &&
7422806Smckusick nsubs(itemp->argsp)==1 )
7522806Smckusick {
7622806Smckusick if(! ftn66flag)
7722806Smckusick warn("1-dim subscript in EQUIVALENCE");
7822806Smckusick cp = NULL;
7922806Smckusick ns = np->vdim->ndim;
8022806Smckusick while(--ns > 0)
8122806Smckusick cp = mkchain( ICON(1), cp);
8222806Smckusick itemp->argsp->listp->nextp = cp;
8322806Smckusick }
8422806Smckusick
8522806Smckusick offp = suboffset(itemp);
8622806Smckusick if(ISICON(offp))
8733256Sbostic offset = offp->constblock.constant.ci;
8822806Smckusick else {
8922806Smckusick dclerr("illegal subscript in equivalence ",
9022806Smckusick np);
9122806Smckusick np = NULL;
9222806Smckusick doeqverr = 1;
9322806Smckusick }
9422806Smckusick frexpr(offp);
9522806Smckusick }
9622806Smckusick frexpr(itemp);
9722806Smckusick
9822806Smckusick if(np && (leng = iarrlen(np))<0)
9922806Smckusick {
10022806Smckusick dclerr("argument in equivalence", np);
10122806Smckusick np = NULL;
10222806Smckusick doeqverr =1;
10322806Smckusick }
10422806Smckusick
10522806Smckusick if(np) switch(np->vstg)
10622806Smckusick {
10722806Smckusick case STGUNKNOWN:
10822806Smckusick case STGBSS:
10922806Smckusick case STGEQUIV:
11022806Smckusick break;
11122806Smckusick
11222806Smckusick case STGCOMMON:
11322806Smckusick comno = np->vardesc.varno;
11422806Smckusick comoffset = np->voffset + offset;
11522806Smckusick break;
11622806Smckusick
11722806Smckusick default:
11822806Smckusick dclerr("bad storage class in equivalence", np);
11922806Smckusick np = NULL;
12022806Smckusick doeqverr = 1;
12122806Smckusick break;
12222806Smckusick }
12322806Smckusick
12422806Smckusick if(np)
12522806Smckusick {
12622806Smckusick q->eqvoffset = offset;
12722806Smckusick p->eqvbottom = lmin(p->eqvbottom, -offset);
12822806Smckusick p->eqvtop = lmax(p->eqvtop, leng-offset);
12922806Smckusick }
13022806Smckusick q->eqvitem.eqvname = np;
13122806Smckusick }
13222806Smckusick
13322806Smckusick if(comno >= 0)
13422806Smckusick eqvcommon(p, comno, comoffset);
13522806Smckusick else for(q = p->equivs ; q ; q = q->eqvnextp)
13622806Smckusick {
13722806Smckusick if(np = q->eqvitem.eqvname)
13822806Smckusick {
13922806Smckusick inequiv = NO;
14022806Smckusick if(np->vstg==STGEQUIV)
14122806Smckusick if( (ovarno = np->vardesc.varno) == i)
14222806Smckusick {
14322806Smckusick if(np->voffset + q->eqvoffset != 0)
14422806Smckusick dclerr("inconsistent equivalence", np);
14522806Smckusick doeqverr = 1;
14622806Smckusick }
14722806Smckusick else {
14822806Smckusick offset = np->voffset;
14922806Smckusick inequiv = YES;
15022806Smckusick }
15122806Smckusick
15222806Smckusick np->vstg = STGEQUIV;
15322806Smckusick np->vardesc.varno = i;
15422806Smckusick np->voffset = - q->eqvoffset;
15522806Smckusick
15622806Smckusick if(inequiv)
15722806Smckusick eqveqv(i, ovarno, q->eqvoffset + offset);
15822806Smckusick }
15922806Smckusick }
16022806Smckusick }
16122806Smckusick
16222806Smckusick if( !doeqverr )
16322806Smckusick for(i = 0 ; i < nequiv ; ++i)
16422806Smckusick {
16522806Smckusick p = & eqvclass[i];
16622806Smckusick if(p->eqvbottom!=0 || p->eqvtop!=0) /* a live chain */
16722806Smckusick {
16822806Smckusick for(q = p->equivs ; q; q = q->eqvnextp)
16922806Smckusick {
17022806Smckusick np = q->eqvitem.eqvname;
17122806Smckusick np->voffset -= p->eqvbottom;
17222806Smckusick if(np->voffset % typealign[np->vtype] != 0)
17322806Smckusick dclerr("bad alignment forced by equivalence", np);
17422806Smckusick }
17522806Smckusick p->eqvtop -= p->eqvbottom;
17622806Smckusick p->eqvbottom = 0;
17722806Smckusick }
17822806Smckusick freqchain(p);
17922806Smckusick }
18022806Smckusick }
18122806Smckusick
18222806Smckusick
18322806Smckusick
18422806Smckusick
18522806Smckusick
18622806Smckusick /* put equivalence chain p at common block comno + comoffset */
18722806Smckusick
eqvcommon(p,comno,comoffset)18822806Smckusick LOCAL eqvcommon(p, comno, comoffset)
18922806Smckusick struct Equivblock *p;
19022806Smckusick int comno;
19122806Smckusick ftnint comoffset;
19222806Smckusick {
19322806Smckusick int ovarno;
19422806Smckusick ftnint k, offq;
19522806Smckusick register Namep np;
19622806Smckusick register struct Eqvchain *q;
19722806Smckusick
19822806Smckusick if(comoffset + p->eqvbottom < 0)
19922806Smckusick {
20022806Smckusick errstr("attempt to extend common %s backward",
20122806Smckusick nounder(XL, extsymtab[comno].extname) );
20222806Smckusick freqchain(p);
20322806Smckusick return;
20422806Smckusick }
20522806Smckusick
20622806Smckusick if( (k = comoffset + p->eqvtop) > extsymtab[comno].extleng)
20722806Smckusick extsymtab[comno].extleng = k;
20822806Smckusick
20922806Smckusick #ifdef SDB
21022806Smckusick if(sdbflag)
21122806Smckusick prstab( varstr(XL,extsymtab[comno].extname), N_BCOMM,0,0);
21222806Smckusick #endif
21322806Smckusick
21422806Smckusick for(q = p->equivs ; q ; q = q->eqvnextp)
21522806Smckusick if(np = q->eqvitem.eqvname)
21622806Smckusick {
21722806Smckusick switch(np->vstg)
21822806Smckusick {
21922806Smckusick case STGUNKNOWN:
22022806Smckusick case STGBSS:
22122806Smckusick np->vstg = STGCOMMON;
22222806Smckusick np->vardesc.varno = comno;
22322806Smckusick np->voffset = comoffset - q->eqvoffset;
22422806Smckusick #ifdef SDB
22522806Smckusick if(sdbflag)
22622806Smckusick {
22722806Smckusick namestab(np);
22822806Smckusick }
22922806Smckusick #endif
23022806Smckusick break;
23122806Smckusick
23222806Smckusick case STGEQUIV:
23322806Smckusick ovarno = np->vardesc.varno;
23422806Smckusick offq = comoffset - q->eqvoffset - np->voffset;
23522806Smckusick np->vstg = STGCOMMON;
23622806Smckusick np->vardesc.varno = comno;
23722806Smckusick np->voffset = comoffset + q->eqvoffset;
23822806Smckusick if(ovarno != (p - eqvclass))
23922806Smckusick eqvcommon(&eqvclass[ovarno], comno, offq);
24022806Smckusick #ifdef SDB
24122806Smckusick if(sdbflag)
24222806Smckusick {
24322806Smckusick namestab(np);
24422806Smckusick }
24522806Smckusick #endif
24622806Smckusick break;
24722806Smckusick
24822806Smckusick case STGCOMMON:
24922806Smckusick if(comno != np->vardesc.varno ||
25022806Smckusick comoffset != np->voffset+q->eqvoffset)
25122806Smckusick dclerr("inconsistent common usage", np);
25222806Smckusick break;
25322806Smckusick
25422806Smckusick
25522806Smckusick default:
25622806Smckusick badstg("eqvcommon", np->vstg);
25722806Smckusick }
25822806Smckusick }
25922806Smckusick
26022806Smckusick #ifdef SDB
26122806Smckusick if(sdbflag)
26222806Smckusick prstab( varstr(XL,extsymtab[comno].extname), N_ECOMM,0,0);
26322806Smckusick #endif
26422806Smckusick
26522806Smckusick freqchain(p);
26622806Smckusick p->eqvbottom = p->eqvtop = 0;
26722806Smckusick }
26822806Smckusick
26922806Smckusick
27022806Smckusick /* put all items on ovarno chain on front of nvarno chain
27122806Smckusick * adjust offsets of ovarno elements and top and bottom of nvarno chain
27222806Smckusick */
27322806Smckusick
eqveqv(nvarno,ovarno,delta)27422806Smckusick LOCAL eqveqv(nvarno, ovarno, delta)
27522806Smckusick int ovarno, nvarno;
27622806Smckusick ftnint delta;
27722806Smckusick {
27822806Smckusick register struct Equivblock *p0, *p;
27922806Smckusick register Namep np;
28022806Smckusick struct Eqvchain *q, *q1;
28122806Smckusick
28222806Smckusick p0 = eqvclass + nvarno;
28322806Smckusick p = eqvclass + ovarno;
28422806Smckusick p0->eqvbottom = lmin(p0->eqvbottom, p->eqvbottom - delta);
28522806Smckusick p0->eqvtop = lmax(p0->eqvtop, p->eqvtop - delta);
28622806Smckusick p->eqvbottom = p->eqvtop = 0;
28722806Smckusick
28822806Smckusick for(q = p->equivs ; q ; q = q1)
28922806Smckusick {
29022806Smckusick q1 = q->eqvnextp;
29122806Smckusick if( (np = q->eqvitem.eqvname) && np->vardesc.varno==ovarno)
29222806Smckusick {
29322806Smckusick q->eqvnextp = p0->equivs;
29422806Smckusick p0->equivs = q;
29522806Smckusick q->eqvoffset -= delta;
29622806Smckusick np->vardesc.varno = nvarno;
29722806Smckusick np->voffset -= delta;
29822806Smckusick }
29922806Smckusick else free( (charptr) q);
30022806Smckusick }
30122806Smckusick p->equivs = NULL;
30222806Smckusick }
30322806Smckusick
30422806Smckusick
30522806Smckusick
30622806Smckusick
freqchain(p)30722806Smckusick LOCAL freqchain(p)
30822806Smckusick register struct Equivblock *p;
30922806Smckusick {
31022806Smckusick register struct Eqvchain *q, *oq;
31122806Smckusick
31222806Smckusick for(q = p->equivs ; q ; q = oq)
31322806Smckusick {
31422806Smckusick oq = q->eqvnextp;
31522806Smckusick free( (charptr) q);
31622806Smckusick }
31722806Smckusick p->equivs = NULL;
31822806Smckusick }
31922806Smckusick
32022806Smckusick
32122806Smckusick
32222806Smckusick
32322806Smckusick
nsubs(p)32422806Smckusick LOCAL nsubs(p)
32522806Smckusick register struct Listblock *p;
32622806Smckusick {
32722806Smckusick register int n;
32822806Smckusick register chainp q;
32922806Smckusick
33022806Smckusick n = 0;
33122806Smckusick if(p)
33222806Smckusick for(q = p->listp ; q ; q = q->nextp)
33322806Smckusick ++n;
33422806Smckusick
33522806Smckusick return(n);
33622806Smckusick }
337