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