+ /*
+ * direct switch
+ */
+directsw( ctab , count )
+ struct ct *ctab;
+ int count;
+{
+ int fromlabel = getlab();
+ long i;
+ long j;
+
+ putprintf( " casel %s,$%d,$%d" , 0 , FORCENAME ,
+ ctab[1].cconst , ctab[ count ].cconst - ctab[1].cconst );
+ putlab( fromlabel );
+ i = 1;
+ j = ctab[1].cconst;
+ while ( i <= count ) {
+ if ( j == ctab[ i ].cconst ) {
+ putprintf( " .word " , 1 );
+ putprintf( PREFIXFORMAT , 1 , LABELPREFIX , ctab[ i ].clabel );
+ putprintf( "-" , 1 );
+ putprintf( PREFIXFORMAT , 0 , LABELPREFIX , fromlabel );
+ i++;
+ } else {
+ putprintf( " .word " , 1 );
+ putprintf( PREFIXFORMAT , 1 , LABELPREFIX , ctab[ 0 ].clabel );
+ putprintf( "-" , 1 );
+ putprintf( PREFIXFORMAT , 0 , LABELPREFIX , fromlabel );
+ }
+ j++;
+ }
+ putjbr( ctab[0].clabel );
+}
+
+ /*
+ * binary switch
+ * special case out default label and start recursion.
+ */
+binarysw( ctab , count )
+ struct ct *ctab;
+ int count;
+{
+
+ bsrecur( ctab[0].clabel , &ctab[0] , count );
+}
+
+ /*
+ * recursive log( count ) search.
+ */
+bsrecur( deflabel , ctab , count )
+ int deflabel;
+ struct ct *ctab;
+ int count;
+{
+
+ if ( count <= 0 ) {
+ putprintf( " jbr L%d" , 0 , deflabel );
+ return;
+ } else if ( count == 1 ) {
+ putprintf( " cmpl %s,$%d" , 0 , FORCENAME , ctab[1].cconst );
+ putprintf( " jeql L%d" , 0 , ctab[1].clabel );
+ putprintf( " jbr L%d" , 0 , deflabel );
+ return;
+ } else {
+ int half = ( count + 1 ) / 2;
+ int gtrlabel = getlab();
+
+ putprintf( " cmpl %s,$%d" , 0 , FORCENAME , ctab[ half ].cconst );
+ putprintf( " jeql L%d" , 0 , ctab[ half ].clabel );
+ putprintf( " jgtr L%d" , 0 , gtrlabel );
+ bsrecur( deflabel , &ctab[0] , half - 1 );
+ putprintf( "L%d:" , 0 , gtrlabel );
+ bsrecur( deflabel , &ctab[ half ] , count - half );
+ return;
+ }
+}
+
+itesw( ctab , count )
+ struct ct *ctab;
+ int count;
+{
+ int i;
+
+ for ( i = 1 ; i <= count ; i++ ) {
+ putprintf( " cmpl %s,$%d" , 0 , FORCENAME , ctab[ i ].cconst );
+ putprintf( " jeql L%d" , 0 , ctab[ i ].clabel );
+ }
+ putprintf( " jbr L%d" , 0 , ctab[0].clabel );
+ return;
+}
+int
+casecmp( this , that )
+ struct ct *this;
+ struct ct *that;
+{
+ if ( this -> cconst < that -> cconst ) {
+ return -1;
+ } else if ( this -> cconst > that -> cconst ) {
+ return 1;
+ } else {
+ return 0;
+ }
+}