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