xref: /csrg-svn/usr.bin/f77/pass1.vax/equiv.c (revision 22806)
1*22806Smckusick /*
2*22806Smckusick  * Copyright (c) 1980 Regents of the University of California.
3*22806Smckusick  * All rights reserved.  The Berkeley software License Agreement
4*22806Smckusick  * specifies the terms and conditions for redistribution.
5*22806Smckusick  */
6*22806Smckusick 
7*22806Smckusick #ifndef lint
8*22806Smckusick static char *sccsid[] = "@(#)equiv.c	5.1 (Berkeley) 06/07/85";
9*22806Smckusick #endif not lint
10*22806Smckusick 
11*22806Smckusick /*
12*22806Smckusick  * equiv.c
13*22806Smckusick  *
14*22806Smckusick  * Routines related to equivalence class processing, f77 compiler, 4.2 BSD.
15*22806Smckusick  *
16*22806Smckusick  * University of Utah CS Dept modification history:
17*22806Smckusick  *
18*22806Smckusick  * Revision 3.2  85/01/14  00:14:12  donn
19*22806Smckusick  * Fixed bug in eqvcommon that was causing the calculations of multilevel
20*22806Smckusick  * equivalences to be screwed up.
21*22806Smckusick  *
22*22806Smckusick  * Revision 3.1  84/10/13  01:16:08  donn
23*22806Smckusick  * Installed Jerry Berkman's version; added UofU comment header.
24*22806Smckusick  *
25*22806Smckusick  */
26*22806Smckusick 
27*22806Smckusick 
28*22806Smckusick #include "defs.h"
29*22806Smckusick 
30*22806Smckusick #ifdef SDB
31*22806Smckusick #	include <a.out.h>
32*22806Smckusick #	ifndef N_SO
33*22806Smckusick #		include <stab.h>
34*22806Smckusick #	endif
35*22806Smckusick #endif
36*22806Smckusick 
37*22806Smckusick /* called at end of declarations section to process chains
38*22806Smckusick    created by EQUIVALENCE statements
39*22806Smckusick  */
40*22806Smckusick 
41*22806Smckusick doequiv()
42*22806Smckusick {
43*22806Smckusick register int i;
44*22806Smckusick int inequiv, comno, ovarno;
45*22806Smckusick ftnint comoffset, offset, leng;
46*22806Smckusick register struct Equivblock *p;
47*22806Smckusick register struct Eqvchain *q;
48*22806Smckusick struct Primblock *itemp;
49*22806Smckusick register Namep np;
50*22806Smckusick expptr offp, suboffset();
51*22806Smckusick int ns, nsubs();
52*22806Smckusick chainp cp;
53*22806Smckusick char *memname();
54*22806Smckusick int doeqverr = 0;
55*22806Smckusick 
56*22806Smckusick for(i = 0 ; i < nequiv ; ++i)
57*22806Smckusick 	{
58*22806Smckusick 	p = &eqvclass[i];
59*22806Smckusick 	p->eqvbottom = p->eqvtop = 0;
60*22806Smckusick 	comno = -1;
61*22806Smckusick 
62*22806Smckusick 	for(q = p->equivs ; q ; q = q->eqvnextp)
63*22806Smckusick 		{
64*22806Smckusick 		offset = 0;
65*22806Smckusick 		itemp = q->eqvitem.eqvlhs;
66*22806Smckusick 		if( itemp == NULL ) fatal("error processing equivalence");
67*22806Smckusick 		equivdcl = YES;
68*22806Smckusick 		vardcl(np = itemp->namep);
69*22806Smckusick 		equivdcl = NO;
70*22806Smckusick 		if(itemp->argsp || itemp->fcharp)
71*22806Smckusick 			{
72*22806Smckusick 			if(np->vdim!=NULL && np->vdim->ndim>1 &&
73*22806Smckusick 			   nsubs(itemp->argsp)==1 )
74*22806Smckusick 				{
75*22806Smckusick 				if(! ftn66flag)
76*22806Smckusick 					warn("1-dim subscript in EQUIVALENCE");
77*22806Smckusick 				cp = NULL;
78*22806Smckusick 				ns = np->vdim->ndim;
79*22806Smckusick 				while(--ns > 0)
80*22806Smckusick 					cp = mkchain( ICON(1), cp);
81*22806Smckusick 				itemp->argsp->listp->nextp = cp;
82*22806Smckusick 				}
83*22806Smckusick 
84*22806Smckusick 			offp = suboffset(itemp);
85*22806Smckusick 			if(ISICON(offp))
86*22806Smckusick 				offset = offp->constblock.const.ci;
87*22806Smckusick 			else	{
88*22806Smckusick 				dclerr("illegal subscript in equivalence ",
89*22806Smckusick 					np);
90*22806Smckusick 				np = NULL;
91*22806Smckusick 				doeqverr = 1;
92*22806Smckusick 				}
93*22806Smckusick 			frexpr(offp);
94*22806Smckusick 			}
95*22806Smckusick 		frexpr(itemp);
96*22806Smckusick 
97*22806Smckusick 		if(np && (leng = iarrlen(np))<0)
98*22806Smckusick 			{
99*22806Smckusick 			dclerr("argument in equivalence", np);
100*22806Smckusick 			np = NULL;
101*22806Smckusick 			doeqverr =1;
102*22806Smckusick 			}
103*22806Smckusick 
104*22806Smckusick 		if(np) switch(np->vstg)
105*22806Smckusick 			{
106*22806Smckusick 			case STGUNKNOWN:
107*22806Smckusick 			case STGBSS:
108*22806Smckusick 			case STGEQUIV:
109*22806Smckusick 				break;
110*22806Smckusick 
111*22806Smckusick 			case STGCOMMON:
112*22806Smckusick 				comno = np->vardesc.varno;
113*22806Smckusick 				comoffset = np->voffset + offset;
114*22806Smckusick 				break;
115*22806Smckusick 
116*22806Smckusick 			default:
117*22806Smckusick 				dclerr("bad storage class in equivalence", np);
118*22806Smckusick 				np = NULL;
119*22806Smckusick 				doeqverr = 1;
120*22806Smckusick 				break;
121*22806Smckusick 			}
122*22806Smckusick 
123*22806Smckusick 		if(np)
124*22806Smckusick 			{
125*22806Smckusick 			q->eqvoffset = offset;
126*22806Smckusick 			p->eqvbottom = lmin(p->eqvbottom, -offset);
127*22806Smckusick 			p->eqvtop = lmax(p->eqvtop, leng-offset);
128*22806Smckusick 			}
129*22806Smckusick 		q->eqvitem.eqvname = np;
130*22806Smckusick 		}
131*22806Smckusick 
132*22806Smckusick 	if(comno >= 0)
133*22806Smckusick 		eqvcommon(p, comno, comoffset);
134*22806Smckusick 	else  for(q = p->equivs ; q ; q = q->eqvnextp)
135*22806Smckusick 		{
136*22806Smckusick 		if(np = q->eqvitem.eqvname)
137*22806Smckusick 			{
138*22806Smckusick 			inequiv = NO;
139*22806Smckusick 			if(np->vstg==STGEQUIV)
140*22806Smckusick 				if( (ovarno = np->vardesc.varno) == i)
141*22806Smckusick 					{
142*22806Smckusick 					if(np->voffset + q->eqvoffset != 0)
143*22806Smckusick 						dclerr("inconsistent equivalence", np);
144*22806Smckusick 						doeqverr = 1;
145*22806Smckusick 					}
146*22806Smckusick 				else	{
147*22806Smckusick 					offset = np->voffset;
148*22806Smckusick 					inequiv = YES;
149*22806Smckusick 					}
150*22806Smckusick 
151*22806Smckusick 			np->vstg = STGEQUIV;
152*22806Smckusick 			np->vardesc.varno = i;
153*22806Smckusick 			np->voffset = - q->eqvoffset;
154*22806Smckusick 
155*22806Smckusick 			if(inequiv)
156*22806Smckusick 				eqveqv(i, ovarno, q->eqvoffset + offset);
157*22806Smckusick 			}
158*22806Smckusick 		}
159*22806Smckusick 	}
160*22806Smckusick 
161*22806Smckusick if( !doeqverr )
162*22806Smckusick   for(i = 0 ; i < nequiv ; ++i)
163*22806Smckusick 	{
164*22806Smckusick 	p = & eqvclass[i];
165*22806Smckusick 	if(p->eqvbottom!=0 || p->eqvtop!=0)	/* a live chain */
166*22806Smckusick 		{
167*22806Smckusick 		for(q = p->equivs ; q; q = q->eqvnextp)
168*22806Smckusick 			{
169*22806Smckusick 			np = q->eqvitem.eqvname;
170*22806Smckusick 			np->voffset -= p->eqvbottom;
171*22806Smckusick 			if(np->voffset % typealign[np->vtype] != 0)
172*22806Smckusick 				dclerr("bad alignment forced by equivalence", np);
173*22806Smckusick 			}
174*22806Smckusick 		p->eqvtop -= p->eqvbottom;
175*22806Smckusick 		p->eqvbottom = 0;
176*22806Smckusick  		}
177*22806Smckusick 	freqchain(p);
178*22806Smckusick 	}
179*22806Smckusick }
180*22806Smckusick 
181*22806Smckusick 
182*22806Smckusick 
183*22806Smckusick 
184*22806Smckusick 
185*22806Smckusick /* put equivalence chain p at common block comno + comoffset */
186*22806Smckusick 
187*22806Smckusick LOCAL eqvcommon(p, comno, comoffset)
188*22806Smckusick struct Equivblock *p;
189*22806Smckusick int comno;
190*22806Smckusick ftnint comoffset;
191*22806Smckusick {
192*22806Smckusick int ovarno;
193*22806Smckusick ftnint k, offq;
194*22806Smckusick register Namep np;
195*22806Smckusick register struct Eqvchain *q;
196*22806Smckusick 
197*22806Smckusick if(comoffset + p->eqvbottom < 0)
198*22806Smckusick 	{
199*22806Smckusick 	errstr("attempt to extend common %s backward",
200*22806Smckusick 		nounder(XL, extsymtab[comno].extname) );
201*22806Smckusick 	freqchain(p);
202*22806Smckusick 	return;
203*22806Smckusick 	}
204*22806Smckusick 
205*22806Smckusick if( (k = comoffset + p->eqvtop) > extsymtab[comno].extleng)
206*22806Smckusick 	extsymtab[comno].extleng = k;
207*22806Smckusick 
208*22806Smckusick #ifdef SDB
209*22806Smckusick if(sdbflag)
210*22806Smckusick 	prstab( varstr(XL,extsymtab[comno].extname), N_BCOMM,0,0);
211*22806Smckusick #endif
212*22806Smckusick 
213*22806Smckusick for(q = p->equivs ; q ; q = q->eqvnextp)
214*22806Smckusick 	if(np = q->eqvitem.eqvname)
215*22806Smckusick 		{
216*22806Smckusick 		switch(np->vstg)
217*22806Smckusick 			{
218*22806Smckusick 			case STGUNKNOWN:
219*22806Smckusick 			case STGBSS:
220*22806Smckusick 				np->vstg = STGCOMMON;
221*22806Smckusick 				np->vardesc.varno = comno;
222*22806Smckusick 				np->voffset = comoffset - q->eqvoffset;
223*22806Smckusick #ifdef SDB
224*22806Smckusick 				if(sdbflag)
225*22806Smckusick 					{
226*22806Smckusick 					namestab(np);
227*22806Smckusick 					}
228*22806Smckusick #endif
229*22806Smckusick 				break;
230*22806Smckusick 
231*22806Smckusick 			case STGEQUIV:
232*22806Smckusick 				ovarno = np->vardesc.varno;
233*22806Smckusick 				offq = comoffset - q->eqvoffset - np->voffset;
234*22806Smckusick 				np->vstg = STGCOMMON;
235*22806Smckusick 				np->vardesc.varno = comno;
236*22806Smckusick 				np->voffset = comoffset + q->eqvoffset;
237*22806Smckusick 				if(ovarno != (p - eqvclass))
238*22806Smckusick 					eqvcommon(&eqvclass[ovarno], comno, offq);
239*22806Smckusick #ifdef SDB
240*22806Smckusick 				if(sdbflag)
241*22806Smckusick 					{
242*22806Smckusick 					namestab(np);
243*22806Smckusick 					}
244*22806Smckusick #endif
245*22806Smckusick 				break;
246*22806Smckusick 
247*22806Smckusick 			case STGCOMMON:
248*22806Smckusick 				if(comno != np->vardesc.varno ||
249*22806Smckusick 				   comoffset != np->voffset+q->eqvoffset)
250*22806Smckusick 					dclerr("inconsistent common usage", np);
251*22806Smckusick 				break;
252*22806Smckusick 
253*22806Smckusick 
254*22806Smckusick 			default:
255*22806Smckusick 				badstg("eqvcommon", np->vstg);
256*22806Smckusick 			}
257*22806Smckusick 		}
258*22806Smckusick 
259*22806Smckusick #ifdef SDB
260*22806Smckusick if(sdbflag)
261*22806Smckusick 	prstab( varstr(XL,extsymtab[comno].extname), N_ECOMM,0,0);
262*22806Smckusick #endif
263*22806Smckusick 
264*22806Smckusick freqchain(p);
265*22806Smckusick p->eqvbottom = p->eqvtop = 0;
266*22806Smckusick }
267*22806Smckusick 
268*22806Smckusick 
269*22806Smckusick /* put all items on ovarno chain on front of nvarno chain
270*22806Smckusick  * adjust offsets of ovarno elements and top and bottom of nvarno chain
271*22806Smckusick  */
272*22806Smckusick 
273*22806Smckusick LOCAL eqveqv(nvarno, ovarno, delta)
274*22806Smckusick int ovarno, nvarno;
275*22806Smckusick ftnint delta;
276*22806Smckusick {
277*22806Smckusick register struct Equivblock *p0, *p;
278*22806Smckusick register Namep np;
279*22806Smckusick struct Eqvchain *q, *q1;
280*22806Smckusick 
281*22806Smckusick p0 = eqvclass + nvarno;
282*22806Smckusick p = eqvclass + ovarno;
283*22806Smckusick p0->eqvbottom = lmin(p0->eqvbottom, p->eqvbottom - delta);
284*22806Smckusick p0->eqvtop = lmax(p0->eqvtop, p->eqvtop - delta);
285*22806Smckusick p->eqvbottom = p->eqvtop = 0;
286*22806Smckusick 
287*22806Smckusick for(q = p->equivs ; q ; q = q1)
288*22806Smckusick 	{
289*22806Smckusick 	q1 = q->eqvnextp;
290*22806Smckusick 	if( (np = q->eqvitem.eqvname) && np->vardesc.varno==ovarno)
291*22806Smckusick 		{
292*22806Smckusick 		q->eqvnextp = p0->equivs;
293*22806Smckusick 		p0->equivs = q;
294*22806Smckusick 		q->eqvoffset -= delta;
295*22806Smckusick 		np->vardesc.varno = nvarno;
296*22806Smckusick 		np->voffset -= delta;
297*22806Smckusick 		}
298*22806Smckusick 	else	free( (charptr) q);
299*22806Smckusick 	}
300*22806Smckusick p->equivs = NULL;
301*22806Smckusick }
302*22806Smckusick 
303*22806Smckusick 
304*22806Smckusick 
305*22806Smckusick 
306*22806Smckusick LOCAL freqchain(p)
307*22806Smckusick register struct Equivblock *p;
308*22806Smckusick {
309*22806Smckusick register struct Eqvchain *q, *oq;
310*22806Smckusick 
311*22806Smckusick for(q = p->equivs ; q ; q = oq)
312*22806Smckusick 	{
313*22806Smckusick 	oq = q->eqvnextp;
314*22806Smckusick 	free( (charptr) q);
315*22806Smckusick 	}
316*22806Smckusick p->equivs = NULL;
317*22806Smckusick }
318*22806Smckusick 
319*22806Smckusick 
320*22806Smckusick 
321*22806Smckusick 
322*22806Smckusick 
323*22806Smckusick LOCAL nsubs(p)
324*22806Smckusick register struct Listblock *p;
325*22806Smckusick {
326*22806Smckusick register int n;
327*22806Smckusick register chainp q;
328*22806Smckusick 
329*22806Smckusick n = 0;
330*22806Smckusick if(p)
331*22806Smckusick 	for(q = p->listp ; q ; q = q->nextp)
332*22806Smckusick 		++n;
333*22806Smckusick 
334*22806Smckusick return(n);
335*22806Smckusick }
336