+ }
+singhang:
+ /*
+ * take this expression off the tree list and
+ * hang it on the list of singletons.
+ */
+ ip = el[2];
+ el[2] = singp;
+ singp = r[2];
+ r[2] = ip;
+ csetp -> singcnt++;
+ }
+ }
+ codeon();
+# ifdef PC
+ if ( pairp != NIL ) {
+ for ( el = pairp ; el[2] != NIL ; el = el[2] ) /* void */;
+ el[2] = singp;
+ r[2] = pairp;
+ } else {
+ r[2] = singp;
+ }
+# endif PC
+# ifdef OBJ
+ if ( singp != NIL ) {
+ for ( el = singp ; el[2] != NIL ; el = el[2] ) /* void */;
+ el[2] = pairp;
+ r[2] = singp;
+ } else {
+ r[2] = pairp;
+ }
+# endif OBJ
+ if ( csetp -> csettype == NIL ) {
+ csetp -> comptime = TRUE;
+ }
+ return csetp -> comptime;
+}
+
+#define BITSPERLONG ( sizeof( long ) * BITSPERBYTE )
+ /*
+ * mask[i] has the low i bits turned off.
+ */
+long mask[] = {
+ 0xffffffff , 0xfffffffe , 0xfffffffc , 0xfffffff8 ,
+ 0xfffffff0 , 0xffffffe0 , 0xffffffc0 , 0xffffff80 ,
+ 0xffffff00 , 0xfffffe00 , 0xfffffc00 , 0xfffff800 ,
+ 0xfffff000 , 0xffffe000 , 0xffffc000 , 0xffff8000 ,
+ 0xffff0000 , 0xfffe0000 , 0xfffc0000 , 0xfff80000 ,
+ 0xfff00000 , 0xffe00000 , 0xffc00000 , 0xff800000 ,
+ 0xff000000 , 0xfe000000 , 0xfc000000 , 0xf8000000 ,
+ 0xf0000000 , 0xe0000000 , 0xc0000000 , 0x80000000 ,
+ 0x00000000
+ };
+ /*
+ * given a csetstr, either
+ * put out a compile time constant set and an lvalue to it.
+ * or
+ * put out rvalues for the singletons and the pairs
+ * and counts of each.
+ */
+postcset( r , csetp )
+ int *r;
+ struct csetstr *csetp;
+ {
+ register int *el;
+ register int *e;
+ int lower;
+ int upper;
+ int lowerdiv;
+ int lowermod;
+ int upperdiv;
+ int uppermod;
+ int label;
+ long *lp;
+ long *limit;
+ long tempset[ ( MAXSET / BITSPERLONG ) + 1 ];
+ long temp;
+ char labelname[ BUFSIZ ];
+
+ if ( csetp -> comptime ) {
+ setran( ( csetp -> csettype ) -> type );
+ limit = &tempset[ ( set.uprbp / BITSPERLONG ) + 1 ];
+ for ( lp = &tempset[0] ; lp < limit ; lp++ ) {
+ *lp = 0;
+ }
+ for ( el = r[2] ; el != NIL ; el = el[2] ) {
+ e = el[1];
+ if ( e[0] == T_RANG ) {
+ constval( e[1] );
+ lower = (long) con.crval;
+ constval( e[2] );
+ upper = (long) con.crval;
+ if ( upper < lower ) {
+ continue;
+ }
+ lowerdiv = ( lower - set.lwrb ) / BITSPERLONG;
+ lowermod = ( lower - set.lwrb ) % BITSPERLONG;
+ upperdiv = ( upper - set.lwrb ) / BITSPERLONG;
+ uppermod = ( upper - set.lwrb ) % BITSPERLONG;
+ temp = mask[ lowermod ];
+ if ( lowerdiv == upperdiv ) {
+ temp &= ~mask[ uppermod + 1 ];
+ }
+ tempset[ lowerdiv ] |= temp;
+ limit = &tempset[ upperdiv-1 ];
+ for ( lp = &tempset[ lowerdiv+1 ] ; lp <= limit ; lp++ ) {
+ *lp |= ~0;
+ }
+ if ( lowerdiv != upperdiv ) {
+ tempset[ upperdiv ] |= ~mask[ uppermod + 1 ];
+ }
+ } else {
+ constval( e );
+ lowerdiv = ( ((long)con.crval) - set.lwrb ) / BITSPERLONG;
+ lowermod = ( ((long)con.crval) - set.lwrb ) % BITSPERLONG;
+ tempset[ lowerdiv ] |= ( 1 << lowermod );
+ }
+ }
+ if ( cgenflg )
+ return;
+# ifdef PC
+ putprintf( " .data" , 0 );
+ putprintf( " .align 2" , 0 );
+ label = getlab();
+ putlab( label );
+ lp = &( tempset[0] );
+ limit = &tempset[ ( set.uprbp / BITSPERLONG ) + 1 ];
+ while ( lp < limit ) {
+ putprintf( " .long 0x%x" , 1 , *lp ++ );
+ for ( temp = 2 ; ( temp <= 8 ) && lp < limit ; temp ++ ) {
+ putprintf( ",0x%x" , 1 , *lp++ );
+ }
+ putprintf( "" , 0 );
+ }
+ putprintf( " .text" , 0 );
+ sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
+ putleaf( P2ICON , 0 , 0 , P2PTR | P2STRTY , labelname );
+# endif PC
+# ifdef OBJ
+ put( 2, O_CON, (set.uprbp / BITSPERLONG + 1) *
+ (BITSPERLONG / BITSPERBYTE));
+ lp = &( tempset[0] );
+ limit = &tempset[ ( set.uprbp / BITSPERLONG ) + 1 ];
+ while ( lp < limit ) {
+ put( 2, O_CASE4, *lp ++);
+ }
+# endif OBJ
+ } else {
+# ifdef PC
+ putleaf( P2ICON , csetp -> paircnt , 0 , P2INT , 0 );
+ putop( P2LISTOP , P2INT );
+ putleaf( P2ICON , csetp -> singcnt , 0 , P2INT , 0 );
+ putop( P2LISTOP , P2INT );
+ for ( el = r[2] ; el != NIL ; el = el[2] ) {
+ e = el[1];
+ if ( e[0] == T_RANG ) {
+ rvalue( e[2] , NIL , RREQ );
+ putop( P2LISTOP , P2INT );
+ rvalue( e[1] , NIL , RREQ );
+ putop( P2LISTOP , P2INT );
+ } else {
+ rvalue( e , NIL , RREQ );
+ putop( P2LISTOP , P2INT );
+ }
+ }
+# endif PC
+# ifdef OBJ
+ for ( el = r[2] ; el != NIL ; el = el[2] ) {
+ e = el[1];
+ if ( e[0] == T_RANG ) {
+ stkrval( e[2] , NIL , RREQ );
+ stkrval( e[1] , NIL , RREQ );
+ } else {
+ stkrval( e , NIL , RREQ );
+ }