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