|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: ! 3: static char sccsid[] = "@(#)cset.c 1.7 2/1/83"; ! 4: ! 5: #include "whoami.h" ! 6: #include "0.h" ! 7: #include "tree.h" ! 8: #include "opcode.h" ! 9: #include "objfmt.h" ! 10: #ifdef PC ! 11: #include "pc.h" ! 12: #include "pcops.h" ! 13: #include "align.h" ! 14: #endif PC ! 15: ! 16: /* ! 17: * CONSETS causes compile time constant sets to be constructed here. ! 18: * ! 19: * COMPSETSZE defines the maximum number of longs to be used in ! 20: * constant set construction ! 21: */ ! 22: #define CONSETS ! 23: #define COMPSETSZE 10 ! 24: ! 25: #define BITSPERBYTE 8 ! 26: #define BITSPERLONG 32 ! 27: #define LG2BITSBYTE 3 ! 28: #define MSKBITSBYTE 0x07 ! 29: #define LG2BITSLONG 5 ! 30: #define MSKBITSLONG 0x1f ! 31: ! 32: /* ! 33: * rummage through a `constant' set (i.e. anything within [ ]'s) tree ! 34: * and decide if this is a compile time constant set or a runtime set. ! 35: * this information is returned in a structure passed from the caller. ! 36: * while rummaging, this also reorders the tree so that all ranges ! 37: * preceed all singletons. ! 38: */ ! 39: bool ! 40: precset( r , settype , csetp ) ! 41: int *r; ! 42: struct nl *settype; ! 43: struct csetstr *csetp; ! 44: { ! 45: register int *e; ! 46: register struct nl *t; ! 47: register struct nl *exptype; ! 48: register int *el; ! 49: register int *pairp; ! 50: register int *singp; ! 51: int *ip; ! 52: int lower; ! 53: int upper; ! 54: bool setofint; ! 55: ! 56: csetp -> csettype = NIL; ! 57: csetp -> paircnt = 0; ! 58: csetp -> singcnt = 0; ! 59: csetp -> comptime = TRUE; ! 60: setofint = FALSE; ! 61: if ( settype != NIL ) { ! 62: if ( settype -> class == SET ) { ! 63: /* ! 64: * the easy case, we are told the type of the set. ! 65: */ ! 66: exptype = settype -> type; ! 67: } else { ! 68: /* ! 69: * we are told the type, but it's not a set ! 70: * supposedly possible if someone tries ! 71: * e.g string context [1,2] = 'abc' ! 72: */ ! 73: error("Constant set involved in non set context"); ! 74: return csetp -> comptime; ! 75: } ! 76: } else { ! 77: /* ! 78: * So far we have no indication ! 79: * of what the set type should be. ! 80: * We "look ahead" and try to infer ! 81: * The type of the constant set ! 82: * by evaluating one of its members. ! 83: */ ! 84: e = r[2]; ! 85: if (e == NIL) { ! 86: /* ! 87: * tentative for [], return type of `intset' ! 88: */ ! 89: settype = lookup( intset ); ! 90: if ( settype == NIL ) { ! 91: panic( "empty set" ); ! 92: } ! 93: settype = settype -> type; ! 94: if ( settype == NIL ) { ! 95: return csetp -> comptime; ! 96: } ! 97: if ( isnta( settype , "t" ) ) { ! 98: error("Set default type \"intset\" is not a set"); ! 99: return csetp -> comptime; ! 100: } ! 101: csetp -> csettype = settype; ! 102: setran( settype -> type ); ! 103: if (((set.uprbp + 1) >> LG2BITSLONG) >= COMPSETSZE) ! 104: csetp -> comptime = FALSE; ! 105: return csetp -> comptime; ! 106: } ! 107: e = e[1]; ! 108: if (e == NIL) { ! 109: return csetp -> comptime; ! 110: } ! 111: if (e[0] == T_RANG) { ! 112: e = e[1]; ! 113: } ! 114: codeoff(); ! 115: t = rvalue(e, NIL , RREQ ); ! 116: codeon(); ! 117: if (t == NIL) { ! 118: return csetp -> comptime; ! 119: } ! 120: /* ! 121: * The type of the set, settype, is ! 122: * deemed to be a set of the base type ! 123: * of t, which we call exptype. If, ! 124: * however, this would involve a ! 125: * "set of integer", we cop out ! 126: * and use "intset"'s current scoped ! 127: * type instead. ! 128: */ ! 129: if (isa(t, "r")) { ! 130: error("Sets may not have 'real' elements"); ! 131: return csetp -> comptime; ! 132: } ! 133: if (isnta(t, "bcsi")) { ! 134: error("Set elements must be scalars, not %ss", nameof(t)); ! 135: return csetp -> comptime; ! 136: } ! 137: if (isa(t, "i")) { ! 138: settype = lookup(intset); ! 139: if (settype == NIL) ! 140: panic("intset"); ! 141: settype = settype->type; ! 142: if (settype == NIL) ! 143: return csetp -> comptime; ! 144: if (isnta(settype, "t")) { ! 145: error("Set default type \"intset\" is not a set"); ! 146: return csetp -> comptime; ! 147: } ! 148: exptype = settype->type; ! 149: /* ! 150: * say we are doing an intset ! 151: * but, if we get out of range errors for intset ! 152: * we punt constructing the set at compile time. ! 153: */ ! 154: setofint = TRUE; ! 155: } else { ! 156: exptype = t->type; ! 157: if (exptype == NIL) ! 158: return csetp -> comptime; ! 159: if (exptype->class != RANGE) ! 160: exptype = exptype->type; ! 161: settype = defnl(0, SET, exptype, 0); ! 162: } ! 163: } ! 164: csetp -> csettype = settype; ! 165: # ifndef CONSETS ! 166: csetp -> comptime = FALSE; ! 167: # endif CONSETS ! 168: setran( exptype ); ! 169: if (((set.uprbp + 1) >> LG2BITSLONG) >= COMPSETSZE) ! 170: csetp -> comptime = FALSE; ! 171: lower = set.lwrb; ! 172: upper = set.lwrb + set.uprbp; ! 173: pairp = NIL; ! 174: singp = NIL; ! 175: codeoff(); ! 176: while ( el = r[2] ) { ! 177: e = el[1]; ! 178: if (e == NIL) { ! 179: /* ! 180: * don't hang this one anywhere. ! 181: */ ! 182: csetp -> csettype = NIL; ! 183: r[2] = el[2]; ! 184: continue; ! 185: } ! 186: if (e[0] == T_RANG) { ! 187: if ( csetp -> comptime && constval( e[2] ) ) { ! 188: #ifdef CONSETS ! 189: t = con.ctype; ! 190: if ( con.crval < lower || con.crval > upper ) { ! 191: if ( setofint ) { ! 192: csetp -> comptime = FALSE; ! 193: } else { ! 194: error("Range upper bound of %D out of set bounds" , ((long)con.crval) ); ! 195: csetp -> csettype = NIL; ! 196: } ! 197: } ! 198: #endif CONSETS ! 199: } else { ! 200: csetp -> comptime = FALSE; ! 201: t = rvalue(e[2], NIL , RREQ ); ! 202: if (t == NIL) { ! 203: rvalue(e[1], NIL , RREQ ); ! 204: goto pairhang; ! 205: } ! 206: } ! 207: if (incompat(t, exptype, e[2])) { ! 208: cerror("Upper bound of element type clashed with set type in constant set"); ! 209: } ! 210: if ( csetp -> comptime && constval( e[1] ) ) { ! 211: #ifdef CONSETS ! 212: t = con.ctype; ! 213: if ( con.crval < lower || con.crval > upper ) { ! 214: if ( setofint ) { ! 215: csetp -> comptime = FALSE; ! 216: } else { ! 217: error("Range lower bound of %D out of set bounds" , ((long)con.crval) ); ! 218: csetp -> csettype = NIL; ! 219: } ! 220: } ! 221: #endif CONSETS ! 222: } else { ! 223: csetp -> comptime = FALSE; ! 224: t = rvalue(e[1], NIL , RREQ ); ! 225: if (t == NIL) { ! 226: goto pairhang; ! 227: } ! 228: } ! 229: if (incompat(t, exptype, e[1])) { ! 230: cerror("Lower bound of element type clashed with set type in constant set"); ! 231: } ! 232: pairhang: ! 233: /* ! 234: * remove this range from the tree list and ! 235: * hang it on the pairs list. ! 236: */ ! 237: ip = el[2]; ! 238: el[2] = pairp; ! 239: pairp = r[2]; ! 240: r[2] = ip; ! 241: csetp -> paircnt++; ! 242: } else { ! 243: if ( csetp -> comptime && constval( e ) ) { ! 244: #ifdef CONSETS ! 245: t = con.ctype; ! 246: if ( con.crval < lower || con.crval > upper ) { ! 247: if ( setofint ) { ! 248: csetp -> comptime = FALSE; ! 249: } else { ! 250: error("Value of %D out of set bounds" , ((long)con.crval) ); ! 251: csetp -> csettype = NIL; ! 252: } ! 253: } ! 254: #endif CONSETS ! 255: } else { ! 256: csetp -> comptime = FALSE; ! 257: t = rvalue((int *) e, NLNIL , RREQ ); ! 258: if (t == NIL) { ! 259: goto singhang; ! 260: } ! 261: } ! 262: if (incompat(t, exptype, e)) { ! 263: cerror("Element type clashed with set type in constant set"); ! 264: } ! 265: singhang: ! 266: /* ! 267: * take this expression off the tree list and ! 268: * hang it on the list of singletons. ! 269: */ ! 270: ip = el[2]; ! 271: el[2] = singp; ! 272: singp = r[2]; ! 273: r[2] = ip; ! 274: csetp -> singcnt++; ! 275: } ! 276: } ! 277: codeon(); ! 278: # ifdef PC ! 279: if ( pairp != NIL ) { ! 280: for ( el = pairp ; el[2] != NIL ; el = el[2] ) /* void */; ! 281: el[2] = singp; ! 282: r[2] = pairp; ! 283: } else { ! 284: r[2] = singp; ! 285: } ! 286: # endif PC ! 287: # ifdef OBJ ! 288: if ( singp != NIL ) { ! 289: for ( el = singp ; el[2] != NIL ; el = el[2] ) /* void */; ! 290: el[2] = pairp; ! 291: r[2] = singp; ! 292: } else { ! 293: r[2] = pairp; ! 294: } ! 295: # endif OBJ ! 296: if ( csetp -> csettype == NIL ) { ! 297: csetp -> comptime = TRUE; ! 298: } ! 299: return csetp -> comptime; ! 300: } ! 301: ! 302: #ifdef CONSETS ! 303: /* ! 304: * mask[i] has the low i bits turned off. ! 305: */ ! 306: long mask[] = { ! 307: # ifdef DEC11 ! 308: 0xffffffff , 0xfffffffe , 0xfffffffc , 0xfffffff8 , ! 309: 0xfffffff0 , 0xffffffe0 , 0xffffffc0 , 0xffffff80 , ! 310: 0xffffff00 , 0xfffffe00 , 0xfffffc00 , 0xfffff800 , ! 311: 0xfffff000 , 0xffffe000 , 0xffffc000 , 0xffff8000 , ! 312: 0xffff0000 , 0xfffe0000 , 0xfffc0000 , 0xfff80000 , ! 313: 0xfff00000 , 0xffe00000 , 0xffc00000 , 0xff800000 , ! 314: 0xff000000 , 0xfe000000 , 0xfc000000 , 0xf8000000 , ! 315: 0xf0000000 , 0xe0000000 , 0xc0000000 , 0x80000000 , ! 316: 0x00000000 ! 317: # else ! 318: 0xffffffff , 0xfeffffff , 0xfcffffff , 0xf8ffffff , ! 319: 0xf0ffffff , 0xe0ffffff , 0xc0ffffff , 0x80ffffff , ! 320: 0x00ffffff , 0x00feffff , 0x00fcffff , 0x00f8ffff , ! 321: 0x00f0ffff , 0x00e0ffff , 0x00c0ffff , 0x0080ffff , ! 322: 0x0000ffff , 0x0000feff , 0x0000fcff , 0x0000f8ff , ! 323: 0x0000f0ff , 0x0000e0ff , 0x0000c0ff , 0x000080ff , ! 324: 0x000000ff , 0x000000fe , 0x000000fc , 0x000000f8 , ! 325: 0x000000f0 , 0x000000e0 , 0x000000c0 , 0x00000080 , ! 326: 0x00000000 ! 327: # endif DEC11 ! 328: }; ! 329: /* ! 330: * given a csetstr, either ! 331: * put out a compile time constant set and an lvalue to it. ! 332: * or ! 333: * put out rvalues for the singletons and the pairs ! 334: * and counts of each. ! 335: */ ! 336: #endif CONSETS ! 337: postcset( r , csetp ) ! 338: int *r; ! 339: struct csetstr *csetp; ! 340: { ! 341: register int *el; ! 342: register int *e; ! 343: int lower; ! 344: int upper; ! 345: int lowerdiv; ! 346: int lowermod; ! 347: int upperdiv; ! 348: int uppermod; ! 349: int label; ! 350: long *lp; ! 351: long *limit; ! 352: long tempset[ COMPSETSZE ]; ! 353: long temp; ! 354: char *cp; ! 355: # ifdef PC ! 356: char labelname[ BUFSIZ ]; ! 357: # endif PC ! 358: ! 359: if ( csetp -> comptime ) { ! 360: #ifdef CONSETS ! 361: setran( ( csetp -> csettype ) -> type ); ! 362: limit = &tempset[ ( set.uprbp >> LG2BITSLONG ) + 1 ]; ! 363: for ( lp = &tempset[0] ; lp < limit ; lp++ ) { ! 364: *lp = 0; ! 365: } ! 366: for ( el = r[2] ; el != NIL ; el = el[2] ) { ! 367: e = el[1]; ! 368: if ( e[0] == T_RANG ) { ! 369: constval( e[1] ); ! 370: lower = con.crval; ! 371: constval( e[2] ); ! 372: upper = con.crval; ! 373: if ( upper < lower ) { ! 374: continue; ! 375: } ! 376: lowerdiv = ( lower - set.lwrb ) >> LG2BITSLONG; ! 377: lowermod = ( lower - set.lwrb ) & MSKBITSLONG; ! 378: upperdiv = ( upper - set.lwrb ) >> LG2BITSLONG; ! 379: uppermod = ( upper - set.lwrb ) & MSKBITSLONG; ! 380: temp = mask[ lowermod ]; ! 381: if ( lowerdiv == upperdiv ) { ! 382: temp &= ~mask[ uppermod + 1 ]; ! 383: } ! 384: tempset[ lowerdiv ] |= temp; ! 385: limit = &tempset[ upperdiv-1 ]; ! 386: for ( lp = &tempset[ lowerdiv+1 ] ; lp <= limit ; lp++ ) { ! 387: *lp |= 0xffffffff; ! 388: } ! 389: if ( lowerdiv != upperdiv ) { ! 390: tempset[ upperdiv ] |= ~mask[ uppermod + 1 ]; ! 391: } ! 392: } else { ! 393: constval( e ); ! 394: temp = con.crval - set.lwrb; ! 395: cp = (char *)tempset; ! 396: cp[temp >> LG2BITSBYTE] |= (1 << (temp & MSKBITSBYTE)); ! 397: } ! 398: } ! 399: if ( !CGENNING ) ! 400: return; ! 401: # ifdef PC ! 402: label = getlab(); ! 403: putprintf(" .data" , 0 ); ! 404: aligndot(A_SET); ! 405: putlab( label ); ! 406: lp = &( tempset[0] ); ! 407: limit = &tempset[ ( set.uprbp >> LG2BITSLONG ) + 1 ]; ! 408: while (lp < limit) { ! 409: putprintf(" .long 0x%x", 1, *lp++); ! 410: for (temp = 2 ; temp <= 8 && lp < limit ; temp++) { ! 411: putprintf(",0x%x", 1, *lp++); ! 412: } ! 413: putprintf("", 0); ! 414: } ! 415: putprintf(" .text", 0); ! 416: sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label ); ! 417: putleaf( P2ICON , 0 , 0 , P2PTR | P2STRTY , labelname ); ! 418: # endif PC ! 419: # ifdef OBJ ! 420: put(2, O_CON, (int)(((set.uprbp >> LG2BITSLONG) + 1) * ! 421: (BITSPERLONG >> LG2BITSBYTE))); ! 422: lp = &( tempset[0] ); ! 423: limit = &tempset[ ( set.uprbp >> LG2BITSLONG ) + 1 ]; ! 424: while ( lp < limit ) { ! 425: put(2, O_CASE4, *lp ++); ! 426: } ! 427: # endif OBJ ! 428: #else ! 429: panic("const cset"); ! 430: #endif CONSETS ! 431: } else { ! 432: # ifdef PC ! 433: putleaf( P2ICON , csetp -> paircnt , 0 , P2INT , 0 ); ! 434: putop( P2LISTOP , P2INT ); ! 435: putleaf( P2ICON , csetp -> singcnt , 0 , P2INT , 0 ); ! 436: putop( P2LISTOP , P2INT ); ! 437: for ( el = r[2] ; el != NIL ; el = el[2] ) { ! 438: e = el[1]; ! 439: if ( e[0] == T_RANG ) { ! 440: rvalue( e[2] , NIL , RREQ ); ! 441: putop( P2LISTOP , P2INT ); ! 442: rvalue( e[1] , NIL , RREQ ); ! 443: putop( P2LISTOP , P2INT ); ! 444: } else { ! 445: rvalue( e , NIL , RREQ ); ! 446: putop( P2LISTOP , P2INT ); ! 447: } ! 448: } ! 449: # endif PC ! 450: # ifdef OBJ ! 451: for ( el = r[2] ; el != NIL ; el = el[2] ) { ! 452: e = el[1]; ! 453: if ( e[0] == T_RANG ) { ! 454: stkrval( e[1] , NIL , RREQ ); ! 455: stkrval( e[2] , NIL , RREQ ); ! 456: } else { ! 457: stkrval( e , NIL , RREQ ); ! 458: } ! 459: } ! 460: put(2 , O_CON24 , (int)csetp -> singcnt ); ! 461: put(2 , O_CON24 , (int)csetp -> paircnt ); ! 462: # endif OBJ ! 463: } ! 464: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.