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