1*40230Sdonn /* 2*40230Sdonn * Copyright (c) 1980 Regents of the University of California. 3*40230Sdonn * All rights reserved. The Berkeley software License Agreement 4*40230Sdonn * specifies the terms and conditions for redistribution. 5*40230Sdonn */ 6*40230Sdonn 7*40230Sdonn #ifndef lint 8*40230Sdonn static char *sccsid[] = "@(#)expr.c 5.3 (Berkeley) 6/23/85"; 9*40230Sdonn #endif not lint 10*40230Sdonn 11*40230Sdonn /* 12*40230Sdonn * expr.c 13*40230Sdonn * 14*40230Sdonn * Routines for handling expressions, f77 compiler pass 1. 15*40230Sdonn * 16*40230Sdonn * University of Utah CS Dept modification history: 17*40230Sdonn * 18*40230Sdonn * $Log: expr.c,v $ 19*40230Sdonn * Revision 1.3 86/02/26 17:13:37 rcs 20*40230Sdonn * Correct COFR 411. 21*40230Sdonn * P. Wong 22*40230Sdonn * 23*40230Sdonn * Revision 3.16 85/06/21 16:38:09 donn 24*40230Sdonn * The fix to mkprim() didn't handle null substring parameters (sigh). 25*40230Sdonn * 26*40230Sdonn * Revision 3.15 85/06/04 04:37:03 donn 27*40230Sdonn * Changed mkprim() to force substring parameters to be integral types. 28*40230Sdonn * 29*40230Sdonn * Revision 3.14 85/06/04 03:41:52 donn 30*40230Sdonn * Change impldcl() to handle functions of type 'undefined'. 31*40230Sdonn * 32*40230Sdonn * Revision 3.13 85/05/06 23:14:55 donn 33*40230Sdonn * Changed mkconv() so that it calls mkaltemp() instead of mktemp() to get 34*40230Sdonn * a temporary when converting character strings to integers; previously we 35*40230Sdonn * were having problems because mkconv() was called after tempalloc(). 36*40230Sdonn * 37*40230Sdonn * Revision 3.12 85/03/18 08:07:47 donn 38*40230Sdonn * Fixes to help out with short integers -- if integers are by default short, 39*40230Sdonn * then so are constants; and if addresses can't be stored in shorts, complain. 40*40230Sdonn * 41*40230Sdonn * Revision 3.11 85/03/16 22:31:27 donn 42*40230Sdonn * Added hack to mkconv() to allow character values of length > 1 to be 43*40230Sdonn * converted to numeric types, for Helge Skrivervik. Note that this does 44*40230Sdonn * not affect use of the intrinsic ichar() conversion. 45*40230Sdonn * 46*40230Sdonn * Revision 3.10 85/01/15 21:06:47 donn 47*40230Sdonn * Changed mkconv() to comment on implicit conversions; added intrconv() for 48*40230Sdonn * use with explicit conversions by intrinsic functions. 49*40230Sdonn * 50*40230Sdonn * Revision 3.9 85/01/11 21:05:49 donn 51*40230Sdonn * Added changes to implement SAVE statements. 52*40230Sdonn * 53*40230Sdonn * Revision 3.8 84/12/17 02:21:06 donn 54*40230Sdonn * Added a test to prevent constant folding from being done on expressions 55*40230Sdonn * whose type is not known at that point in mkexpr(). 56*40230Sdonn * 57*40230Sdonn * Revision 3.7 84/12/11 21:14:17 donn 58*40230Sdonn * Removed obnoxious 'excess precision' warning. 59*40230Sdonn * 60*40230Sdonn * Revision 3.6 84/11/23 01:00:36 donn 61*40230Sdonn * Added code to trim excess precision from single-precision constants, and 62*40230Sdonn * to warn the user when this occurs. 63*40230Sdonn * 64*40230Sdonn * Revision 3.5 84/11/23 00:10:39 donn 65*40230Sdonn * Changed stfcall() to remark on argument type clashes in 'calls' to 66*40230Sdonn * statement functions. 67*40230Sdonn * 68*40230Sdonn * Revision 3.4 84/11/22 21:21:17 donn 69*40230Sdonn * Fixed bug in fix to mkexpr() that caused IMPLICIT to affect intrinsics. 70*40230Sdonn * 71*40230Sdonn * Revision 3.3 84/11/12 18:26:14 donn 72*40230Sdonn * Shuffled some code around so that the compiler remembers to free some vleng 73*40230Sdonn * structures which used to just sit around. 74*40230Sdonn * 75*40230Sdonn * Revision 3.2 84/10/16 19:24:15 donn 76*40230Sdonn * Fix for Peter Montgomery's bug with -C and invalid subscripts -- prevent 77*40230Sdonn * core dumps by replacing bad subscripts with good ones. 78*40230Sdonn * 79*40230Sdonn * Revision 3.1 84/10/13 01:31:32 donn 80*40230Sdonn * Merged Jerry Berkman's version into mine. 81*40230Sdonn * 82*40230Sdonn * Revision 2.7 84/09/27 15:42:52 donn 83*40230Sdonn * The last fix for multiplying undeclared variables by 0 isn't sufficient, 84*40230Sdonn * since the type of the 0 may not be the (implicit) type of the variable. 85*40230Sdonn * I added a hack to check the implicit type of implicitly declared 86*40230Sdonn * variables... 87*40230Sdonn * 88*40230Sdonn * Revision 2.6 84/09/14 19:34:03 donn 89*40230Sdonn * Problem noted by Mike Vevea -- mkexpr will sometimes attempt to convert 90*40230Sdonn * 0 to type UNKNOWN, which is illegal. Fix is to use native type instead. 91*40230Sdonn * Not sure how correct (or important) this is... 92*40230Sdonn * 93*40230Sdonn * Revision 2.5 84/08/05 23:05:27 donn 94*40230Sdonn * Added fixes to prevent fixexpr() from slicing and dicing complex conversions 95*40230Sdonn * with two operands. 96*40230Sdonn * 97*40230Sdonn * Revision 2.4 84/08/05 17:34:48 donn 98*40230Sdonn * Added an optimization to mklhs() to detect substrings of the form ch(i:i) 99*40230Sdonn * and assign constant length 1 to them. 100*40230Sdonn * 101*40230Sdonn * Revision 2.3 84/07/19 19:38:33 donn 102*40230Sdonn * Added a typecast to the last fix. Somehow I missed it the first time... 103*40230Sdonn * 104*40230Sdonn * Revision 2.2 84/07/19 17:19:57 donn 105*40230Sdonn * Caused OPPAREN expressions to inherit the length of their operands, so 106*40230Sdonn * that parenthesized character expressions work correctly. 107*40230Sdonn * 108*40230Sdonn * Revision 2.1 84/07/19 12:03:02 donn 109*40230Sdonn * Changed comment headers for UofU. 110*40230Sdonn * 111*40230Sdonn * Revision 1.2 84/04/06 20:12:17 donn 112*40230Sdonn * Fixed bug which caused programs with mixed-type multiplications involving 113*40230Sdonn * the constant 0 to choke the compiler. 114*40230Sdonn * 115*40230Sdonn */ 116*40230Sdonn 117*40230Sdonn #include "defs.h" 118*40230Sdonn 119*40230Sdonn 120*40230Sdonn /* little routines to create constant blocks */ 121*40230Sdonn 122*40230Sdonn Constp mkconst(t) 123*40230Sdonn register int t; 124*40230Sdonn { 125*40230Sdonn register Constp p; 126*40230Sdonn 127*40230Sdonn p = ALLOC(Constblock); 128*40230Sdonn p->tag = TCONST; 129*40230Sdonn p->vtype = t; 130*40230Sdonn return(p); 131*40230Sdonn } 132*40230Sdonn 133*40230Sdonn 134*40230Sdonn expptr mklogcon(l) 135*40230Sdonn register int l; 136*40230Sdonn { 137*40230Sdonn register Constp p; 138*40230Sdonn 139*40230Sdonn p = mkconst(TYLOGICAL); 140*40230Sdonn p->const.ci = l; 141*40230Sdonn return( (expptr) p ); 142*40230Sdonn } 143*40230Sdonn 144*40230Sdonn 145*40230Sdonn 146*40230Sdonn expptr mkintcon(l) 147*40230Sdonn ftnint l; 148*40230Sdonn { 149*40230Sdonn register Constp p; 150*40230Sdonn int usetype; 151*40230Sdonn 152*40230Sdonn if(tyint == TYSHORT) 153*40230Sdonn { 154*40230Sdonn short s = l; 155*40230Sdonn if(l != s) 156*40230Sdonn usetype = TYLONG; 157*40230Sdonn else 158*40230Sdonn usetype = TYSHORT; 159*40230Sdonn } 160*40230Sdonn else 161*40230Sdonn usetype = tyint; 162*40230Sdonn p = mkconst(usetype); 163*40230Sdonn p->const.ci = l; 164*40230Sdonn return( (expptr) p ); 165*40230Sdonn } 166*40230Sdonn 167*40230Sdonn 168*40230Sdonn 169*40230Sdonn expptr mkaddcon(l) 170*40230Sdonn register int l; 171*40230Sdonn { 172*40230Sdonn register Constp p; 173*40230Sdonn 174*40230Sdonn p = mkconst(TYADDR); 175*40230Sdonn p->const.ci = l; 176*40230Sdonn return( (expptr) p ); 177*40230Sdonn } 178*40230Sdonn 179*40230Sdonn 180*40230Sdonn 181*40230Sdonn expptr mkrealcon(t, d) 182*40230Sdonn register int t; 183*40230Sdonn double d; 184*40230Sdonn { 185*40230Sdonn register Constp p; 186*40230Sdonn 187*40230Sdonn p = mkconst(t); 188*40230Sdonn p->const.cd[0] = d; 189*40230Sdonn return( (expptr) p ); 190*40230Sdonn } 191*40230Sdonn 192*40230Sdonn expptr mkbitcon(shift, leng, s) 193*40230Sdonn int shift; 194*40230Sdonn register int leng; 195*40230Sdonn register char *s; 196*40230Sdonn { 197*40230Sdonn Constp p; 198*40230Sdonn register int i, j, k; 199*40230Sdonn register char *bp; 200*40230Sdonn int size; 201*40230Sdonn 202*40230Sdonn size = (shift*leng + BYTESIZE -1)/BYTESIZE; 203*40230Sdonn bp = (char *) ckalloc(size); 204*40230Sdonn 205*40230Sdonn i = 0; 206*40230Sdonn 207*40230Sdonn #if (HERE == PDP11 || HERE == VAX) 208*40230Sdonn j = 0; 209*40230Sdonn #else 210*40230Sdonn j = size; 211*40230Sdonn #endif 212*40230Sdonn 213*40230Sdonn k = 0; 214*40230Sdonn 215*40230Sdonn while (leng > 0) 216*40230Sdonn { 217*40230Sdonn k |= (hextoi(s[--leng]) << i); 218*40230Sdonn i += shift; 219*40230Sdonn if (i >= BYTESIZE) 220*40230Sdonn { 221*40230Sdonn #if (HERE == PDP11 || HERE == VAX) 222*40230Sdonn bp[j++] = k & MAXBYTE; 223*40230Sdonn #else 224*40230Sdonn bp[--j] = k & MAXBYTE; 225*40230Sdonn #endif 226*40230Sdonn k = k >> BYTESIZE; 227*40230Sdonn i -= BYTESIZE; 228*40230Sdonn } 229*40230Sdonn } 230*40230Sdonn 231*40230Sdonn if (k != 0) 232*40230Sdonn #if (HERE == PDP11 || HERE == VAX) 233*40230Sdonn bp[j++] = k; 234*40230Sdonn #else 235*40230Sdonn bp[--j] = k; 236*40230Sdonn #endif 237*40230Sdonn 238*40230Sdonn p = mkconst(TYBITSTR); 239*40230Sdonn p->vleng = ICON(size); 240*40230Sdonn p->const.ccp = bp; 241*40230Sdonn 242*40230Sdonn return ((expptr) p); 243*40230Sdonn } 244*40230Sdonn 245*40230Sdonn 246*40230Sdonn 247*40230Sdonn expptr mkstrcon(l,v) 248*40230Sdonn int l; 249*40230Sdonn register char *v; 250*40230Sdonn { 251*40230Sdonn register Constp p; 252*40230Sdonn register char *s; 253*40230Sdonn 254*40230Sdonn p = mkconst(TYCHAR); 255*40230Sdonn p->vleng = ICON(l); 256*40230Sdonn p->const.ccp = s = (char *) ckalloc(l); 257*40230Sdonn while(--l >= 0) 258*40230Sdonn *s++ = *v++; 259*40230Sdonn return( (expptr) p ); 260*40230Sdonn } 261*40230Sdonn 262*40230Sdonn 263*40230Sdonn expptr mkcxcon(realp,imagp) 264*40230Sdonn register expptr realp, imagp; 265*40230Sdonn { 266*40230Sdonn int rtype, itype; 267*40230Sdonn register Constp p; 268*40230Sdonn 269*40230Sdonn rtype = realp->headblock.vtype; 270*40230Sdonn itype = imagp->headblock.vtype; 271*40230Sdonn 272*40230Sdonn if( ISCONST(realp) && ISNUMERIC(rtype) && ISCONST(imagp) && ISNUMERIC(itype) ) 273*40230Sdonn { 274*40230Sdonn p = mkconst( (rtype==TYDREAL||itype==TYDREAL) ? TYDCOMPLEX : TYCOMPLEX); 275*40230Sdonn if( ISINT(rtype) ) 276*40230Sdonn p->const.cd[0] = realp->constblock.const.ci; 277*40230Sdonn else p->const.cd[0] = realp->constblock.const.cd[0]; 278*40230Sdonn if( ISINT(itype) ) 279*40230Sdonn p->const.cd[1] = imagp->constblock.const.ci; 280*40230Sdonn else p->const.cd[1] = imagp->constblock.const.cd[0]; 281*40230Sdonn } 282*40230Sdonn else 283*40230Sdonn { 284*40230Sdonn err("invalid complex constant"); 285*40230Sdonn p = (Constp) errnode(); 286*40230Sdonn } 287*40230Sdonn 288*40230Sdonn frexpr(realp); 289*40230Sdonn frexpr(imagp); 290*40230Sdonn return( (expptr) p ); 291*40230Sdonn } 292*40230Sdonn 293*40230Sdonn 294*40230Sdonn expptr errnode() 295*40230Sdonn { 296*40230Sdonn struct Errorblock *p; 297*40230Sdonn p = ALLOC(Errorblock); 298*40230Sdonn p->tag = TERROR; 299*40230Sdonn p->vtype = TYERROR; 300*40230Sdonn return( (expptr) p ); 301*40230Sdonn } 302*40230Sdonn 303*40230Sdonn 304*40230Sdonn 305*40230Sdonn 306*40230Sdonn 307*40230Sdonn expptr mkconv(t, p) 308*40230Sdonn register int t; 309*40230Sdonn register expptr p; 310*40230Sdonn { 311*40230Sdonn register expptr q; 312*40230Sdonn Addrp r, s; 313*40230Sdonn register int pt; 314*40230Sdonn expptr opconv(); 315*40230Sdonn 316*40230Sdonn if(t==TYUNKNOWN || t==TYERROR) 317*40230Sdonn badtype("mkconv", t); 318*40230Sdonn pt = p->headblock.vtype; 319*40230Sdonn if(t == pt) 320*40230Sdonn return(p); 321*40230Sdonn 322*40230Sdonn if( pt == TYCHAR && ISNUMERIC(t) ) 323*40230Sdonn { 324*40230Sdonn warn("implicit conversion of character to numeric type"); 325*40230Sdonn 326*40230Sdonn /* 327*40230Sdonn * Ugly kluge to copy character values into numerics. 328*40230Sdonn */ 329*40230Sdonn s = mkaltemp(t, ENULL); 330*40230Sdonn r = (Addrp) cpexpr(s); 331*40230Sdonn r->vtype = TYCHAR; 332*40230Sdonn r->varleng = typesize[t]; 333*40230Sdonn r->vleng = mkintcon(r->varleng); 334*40230Sdonn q = mkexpr(OPASSIGN, r, p); 335*40230Sdonn q = mkexpr(OPCOMMA, q, s); 336*40230Sdonn return(q); 337*40230Sdonn } 338*40230Sdonn 339*40230Sdonn #if SZADDR > SZSHORT 340*40230Sdonn if( pt == TYADDR && t == TYSHORT) 341*40230Sdonn { 342*40230Sdonn err("insufficient precision to hold address type"); 343*40230Sdonn return( errnode() ); 344*40230Sdonn } 345*40230Sdonn #endif 346*40230Sdonn if( pt == TYADDR && ISNUMERIC(t) ) 347*40230Sdonn warn("implicit conversion of address to numeric type"); 348*40230Sdonn 349*40230Sdonn if( ISCONST(p) && pt!=TYADDR) 350*40230Sdonn { 351*40230Sdonn q = (expptr) mkconst(t); 352*40230Sdonn consconv(t, &(q->constblock.const), 353*40230Sdonn p->constblock.vtype, &(p->constblock.const) ); 354*40230Sdonn frexpr(p); 355*40230Sdonn } 356*40230Sdonn #if TARGET == PDP11 357*40230Sdonn else if(ISINT(t) && pt==TYCHAR) 358*40230Sdonn { 359*40230Sdonn q = mkexpr(OPBITAND, opconv(p,TYSHORT), ICON(255)); 360*40230Sdonn if(t == TYLONG) 361*40230Sdonn q = opconv(q, TYLONG); 362*40230Sdonn } 363*40230Sdonn #endif 364*40230Sdonn else 365*40230Sdonn q = opconv(p, t); 366*40230Sdonn 367*40230Sdonn if(t == TYCHAR) 368*40230Sdonn q->constblock.vleng = ICON(1); 369*40230Sdonn return(q); 370*40230Sdonn } 371*40230Sdonn 372*40230Sdonn 373*40230Sdonn 374*40230Sdonn /* intrinsic conversions */ 375*40230Sdonn expptr intrconv(t, p) 376*40230Sdonn register int t; 377*40230Sdonn register expptr p; 378*40230Sdonn { 379*40230Sdonn register expptr q; 380*40230Sdonn register int pt; 381*40230Sdonn expptr opconv(); 382*40230Sdonn 383*40230Sdonn if(t==TYUNKNOWN || t==TYERROR) 384*40230Sdonn badtype("intrconv", t); 385*40230Sdonn pt = p->headblock.vtype; 386*40230Sdonn if(t == pt) 387*40230Sdonn return(p); 388*40230Sdonn 389*40230Sdonn else if( ISCONST(p) && pt!=TYADDR) 390*40230Sdonn { 391*40230Sdonn q = (expptr) mkconst(t); 392*40230Sdonn consconv(t, &(q->constblock.const), 393*40230Sdonn p->constblock.vtype, &(p->constblock.const) ); 394*40230Sdonn frexpr(p); 395*40230Sdonn } 396*40230Sdonn #if TARGET == PDP11 397*40230Sdonn else if(ISINT(t) && pt==TYCHAR) 398*40230Sdonn { 399*40230Sdonn q = mkexpr(OPBITAND, opconv(p,TYSHORT), ICON(255)); 400*40230Sdonn if(t == TYLONG) 401*40230Sdonn q = opconv(q, TYLONG); 402*40230Sdonn } 403*40230Sdonn #endif 404*40230Sdonn else 405*40230Sdonn q = opconv(p, t); 406*40230Sdonn 407*40230Sdonn if(t == TYCHAR) 408*40230Sdonn q->constblock.vleng = ICON(1); 409*40230Sdonn return(q); 410*40230Sdonn } 411*40230Sdonn 412*40230Sdonn 413*40230Sdonn 414*40230Sdonn expptr opconv(p, t) 415*40230Sdonn expptr p; 416*40230Sdonn int t; 417*40230Sdonn { 418*40230Sdonn register expptr q; 419*40230Sdonn 420*40230Sdonn q = mkexpr(OPCONV, p, PNULL); 421*40230Sdonn q->headblock.vtype = t; 422*40230Sdonn return(q); 423*40230Sdonn } 424*40230Sdonn 425*40230Sdonn 426*40230Sdonn 427*40230Sdonn expptr addrof(p) 428*40230Sdonn expptr p; 429*40230Sdonn { 430*40230Sdonn return( mkexpr(OPADDR, p, PNULL) ); 431*40230Sdonn } 432*40230Sdonn 433*40230Sdonn 434*40230Sdonn 435*40230Sdonn tagptr cpexpr(p) 436*40230Sdonn register tagptr p; 437*40230Sdonn { 438*40230Sdonn register tagptr e; 439*40230Sdonn int tag; 440*40230Sdonn register chainp ep, pp; 441*40230Sdonn tagptr cpblock(); 442*40230Sdonn 443*40230Sdonn static int blksize[ ] = 444*40230Sdonn { 0, 445*40230Sdonn sizeof(struct Nameblock), 446*40230Sdonn sizeof(struct Constblock), 447*40230Sdonn sizeof(struct Exprblock), 448*40230Sdonn sizeof(struct Addrblock), 449*40230Sdonn sizeof(struct Tempblock), 450*40230Sdonn sizeof(struct Primblock), 451*40230Sdonn sizeof(struct Listblock), 452*40230Sdonn sizeof(struct Errorblock) 453*40230Sdonn }; 454*40230Sdonn 455*40230Sdonn if(p == NULL) 456*40230Sdonn return(NULL); 457*40230Sdonn 458*40230Sdonn if( (tag = p->tag) == TNAME) 459*40230Sdonn return(p); 460*40230Sdonn 461*40230Sdonn e = cpblock( blksize[p->tag] , p); 462*40230Sdonn 463*40230Sdonn switch(tag) 464*40230Sdonn { 465*40230Sdonn case TCONST: 466*40230Sdonn if(e->constblock.vtype == TYCHAR) 467*40230Sdonn { 468*40230Sdonn e->constblock.const.ccp = 469*40230Sdonn copyn(1+strlen(e->constblock.const.ccp), 470*40230Sdonn e->constblock.const.ccp); 471*40230Sdonn e->constblock.vleng = 472*40230Sdonn (expptr) cpexpr(e->constblock.vleng); 473*40230Sdonn } 474*40230Sdonn case TERROR: 475*40230Sdonn break; 476*40230Sdonn 477*40230Sdonn case TEXPR: 478*40230Sdonn e->exprblock.leftp = (expptr) cpexpr(p->exprblock.leftp); 479*40230Sdonn e->exprblock.rightp = (expptr) cpexpr(p->exprblock.rightp); 480*40230Sdonn break; 481*40230Sdonn 482*40230Sdonn case TLIST: 483*40230Sdonn if(pp = p->listblock.listp) 484*40230Sdonn { 485*40230Sdonn ep = e->listblock.listp = 486*40230Sdonn mkchain( cpexpr(pp->datap), CHNULL); 487*40230Sdonn for(pp = pp->nextp ; pp ; pp = pp->nextp) 488*40230Sdonn ep = ep->nextp = 489*40230Sdonn mkchain( cpexpr(pp->datap), CHNULL); 490*40230Sdonn } 491*40230Sdonn break; 492*40230Sdonn 493*40230Sdonn case TADDR: 494*40230Sdonn e->addrblock.vleng = (expptr) cpexpr(e->addrblock.vleng); 495*40230Sdonn e->addrblock.memoffset = (expptr)cpexpr(e->addrblock.memoffset); 496*40230Sdonn e->addrblock.istemp = NO; 497*40230Sdonn break; 498*40230Sdonn 499*40230Sdonn case TTEMP: 500*40230Sdonn e->tempblock.vleng = (expptr) cpexpr(e->tempblock.vleng); 501*40230Sdonn e->tempblock.istemp = NO; 502*40230Sdonn break; 503*40230Sdonn 504*40230Sdonn case TPRIM: 505*40230Sdonn e->primblock.argsp = (struct Listblock *) 506*40230Sdonn cpexpr(e->primblock.argsp); 507*40230Sdonn e->primblock.fcharp = (expptr) cpexpr(e->primblock.fcharp); 508*40230Sdonn e->primblock.lcharp = (expptr) cpexpr(e->primblock.lcharp); 509*40230Sdonn break; 510*40230Sdonn 511*40230Sdonn default: 512*40230Sdonn badtag("cpexpr", tag); 513*40230Sdonn } 514*40230Sdonn 515*40230Sdonn return(e); 516*40230Sdonn } 517*40230Sdonn 518*40230Sdonn frexpr(p) 519*40230Sdonn register tagptr p; 520*40230Sdonn { 521*40230Sdonn register chainp q; 522*40230Sdonn 523*40230Sdonn if(p == NULL) 524*40230Sdonn return; 525*40230Sdonn 526*40230Sdonn switch(p->tag) 527*40230Sdonn { 528*40230Sdonn case TCONST: 529*40230Sdonn switch (p->constblock.vtype) 530*40230Sdonn { 531*40230Sdonn case TYBITSTR: 532*40230Sdonn case TYCHAR: 533*40230Sdonn case TYHOLLERITH: 534*40230Sdonn free( (charptr) (p->constblock.const.ccp) ); 535*40230Sdonn frexpr(p->constblock.vleng); 536*40230Sdonn } 537*40230Sdonn break; 538*40230Sdonn 539*40230Sdonn case TADDR: 540*40230Sdonn if (!optimflag && p->addrblock.istemp) 541*40230Sdonn { 542*40230Sdonn frtemp(p); 543*40230Sdonn return; 544*40230Sdonn } 545*40230Sdonn frexpr(p->addrblock.vleng); 546*40230Sdonn frexpr(p->addrblock.memoffset); 547*40230Sdonn break; 548*40230Sdonn 549*40230Sdonn case TTEMP: 550*40230Sdonn frexpr(p->tempblock.vleng); 551*40230Sdonn break; 552*40230Sdonn 553*40230Sdonn case TERROR: 554*40230Sdonn break; 555*40230Sdonn 556*40230Sdonn case TNAME: 557*40230Sdonn return; 558*40230Sdonn 559*40230Sdonn case TPRIM: 560*40230Sdonn frexpr(p->primblock.argsp); 561*40230Sdonn frexpr(p->primblock.fcharp); 562*40230Sdonn frexpr(p->primblock.lcharp); 563*40230Sdonn break; 564*40230Sdonn 565*40230Sdonn case TEXPR: 566*40230Sdonn frexpr(p->exprblock.leftp); 567*40230Sdonn if(p->exprblock.rightp) 568*40230Sdonn frexpr(p->exprblock.rightp); 569*40230Sdonn break; 570*40230Sdonn 571*40230Sdonn case TLIST: 572*40230Sdonn for(q = p->listblock.listp ; q ; q = q->nextp) 573*40230Sdonn frexpr(q->datap); 574*40230Sdonn frchain( &(p->listblock.listp) ); 575*40230Sdonn break; 576*40230Sdonn 577*40230Sdonn default: 578*40230Sdonn badtag("frexpr", p->tag); 579*40230Sdonn } 580*40230Sdonn 581*40230Sdonn free( (charptr) p ); 582*40230Sdonn } 583*40230Sdonn 584*40230Sdonn /* fix up types in expression; replace subtrees and convert 585*40230Sdonn names to address blocks */ 586*40230Sdonn 587*40230Sdonn expptr fixtype(p) 588*40230Sdonn register tagptr p; 589*40230Sdonn { 590*40230Sdonn 591*40230Sdonn if(p == 0) 592*40230Sdonn return(0); 593*40230Sdonn 594*40230Sdonn switch(p->tag) 595*40230Sdonn { 596*40230Sdonn case TCONST: 597*40230Sdonn return( (expptr) p ); 598*40230Sdonn 599*40230Sdonn case TADDR: 600*40230Sdonn p->addrblock.memoffset = fixtype(p->addrblock.memoffset); 601*40230Sdonn return( (expptr) p); 602*40230Sdonn 603*40230Sdonn case TTEMP: 604*40230Sdonn return( (expptr) p); 605*40230Sdonn 606*40230Sdonn case TERROR: 607*40230Sdonn return( (expptr) p); 608*40230Sdonn 609*40230Sdonn default: 610*40230Sdonn badtag("fixtype", p->tag); 611*40230Sdonn 612*40230Sdonn case TEXPR: 613*40230Sdonn return( fixexpr(p) ); 614*40230Sdonn 615*40230Sdonn case TLIST: 616*40230Sdonn return( (expptr) p ); 617*40230Sdonn 618*40230Sdonn case TPRIM: 619*40230Sdonn if(p->primblock.argsp && p->primblock.namep->vclass!=CLVAR) 620*40230Sdonn { 621*40230Sdonn if(p->primblock.namep->vtype == TYSUBR) 622*40230Sdonn { 623*40230Sdonn err("function invocation of subroutine"); 624*40230Sdonn return( errnode() ); 625*40230Sdonn } 626*40230Sdonn else 627*40230Sdonn return( mkfunct(p) ); 628*40230Sdonn } 629*40230Sdonn else return( mklhs(p) ); 630*40230Sdonn } 631*40230Sdonn } 632*40230Sdonn 633*40230Sdonn 634*40230Sdonn 635*40230Sdonn 636*40230Sdonn 637*40230Sdonn /* special case tree transformations and cleanups of expression trees */ 638*40230Sdonn 639*40230Sdonn expptr fixexpr(p) 640*40230Sdonn register Exprp p; 641*40230Sdonn { 642*40230Sdonn expptr lp; 643*40230Sdonn register expptr rp; 644*40230Sdonn register expptr q; 645*40230Sdonn int opcode, ltype, rtype, ptype, mtype; 646*40230Sdonn expptr lconst, rconst; 647*40230Sdonn expptr mkpower(); 648*40230Sdonn 649*40230Sdonn if( ISERROR(p) ) 650*40230Sdonn return( (expptr) p ); 651*40230Sdonn else if(p->tag != TEXPR) 652*40230Sdonn badtag("fixexpr", p->tag); 653*40230Sdonn opcode = p->opcode; 654*40230Sdonn if (ISCONST(p->leftp)) 655*40230Sdonn lconst = (expptr) cpexpr(p->leftp); 656*40230Sdonn else 657*40230Sdonn lconst = NULL; 658*40230Sdonn if (p->rightp && ISCONST(p->rightp)) 659*40230Sdonn rconst = (expptr) cpexpr(p->rightp); 660*40230Sdonn else 661*40230Sdonn rconst = NULL; 662*40230Sdonn lp = p->leftp = fixtype(p->leftp); 663*40230Sdonn ltype = lp->headblock.vtype; 664*40230Sdonn if(opcode==OPASSIGN && lp->tag!=TADDR && lp->tag!=TTEMP) 665*40230Sdonn { 666*40230Sdonn err("left side of assignment must be variable"); 667*40230Sdonn frexpr(p); 668*40230Sdonn return( errnode() ); 669*40230Sdonn } 670*40230Sdonn 671*40230Sdonn if(p->rightp) 672*40230Sdonn { 673*40230Sdonn rp = p->rightp = fixtype(p->rightp); 674*40230Sdonn rtype = rp->headblock.vtype; 675*40230Sdonn } 676*40230Sdonn else 677*40230Sdonn { 678*40230Sdonn rp = NULL; 679*40230Sdonn rtype = 0; 680*40230Sdonn } 681*40230Sdonn 682*40230Sdonn if(ltype==TYERROR || rtype==TYERROR) 683*40230Sdonn { 684*40230Sdonn frexpr(p); 685*40230Sdonn frexpr(lconst); 686*40230Sdonn frexpr(rconst); 687*40230Sdonn return( errnode() ); 688*40230Sdonn } 689*40230Sdonn 690*40230Sdonn /* force folding if possible */ 691*40230Sdonn if( ISCONST(lp) && (rp==NULL || ISCONST(rp)) ) 692*40230Sdonn { 693*40230Sdonn q = mkexpr(opcode, lp, rp); 694*40230Sdonn if( ISCONST(q) ) 695*40230Sdonn { 696*40230Sdonn frexpr(lconst); 697*40230Sdonn frexpr(rconst); 698*40230Sdonn return(q); 699*40230Sdonn } 700*40230Sdonn free( (charptr) q ); /* constants did not fold */ 701*40230Sdonn } 702*40230Sdonn 703*40230Sdonn if( (ptype = cktype(opcode, ltype, rtype)) == TYERROR) 704*40230Sdonn { 705*40230Sdonn frexpr(p); 706*40230Sdonn frexpr(lconst); 707*40230Sdonn frexpr(rconst); 708*40230Sdonn return( errnode() ); 709*40230Sdonn } 710*40230Sdonn 711*40230Sdonn switch(opcode) 712*40230Sdonn { 713*40230Sdonn case OPCONCAT: 714*40230Sdonn if(p->vleng == NULL) 715*40230Sdonn p->vleng = mkexpr(OPPLUS, 716*40230Sdonn cpexpr(lp->headblock.vleng), 717*40230Sdonn cpexpr(rp->headblock.vleng) ); 718*40230Sdonn break; 719*40230Sdonn 720*40230Sdonn case OPASSIGN: 721*40230Sdonn case OPPLUSEQ: 722*40230Sdonn case OPSTAREQ: 723*40230Sdonn if(ltype == rtype) 724*40230Sdonn break; 725*40230Sdonn #if TARGET == VAX 726*40230Sdonn if( ! rconst && ISREAL(ltype) && ISREAL(rtype) ) 727*40230Sdonn break; 728*40230Sdonn #endif 729*40230Sdonn if( ISCOMPLEX(ltype) || ISCOMPLEX(rtype) ) 730*40230Sdonn break; 731*40230Sdonn if( ONEOF(ltype, MSKADDR|MSKINT) && ONEOF(rtype, MSKADDR|MSKINT) 732*40230Sdonn #if FAMILY==PCC 733*40230Sdonn && typesize[ltype]>=typesize[rtype] ) 734*40230Sdonn #else 735*40230Sdonn && typesize[ltype]==typesize[rtype] ) 736*40230Sdonn #endif 737*40230Sdonn break; 738*40230Sdonn if (rconst) 739*40230Sdonn { 740*40230Sdonn p->rightp = fixtype( mkconv(ptype, cpexpr(rconst)) ); 741*40230Sdonn frexpr(rp); 742*40230Sdonn } 743*40230Sdonn else 744*40230Sdonn p->rightp = fixtype(mkconv(ptype, rp)); 745*40230Sdonn break; 746*40230Sdonn 747*40230Sdonn case OPSLASH: 748*40230Sdonn if( ISCOMPLEX(rtype) ) 749*40230Sdonn { 750*40230Sdonn p = (Exprp) call2(ptype, 751*40230Sdonn ptype==TYCOMPLEX? "c_div" : "z_div", 752*40230Sdonn mkconv(ptype, lp), mkconv(ptype, rp) ); 753*40230Sdonn break; 754*40230Sdonn } 755*40230Sdonn case OPPLUS: 756*40230Sdonn case OPMINUS: 757*40230Sdonn case OPSTAR: 758*40230Sdonn case OPMOD: 759*40230Sdonn #if TARGET == VAX 760*40230Sdonn if(ptype==TYDREAL && ( (ltype==TYREAL && ! lconst ) || 761*40230Sdonn (rtype==TYREAL && ! rconst ) )) 762*40230Sdonn break; 763*40230Sdonn #endif 764*40230Sdonn if( ISCOMPLEX(ptype) ) 765*40230Sdonn break; 766*40230Sdonn if(ltype != ptype) 767*40230Sdonn if (lconst) 768*40230Sdonn { 769*40230Sdonn p->leftp = fixtype(mkconv(ptype, 770*40230Sdonn cpexpr(lconst))); 771*40230Sdonn frexpr(lp); 772*40230Sdonn } 773*40230Sdonn else 774*40230Sdonn p->leftp = fixtype(mkconv(ptype,lp)); 775*40230Sdonn if(rtype != ptype) 776*40230Sdonn if (rconst) 777*40230Sdonn { 778*40230Sdonn p->rightp = fixtype(mkconv(ptype, 779*40230Sdonn cpexpr(rconst))); 780*40230Sdonn frexpr(rp); 781*40230Sdonn } 782*40230Sdonn else 783*40230Sdonn p->rightp = fixtype(mkconv(ptype,rp)); 784*40230Sdonn break; 785*40230Sdonn 786*40230Sdonn case OPPOWER: 787*40230Sdonn return( mkpower(p) ); 788*40230Sdonn 789*40230Sdonn case OPLT: 790*40230Sdonn case OPLE: 791*40230Sdonn case OPGT: 792*40230Sdonn case OPGE: 793*40230Sdonn case OPEQ: 794*40230Sdonn case OPNE: 795*40230Sdonn if(ltype == rtype) 796*40230Sdonn break; 797*40230Sdonn mtype = cktype(OPMINUS, ltype, rtype); 798*40230Sdonn #if TARGET == VAX 799*40230Sdonn if(mtype==TYDREAL && ( (ltype==TYREAL && ! lconst) || 800*40230Sdonn (rtype==TYREAL && ! rconst) )) 801*40230Sdonn break; 802*40230Sdonn #endif 803*40230Sdonn if( ISCOMPLEX(mtype) ) 804*40230Sdonn break; 805*40230Sdonn if(ltype != mtype) 806*40230Sdonn if (lconst) 807*40230Sdonn { 808*40230Sdonn p->leftp = fixtype(mkconv(mtype, 809*40230Sdonn cpexpr(lconst))); 810*40230Sdonn frexpr(lp); 811*40230Sdonn } 812*40230Sdonn else 813*40230Sdonn p->leftp = fixtype(mkconv(mtype,lp)); 814*40230Sdonn if(rtype != mtype) 815*40230Sdonn if (rconst) 816*40230Sdonn { 817*40230Sdonn p->rightp = fixtype(mkconv(mtype, 818*40230Sdonn cpexpr(rconst))); 819*40230Sdonn frexpr(rp); 820*40230Sdonn } 821*40230Sdonn else 822*40230Sdonn p->rightp = fixtype(mkconv(mtype,rp)); 823*40230Sdonn break; 824*40230Sdonn 825*40230Sdonn 826*40230Sdonn case OPCONV: 827*40230Sdonn if(ISCOMPLEX(p->vtype)) 828*40230Sdonn { 829*40230Sdonn ptype = cktype(OPCONV, p->vtype, ltype); 830*40230Sdonn if(p->rightp) 831*40230Sdonn ptype = cktype(OPCONV, ptype, rtype); 832*40230Sdonn break; 833*40230Sdonn } 834*40230Sdonn ptype = cktype(OPCONV, p->vtype, ltype); 835*40230Sdonn if(lp->tag==TEXPR && lp->exprblock.opcode==OPCOMMA) 836*40230Sdonn { 837*40230Sdonn lp->exprblock.rightp = 838*40230Sdonn fixtype( mkconv(ptype, lp->exprblock.rightp) ); 839*40230Sdonn free( (charptr) p ); 840*40230Sdonn p = (Exprp) lp; 841*40230Sdonn } 842*40230Sdonn break; 843*40230Sdonn 844*40230Sdonn case OPADDR: 845*40230Sdonn if(lp->tag==TEXPR && lp->exprblock.opcode==OPADDR) 846*40230Sdonn fatal("addr of addr"); 847*40230Sdonn break; 848*40230Sdonn 849*40230Sdonn case OPCOMMA: 850*40230Sdonn case OPQUEST: 851*40230Sdonn case OPCOLON: 852*40230Sdonn break; 853*40230Sdonn 854*40230Sdonn case OPPAREN: 855*40230Sdonn p->vleng = (expptr) cpexpr( lp->headblock.vleng ); 856*40230Sdonn break; 857*40230Sdonn 858*40230Sdonn case OPMIN: 859*40230Sdonn case OPMAX: 860*40230Sdonn ptype = p->vtype; 861*40230Sdonn break; 862*40230Sdonn 863*40230Sdonn default: 864*40230Sdonn break; 865*40230Sdonn } 866*40230Sdonn 867*40230Sdonn p->vtype = ptype; 868*40230Sdonn frexpr(lconst); 869*40230Sdonn frexpr(rconst); 870*40230Sdonn return((expptr) p); 871*40230Sdonn } 872*40230Sdonn 873*40230Sdonn #if SZINT < SZLONG 874*40230Sdonn /* 875*40230Sdonn for efficient subscripting, replace long ints by shorts 876*40230Sdonn in easy places 877*40230Sdonn */ 878*40230Sdonn 879*40230Sdonn expptr shorten(p) 880*40230Sdonn register expptr p; 881*40230Sdonn { 882*40230Sdonn register expptr q; 883*40230Sdonn 884*40230Sdonn if(p->headblock.vtype != TYLONG) 885*40230Sdonn return(p); 886*40230Sdonn 887*40230Sdonn switch(p->tag) 888*40230Sdonn { 889*40230Sdonn case TERROR: 890*40230Sdonn case TLIST: 891*40230Sdonn return(p); 892*40230Sdonn 893*40230Sdonn case TCONST: 894*40230Sdonn case TADDR: 895*40230Sdonn return( mkconv(TYINT,p) ); 896*40230Sdonn 897*40230Sdonn case TEXPR: 898*40230Sdonn break; 899*40230Sdonn 900*40230Sdonn default: 901*40230Sdonn badtag("shorten", p->tag); 902*40230Sdonn } 903*40230Sdonn 904*40230Sdonn switch(p->exprblock.opcode) 905*40230Sdonn { 906*40230Sdonn case OPPLUS: 907*40230Sdonn case OPMINUS: 908*40230Sdonn case OPSTAR: 909*40230Sdonn q = shorten( cpexpr(p->exprblock.rightp) ); 910*40230Sdonn if(q->headblock.vtype == TYINT) 911*40230Sdonn { 912*40230Sdonn p->exprblock.leftp = shorten(p->exprblock.leftp); 913*40230Sdonn if(p->exprblock.leftp->headblock.vtype == TYLONG) 914*40230Sdonn frexpr(q); 915*40230Sdonn else 916*40230Sdonn { 917*40230Sdonn frexpr(p->exprblock.rightp); 918*40230Sdonn p->exprblock.rightp = q; 919*40230Sdonn p->exprblock.vtype = TYINT; 920*40230Sdonn } 921*40230Sdonn } 922*40230Sdonn break; 923*40230Sdonn 924*40230Sdonn case OPNEG: 925*40230Sdonn case OPPAREN: 926*40230Sdonn p->exprblock.leftp = shorten(p->exprblock.leftp); 927*40230Sdonn if(p->exprblock.leftp->headblock.vtype == TYINT) 928*40230Sdonn p->exprblock.vtype = TYINT; 929*40230Sdonn break; 930*40230Sdonn 931*40230Sdonn case OPCALL: 932*40230Sdonn case OPCCALL: 933*40230Sdonn p = mkconv(TYINT,p); 934*40230Sdonn break; 935*40230Sdonn default: 936*40230Sdonn break; 937*40230Sdonn } 938*40230Sdonn 939*40230Sdonn return(p); 940*40230Sdonn } 941*40230Sdonn #endif 942*40230Sdonn /* fix an argument list, taking due care for special first level cases */ 943*40230Sdonn 944*40230Sdonn fixargs(doput, p0) 945*40230Sdonn int doput; /* doput is true if the function is not intrinsic; 946*40230Sdonn was used to decide whether to do a putconst, 947*40230Sdonn but this is no longer done here (Feb82)*/ 948*40230Sdonn struct Listblock *p0; 949*40230Sdonn { 950*40230Sdonn register chainp p; 951*40230Sdonn register tagptr q, t; 952*40230Sdonn register int qtag; 953*40230Sdonn int nargs; 954*40230Sdonn Addrp mkscalar(); 955*40230Sdonn 956*40230Sdonn nargs = 0; 957*40230Sdonn if(p0) 958*40230Sdonn for(p = p0->listp ; p ; p = p->nextp) 959*40230Sdonn { 960*40230Sdonn ++nargs; 961*40230Sdonn q = p->datap; 962*40230Sdonn qtag = q->tag; 963*40230Sdonn if(qtag == TCONST) 964*40230Sdonn { 965*40230Sdonn 966*40230Sdonn /* 967*40230Sdonn if(q->constblock.vtype == TYSHORT) 968*40230Sdonn q = (tagptr) mkconv(tyint, q); 969*40230Sdonn */ 970*40230Sdonn p->datap = q ; 971*40230Sdonn } 972*40230Sdonn else if(qtag==TPRIM && q->primblock.argsp==0 && 973*40230Sdonn q->primblock.namep->vclass==CLPROC) 974*40230Sdonn p->datap = (tagptr) mkaddr(q->primblock.namep); 975*40230Sdonn else if(qtag==TPRIM && q->primblock.argsp==0 && 976*40230Sdonn q->primblock.namep->vdim!=NULL) 977*40230Sdonn p->datap = (tagptr) mkscalar(q->primblock.namep); 978*40230Sdonn else if(qtag==TPRIM && q->primblock.argsp==0 && 979*40230Sdonn q->primblock.namep->vdovar && 980*40230Sdonn (t = (tagptr) memversion(q->primblock.namep)) ) 981*40230Sdonn p->datap = (tagptr) fixtype(t); 982*40230Sdonn else 983*40230Sdonn p->datap = (tagptr) fixtype(q); 984*40230Sdonn } 985*40230Sdonn return(nargs); 986*40230Sdonn } 987*40230Sdonn 988*40230Sdonn 989*40230Sdonn Addrp mkscalar(np) 990*40230Sdonn register Namep np; 991*40230Sdonn { 992*40230Sdonn register Addrp ap; 993*40230Sdonn 994*40230Sdonn vardcl(np); 995*40230Sdonn ap = mkaddr(np); 996*40230Sdonn 997*40230Sdonn #if TARGET == VAX || TARGET == TAHOE 998*40230Sdonn /* on the VAX, prolog causes array arguments 999*40230Sdonn to point at the (0,...,0) element, except when 1000*40230Sdonn subscript checking is on 1001*40230Sdonn */ 1002*40230Sdonn #ifdef SDB 1003*40230Sdonn if( !checksubs && !sdbflag && np->vstg==STGARG) 1004*40230Sdonn #else 1005*40230Sdonn if( !checksubs && np->vstg==STGARG) 1006*40230Sdonn #endif 1007*40230Sdonn { 1008*40230Sdonn register struct Dimblock *dp; 1009*40230Sdonn dp = np->vdim; 1010*40230Sdonn frexpr(ap->memoffset); 1011*40230Sdonn ap->memoffset = mkexpr(OPSTAR, 1012*40230Sdonn (np->vtype==TYCHAR ? 1013*40230Sdonn cpexpr(np->vleng) : 1014*40230Sdonn (tagptr)ICON(typesize[np->vtype]) ), 1015*40230Sdonn cpexpr(dp->baseoffset) ); 1016*40230Sdonn } 1017*40230Sdonn #endif 1018*40230Sdonn return(ap); 1019*40230Sdonn } 1020*40230Sdonn 1021*40230Sdonn 1022*40230Sdonn 1023*40230Sdonn 1024*40230Sdonn 1025*40230Sdonn expptr mkfunct(p) 1026*40230Sdonn register struct Primblock *p; 1027*40230Sdonn { 1028*40230Sdonn struct Entrypoint *ep; 1029*40230Sdonn Addrp ap; 1030*40230Sdonn struct Extsym *extp; 1031*40230Sdonn register Namep np; 1032*40230Sdonn register expptr q; 1033*40230Sdonn expptr intrcall(), stfcall(); 1034*40230Sdonn int k, nargs; 1035*40230Sdonn int class; 1036*40230Sdonn 1037*40230Sdonn if(p->tag != TPRIM) 1038*40230Sdonn return( errnode() ); 1039*40230Sdonn 1040*40230Sdonn np = p->namep; 1041*40230Sdonn class = np->vclass; 1042*40230Sdonn 1043*40230Sdonn if(class == CLUNKNOWN) 1044*40230Sdonn { 1045*40230Sdonn np->vclass = class = CLPROC; 1046*40230Sdonn if(np->vstg == STGUNKNOWN) 1047*40230Sdonn { 1048*40230Sdonn if(np->vtype!=TYSUBR && (k = intrfunct(np->varname)) ) 1049*40230Sdonn { 1050*40230Sdonn np->vstg = STGINTR; 1051*40230Sdonn np->vardesc.varno = k; 1052*40230Sdonn np->vprocclass = PINTRINSIC; 1053*40230Sdonn } 1054*40230Sdonn else 1055*40230Sdonn { 1056*40230Sdonn extp = mkext( varunder(VL,np->varname) ); 1057*40230Sdonn if(extp->extstg == STGCOMMON) 1058*40230Sdonn warn("conflicting declarations", np->varname); 1059*40230Sdonn extp->extstg = STGEXT; 1060*40230Sdonn np->vstg = STGEXT; 1061*40230Sdonn np->vardesc.varno = extp - extsymtab; 1062*40230Sdonn np->vprocclass = PEXTERNAL; 1063*40230Sdonn } 1064*40230Sdonn } 1065*40230Sdonn else if(np->vstg==STGARG) 1066*40230Sdonn { 1067*40230Sdonn if(np->vtype!=TYCHAR && !ftn66flag) 1068*40230Sdonn warn("Dummy procedure not declared EXTERNAL. Code may be wrong."); 1069*40230Sdonn np->vprocclass = PEXTERNAL; 1070*40230Sdonn } 1071*40230Sdonn } 1072*40230Sdonn 1073*40230Sdonn if(class != CLPROC) 1074*40230Sdonn fatali("invalid class code %d for function", class); 1075*40230Sdonn if(p->fcharp || p->lcharp) 1076*40230Sdonn { 1077*40230Sdonn err("no substring of function call"); 1078*40230Sdonn goto error; 1079*40230Sdonn } 1080*40230Sdonn impldcl(np); 1081*40230Sdonn nargs = fixargs( np->vprocclass!=PINTRINSIC, p->argsp); 1082*40230Sdonn 1083*40230Sdonn switch(np->vprocclass) 1084*40230Sdonn { 1085*40230Sdonn case PEXTERNAL: 1086*40230Sdonn ap = mkaddr(np); 1087*40230Sdonn call: 1088*40230Sdonn q = mkexpr(OPCALL, ap, p->argsp); 1089*40230Sdonn if( (q->exprblock.vtype = np->vtype) == TYUNKNOWN) 1090*40230Sdonn { 1091*40230Sdonn err("attempt to use untyped function"); 1092*40230Sdonn goto error; 1093*40230Sdonn } 1094*40230Sdonn if(np->vleng) 1095*40230Sdonn q->exprblock.vleng = (expptr) cpexpr(np->vleng); 1096*40230Sdonn break; 1097*40230Sdonn 1098*40230Sdonn case PINTRINSIC: 1099*40230Sdonn q = intrcall(np, p->argsp, nargs); 1100*40230Sdonn break; 1101*40230Sdonn 1102*40230Sdonn case PSTFUNCT: 1103*40230Sdonn q = stfcall(np, p->argsp); 1104*40230Sdonn break; 1105*40230Sdonn 1106*40230Sdonn case PTHISPROC: 1107*40230Sdonn warn("recursive call"); 1108*40230Sdonn for(ep = entries ; ep ; ep = ep->entnextp) 1109*40230Sdonn if(ep->enamep == np) 1110*40230Sdonn break; 1111*40230Sdonn if(ep == NULL) 1112*40230Sdonn fatal("mkfunct: impossible recursion"); 1113*40230Sdonn ap = builtin(np->vtype, varstr(XL, ep->entryname->extname) ); 1114*40230Sdonn goto call; 1115*40230Sdonn 1116*40230Sdonn default: 1117*40230Sdonn fatali("mkfunct: impossible vprocclass %d", 1118*40230Sdonn (int) (np->vprocclass) ); 1119*40230Sdonn } 1120*40230Sdonn free( (charptr) p ); 1121*40230Sdonn return(q); 1122*40230Sdonn 1123*40230Sdonn error: 1124*40230Sdonn frexpr(p); 1125*40230Sdonn return( errnode() ); 1126*40230Sdonn } 1127*40230Sdonn 1128*40230Sdonn 1129*40230Sdonn 1130*40230Sdonn LOCAL expptr stfcall(np, actlist) 1131*40230Sdonn Namep np; 1132*40230Sdonn struct Listblock *actlist; 1133*40230Sdonn { 1134*40230Sdonn register chainp actuals; 1135*40230Sdonn int nargs; 1136*40230Sdonn chainp oactp, formals; 1137*40230Sdonn int type; 1138*40230Sdonn expptr q, rhs, ap; 1139*40230Sdonn Namep tnp; 1140*40230Sdonn register struct Rplblock *rp; 1141*40230Sdonn struct Rplblock *tlist; 1142*40230Sdonn 1143*40230Sdonn if(actlist) 1144*40230Sdonn { 1145*40230Sdonn actuals = actlist->listp; 1146*40230Sdonn free( (charptr) actlist); 1147*40230Sdonn } 1148*40230Sdonn else 1149*40230Sdonn actuals = NULL; 1150*40230Sdonn oactp = actuals; 1151*40230Sdonn 1152*40230Sdonn nargs = 0; 1153*40230Sdonn tlist = NULL; 1154*40230Sdonn if( (type = np->vtype) == TYUNKNOWN) 1155*40230Sdonn { 1156*40230Sdonn err("attempt to use untyped statement function"); 1157*40230Sdonn q = errnode(); 1158*40230Sdonn goto ret; 1159*40230Sdonn } 1160*40230Sdonn formals = (chainp) (np->varxptr.vstfdesc->datap); 1161*40230Sdonn rhs = (expptr) (np->varxptr.vstfdesc->nextp); 1162*40230Sdonn 1163*40230Sdonn /* copy actual arguments into temporaries */ 1164*40230Sdonn while(actuals!=NULL && formals!=NULL) 1165*40230Sdonn { 1166*40230Sdonn rp = ALLOC(Rplblock); 1167*40230Sdonn rp->rplnp = tnp = (Namep) (formals->datap); 1168*40230Sdonn ap = fixtype(actuals->datap); 1169*40230Sdonn if(tnp->vtype==ap->headblock.vtype && tnp->vtype!=TYCHAR 1170*40230Sdonn && (ap->tag==TCONST || ap->tag==TADDR || ap->tag==TTEMP) ) 1171*40230Sdonn { 1172*40230Sdonn rp->rplvp = (expptr) ap; 1173*40230Sdonn rp->rplxp = NULL; 1174*40230Sdonn rp->rpltag = ap->tag; 1175*40230Sdonn } 1176*40230Sdonn else { 1177*40230Sdonn rp->rplvp = (expptr) mktemp(tnp->vtype, tnp->vleng); 1178*40230Sdonn rp->rplxp = fixtype( mkexpr(OPASSIGN, cpexpr(rp->rplvp), ap) ); 1179*40230Sdonn if( (rp->rpltag = rp->rplxp->tag) == TERROR) 1180*40230Sdonn err("disagreement of argument types in statement function call"); 1181*40230Sdonn else if(tnp->vtype!=ap->headblock.vtype) 1182*40230Sdonn warn("argument type mismatch in statement function"); 1183*40230Sdonn } 1184*40230Sdonn rp->rplnextp = tlist; 1185*40230Sdonn tlist = rp; 1186*40230Sdonn actuals = actuals->nextp; 1187*40230Sdonn formals = formals->nextp; 1188*40230Sdonn ++nargs; 1189*40230Sdonn } 1190*40230Sdonn 1191*40230Sdonn if(actuals!=NULL || formals!=NULL) 1192*40230Sdonn err("statement function definition and argument list differ"); 1193*40230Sdonn 1194*40230Sdonn /* 1195*40230Sdonn now push down names involved in formal argument list, then 1196*40230Sdonn evaluate rhs of statement function definition in this environment 1197*40230Sdonn */ 1198*40230Sdonn 1199*40230Sdonn if(tlist) /* put tlist in front of the rpllist */ 1200*40230Sdonn { 1201*40230Sdonn for(rp = tlist; rp->rplnextp; rp = rp->rplnextp) 1202*40230Sdonn ; 1203*40230Sdonn rp->rplnextp = rpllist; 1204*40230Sdonn rpllist = tlist; 1205*40230Sdonn } 1206*40230Sdonn 1207*40230Sdonn q = (expptr) mkconv(type, fixtype(cpexpr(rhs)) ); 1208*40230Sdonn 1209*40230Sdonn /* now generate the tree ( t1=a1, (t2=a2,... , f))))) */ 1210*40230Sdonn while(--nargs >= 0) 1211*40230Sdonn { 1212*40230Sdonn if(rpllist->rplxp) 1213*40230Sdonn q = mkexpr(OPCOMMA, rpllist->rplxp, q); 1214*40230Sdonn rp = rpllist->rplnextp; 1215*40230Sdonn frexpr(rpllist->rplvp); 1216*40230Sdonn free(rpllist); 1217*40230Sdonn rpllist = rp; 1218*40230Sdonn } 1219*40230Sdonn 1220*40230Sdonn ret: 1221*40230Sdonn frchain( &oactp ); 1222*40230Sdonn return(q); 1223*40230Sdonn } 1224*40230Sdonn 1225*40230Sdonn 1226*40230Sdonn 1227*40230Sdonn 1228*40230Sdonn Addrp mkplace(np) 1229*40230Sdonn register Namep np; 1230*40230Sdonn { 1231*40230Sdonn register Addrp s; 1232*40230Sdonn register struct Rplblock *rp; 1233*40230Sdonn int regn; 1234*40230Sdonn 1235*40230Sdonn /* is name on the replace list? */ 1236*40230Sdonn 1237*40230Sdonn for(rp = rpllist ; rp ; rp = rp->rplnextp) 1238*40230Sdonn { 1239*40230Sdonn if(np == rp->rplnp) 1240*40230Sdonn { 1241*40230Sdonn if(rp->rpltag == TNAME) 1242*40230Sdonn { 1243*40230Sdonn np = (Namep) (rp->rplvp); 1244*40230Sdonn break; 1245*40230Sdonn } 1246*40230Sdonn else return( (Addrp) cpexpr(rp->rplvp) ); 1247*40230Sdonn } 1248*40230Sdonn } 1249*40230Sdonn 1250*40230Sdonn /* is variable a DO index in a register ? */ 1251*40230Sdonn 1252*40230Sdonn if(np->vdovar && ( (regn = inregister(np)) >= 0) ) 1253*40230Sdonn if(np->vtype == TYERROR) 1254*40230Sdonn return( (Addrp) errnode() ); 1255*40230Sdonn else 1256*40230Sdonn { 1257*40230Sdonn s = ALLOC(Addrblock); 1258*40230Sdonn s->tag = TADDR; 1259*40230Sdonn s->vstg = STGREG; 1260*40230Sdonn s->vtype = TYIREG; 1261*40230Sdonn s->issaved = np->vsave; 1262*40230Sdonn s->memno = regn; 1263*40230Sdonn s->memoffset = ICON(0); 1264*40230Sdonn return(s); 1265*40230Sdonn } 1266*40230Sdonn 1267*40230Sdonn vardcl(np); 1268*40230Sdonn return(mkaddr(np)); 1269*40230Sdonn } 1270*40230Sdonn 1271*40230Sdonn 1272*40230Sdonn 1273*40230Sdonn 1274*40230Sdonn expptr mklhs(p) 1275*40230Sdonn register struct Primblock *p; 1276*40230Sdonn { 1277*40230Sdonn expptr suboffset(); 1278*40230Sdonn register Addrp s; 1279*40230Sdonn Namep np; 1280*40230Sdonn 1281*40230Sdonn if(p->tag != TPRIM) 1282*40230Sdonn return( (expptr) p ); 1283*40230Sdonn np = p->namep; 1284*40230Sdonn 1285*40230Sdonn s = mkplace(np); 1286*40230Sdonn if(s->tag!=TADDR || s->vstg==STGREG) 1287*40230Sdonn { 1288*40230Sdonn free( (charptr) p ); 1289*40230Sdonn return( (expptr) s ); 1290*40230Sdonn } 1291*40230Sdonn 1292*40230Sdonn /* compute the address modified by subscripts */ 1293*40230Sdonn 1294*40230Sdonn s->memoffset = mkexpr(OPPLUS, s->memoffset, suboffset(p) ); 1295*40230Sdonn frexpr(p->argsp); 1296*40230Sdonn p->argsp = NULL; 1297*40230Sdonn 1298*40230Sdonn /* now do substring part */ 1299*40230Sdonn 1300*40230Sdonn if(p->fcharp || p->lcharp) 1301*40230Sdonn { 1302*40230Sdonn if(np->vtype != TYCHAR) 1303*40230Sdonn errstr("substring of noncharacter %s", varstr(VL,np->varname)); 1304*40230Sdonn else { 1305*40230Sdonn if(p->lcharp == NULL) 1306*40230Sdonn p->lcharp = (expptr) cpexpr(s->vleng); 1307*40230Sdonn frexpr(s->vleng); 1308*40230Sdonn if(p->fcharp) 1309*40230Sdonn { 1310*40230Sdonn if(p->fcharp->tag == TPRIM && p->lcharp->tag == TPRIM 1311*40230Sdonn && p->fcharp->primblock.namep == p->lcharp->primblock.namep) 1312*40230Sdonn /* A trivial optimization -- upper == lower */ 1313*40230Sdonn s->vleng = ICON(1); 1314*40230Sdonn else 1315*40230Sdonn s->vleng = mkexpr(OPMINUS, p->lcharp, 1316*40230Sdonn mkexpr(OPMINUS, p->fcharp, ICON(1) )); 1317*40230Sdonn } 1318*40230Sdonn else 1319*40230Sdonn s->vleng = p->lcharp; 1320*40230Sdonn } 1321*40230Sdonn } 1322*40230Sdonn 1323*40230Sdonn s->vleng = fixtype( s->vleng ); 1324*40230Sdonn s->memoffset = fixtype( s->memoffset ); 1325*40230Sdonn free( (charptr) p ); 1326*40230Sdonn return( (expptr) s ); 1327*40230Sdonn } 1328*40230Sdonn 1329*40230Sdonn 1330*40230Sdonn 1331*40230Sdonn 1332*40230Sdonn 1333*40230Sdonn deregister(np) 1334*40230Sdonn Namep np; 1335*40230Sdonn { 1336*40230Sdonn if(nregvar>0 && regnamep[nregvar-1]==np) 1337*40230Sdonn { 1338*40230Sdonn --nregvar; 1339*40230Sdonn #if FAMILY == DMR 1340*40230Sdonn putnreg(); 1341*40230Sdonn #endif 1342*40230Sdonn } 1343*40230Sdonn } 1344*40230Sdonn 1345*40230Sdonn 1346*40230Sdonn 1347*40230Sdonn 1348*40230Sdonn Addrp memversion(np) 1349*40230Sdonn register Namep np; 1350*40230Sdonn { 1351*40230Sdonn register Addrp s; 1352*40230Sdonn 1353*40230Sdonn if(np->vdovar==NO || (inregister(np)<0) ) 1354*40230Sdonn return(NULL); 1355*40230Sdonn np->vdovar = NO; 1356*40230Sdonn s = mkplace(np); 1357*40230Sdonn np->vdovar = YES; 1358*40230Sdonn return(s); 1359*40230Sdonn } 1360*40230Sdonn 1361*40230Sdonn 1362*40230Sdonn 1363*40230Sdonn inregister(np) 1364*40230Sdonn register Namep np; 1365*40230Sdonn { 1366*40230Sdonn register int i; 1367*40230Sdonn 1368*40230Sdonn for(i = 0 ; i < nregvar ; ++i) 1369*40230Sdonn if(regnamep[i] == np) 1370*40230Sdonn return( regnum[i] ); 1371*40230Sdonn return(-1); 1372*40230Sdonn } 1373*40230Sdonn 1374*40230Sdonn 1375*40230Sdonn 1376*40230Sdonn 1377*40230Sdonn enregister(np) 1378*40230Sdonn Namep np; 1379*40230Sdonn { 1380*40230Sdonn if( inregister(np) >= 0) 1381*40230Sdonn return(YES); 1382*40230Sdonn if(nregvar >= maxregvar) 1383*40230Sdonn return(NO); 1384*40230Sdonn vardcl(np); 1385*40230Sdonn if( ONEOF(np->vtype, MSKIREG) ) 1386*40230Sdonn { 1387*40230Sdonn regnamep[nregvar++] = np; 1388*40230Sdonn if(nregvar > highregvar) 1389*40230Sdonn highregvar = nregvar; 1390*40230Sdonn #if FAMILY == DMR 1391*40230Sdonn putnreg(); 1392*40230Sdonn #endif 1393*40230Sdonn return(YES); 1394*40230Sdonn } 1395*40230Sdonn else 1396*40230Sdonn return(NO); 1397*40230Sdonn } 1398*40230Sdonn 1399*40230Sdonn 1400*40230Sdonn 1401*40230Sdonn 1402*40230Sdonn expptr suboffset(p) 1403*40230Sdonn register struct Primblock *p; 1404*40230Sdonn { 1405*40230Sdonn int n; 1406*40230Sdonn expptr size; 1407*40230Sdonn expptr oftwo(); 1408*40230Sdonn chainp cp; 1409*40230Sdonn expptr offp, prod; 1410*40230Sdonn expptr subcheck(); 1411*40230Sdonn struct Dimblock *dimp; 1412*40230Sdonn expptr sub[MAXDIM+1]; 1413*40230Sdonn register Namep np; 1414*40230Sdonn 1415*40230Sdonn np = p->namep; 1416*40230Sdonn offp = ICON(0); 1417*40230Sdonn n = 0; 1418*40230Sdonn if(p->argsp) 1419*40230Sdonn for(cp = p->argsp->listp ; cp ; ++n, cp = cp->nextp) 1420*40230Sdonn { 1421*40230Sdonn sub[n] = fixtype(cpexpr(cp->datap)); 1422*40230Sdonn if ( ! ISINT(sub[n]->headblock.vtype)) { 1423*40230Sdonn errstr("%s: non-integer subscript expression", 1424*40230Sdonn varstr(VL, np->varname) ); 1425*40230Sdonn /* Provide a substitute -- go on to find more errors */ 1426*40230Sdonn frexpr(sub[n]); 1427*40230Sdonn sub[n] = ICON(1); 1428*40230Sdonn } 1429*40230Sdonn if(n > maxdim) 1430*40230Sdonn { 1431*40230Sdonn char str[28+VL]; 1432*40230Sdonn sprintf(str, "%s: more than %d subscripts", 1433*40230Sdonn varstr(VL, np->varname), maxdim ); 1434*40230Sdonn err( str ); 1435*40230Sdonn break; 1436*40230Sdonn } 1437*40230Sdonn } 1438*40230Sdonn 1439*40230Sdonn dimp = np->vdim; 1440*40230Sdonn if(n>0 && dimp==NULL) 1441*40230Sdonn errstr("%s: subscripts on scalar variable", 1442*40230Sdonn varstr(VL, np->varname), maxdim ); 1443*40230Sdonn else if(dimp && dimp->ndim!=n) 1444*40230Sdonn errstr("wrong number of subscripts on %s", 1445*40230Sdonn varstr(VL, np->varname) ); 1446*40230Sdonn else if(n > 0) 1447*40230Sdonn { 1448*40230Sdonn prod = sub[--n]; 1449*40230Sdonn while( --n >= 0) 1450*40230Sdonn prod = mkexpr(OPPLUS, sub[n], 1451*40230Sdonn mkexpr(OPSTAR, prod, cpexpr(dimp->dims[n].dimsize)) ); 1452*40230Sdonn #if TARGET == VAX || TARGET == TAHOE 1453*40230Sdonn #ifdef SDB 1454*40230Sdonn if(checksubs || np->vstg!=STGARG || sdbflag) 1455*40230Sdonn #else 1456*40230Sdonn if(checksubs || np->vstg!=STGARG) 1457*40230Sdonn #endif 1458*40230Sdonn prod = mkexpr(OPMINUS, prod, cpexpr(dimp->baseoffset)); 1459*40230Sdonn #else 1460*40230Sdonn prod = mkexpr(OPMINUS, prod, cpexpr(dimp->baseoffset)); 1461*40230Sdonn #endif 1462*40230Sdonn if(checksubs) 1463*40230Sdonn prod = subcheck(np, prod); 1464*40230Sdonn size = np->vtype == TYCHAR ? 1465*40230Sdonn (expptr) cpexpr(np->vleng) : ICON(typesize[np->vtype]); 1466*40230Sdonn if (!oftwo(size)) 1467*40230Sdonn prod = mkexpr(OPSTAR, prod, size); 1468*40230Sdonn else 1469*40230Sdonn prod = mkexpr(OPLSHIFT,prod,oftwo(size)); 1470*40230Sdonn 1471*40230Sdonn offp = mkexpr(OPPLUS, offp, prod); 1472*40230Sdonn } 1473*40230Sdonn 1474*40230Sdonn if(p->fcharp && np->vtype==TYCHAR) 1475*40230Sdonn offp = mkexpr(OPPLUS, offp, mkexpr(OPMINUS, cpexpr(p->fcharp), ICON(1) )); 1476*40230Sdonn 1477*40230Sdonn return(offp); 1478*40230Sdonn } 1479*40230Sdonn 1480*40230Sdonn 1481*40230Sdonn 1482*40230Sdonn 1483*40230Sdonn expptr subcheck(np, p) 1484*40230Sdonn Namep np; 1485*40230Sdonn register expptr p; 1486*40230Sdonn { 1487*40230Sdonn struct Dimblock *dimp; 1488*40230Sdonn expptr t, checkvar, checkcond, badcall; 1489*40230Sdonn 1490*40230Sdonn dimp = np->vdim; 1491*40230Sdonn if(dimp->nelt == NULL) 1492*40230Sdonn return(p); /* don't check arrays with * bounds */ 1493*40230Sdonn checkvar = NULL; 1494*40230Sdonn checkcond = NULL; 1495*40230Sdonn if( ISICON(p) ) 1496*40230Sdonn { 1497*40230Sdonn if(p->constblock.const.ci < 0) 1498*40230Sdonn goto badsub; 1499*40230Sdonn if( ISICON(dimp->nelt) ) 1500*40230Sdonn if(p->constblock.const.ci < dimp->nelt->constblock.const.ci) 1501*40230Sdonn return(p); 1502*40230Sdonn else 1503*40230Sdonn goto badsub; 1504*40230Sdonn } 1505*40230Sdonn if(p->tag==TADDR && p->addrblock.vstg==STGREG) 1506*40230Sdonn { 1507*40230Sdonn checkvar = (expptr) cpexpr(p); 1508*40230Sdonn t = p; 1509*40230Sdonn } 1510*40230Sdonn else { 1511*40230Sdonn checkvar = (expptr) mktemp(p->headblock.vtype, ENULL); 1512*40230Sdonn t = mkexpr(OPASSIGN, cpexpr(checkvar), p); 1513*40230Sdonn } 1514*40230Sdonn checkcond = mkexpr(OPLT, t, cpexpr(dimp->nelt) ); 1515*40230Sdonn if( ! ISICON(p) ) 1516*40230Sdonn checkcond = mkexpr(OPAND, checkcond, 1517*40230Sdonn mkexpr(OPLE, ICON(0), cpexpr(checkvar)) ); 1518*40230Sdonn 1519*40230Sdonn badcall = call4(p->headblock.vtype, "s_rnge", 1520*40230Sdonn mkstrcon(VL, np->varname), 1521*40230Sdonn mkconv(TYLONG, cpexpr(checkvar)), 1522*40230Sdonn mkstrcon(XL, procname), 1523*40230Sdonn ICON(lineno) ); 1524*40230Sdonn badcall->exprblock.opcode = OPCCALL; 1525*40230Sdonn p = mkexpr(OPQUEST, checkcond, 1526*40230Sdonn mkexpr(OPCOLON, checkvar, badcall)); 1527*40230Sdonn 1528*40230Sdonn return(p); 1529*40230Sdonn 1530*40230Sdonn badsub: 1531*40230Sdonn frexpr(p); 1532*40230Sdonn errstr("subscript on variable %s out of range", varstr(VL,np->varname)); 1533*40230Sdonn return ( ICON(0) ); 1534*40230Sdonn } 1535*40230Sdonn 1536*40230Sdonn 1537*40230Sdonn 1538*40230Sdonn 1539*40230Sdonn Addrp mkaddr(p) 1540*40230Sdonn register Namep p; 1541*40230Sdonn { 1542*40230Sdonn struct Extsym *extp; 1543*40230Sdonn register Addrp t; 1544*40230Sdonn Addrp intraddr(); 1545*40230Sdonn 1546*40230Sdonn switch( p->vstg) 1547*40230Sdonn { 1548*40230Sdonn case STGUNKNOWN: 1549*40230Sdonn if(p->vclass != CLPROC) 1550*40230Sdonn break; 1551*40230Sdonn extp = mkext( varunder(VL, p->varname) ); 1552*40230Sdonn extp->extstg = STGEXT; 1553*40230Sdonn p->vstg = STGEXT; 1554*40230Sdonn p->vardesc.varno = extp - extsymtab; 1555*40230Sdonn p->vprocclass = PEXTERNAL; 1556*40230Sdonn 1557*40230Sdonn case STGCOMMON: 1558*40230Sdonn case STGEXT: 1559*40230Sdonn case STGBSS: 1560*40230Sdonn case STGINIT: 1561*40230Sdonn case STGEQUIV: 1562*40230Sdonn case STGARG: 1563*40230Sdonn case STGLENG: 1564*40230Sdonn case STGAUTO: 1565*40230Sdonn t = ALLOC(Addrblock); 1566*40230Sdonn t->tag = TADDR; 1567*40230Sdonn if(p->vclass==CLPROC && p->vprocclass==PTHISPROC) 1568*40230Sdonn t->vclass = CLVAR; 1569*40230Sdonn else 1570*40230Sdonn t->vclass = p->vclass; 1571*40230Sdonn t->vtype = p->vtype; 1572*40230Sdonn t->vstg = p->vstg; 1573*40230Sdonn t->memno = p->vardesc.varno; 1574*40230Sdonn t->issaved = p->vsave; 1575*40230Sdonn if(p->vdim) t->isarray = YES; 1576*40230Sdonn t->memoffset = ICON(p->voffset); 1577*40230Sdonn if(p->vleng) 1578*40230Sdonn { 1579*40230Sdonn t->vleng = (expptr) cpexpr(p->vleng); 1580*40230Sdonn if( ISICON(t->vleng) ) 1581*40230Sdonn t->varleng = t->vleng->constblock.const.ci; 1582*40230Sdonn } 1583*40230Sdonn if (p->vstg == STGBSS) 1584*40230Sdonn t->varsize = p->varsize; 1585*40230Sdonn else if (p->vstg == STGEQUIV) 1586*40230Sdonn t->varsize = eqvclass[t->memno].eqvleng; 1587*40230Sdonn return(t); 1588*40230Sdonn 1589*40230Sdonn case STGINTR: 1590*40230Sdonn return( intraddr(p) ); 1591*40230Sdonn 1592*40230Sdonn } 1593*40230Sdonn /*debug*/fprintf(diagfile,"mkaddr. vtype=%d, vclass=%d\n", p->vtype, p->vclass); 1594*40230Sdonn badstg("mkaddr", p->vstg); 1595*40230Sdonn /* NOTREACHED */ 1596*40230Sdonn } 1597*40230Sdonn 1598*40230Sdonn 1599*40230Sdonn 1600*40230Sdonn 1601*40230Sdonn Addrp mkarg(type, argno) 1602*40230Sdonn int type, argno; 1603*40230Sdonn { 1604*40230Sdonn register Addrp p; 1605*40230Sdonn 1606*40230Sdonn p = ALLOC(Addrblock); 1607*40230Sdonn p->tag = TADDR; 1608*40230Sdonn p->vtype = type; 1609*40230Sdonn p->vclass = CLVAR; 1610*40230Sdonn p->vstg = (type==TYLENG ? STGLENG : STGARG); 1611*40230Sdonn p->memno = argno; 1612*40230Sdonn return(p); 1613*40230Sdonn } 1614*40230Sdonn 1615*40230Sdonn 1616*40230Sdonn 1617*40230Sdonn 1618*40230Sdonn expptr mkprim(v, args, substr) 1619*40230Sdonn register union 1620*40230Sdonn { 1621*40230Sdonn struct Paramblock paramblock; 1622*40230Sdonn struct Nameblock nameblock; 1623*40230Sdonn struct Headblock headblock; 1624*40230Sdonn } *v; 1625*40230Sdonn struct Listblock *args; 1626*40230Sdonn chainp substr; 1627*40230Sdonn { 1628*40230Sdonn register struct Primblock *p; 1629*40230Sdonn 1630*40230Sdonn if(v->headblock.vclass == CLPARAM) 1631*40230Sdonn { 1632*40230Sdonn if(args || substr) 1633*40230Sdonn { 1634*40230Sdonn errstr("no qualifiers on parameter name %s", 1635*40230Sdonn varstr(VL,v->paramblock.varname)); 1636*40230Sdonn frexpr(args); 1637*40230Sdonn if(substr) 1638*40230Sdonn { 1639*40230Sdonn frexpr(substr->datap); 1640*40230Sdonn frexpr(substr->nextp->datap); 1641*40230Sdonn frchain(&substr); 1642*40230Sdonn } 1643*40230Sdonn frexpr(v); 1644*40230Sdonn return( errnode() ); 1645*40230Sdonn } 1646*40230Sdonn return( (expptr) cpexpr(v->paramblock.paramval) ); 1647*40230Sdonn } 1648*40230Sdonn 1649*40230Sdonn p = ALLOC(Primblock); 1650*40230Sdonn p->tag = TPRIM; 1651*40230Sdonn p->vtype = v->nameblock.vtype; 1652*40230Sdonn p->namep = (Namep) v; 1653*40230Sdonn p->argsp = args; 1654*40230Sdonn if(substr) 1655*40230Sdonn { 1656*40230Sdonn p->fcharp = (expptr) substr->datap; 1657*40230Sdonn if (p->fcharp != ENULL && ! ISINT(p->fcharp.headblock->vtype)) 1658*40230Sdonn p->fcharp = mkconv(TYINT, p->fcharp); 1659*40230Sdonn p->lcharp = (expptr) substr->nextp->datap; 1660*40230Sdonn if (p->lcharp != ENULL && ! ISINT(p->lcharp.headblock->vtype)) 1661*40230Sdonn p->lcharp = mkconv(TYINT, p->lcharp); 1662*40230Sdonn frchain(&substr); 1663*40230Sdonn } 1664*40230Sdonn return( (expptr) p); 1665*40230Sdonn } 1666*40230Sdonn 1667*40230Sdonn 1668*40230Sdonn 1669*40230Sdonn vardcl(v) 1670*40230Sdonn register Namep v; 1671*40230Sdonn { 1672*40230Sdonn int nelt; 1673*40230Sdonn struct Dimblock *t; 1674*40230Sdonn Addrp p; 1675*40230Sdonn expptr neltp; 1676*40230Sdonn int eltsize; 1677*40230Sdonn int varsize; 1678*40230Sdonn int tsize; 1679*40230Sdonn int align; 1680*40230Sdonn 1681*40230Sdonn if(v->vdcldone) 1682*40230Sdonn return; 1683*40230Sdonn if(v->vclass == CLNAMELIST) 1684*40230Sdonn return; 1685*40230Sdonn 1686*40230Sdonn if(v->vtype == TYUNKNOWN) 1687*40230Sdonn impldcl(v); 1688*40230Sdonn if(v->vclass == CLUNKNOWN) 1689*40230Sdonn v->vclass = CLVAR; 1690*40230Sdonn else if(v->vclass!=CLVAR && v->vprocclass!=PTHISPROC) 1691*40230Sdonn { 1692*40230Sdonn dclerr("used both as variable and non-variable", v); 1693*40230Sdonn return; 1694*40230Sdonn } 1695*40230Sdonn if(v->vstg==STGUNKNOWN) 1696*40230Sdonn v->vstg = implstg[ letter(v->varname[0]) ]; 1697*40230Sdonn 1698*40230Sdonn switch(v->vstg) 1699*40230Sdonn { 1700*40230Sdonn case STGBSS: 1701*40230Sdonn v->vardesc.varno = ++lastvarno; 1702*40230Sdonn if (v->vclass != CLVAR) 1703*40230Sdonn break; 1704*40230Sdonn nelt = 1; 1705*40230Sdonn t = v->vdim; 1706*40230Sdonn if (t) 1707*40230Sdonn { 1708*40230Sdonn neltp = t->nelt; 1709*40230Sdonn if (neltp && ISICON(neltp)) 1710*40230Sdonn nelt = neltp->constblock.const.ci; 1711*40230Sdonn else 1712*40230Sdonn dclerr("improperly dimensioned array", v); 1713*40230Sdonn } 1714*40230Sdonn 1715*40230Sdonn if (v->vtype == TYCHAR) 1716*40230Sdonn { 1717*40230Sdonn v->vleng = fixtype(v->vleng); 1718*40230Sdonn if (v->vleng == NULL) 1719*40230Sdonn eltsize = typesize[TYCHAR]; 1720*40230Sdonn else if (ISICON(v->vleng)) 1721*40230Sdonn eltsize = typesize[TYCHAR] * 1722*40230Sdonn v->vleng->constblock.const.ci; 1723*40230Sdonn else if (v->vleng->tag != TERROR) 1724*40230Sdonn { 1725*40230Sdonn errstr("nonconstant string length on %s", 1726*40230Sdonn varstr(VL, v->varname)); 1727*40230Sdonn eltsize = 0; 1728*40230Sdonn } 1729*40230Sdonn } 1730*40230Sdonn else 1731*40230Sdonn eltsize = typesize[v->vtype]; 1732*40230Sdonn 1733*40230Sdonn v->varsize = nelt * eltsize; 1734*40230Sdonn break; 1735*40230Sdonn case STGAUTO: 1736*40230Sdonn if(v->vclass==CLPROC && v->vprocclass==PTHISPROC) 1737*40230Sdonn break; 1738*40230Sdonn nelt = 1; 1739*40230Sdonn if(t = v->vdim) 1740*40230Sdonn if( (neltp = t->nelt) && ISCONST(neltp) ) 1741*40230Sdonn nelt = neltp->constblock.const.ci; 1742*40230Sdonn else 1743*40230Sdonn dclerr("adjustable automatic array", v); 1744*40230Sdonn p = autovar(nelt, v->vtype, v->vleng); 1745*40230Sdonn v->vardesc.varno = p->memno; 1746*40230Sdonn v->voffset = p->memoffset->constblock.const.ci; 1747*40230Sdonn frexpr(p); 1748*40230Sdonn break; 1749*40230Sdonn 1750*40230Sdonn default: 1751*40230Sdonn break; 1752*40230Sdonn } 1753*40230Sdonn v->vdcldone = YES; 1754*40230Sdonn } 1755*40230Sdonn 1756*40230Sdonn 1757*40230Sdonn 1758*40230Sdonn 1759*40230Sdonn impldcl(p) 1760*40230Sdonn register Namep p; 1761*40230Sdonn { 1762*40230Sdonn register int k; 1763*40230Sdonn int type, leng; 1764*40230Sdonn 1765*40230Sdonn if(p->vdcldone || (p->vclass==CLPROC && p->vprocclass==PINTRINSIC) ) 1766*40230Sdonn return; 1767*40230Sdonn if(p->vtype == TYUNKNOWN) 1768*40230Sdonn { 1769*40230Sdonn k = letter(p->varname[0]); 1770*40230Sdonn type = impltype[ k ]; 1771*40230Sdonn leng = implleng[ k ]; 1772*40230Sdonn if(type == TYUNKNOWN) 1773*40230Sdonn { 1774*40230Sdonn if(p->vclass == CLPROC) 1775*40230Sdonn dclerr("attempt to use function of undefined type", p); 1776*40230Sdonn else 1777*40230Sdonn dclerr("attempt to use undefined variable", p); 1778*40230Sdonn type = TYERROR; 1779*40230Sdonn leng = 1; 1780*40230Sdonn } 1781*40230Sdonn settype(p, type, leng); 1782*40230Sdonn } 1783*40230Sdonn } 1784*40230Sdonn 1785*40230Sdonn 1786*40230Sdonn 1787*40230Sdonn 1788*40230Sdonn LOCAL letter(c) 1789*40230Sdonn register int c; 1790*40230Sdonn { 1791*40230Sdonn if( isupper(c) ) 1792*40230Sdonn c = tolower(c); 1793*40230Sdonn return(c - 'a'); 1794*40230Sdonn } 1795*40230Sdonn 1796*40230Sdonn #define ICONEQ(z, c) (ISICON(z) && z->constblock.const.ci==c) 1797*40230Sdonn #define COMMUTE { e = lp; lp = rp; rp = e; } 1798*40230Sdonn 1799*40230Sdonn 1800*40230Sdonn expptr mkexpr(opcode, lp, rp) 1801*40230Sdonn int opcode; 1802*40230Sdonn register expptr lp, rp; 1803*40230Sdonn { 1804*40230Sdonn register expptr e, e1; 1805*40230Sdonn int etype; 1806*40230Sdonn int ltype, rtype; 1807*40230Sdonn int ltag, rtag; 1808*40230Sdonn expptr q, q1; 1809*40230Sdonn expptr fold(); 1810*40230Sdonn int k; 1811*40230Sdonn 1812*40230Sdonn ltype = lp->headblock.vtype; 1813*40230Sdonn ltag = lp->tag; 1814*40230Sdonn if(rp && opcode!=OPCALL && opcode!=OPCCALL) 1815*40230Sdonn { 1816*40230Sdonn rtype = rp->headblock.vtype; 1817*40230Sdonn rtag = rp->tag; 1818*40230Sdonn } 1819*40230Sdonn else { 1820*40230Sdonn rtype = 0; 1821*40230Sdonn rtag = 0; 1822*40230Sdonn } 1823*40230Sdonn 1824*40230Sdonn /* 1825*40230Sdonn * Yuck. Why can't we fold constants AFTER 1826*40230Sdonn * variables are implicitly declared??? 1827*40230Sdonn */ 1828*40230Sdonn if(ltype == TYUNKNOWN && ltag == TPRIM && lp->primblock.argsp == NULL) 1829*40230Sdonn { 1830*40230Sdonn k = letter(lp->primblock.namep->varname[0]); 1831*40230Sdonn ltype = impltype[ k ]; 1832*40230Sdonn } 1833*40230Sdonn if(rtype == TYUNKNOWN && rtag == TPRIM && rp->primblock.argsp == NULL) 1834*40230Sdonn { 1835*40230Sdonn k = letter(rp->primblock.namep->varname[0]); 1836*40230Sdonn rtype = impltype[ k ]; 1837*40230Sdonn } 1838*40230Sdonn 1839*40230Sdonn etype = cktype(opcode, ltype, rtype); 1840*40230Sdonn if(etype == TYERROR) 1841*40230Sdonn goto error; 1842*40230Sdonn 1843*40230Sdonn if(etype != TYUNKNOWN) 1844*40230Sdonn switch(opcode) 1845*40230Sdonn { 1846*40230Sdonn /* check for multiplication by 0 and 1 and addition to 0 */ 1847*40230Sdonn 1848*40230Sdonn case OPSTAR: 1849*40230Sdonn if( ISCONST(lp) ) 1850*40230Sdonn COMMUTE 1851*40230Sdonn 1852*40230Sdonn if( ISICON(rp) ) 1853*40230Sdonn { 1854*40230Sdonn if(rp->constblock.const.ci == 0) 1855*40230Sdonn { 1856*40230Sdonn if(etype == TYUNKNOWN) 1857*40230Sdonn break; 1858*40230Sdonn rp = mkconv(etype, rp); 1859*40230Sdonn goto retright; 1860*40230Sdonn } 1861*40230Sdonn if ((lp->tag == TEXPR) && 1862*40230Sdonn ((lp->exprblock.opcode == OPPLUS) || 1863*40230Sdonn (lp->exprblock.opcode == OPMINUS)) && 1864*40230Sdonn ISCONST(lp->exprblock.rightp) && 1865*40230Sdonn ISINT(lp->exprblock.rightp->constblock.vtype)) 1866*40230Sdonn { 1867*40230Sdonn q1 = mkexpr(OPSTAR, lp->exprblock.rightp, 1868*40230Sdonn cpexpr(rp)); 1869*40230Sdonn q = mkexpr(OPSTAR, lp->exprblock.leftp, rp); 1870*40230Sdonn q = mkexpr(lp->exprblock.opcode, q, q1); 1871*40230Sdonn free ((char *) lp); 1872*40230Sdonn return q; 1873*40230Sdonn } 1874*40230Sdonn else 1875*40230Sdonn goto mulop; 1876*40230Sdonn } 1877*40230Sdonn break; 1878*40230Sdonn 1879*40230Sdonn case OPSLASH: 1880*40230Sdonn case OPMOD: 1881*40230Sdonn if( ICONEQ(rp, 0) ) 1882*40230Sdonn { 1883*40230Sdonn err("attempted division by zero"); 1884*40230Sdonn rp = ICON(1); 1885*40230Sdonn break; 1886*40230Sdonn } 1887*40230Sdonn if(opcode == OPMOD) 1888*40230Sdonn break; 1889*40230Sdonn 1890*40230Sdonn 1891*40230Sdonn mulop: 1892*40230Sdonn if( ISICON(rp) ) 1893*40230Sdonn { 1894*40230Sdonn if(rp->constblock.const.ci == 1) 1895*40230Sdonn goto retleft; 1896*40230Sdonn 1897*40230Sdonn if(rp->constblock.const.ci == -1) 1898*40230Sdonn { 1899*40230Sdonn frexpr(rp); 1900*40230Sdonn return( mkexpr(OPNEG, lp, PNULL) ); 1901*40230Sdonn } 1902*40230Sdonn } 1903*40230Sdonn 1904*40230Sdonn if( ISSTAROP(lp) && ISICON(lp->exprblock.rightp) ) 1905*40230Sdonn { 1906*40230Sdonn if(opcode == OPSTAR) 1907*40230Sdonn e = mkexpr(OPSTAR, lp->exprblock.rightp, rp); 1908*40230Sdonn else if(ISICON(rp) && 1909*40230Sdonn (lp->exprblock.rightp->constblock.const.ci % 1910*40230Sdonn rp->constblock.const.ci) == 0) 1911*40230Sdonn e = mkexpr(OPSLASH, lp->exprblock.rightp, rp); 1912*40230Sdonn else break; 1913*40230Sdonn 1914*40230Sdonn e1 = lp->exprblock.leftp; 1915*40230Sdonn free( (charptr) lp ); 1916*40230Sdonn return( mkexpr(OPSTAR, e1, e) ); 1917*40230Sdonn } 1918*40230Sdonn break; 1919*40230Sdonn 1920*40230Sdonn 1921*40230Sdonn case OPPLUS: 1922*40230Sdonn if( ISCONST(lp) ) 1923*40230Sdonn COMMUTE 1924*40230Sdonn goto addop; 1925*40230Sdonn 1926*40230Sdonn case OPMINUS: 1927*40230Sdonn if( ICONEQ(lp, 0) ) 1928*40230Sdonn { 1929*40230Sdonn frexpr(lp); 1930*40230Sdonn return( mkexpr(OPNEG, rp, ENULL) ); 1931*40230Sdonn } 1932*40230Sdonn 1933*40230Sdonn if( ISCONST(rp) ) 1934*40230Sdonn { 1935*40230Sdonn opcode = OPPLUS; 1936*40230Sdonn consnegop(rp); 1937*40230Sdonn } 1938*40230Sdonn 1939*40230Sdonn addop: 1940*40230Sdonn if( ISICON(rp) ) 1941*40230Sdonn { 1942*40230Sdonn if(rp->constblock.const.ci == 0) 1943*40230Sdonn goto retleft; 1944*40230Sdonn if( ISPLUSOP(lp) && ISICON(lp->exprblock.rightp) ) 1945*40230Sdonn { 1946*40230Sdonn e = mkexpr(OPPLUS, lp->exprblock.rightp, rp); 1947*40230Sdonn e1 = lp->exprblock.leftp; 1948*40230Sdonn free( (charptr) lp ); 1949*40230Sdonn return( mkexpr(OPPLUS, e1, e) ); 1950*40230Sdonn } 1951*40230Sdonn } 1952*40230Sdonn break; 1953*40230Sdonn 1954*40230Sdonn 1955*40230Sdonn case OPPOWER: 1956*40230Sdonn break; 1957*40230Sdonn 1958*40230Sdonn case OPNEG: 1959*40230Sdonn if(ltag==TEXPR && lp->exprblock.opcode==OPNEG) 1960*40230Sdonn { 1961*40230Sdonn e = lp->exprblock.leftp; 1962*40230Sdonn free( (charptr) lp ); 1963*40230Sdonn return(e); 1964*40230Sdonn } 1965*40230Sdonn break; 1966*40230Sdonn 1967*40230Sdonn case OPNOT: 1968*40230Sdonn if(ltag==TEXPR && lp->exprblock.opcode==OPNOT) 1969*40230Sdonn { 1970*40230Sdonn e = lp->exprblock.leftp; 1971*40230Sdonn free( (charptr) lp ); 1972*40230Sdonn return(e); 1973*40230Sdonn } 1974*40230Sdonn break; 1975*40230Sdonn 1976*40230Sdonn case OPCALL: 1977*40230Sdonn case OPCCALL: 1978*40230Sdonn etype = ltype; 1979*40230Sdonn if(rp!=NULL && rp->listblock.listp==NULL) 1980*40230Sdonn { 1981*40230Sdonn free( (charptr) rp ); 1982*40230Sdonn rp = NULL; 1983*40230Sdonn } 1984*40230Sdonn break; 1985*40230Sdonn 1986*40230Sdonn case OPAND: 1987*40230Sdonn case OPOR: 1988*40230Sdonn if( ISCONST(lp) ) 1989*40230Sdonn COMMUTE 1990*40230Sdonn 1991*40230Sdonn if( ISCONST(rp) ) 1992*40230Sdonn { 1993*40230Sdonn if(rp->constblock.const.ci == 0) 1994*40230Sdonn if(opcode == OPOR) 1995*40230Sdonn goto retleft; 1996*40230Sdonn else 1997*40230Sdonn goto retright; 1998*40230Sdonn else if(opcode == OPOR) 1999*40230Sdonn goto retright; 2000*40230Sdonn else 2001*40230Sdonn goto retleft; 2002*40230Sdonn } 2003*40230Sdonn case OPLSHIFT: 2004*40230Sdonn if (ISICON(rp)) 2005*40230Sdonn { 2006*40230Sdonn if (rp->constblock.const.ci == 0) 2007*40230Sdonn goto retleft; 2008*40230Sdonn if ((lp->tag == TEXPR) && 2009*40230Sdonn ((lp->exprblock.opcode == OPPLUS) || 2010*40230Sdonn (lp->exprblock.opcode == OPMINUS)) && 2011*40230Sdonn ISICON(lp->exprblock.rightp)) 2012*40230Sdonn { 2013*40230Sdonn q1 = mkexpr(OPLSHIFT, lp->exprblock.rightp, 2014*40230Sdonn cpexpr(rp)); 2015*40230Sdonn q = mkexpr(OPLSHIFT, lp->exprblock.leftp, rp); 2016*40230Sdonn q = mkexpr(lp->exprblock.opcode, q, q1); 2017*40230Sdonn free((char *) lp); 2018*40230Sdonn return q; 2019*40230Sdonn } 2020*40230Sdonn } 2021*40230Sdonn 2022*40230Sdonn case OPEQV: 2023*40230Sdonn case OPNEQV: 2024*40230Sdonn 2025*40230Sdonn case OPBITAND: 2026*40230Sdonn case OPBITOR: 2027*40230Sdonn case OPBITXOR: 2028*40230Sdonn case OPBITNOT: 2029*40230Sdonn case OPRSHIFT: 2030*40230Sdonn 2031*40230Sdonn case OPLT: 2032*40230Sdonn case OPGT: 2033*40230Sdonn case OPLE: 2034*40230Sdonn case OPGE: 2035*40230Sdonn case OPEQ: 2036*40230Sdonn case OPNE: 2037*40230Sdonn 2038*40230Sdonn case OPCONCAT: 2039*40230Sdonn break; 2040*40230Sdonn case OPMIN: 2041*40230Sdonn case OPMAX: 2042*40230Sdonn 2043*40230Sdonn case OPASSIGN: 2044*40230Sdonn case OPPLUSEQ: 2045*40230Sdonn case OPSTAREQ: 2046*40230Sdonn 2047*40230Sdonn case OPCONV: 2048*40230Sdonn case OPADDR: 2049*40230Sdonn 2050*40230Sdonn case OPCOMMA: 2051*40230Sdonn case OPQUEST: 2052*40230Sdonn case OPCOLON: 2053*40230Sdonn 2054*40230Sdonn case OPPAREN: 2055*40230Sdonn break; 2056*40230Sdonn 2057*40230Sdonn default: 2058*40230Sdonn badop("mkexpr", opcode); 2059*40230Sdonn } 2060*40230Sdonn 2061*40230Sdonn e = (expptr) ALLOC(Exprblock); 2062*40230Sdonn e->exprblock.tag = TEXPR; 2063*40230Sdonn e->exprblock.opcode = opcode; 2064*40230Sdonn e->exprblock.vtype = etype; 2065*40230Sdonn e->exprblock.leftp = lp; 2066*40230Sdonn e->exprblock.rightp = rp; 2067*40230Sdonn if(ltag==TCONST && (rp==0 || rtag==TCONST) ) 2068*40230Sdonn e = fold(e); 2069*40230Sdonn return(e); 2070*40230Sdonn 2071*40230Sdonn retleft: 2072*40230Sdonn frexpr(rp); 2073*40230Sdonn return(lp); 2074*40230Sdonn 2075*40230Sdonn retright: 2076*40230Sdonn frexpr(lp); 2077*40230Sdonn return(rp); 2078*40230Sdonn 2079*40230Sdonn error: 2080*40230Sdonn frexpr(lp); 2081*40230Sdonn if(rp && opcode!=OPCALL && opcode!=OPCCALL) 2082*40230Sdonn frexpr(rp); 2083*40230Sdonn return( errnode() ); 2084*40230Sdonn } 2085*40230Sdonn 2086*40230Sdonn #define ERR(s) { errs = s; goto error; } 2087*40230Sdonn 2088*40230Sdonn cktype(op, lt, rt) 2089*40230Sdonn register int op, lt, rt; 2090*40230Sdonn { 2091*40230Sdonn char *errs; 2092*40230Sdonn 2093*40230Sdonn if(lt==TYERROR || rt==TYERROR) 2094*40230Sdonn goto error1; 2095*40230Sdonn 2096*40230Sdonn if(lt==TYUNKNOWN) 2097*40230Sdonn return(TYUNKNOWN); 2098*40230Sdonn if(rt==TYUNKNOWN) 2099*40230Sdonn if (op!=OPNOT && op!=OPBITNOT && op!=OPNEG && op!=OPCALL && 2100*40230Sdonn op!=OPCCALL && op!=OPADDR && op!=OPPAREN) 2101*40230Sdonn return(TYUNKNOWN); 2102*40230Sdonn 2103*40230Sdonn switch(op) 2104*40230Sdonn { 2105*40230Sdonn case OPPLUS: 2106*40230Sdonn case OPMINUS: 2107*40230Sdonn case OPSTAR: 2108*40230Sdonn case OPSLASH: 2109*40230Sdonn case OPPOWER: 2110*40230Sdonn case OPMOD: 2111*40230Sdonn if( ISNUMERIC(lt) && ISNUMERIC(rt) ) 2112*40230Sdonn return( maxtype(lt, rt) ); 2113*40230Sdonn ERR("nonarithmetic operand of arithmetic operator") 2114*40230Sdonn 2115*40230Sdonn case OPNEG: 2116*40230Sdonn if( ISNUMERIC(lt) ) 2117*40230Sdonn return(lt); 2118*40230Sdonn ERR("nonarithmetic operand of negation") 2119*40230Sdonn 2120*40230Sdonn case OPNOT: 2121*40230Sdonn if(lt == TYLOGICAL) 2122*40230Sdonn return(TYLOGICAL); 2123*40230Sdonn ERR("NOT of nonlogical") 2124*40230Sdonn 2125*40230Sdonn case OPAND: 2126*40230Sdonn case OPOR: 2127*40230Sdonn case OPEQV: 2128*40230Sdonn case OPNEQV: 2129*40230Sdonn if(lt==TYLOGICAL && rt==TYLOGICAL) 2130*40230Sdonn return(TYLOGICAL); 2131*40230Sdonn ERR("nonlogical operand of logical operator") 2132*40230Sdonn 2133*40230Sdonn case OPLT: 2134*40230Sdonn case OPGT: 2135*40230Sdonn case OPLE: 2136*40230Sdonn case OPGE: 2137*40230Sdonn case OPEQ: 2138*40230Sdonn case OPNE: 2139*40230Sdonn if(lt==TYCHAR || rt==TYCHAR || lt==TYLOGICAL || rt==TYLOGICAL) 2140*40230Sdonn { 2141*40230Sdonn if(lt != rt) 2142*40230Sdonn ERR("illegal comparison") 2143*40230Sdonn } 2144*40230Sdonn 2145*40230Sdonn else if( ISCOMPLEX(lt) || ISCOMPLEX(rt) ) 2146*40230Sdonn { 2147*40230Sdonn if(op!=OPEQ && op!=OPNE) 2148*40230Sdonn ERR("order comparison of complex data") 2149*40230Sdonn } 2150*40230Sdonn 2151*40230Sdonn else if( ! ISNUMERIC(lt) || ! ISNUMERIC(rt) ) 2152*40230Sdonn ERR("comparison of nonarithmetic data") 2153*40230Sdonn return(TYLOGICAL); 2154*40230Sdonn 2155*40230Sdonn case OPCONCAT: 2156*40230Sdonn if(lt==TYCHAR && rt==TYCHAR) 2157*40230Sdonn return(TYCHAR); 2158*40230Sdonn ERR("concatenation of nonchar data") 2159*40230Sdonn 2160*40230Sdonn case OPCALL: 2161*40230Sdonn case OPCCALL: 2162*40230Sdonn return(lt); 2163*40230Sdonn 2164*40230Sdonn case OPADDR: 2165*40230Sdonn return(TYADDR); 2166*40230Sdonn 2167*40230Sdonn case OPCONV: 2168*40230Sdonn if(ISCOMPLEX(lt)) 2169*40230Sdonn { 2170*40230Sdonn if(ISNUMERIC(rt)) 2171*40230Sdonn return(lt); 2172*40230Sdonn ERR("impossible conversion") 2173*40230Sdonn } 2174*40230Sdonn if(rt == 0) 2175*40230Sdonn return(0); 2176*40230Sdonn if(lt==TYCHAR && ISINT(rt) ) 2177*40230Sdonn return(TYCHAR); 2178*40230Sdonn case OPASSIGN: 2179*40230Sdonn case OPPLUSEQ: 2180*40230Sdonn case OPSTAREQ: 2181*40230Sdonn if( ISINT(lt) && rt==TYCHAR) 2182*40230Sdonn return(lt); 2183*40230Sdonn if(lt==TYCHAR || rt==TYCHAR || lt==TYLOGICAL || rt==TYLOGICAL) 2184*40230Sdonn if(op!=OPASSIGN || lt!=rt) 2185*40230Sdonn { 2186*40230Sdonn /* debug fprintf(diagfile, " lt=%d, rt=%d, op=%d\n", lt, rt, op); */ 2187*40230Sdonn /* debug fatal("impossible conversion. possible compiler bug"); */ 2188*40230Sdonn ERR("impossible conversion") 2189*40230Sdonn } 2190*40230Sdonn return(lt); 2191*40230Sdonn 2192*40230Sdonn case OPMIN: 2193*40230Sdonn case OPMAX: 2194*40230Sdonn case OPBITOR: 2195*40230Sdonn case OPBITAND: 2196*40230Sdonn case OPBITXOR: 2197*40230Sdonn case OPBITNOT: 2198*40230Sdonn case OPLSHIFT: 2199*40230Sdonn case OPRSHIFT: 2200*40230Sdonn case OPPAREN: 2201*40230Sdonn return(lt); 2202*40230Sdonn 2203*40230Sdonn case OPCOMMA: 2204*40230Sdonn case OPQUEST: 2205*40230Sdonn case OPCOLON: 2206*40230Sdonn return(rt); 2207*40230Sdonn 2208*40230Sdonn default: 2209*40230Sdonn badop("cktype", op); 2210*40230Sdonn } 2211*40230Sdonn error: err(errs); 2212*40230Sdonn error1: return(TYERROR); 2213*40230Sdonn } 2214*40230Sdonn 2215*40230Sdonn LOCAL expptr fold(e) 2216*40230Sdonn register expptr e; 2217*40230Sdonn { 2218*40230Sdonn Constp p; 2219*40230Sdonn register expptr lp, rp; 2220*40230Sdonn int etype, mtype, ltype, rtype, opcode; 2221*40230Sdonn int i, ll, lr; 2222*40230Sdonn char *q, *s; 2223*40230Sdonn union Constant lcon, rcon; 2224*40230Sdonn 2225*40230Sdonn opcode = e->exprblock.opcode; 2226*40230Sdonn etype = e->exprblock.vtype; 2227*40230Sdonn 2228*40230Sdonn lp = e->exprblock.leftp; 2229*40230Sdonn ltype = lp->headblock.vtype; 2230*40230Sdonn rp = e->exprblock.rightp; 2231*40230Sdonn 2232*40230Sdonn if(rp == 0) 2233*40230Sdonn switch(opcode) 2234*40230Sdonn { 2235*40230Sdonn case OPNOT: 2236*40230Sdonn lp->constblock.const.ci = ! lp->constblock.const.ci; 2237*40230Sdonn return(lp); 2238*40230Sdonn 2239*40230Sdonn case OPBITNOT: 2240*40230Sdonn lp->constblock.const.ci = ~ lp->constblock.const.ci; 2241*40230Sdonn return(lp); 2242*40230Sdonn 2243*40230Sdonn case OPNEG: 2244*40230Sdonn consnegop(lp); 2245*40230Sdonn return(lp); 2246*40230Sdonn 2247*40230Sdonn case OPCONV: 2248*40230Sdonn case OPADDR: 2249*40230Sdonn case OPPAREN: 2250*40230Sdonn return(e); 2251*40230Sdonn 2252*40230Sdonn default: 2253*40230Sdonn badop("fold", opcode); 2254*40230Sdonn } 2255*40230Sdonn 2256*40230Sdonn rtype = rp->headblock.vtype; 2257*40230Sdonn 2258*40230Sdonn p = ALLOC(Constblock); 2259*40230Sdonn p->tag = TCONST; 2260*40230Sdonn p->vtype = etype; 2261*40230Sdonn p->vleng = e->exprblock.vleng; 2262*40230Sdonn 2263*40230Sdonn switch(opcode) 2264*40230Sdonn { 2265*40230Sdonn case OPCOMMA: 2266*40230Sdonn case OPQUEST: 2267*40230Sdonn case OPCOLON: 2268*40230Sdonn return(e); 2269*40230Sdonn 2270*40230Sdonn case OPAND: 2271*40230Sdonn p->const.ci = lp->constblock.const.ci && 2272*40230Sdonn rp->constblock.const.ci; 2273*40230Sdonn break; 2274*40230Sdonn 2275*40230Sdonn case OPOR: 2276*40230Sdonn p->const.ci = lp->constblock.const.ci || 2277*40230Sdonn rp->constblock.const.ci; 2278*40230Sdonn break; 2279*40230Sdonn 2280*40230Sdonn case OPEQV: 2281*40230Sdonn p->const.ci = lp->constblock.const.ci == 2282*40230Sdonn rp->constblock.const.ci; 2283*40230Sdonn break; 2284*40230Sdonn 2285*40230Sdonn case OPNEQV: 2286*40230Sdonn p->const.ci = lp->constblock.const.ci != 2287*40230Sdonn rp->constblock.const.ci; 2288*40230Sdonn break; 2289*40230Sdonn 2290*40230Sdonn case OPBITAND: 2291*40230Sdonn p->const.ci = lp->constblock.const.ci & 2292*40230Sdonn rp->constblock.const.ci; 2293*40230Sdonn break; 2294*40230Sdonn 2295*40230Sdonn case OPBITOR: 2296*40230Sdonn p->const.ci = lp->constblock.const.ci | 2297*40230Sdonn rp->constblock.const.ci; 2298*40230Sdonn break; 2299*40230Sdonn 2300*40230Sdonn case OPBITXOR: 2301*40230Sdonn p->const.ci = lp->constblock.const.ci ^ 2302*40230Sdonn rp->constblock.const.ci; 2303*40230Sdonn break; 2304*40230Sdonn 2305*40230Sdonn case OPLSHIFT: 2306*40230Sdonn p->const.ci = lp->constblock.const.ci << 2307*40230Sdonn rp->constblock.const.ci; 2308*40230Sdonn break; 2309*40230Sdonn 2310*40230Sdonn case OPRSHIFT: 2311*40230Sdonn p->const.ci = lp->constblock.const.ci >> 2312*40230Sdonn rp->constblock.const.ci; 2313*40230Sdonn break; 2314*40230Sdonn 2315*40230Sdonn case OPCONCAT: 2316*40230Sdonn ll = lp->constblock.vleng->constblock.const.ci; 2317*40230Sdonn lr = rp->constblock.vleng->constblock.const.ci; 2318*40230Sdonn p->const.ccp = q = (char *) ckalloc(ll+lr); 2319*40230Sdonn p->vleng = ICON(ll+lr); 2320*40230Sdonn s = lp->constblock.const.ccp; 2321*40230Sdonn for(i = 0 ; i < ll ; ++i) 2322*40230Sdonn *q++ = *s++; 2323*40230Sdonn s = rp->constblock.const.ccp; 2324*40230Sdonn for(i = 0; i < lr; ++i) 2325*40230Sdonn *q++ = *s++; 2326*40230Sdonn break; 2327*40230Sdonn 2328*40230Sdonn 2329*40230Sdonn case OPPOWER: 2330*40230Sdonn if( ! ISINT(rtype) ) 2331*40230Sdonn return(e); 2332*40230Sdonn conspower(&(p->const), lp, rp->constblock.const.ci); 2333*40230Sdonn break; 2334*40230Sdonn 2335*40230Sdonn 2336*40230Sdonn default: 2337*40230Sdonn if(ltype == TYCHAR) 2338*40230Sdonn { 2339*40230Sdonn lcon.ci = cmpstr(lp->constblock.const.ccp, 2340*40230Sdonn rp->constblock.const.ccp, 2341*40230Sdonn lp->constblock.vleng->constblock.const.ci, 2342*40230Sdonn rp->constblock.vleng->constblock.const.ci); 2343*40230Sdonn rcon.ci = 0; 2344*40230Sdonn mtype = tyint; 2345*40230Sdonn } 2346*40230Sdonn else { 2347*40230Sdonn mtype = maxtype(ltype, rtype); 2348*40230Sdonn consconv(mtype, &lcon, ltype, &(lp->constblock.const) ); 2349*40230Sdonn consconv(mtype, &rcon, rtype, &(rp->constblock.const) ); 2350*40230Sdonn } 2351*40230Sdonn consbinop(opcode, mtype, &(p->const), &lcon, &rcon); 2352*40230Sdonn break; 2353*40230Sdonn } 2354*40230Sdonn 2355*40230Sdonn frexpr(e); 2356*40230Sdonn return( (expptr) p ); 2357*40230Sdonn } 2358*40230Sdonn 2359*40230Sdonn 2360*40230Sdonn 2361*40230Sdonn /* assign constant l = r , doing coercion */ 2362*40230Sdonn 2363*40230Sdonn consconv(lt, lv, rt, rv) 2364*40230Sdonn int lt, rt; 2365*40230Sdonn register union Constant *lv, *rv; 2366*40230Sdonn { 2367*40230Sdonn switch(lt) 2368*40230Sdonn { 2369*40230Sdonn case TYCHAR: 2370*40230Sdonn *(lv->ccp = (char *) ckalloc(1)) = rv->ci; 2371*40230Sdonn break; 2372*40230Sdonn 2373*40230Sdonn case TYSHORT: 2374*40230Sdonn case TYLONG: 2375*40230Sdonn if(rt == TYCHAR) 2376*40230Sdonn lv->ci = rv->ccp[0]; 2377*40230Sdonn else if( ISINT(rt) ) 2378*40230Sdonn lv->ci = rv->ci; 2379*40230Sdonn else lv->ci = rv->cd[0]; 2380*40230Sdonn break; 2381*40230Sdonn 2382*40230Sdonn case TYCOMPLEX: 2383*40230Sdonn case TYDCOMPLEX: 2384*40230Sdonn switch(rt) 2385*40230Sdonn { 2386*40230Sdonn case TYSHORT: 2387*40230Sdonn case TYLONG: 2388*40230Sdonn /* fall through and do real assignment of 2389*40230Sdonn first element 2390*40230Sdonn */ 2391*40230Sdonn case TYREAL: 2392*40230Sdonn case TYDREAL: 2393*40230Sdonn lv->cd[1] = 0; break; 2394*40230Sdonn case TYCOMPLEX: 2395*40230Sdonn case TYDCOMPLEX: 2396*40230Sdonn lv->cd[1] = rv->cd[1]; break; 2397*40230Sdonn } 2398*40230Sdonn 2399*40230Sdonn case TYREAL: 2400*40230Sdonn case TYDREAL: 2401*40230Sdonn if( ISINT(rt) ) 2402*40230Sdonn lv->cd[0] = rv->ci; 2403*40230Sdonn else lv->cd[0] = rv->cd[0]; 2404*40230Sdonn if( lt == TYREAL) 2405*40230Sdonn { 2406*40230Sdonn float f = lv->cd[0]; 2407*40230Sdonn lv->cd[0] = f; 2408*40230Sdonn } 2409*40230Sdonn break; 2410*40230Sdonn 2411*40230Sdonn case TYLOGICAL: 2412*40230Sdonn lv->ci = rv->ci; 2413*40230Sdonn break; 2414*40230Sdonn } 2415*40230Sdonn } 2416*40230Sdonn 2417*40230Sdonn 2418*40230Sdonn 2419*40230Sdonn consnegop(p) 2420*40230Sdonn register Constp p; 2421*40230Sdonn { 2422*40230Sdonn switch(p->vtype) 2423*40230Sdonn { 2424*40230Sdonn case TYSHORT: 2425*40230Sdonn case TYLONG: 2426*40230Sdonn p->const.ci = - p->const.ci; 2427*40230Sdonn break; 2428*40230Sdonn 2429*40230Sdonn case TYCOMPLEX: 2430*40230Sdonn case TYDCOMPLEX: 2431*40230Sdonn p->const.cd[1] = - p->const.cd[1]; 2432*40230Sdonn /* fall through and do the real parts */ 2433*40230Sdonn case TYREAL: 2434*40230Sdonn case TYDREAL: 2435*40230Sdonn p->const.cd[0] = - p->const.cd[0]; 2436*40230Sdonn break; 2437*40230Sdonn default: 2438*40230Sdonn badtype("consnegop", p->vtype); 2439*40230Sdonn } 2440*40230Sdonn } 2441*40230Sdonn 2442*40230Sdonn 2443*40230Sdonn 2444*40230Sdonn LOCAL conspower(powp, ap, n) 2445*40230Sdonn register union Constant *powp; 2446*40230Sdonn Constp ap; 2447*40230Sdonn ftnint n; 2448*40230Sdonn { 2449*40230Sdonn register int type; 2450*40230Sdonn union Constant x; 2451*40230Sdonn 2452*40230Sdonn switch(type = ap->vtype) /* pow = 1 */ 2453*40230Sdonn { 2454*40230Sdonn case TYSHORT: 2455*40230Sdonn case TYLONG: 2456*40230Sdonn powp->ci = 1; 2457*40230Sdonn break; 2458*40230Sdonn case TYCOMPLEX: 2459*40230Sdonn case TYDCOMPLEX: 2460*40230Sdonn powp->cd[1] = 0; 2461*40230Sdonn case TYREAL: 2462*40230Sdonn case TYDREAL: 2463*40230Sdonn powp->cd[0] = 1; 2464*40230Sdonn break; 2465*40230Sdonn default: 2466*40230Sdonn badtype("conspower", type); 2467*40230Sdonn } 2468*40230Sdonn 2469*40230Sdonn if(n == 0) 2470*40230Sdonn return; 2471*40230Sdonn if(n < 0) 2472*40230Sdonn { 2473*40230Sdonn if( ISINT(type) ) 2474*40230Sdonn { 2475*40230Sdonn if (ap->const.ci == 0) 2476*40230Sdonn err("zero raised to a negative power"); 2477*40230Sdonn else if (ap->const.ci == 1) 2478*40230Sdonn return; 2479*40230Sdonn else if (ap->const.ci == -1) 2480*40230Sdonn { 2481*40230Sdonn if (n < -2) 2482*40230Sdonn n = n + 2; 2483*40230Sdonn n = -n; 2484*40230Sdonn if (n % 2 == 1) 2485*40230Sdonn powp->ci = -1; 2486*40230Sdonn } 2487*40230Sdonn else 2488*40230Sdonn powp->ci = 0; 2489*40230Sdonn return; 2490*40230Sdonn } 2491*40230Sdonn n = - n; 2492*40230Sdonn consbinop(OPSLASH, type, &x, powp, &(ap->const)); 2493*40230Sdonn } 2494*40230Sdonn else 2495*40230Sdonn consbinop(OPSTAR, type, &x, powp, &(ap->const)); 2496*40230Sdonn 2497*40230Sdonn for( ; ; ) 2498*40230Sdonn { 2499*40230Sdonn if(n & 01) 2500*40230Sdonn consbinop(OPSTAR, type, powp, powp, &x); 2501*40230Sdonn if(n >>= 1) 2502*40230Sdonn consbinop(OPSTAR, type, &x, &x, &x); 2503*40230Sdonn else 2504*40230Sdonn break; 2505*40230Sdonn } 2506*40230Sdonn } 2507*40230Sdonn 2508*40230Sdonn 2509*40230Sdonn 2510*40230Sdonn /* do constant operation cp = a op b */ 2511*40230Sdonn 2512*40230Sdonn 2513*40230Sdonn LOCAL consbinop(opcode, type, cp, ap, bp) 2514*40230Sdonn int opcode, type; 2515*40230Sdonn register union Constant *ap, *bp, *cp; 2516*40230Sdonn { 2517*40230Sdonn int k; 2518*40230Sdonn double temp; 2519*40230Sdonn 2520*40230Sdonn switch(opcode) 2521*40230Sdonn { 2522*40230Sdonn case OPPLUS: 2523*40230Sdonn switch(type) 2524*40230Sdonn { 2525*40230Sdonn case TYSHORT: 2526*40230Sdonn case TYLONG: 2527*40230Sdonn cp->ci = ap->ci + bp->ci; 2528*40230Sdonn break; 2529*40230Sdonn case TYCOMPLEX: 2530*40230Sdonn case TYDCOMPLEX: 2531*40230Sdonn cp->cd[1] = ap->cd[1] + bp->cd[1]; 2532*40230Sdonn case TYREAL: 2533*40230Sdonn case TYDREAL: 2534*40230Sdonn cp->cd[0] = ap->cd[0] + bp->cd[0]; 2535*40230Sdonn break; 2536*40230Sdonn } 2537*40230Sdonn break; 2538*40230Sdonn 2539*40230Sdonn case OPMINUS: 2540*40230Sdonn switch(type) 2541*40230Sdonn { 2542*40230Sdonn case TYSHORT: 2543*40230Sdonn case TYLONG: 2544*40230Sdonn cp->ci = ap->ci - bp->ci; 2545*40230Sdonn break; 2546*40230Sdonn case TYCOMPLEX: 2547*40230Sdonn case TYDCOMPLEX: 2548*40230Sdonn cp->cd[1] = ap->cd[1] - bp->cd[1]; 2549*40230Sdonn case TYREAL: 2550*40230Sdonn case TYDREAL: 2551*40230Sdonn cp->cd[0] = ap->cd[0] - bp->cd[0]; 2552*40230Sdonn break; 2553*40230Sdonn } 2554*40230Sdonn break; 2555*40230Sdonn 2556*40230Sdonn case OPSTAR: 2557*40230Sdonn switch(type) 2558*40230Sdonn { 2559*40230Sdonn case TYSHORT: 2560*40230Sdonn case TYLONG: 2561*40230Sdonn cp->ci = ap->ci * bp->ci; 2562*40230Sdonn break; 2563*40230Sdonn case TYREAL: 2564*40230Sdonn case TYDREAL: 2565*40230Sdonn cp->cd[0] = ap->cd[0] * bp->cd[0]; 2566*40230Sdonn break; 2567*40230Sdonn case TYCOMPLEX: 2568*40230Sdonn case TYDCOMPLEX: 2569*40230Sdonn temp = ap->cd[0] * bp->cd[0] - 2570*40230Sdonn ap->cd[1] * bp->cd[1] ; 2571*40230Sdonn cp->cd[1] = ap->cd[0] * bp->cd[1] + 2572*40230Sdonn ap->cd[1] * bp->cd[0] ; 2573*40230Sdonn cp->cd[0] = temp; 2574*40230Sdonn break; 2575*40230Sdonn } 2576*40230Sdonn break; 2577*40230Sdonn case OPSLASH: 2578*40230Sdonn switch(type) 2579*40230Sdonn { 2580*40230Sdonn case TYSHORT: 2581*40230Sdonn case TYLONG: 2582*40230Sdonn cp->ci = ap->ci / bp->ci; 2583*40230Sdonn break; 2584*40230Sdonn case TYREAL: 2585*40230Sdonn case TYDREAL: 2586*40230Sdonn cp->cd[0] = ap->cd[0] / bp->cd[0]; 2587*40230Sdonn break; 2588*40230Sdonn case TYCOMPLEX: 2589*40230Sdonn case TYDCOMPLEX: 2590*40230Sdonn zdiv(cp,ap,bp); 2591*40230Sdonn break; 2592*40230Sdonn } 2593*40230Sdonn break; 2594*40230Sdonn 2595*40230Sdonn case OPMOD: 2596*40230Sdonn if( ISINT(type) ) 2597*40230Sdonn { 2598*40230Sdonn cp->ci = ap->ci % bp->ci; 2599*40230Sdonn break; 2600*40230Sdonn } 2601*40230Sdonn else 2602*40230Sdonn fatal("inline mod of noninteger"); 2603*40230Sdonn 2604*40230Sdonn default: /* relational ops */ 2605*40230Sdonn switch(type) 2606*40230Sdonn { 2607*40230Sdonn case TYSHORT: 2608*40230Sdonn case TYLONG: 2609*40230Sdonn if(ap->ci < bp->ci) 2610*40230Sdonn k = -1; 2611*40230Sdonn else if(ap->ci == bp->ci) 2612*40230Sdonn k = 0; 2613*40230Sdonn else k = 1; 2614*40230Sdonn break; 2615*40230Sdonn case TYREAL: 2616*40230Sdonn case TYDREAL: 2617*40230Sdonn if(ap->cd[0] < bp->cd[0]) 2618*40230Sdonn k = -1; 2619*40230Sdonn else if(ap->cd[0] == bp->cd[0]) 2620*40230Sdonn k = 0; 2621*40230Sdonn else k = 1; 2622*40230Sdonn break; 2623*40230Sdonn case TYCOMPLEX: 2624*40230Sdonn case TYDCOMPLEX: 2625*40230Sdonn if(ap->cd[0] == bp->cd[0] && 2626*40230Sdonn ap->cd[1] == bp->cd[1] ) 2627*40230Sdonn k = 0; 2628*40230Sdonn else k = 1; 2629*40230Sdonn break; 2630*40230Sdonn } 2631*40230Sdonn 2632*40230Sdonn switch(opcode) 2633*40230Sdonn { 2634*40230Sdonn case OPEQ: 2635*40230Sdonn cp->ci = (k == 0); 2636*40230Sdonn break; 2637*40230Sdonn case OPNE: 2638*40230Sdonn cp->ci = (k != 0); 2639*40230Sdonn break; 2640*40230Sdonn case OPGT: 2641*40230Sdonn cp->ci = (k == 1); 2642*40230Sdonn break; 2643*40230Sdonn case OPLT: 2644*40230Sdonn cp->ci = (k == -1); 2645*40230Sdonn break; 2646*40230Sdonn case OPGE: 2647*40230Sdonn cp->ci = (k >= 0); 2648*40230Sdonn break; 2649*40230Sdonn case OPLE: 2650*40230Sdonn cp->ci = (k <= 0); 2651*40230Sdonn break; 2652*40230Sdonn default: 2653*40230Sdonn badop ("consbinop", opcode); 2654*40230Sdonn } 2655*40230Sdonn break; 2656*40230Sdonn } 2657*40230Sdonn } 2658*40230Sdonn 2659*40230Sdonn 2660*40230Sdonn 2661*40230Sdonn 2662*40230Sdonn conssgn(p) 2663*40230Sdonn register expptr p; 2664*40230Sdonn { 2665*40230Sdonn if( ! ISCONST(p) ) 2666*40230Sdonn fatal( "sgn(nonconstant)" ); 2667*40230Sdonn 2668*40230Sdonn switch(p->headblock.vtype) 2669*40230Sdonn { 2670*40230Sdonn case TYSHORT: 2671*40230Sdonn case TYLONG: 2672*40230Sdonn if(p->constblock.const.ci > 0) return(1); 2673*40230Sdonn if(p->constblock.const.ci < 0) return(-1); 2674*40230Sdonn return(0); 2675*40230Sdonn 2676*40230Sdonn case TYREAL: 2677*40230Sdonn case TYDREAL: 2678*40230Sdonn if(p->constblock.const.cd[0] > 0) return(1); 2679*40230Sdonn if(p->constblock.const.cd[0] < 0) return(-1); 2680*40230Sdonn return(0); 2681*40230Sdonn 2682*40230Sdonn case TYCOMPLEX: 2683*40230Sdonn case TYDCOMPLEX: 2684*40230Sdonn return(p->constblock.const.cd[0]!=0 || p->constblock.const.cd[1]!=0); 2685*40230Sdonn 2686*40230Sdonn default: 2687*40230Sdonn badtype( "conssgn", p->constblock.vtype); 2688*40230Sdonn } 2689*40230Sdonn /* NOTREACHED */ 2690*40230Sdonn } 2691*40230Sdonn 2692*40230Sdonn char *powint[ ] = { "pow_ii", "pow_ri", "pow_di", "pow_ci", "pow_zi" }; 2693*40230Sdonn 2694*40230Sdonn 2695*40230Sdonn LOCAL expptr mkpower(p) 2696*40230Sdonn register expptr p; 2697*40230Sdonn { 2698*40230Sdonn register expptr q, lp, rp; 2699*40230Sdonn int ltype, rtype, mtype; 2700*40230Sdonn 2701*40230Sdonn lp = p->exprblock.leftp; 2702*40230Sdonn rp = p->exprblock.rightp; 2703*40230Sdonn ltype = lp->headblock.vtype; 2704*40230Sdonn rtype = rp->headblock.vtype; 2705*40230Sdonn 2706*40230Sdonn if(ISICON(rp)) 2707*40230Sdonn { 2708*40230Sdonn if(rp->constblock.const.ci == 0) 2709*40230Sdonn { 2710*40230Sdonn frexpr(p); 2711*40230Sdonn if( ISINT(ltype) ) 2712*40230Sdonn return( ICON(1) ); 2713*40230Sdonn else 2714*40230Sdonn { 2715*40230Sdonn expptr pp; 2716*40230Sdonn pp = mkconv(ltype, ICON(1)); 2717*40230Sdonn return( pp ); 2718*40230Sdonn } 2719*40230Sdonn } 2720*40230Sdonn if(rp->constblock.const.ci < 0) 2721*40230Sdonn { 2722*40230Sdonn if( ISINT(ltype) ) 2723*40230Sdonn { 2724*40230Sdonn frexpr(p); 2725*40230Sdonn err("integer**negative"); 2726*40230Sdonn return( errnode() ); 2727*40230Sdonn } 2728*40230Sdonn rp->constblock.const.ci = - rp->constblock.const.ci; 2729*40230Sdonn p->exprblock.leftp = lp = fixexpr(mkexpr(OPSLASH, ICON(1), lp)); 2730*40230Sdonn } 2731*40230Sdonn if(rp->constblock.const.ci == 1) 2732*40230Sdonn { 2733*40230Sdonn frexpr(rp); 2734*40230Sdonn free( (charptr) p ); 2735*40230Sdonn return(lp); 2736*40230Sdonn } 2737*40230Sdonn 2738*40230Sdonn if( ONEOF(ltype, MSKINT|MSKREAL) ) 2739*40230Sdonn { 2740*40230Sdonn p->exprblock.vtype = ltype; 2741*40230Sdonn return(p); 2742*40230Sdonn } 2743*40230Sdonn } 2744*40230Sdonn if( ISINT(rtype) ) 2745*40230Sdonn { 2746*40230Sdonn if(ltype==TYSHORT && rtype==TYSHORT && (!ISCONST(lp) || tyint==TYSHORT) ) 2747*40230Sdonn q = call2(TYSHORT, "pow_hh", lp, rp); 2748*40230Sdonn else { 2749*40230Sdonn if(ltype == TYSHORT) 2750*40230Sdonn { 2751*40230Sdonn ltype = TYLONG; 2752*40230Sdonn lp = mkconv(TYLONG,lp); 2753*40230Sdonn } 2754*40230Sdonn q = call2(ltype, powint[ltype-TYLONG], lp, mkconv(TYLONG, rp)); 2755*40230Sdonn } 2756*40230Sdonn } 2757*40230Sdonn else if( ISREAL( (mtype = maxtype(ltype,rtype)) )) 2758*40230Sdonn q = call2(mtype, "pow_dd", mkconv(TYDREAL,lp), mkconv(TYDREAL,rp)); 2759*40230Sdonn else { 2760*40230Sdonn q = call2(TYDCOMPLEX, "pow_zz", 2761*40230Sdonn mkconv(TYDCOMPLEX,lp), mkconv(TYDCOMPLEX,rp)); 2762*40230Sdonn if(mtype == TYCOMPLEX) 2763*40230Sdonn q = mkconv(TYCOMPLEX, q); 2764*40230Sdonn } 2765*40230Sdonn free( (charptr) p ); 2766*40230Sdonn return(q); 2767*40230Sdonn } 2768*40230Sdonn 2769*40230Sdonn 2770*40230Sdonn 2771*40230Sdonn /* Complex Division. Same code as in Runtime Library 2772*40230Sdonn */ 2773*40230Sdonn 2774*40230Sdonn struct dcomplex { double dreal, dimag; }; 2775*40230Sdonn 2776*40230Sdonn 2777*40230Sdonn LOCAL zdiv(c, a, b) 2778*40230Sdonn register struct dcomplex *a, *b, *c; 2779*40230Sdonn { 2780*40230Sdonn double ratio, den; 2781*40230Sdonn double abr, abi; 2782*40230Sdonn 2783*40230Sdonn if( (abr = b->dreal) < 0.) 2784*40230Sdonn abr = - abr; 2785*40230Sdonn if( (abi = b->dimag) < 0.) 2786*40230Sdonn abi = - abi; 2787*40230Sdonn if( abr <= abi ) 2788*40230Sdonn { 2789*40230Sdonn if(abi == 0) 2790*40230Sdonn fatal("complex division by zero"); 2791*40230Sdonn ratio = b->dreal / b->dimag ; 2792*40230Sdonn den = b->dimag * (1 + ratio*ratio); 2793*40230Sdonn c->dreal = (a->dreal*ratio + a->dimag) / den; 2794*40230Sdonn c->dimag = (a->dimag*ratio - a->dreal) / den; 2795*40230Sdonn } 2796*40230Sdonn 2797*40230Sdonn else 2798*40230Sdonn { 2799*40230Sdonn ratio = b->dimag / b->dreal ; 2800*40230Sdonn den = b->dreal * (1 + ratio*ratio); 2801*40230Sdonn c->dreal = (a->dreal + a->dimag*ratio) / den; 2802*40230Sdonn c->dimag = (a->dimag - a->dreal*ratio) / den; 2803*40230Sdonn } 2804*40230Sdonn 2805*40230Sdonn } 2806*40230Sdonn 2807*40230Sdonn expptr oftwo(e) 2808*40230Sdonn expptr e; 2809*40230Sdonn { 2810*40230Sdonn int val,res; 2811*40230Sdonn 2812*40230Sdonn if (! ISCONST (e)) 2813*40230Sdonn return (0); 2814*40230Sdonn 2815*40230Sdonn val = e->constblock.const.ci; 2816*40230Sdonn switch (val) 2817*40230Sdonn { 2818*40230Sdonn case 2: res = 1; break; 2819*40230Sdonn case 4: res = 2; break; 2820*40230Sdonn case 8: res = 3; break; 2821*40230Sdonn case 16: res = 4; break; 2822*40230Sdonn case 32: res = 5; break; 2823*40230Sdonn case 64: res = 6; break; 2824*40230Sdonn case 128: res = 7; break; 2825*40230Sdonn case 256: res = 8; break; 2826*40230Sdonn default: return (0); 2827*40230Sdonn } 2828*40230Sdonn return (ICON (res)); 2829*40230Sdonn } 2830