SmallInteger.st
changeset 20339 5d56805b999a
parent 20333 8b2b36463804
child 20346 fd33c56536df
child 20819 b64a4707d4ea
equal deleted inserted replaced
20338:d6c7cb1e32df 20339:5d56805b999a
     1 "{ Encoding: utf8 }"
     1 "{ Encoding: utf8 }"
     2 
     2 
     3 "
     3 "
     4  COPYRIGHT (c) 1988 by Claus Gittinger
     4  COPYRIGHT (c) 1988 by Claus Gittinger
     5 	      All Rights Reserved
     5               All Rights Reserved
     6 
     6 
     7  This software is furnished under a license and may be used
     7  This software is furnished under a license and may be used
     8  only in accordance with the terms of that license and with the
     8  only in accordance with the terms of that license and with the
     9  inclusion of the above copyright notice.   This software may not
     9  inclusion of the above copyright notice.   This software may not
    10  be provided or otherwise made available to, or used by, any
    10  be provided or otherwise made available to, or used by, any
    14 "{ Package: 'stx:libbasic' }"
    14 "{ Package: 'stx:libbasic' }"
    15 
    15 
    16 "{ NameSpace: Smalltalk }"
    16 "{ NameSpace: Smalltalk }"
    17 
    17 
    18 Integer subclass:#SmallInteger
    18 Integer subclass:#SmallInteger
    19 	instanceVariableNames:''
    19         instanceVariableNames:''
    20 	classVariableNames:'ZeroString'
    20         classVariableNames:'ZeroString'
    21 	poolDictionaries:''
    21         poolDictionaries:''
    22 	category:'Magnitude-Numbers'
    22         category:'Magnitude-Numbers'
    23 !
    23 !
    24 
    24 
    25 !SmallInteger primitiveDefinitions!
    25 !SmallInteger primitiveDefinitions!
    26 %{
    26 %{
    27 #include <stdio.h>
    27 #include <stdio.h>
    31 !SmallInteger class methodsFor:'documentation'!
    31 !SmallInteger class methodsFor:'documentation'!
    32 
    32 
    33 copyright
    33 copyright
    34 "
    34 "
    35  COPYRIGHT (c) 1988 by Claus Gittinger
    35  COPYRIGHT (c) 1988 by Claus Gittinger
    36 	      All Rights Reserved
    36               All Rights Reserved
    37 
    37 
    38  This software is furnished under a license and may be used
    38  This software is furnished under a license and may be used
    39  only in accordance with the terms of that license and with the
    39  only in accordance with the terms of that license and with the
    40  inclusion of the above copyright notice.   This software may not
    40  inclusion of the above copyright notice.   This software may not
    41  be provided or otherwise made available to, or used by, any
    41  be provided or otherwise made available to, or used by, any
    46 
    46 
    47 documentation
    47 documentation
    48 "
    48 "
    49     SmallIntegers are Integers in the range of at least +/- 2^30
    49     SmallIntegers are Integers in the range of at least +/- 2^30
    50     i.e. 31 bits, but this is not a guaranteed:
    50     i.e. 31 bits, but this is not a guaranteed:
    51 	on an alpha or x86_64, 63 bits are used, if the system was configured for 64bit mode.
    51         on an alpha or x86_64, 63 bits are used, if the system was configured for 64bit mode.
    52 	under the Schteam-VM, 64 bits are used (i.e. a full long integer)
    52         under the Schteam-VM, 64 bits are used (i.e. a full long integer)
    53 
    53 
    54     These are no real objects - they have no instances (not even storage !!)
    54     These are no real objects - they have no instances (not even storage !!)
    55     and cannot be subclassed.
    55     and cannot be subclassed.
    56     The reason is to save both storage and runtime by not collecting
    56     The reason is to save both storage and runtime by not collecting
    57     SmallIntegers in the system. SmallInts are marked by having the TAG_INT
    57     SmallIntegers in the system. SmallInts are marked by having the TAG_INT
    62 
    62 
    63     If you really need this kind of thing, create a subclass of Integer,
    63     If you really need this kind of thing, create a subclass of Integer,
    64     with an instance variable holding the value.
    64     with an instance variable holding the value.
    65 
    65 
    66     [author:]
    66     [author:]
    67 	Claus Gittinger
    67         Claus Gittinger
    68 
    68 
    69     [see also:]
    69     [see also:]
    70 	Number
    70         Number
    71 	Float Fraction FixedPoint
    71         Float Fraction FixedPoint
    72 	LargeInteger
    72         LargeInteger
    73 "
    73 "
    74 ! !
    74 ! !
    75 
    75 
    76 !SmallInteger class methodsFor:'instance creation'!
    76 !SmallInteger class methodsFor:'instance creation'!
    77 
    77 
    93 
    93 
    94 bitMaskFor:index
    94 bitMaskFor:index
    95     "return a bitmask for the index's bit (index starts at 1)"
    95     "return a bitmask for the index's bit (index starts at 1)"
    96 
    96 
    97     (index between:1 and:SmallInteger maxBits) ifFalse:[
    97     (index between:1 and:SmallInteger maxBits) ifFalse:[
    98 	^ SubscriptOutOfBoundsSignal
    98         ^ SubscriptOutOfBoundsSignal
    99 		raiseRequestWith:index
    99                 raiseRequestWith:index
   100 		errorString:'index out of bounds'
   100                 errorString:'index out of bounds'
   101     ].
   101     ].
   102     ^ 1 bitShift:(index - 1)
   102     ^ 1 bitShift:(index - 1)
   103 ! !
   103 ! !
   104 
   104 
   105 !SmallInteger class methodsFor:'class initialization'!
   105 !SmallInteger class methodsFor:'class initialization'!
   255 # if defined(__i386__) && defined(__GNUC__) && (__GNUC__ >= 2)
   255 # if defined(__i386__) && defined(__GNUC__) && (__GNUC__ >= 2)
   256 #  define USE_LONGLONG_FOR_MUL
   256 #  define USE_LONGLONG_FOR_MUL
   257 # endif
   257 # endif
   258 
   258 
   259     if (__isSmallInteger(aNumber)) {
   259     if (__isSmallInteger(aNumber)) {
   260 	otherValue = __intVal(aNumber);
   260         otherValue = __intVal(aNumber);
   261 
   261 
   262 # if defined(USE_LONGLONG_FOR_MUL)
   262 # if defined(USE_LONGLONG_FOR_MUL)
   263 	{
   263         {
   264 #  if defined(__alpha__) && !defined(__alpha64__)
   264 #  if defined(__alpha__) && !defined(__alpha64__)
   265 #   define LONGLONG      INT64
   265 #   define LONGLONG      INT64
   266 #  else
   266 #  else
   267 #   define LONGLONG      long long
   267 #   define LONGLONG      long long
   268 #  endif
   268 #  endif
   269 	    LONGLONG product;
   269             LONGLONG product;
   270 
   270 
   271 	    product = (LONGLONG)myValue * (LONGLONG)otherValue;
   271             product = (LONGLONG)myValue * (LONGLONG)otherValue;
   272 	    if ((product >= (LONGLONG)_MIN_INT)
   272             if ((product >= (LONGLONG)_MIN_INT)
   273 	     && (product <= (LONGLONG)_MAX_INT)) {
   273              && (product <= (LONGLONG)_MAX_INT)) {
   274 		RETURN ( __mkSmallInteger((INT)product) );
   274                 RETURN ( __mkSmallInteger((INT)product) );
   275 	    }
   275             }
   276 	    if (product < 0) {
   276             if (product < 0) {
   277 		negative = -1;
   277                 negative = -1;
   278 		product = -product;
   278                 product = -product;
   279 	    } else {
   279             } else {
   280 		negative = 1;
   280                 negative = 1;
   281 	    }
   281             }
   282 	    productHi = product >> 32;
   282             productHi = product >> 32;
   283 	    productLow = product & 0xFFFFFFFFLL;
   283             productLow = product & 0xFFFFFFFFLL;
   284 	}
   284         }
   285 # else /* no long-long */
   285 # else /* no long-long */
   286 	negative = 1;
   286         negative = 1;
   287 	if (myValue < 0) {
   287         if (myValue < 0) {
   288 	    negative = -1;
   288             negative = -1;
   289 	    myValue = -myValue;
   289             myValue = -myValue;
   290 	}
   290         }
   291 	if (otherValue < 0) {
   291         if (otherValue < 0) {
   292 	    negative = -negative;
   292             negative = -negative;
   293 	    otherValue = -otherValue;
   293             otherValue = -otherValue;
   294 	}
   294         }
   295 
   295 
   296 #  if defined(__GNUC__) && defined(__mc68k__)
   296 #  if defined(__GNUC__) && defined(__mc68k__)
   297 	asm ("mulu%.l %3,%1:%0"
   297         asm ("mulu%.l %3,%1:%0"
   298 		: "=d"  ((unsigned long)(productLow)),
   298                 : "=d"  ((unsigned long)(productLow)),
   299 		  "=d"  ((unsigned long)(productHi))
   299                   "=d"  ((unsigned long)(productHi))
   300 		: "%0"  ((unsigned long)(myValue)),
   300                 : "%0"  ((unsigned long)(myValue)),
   301 		  "dmi" ((unsigned long)(otherValue)));
   301                   "dmi" ((unsigned long)(otherValue)));
   302 #  else
   302 #  else
   303 #   if defined (__GNUC__) && defined(__x86__)
   303 #   if defined (__GNUC__) && defined(__x86__)
   304 	asm ("mull %3"
   304         asm ("mull %3"
   305 		: "=a"  ((unsigned long)(productLow)),
   305                 : "=a"  ((unsigned long)(productLow)),
   306 		  "=d"  ((unsigned long)(productHi))
   306                   "=d"  ((unsigned long)(productHi))
   307 		: "%0"  ((unsigned long)(myValue)),
   307                 : "%0"  ((unsigned long)(myValue)),
   308 		  "rm"  ((unsigned long)(otherValue)));
   308                   "rm"  ((unsigned long)(otherValue)));
   309 #   else
   309 #   else
   310 #    if defined(__win32__) && defined(__BORLANDC__)
   310 #    if defined(__win32__) && defined(__BORLANDC__)
   311 	asm {
   311         asm {
   312 	    mov   eax, myValue
   312             mov   eax, myValue
   313 	    mov   edx, otherValue
   313             mov   edx, otherValue
   314 	    mul   edx
   314             mul   edx
   315 	    mov   productLow, eax
   315             mov   productLow, eax
   316 	    mov   productHi, edx
   316             mov   productHi, edx
   317 	}
   317         }
   318 #    else /* generic */
   318 #    else /* generic */
   319 	{
   319         {
   320 	    unsigned INT pHH, pHL, pLH, pLL;
   320             unsigned INT pHH, pHL, pLH, pLL;
   321 	    unsigned INT low1, low2, hi1, hi2;
   321             unsigned INT low1, low2, hi1, hi2;
   322 	    unsigned INT t;
   322             unsigned INT t;
   323 
   323 
   324 	    /* unsigned multiply myValue * otherValue -> productHi, productLow
   324             /* unsigned multiply myValue * otherValue -> productHi, productLow
   325 	     *
   325              *
   326 	     * this is too slow:
   326              * this is too slow:
   327 	     * since most machines can do 32*32 to 64 bit multiply,
   327              * since most machines can do 32*32 to 64 bit multiply,
   328 	     * (or at least 32*32 with Overflow check)
   328              * (or at least 32*32 with Overflow check)
   329 	     * - need more assembler (inline) functions here
   329              * - need more assembler (inline) functions here
   330 	     */
   330              */
   331 #     if __POINTER_SIZE__ == 8
   331 #     if __POINTER_SIZE__ == 8
   332 	    low1 = low32Bits((unsigned INT)myValue);
   332             low1 = low32Bits((unsigned INT)myValue);
   333 	    hi1 = hi32Bits((unsigned INT)myValue);
   333             hi1 = hi32Bits((unsigned INT)myValue);
   334 	    low2 = low32Bits((unsigned INT)otherValue);
   334             low2 = low32Bits((unsigned INT)otherValue);
   335 	    hi2 = hi32Bits((unsigned INT)otherValue);
   335             hi2 = hi32Bits((unsigned INT)otherValue);
   336 #      define LLMASK 0xC000000000000000LL
   336 #      define LLMASK 0xC000000000000000LL
   337 #     else
   337 #     else
   338 	    low1 = low16Bits((unsigned INT)myValue);
   338             low1 = low16Bits((unsigned INT)myValue);
   339 	    hi1 = hi16Bits((unsigned INT)myValue);
   339             hi1 = hi16Bits((unsigned INT)myValue);
   340 	    low2 = low16Bits((unsigned INT)otherValue);
   340             low2 = low16Bits((unsigned INT)otherValue);
   341 	    hi2 = hi16Bits((unsigned INT)otherValue);
   341             hi2 = hi16Bits((unsigned INT)otherValue);
   342 #      define LLMASK 0xC0000000L
   342 #      define LLMASK 0xC0000000L
   343 #     endif
   343 #     endif
   344 
   344 
   345 	    pLH = low1 * hi2;
   345             pLH = low1 * hi2;
   346 	    pHL = hi1 * low2;
   346             pHL = hi1 * low2;
   347 	    pLL = low1 * low2;
   347             pLL = low1 * low2;
   348 	    pHH = hi1 * hi2;
   348             pHH = hi1 * hi2;
   349 
   349 
   350 	    /*
   350             /*
   351 	     * the common case ...
   351              * the common case ...
   352 	     */
   352              */
   353 	    if ((pHL == 0)
   353             if ((pHL == 0)
   354 	     && (pLH == 0)
   354              && (pLH == 0)
   355 	     && (pHH == 0)
   355              && (pHH == 0)
   356 	     && ((pLL & LLMASK) == 0)) {
   356              && ((pLL & LLMASK) == 0)) {
   357 		if (negative < 0) {
   357                 if (negative < 0) {
   358 		    RETURN ( __mkSmallInteger(- ((INT)pLL)) );
   358                     RETURN ( __mkSmallInteger(- ((INT)pLL)) );
   359 		}
   359                 }
   360 		RETURN ( __mkSmallInteger((INT)pLL) );
   360                 RETURN ( __mkSmallInteger((INT)pLL) );
   361 	    }
   361             }
   362 
   362 
   363 	    /*
   363             /*
   364 	     *   pHH |--------|--------|
   364              *   pHH |--------|--------|
   365 	     *   pLH          |--------|--------|
   365              *   pLH          |--------|--------|
   366 	     *   pHL          |--------|--------|
   366              *   pHL          |--------|--------|
   367 	     *   pLL                   |--------|--------|
   367              *   pLL                   |--------|--------|
   368 	     */
   368              */
   369 
   369 
   370 #     if __POINTER_SIZE__ == 8
   370 #     if __POINTER_SIZE__ == 8
   371 	    t = low32Bits(pLH) + low32Bits(pHL) + hi32Bits(pLL);
   371             t = low32Bits(pLH) + low32Bits(pHL) + hi32Bits(pLL);
   372 	    productLow = (t << 32) + low32Bits(pLL);
   372             productLow = (t << 32) + low32Bits(pLL);
   373 	    productHi = pHH + hi32Bits(t) + hi32Bits(pHL) + hi32Bits(pLH);
   373             productHi = pHH + hi32Bits(t) + hi32Bits(pHL) + hi32Bits(pLH);
   374 #     else
   374 #     else
   375 	    t = low16Bits(pLH) + low16Bits(pHL) + hi16Bits(pLL);
   375             t = low16Bits(pLH) + low16Bits(pHL) + hi16Bits(pLL);
   376 	    productLow = (t << 16) + low16Bits(pLL);
   376             productLow = (t << 16) + low16Bits(pLL);
   377 	    productHi = pHH + hi16Bits(t) + hi16Bits(pHL) + hi16Bits(pLH);
   377             productHi = pHH + hi16Bits(t) + hi16Bits(pHL) + hi16Bits(pLH);
   378 #     endif
   378 #     endif
   379 	}
   379         }
   380 #    endif /* ! __win32__ */
   380 #    endif /* ! __win32__ */
   381 #   endif /* ! (__GNUC__ && __x86__) */
   381 #   endif /* ! (__GNUC__ && __x86__) */
   382 #  endif /* ! (__GNUC__ && __mc68k__) */
   382 #  endif /* ! (__GNUC__ && __mc68k__) */
   383 
   383 
   384 	if (productHi == 0) {
   384         if (productHi == 0) {
   385 	    if (negative < 0) {
   385             if (negative < 0) {
   386 		if (productLow <= -(_MIN_INT)) {
   386                 if (productLow <= -(_MIN_INT)) {
   387 		    RETURN ( __mkSmallInteger(-((INT)productLow)) );
   387                     RETURN ( __mkSmallInteger(-((INT)productLow)) );
   388 		}
   388                 }
   389 	    } else {
   389             } else {
   390 		if (productLow <= _MAX_INT) {
   390                 if (productLow <= _MAX_INT) {
   391 		    RETURN ( __mkSmallInteger(productLow) );
   391                     RETURN ( __mkSmallInteger(productLow) );
   392 		}
   392                 }
   393 	    }
   393             }
   394 	}
   394         }
   395 # endif /* ! USE_LONGLONG */
   395 # endif /* ! USE_LONGLONG */
   396 
   396 
   397 # if __POINTER_SIZE__ == 8
   397 # if __POINTER_SIZE__ == 8
   398 	RETURN (__MKLARGEINT128(negative, productLow, productHi));
   398         RETURN (__MKLARGEINT128(negative, productLow, productHi));
   399 # else
   399 # else
   400 	RETURN (__MKLARGEINT64(negative, productLow, productHi));
   400         RETURN (__MKLARGEINT64(negative, productLow, productHi));
   401 # endif
   401 # endif
   402     } else if (__isFloatLike(aNumber)) {
   402     } else if (__isFloatLike(aNumber)) {
   403 	OBJ newFloat;
   403         OBJ newFloat;
   404 	double val = (double)myValue * __floatVal(aNumber);
   404         double val = (double)myValue * __floatVal(aNumber);
   405 
   405 
   406 	__qMKFLOAT(newFloat, val);
   406         __qMKFLOAT(newFloat, val);
   407 	RETURN ( newFloat );
   407         RETURN ( newFloat );
   408     } else if (__isShortFloat(aNumber)) {
   408     } else if (__isShortFloat(aNumber)) {
   409 	OBJ newFloat;
   409         OBJ newFloat;
   410 	float val = (float)myValue * __shortFloatVal(aNumber);
   410         float val = (float)myValue * __shortFloatVal(aNumber);
   411 
   411 
   412 	__qMKSFLOAT(newFloat, val);
   412         __qMKSFLOAT(newFloat, val);
   413 	RETURN ( newFloat );
   413         RETURN ( newFloat );
   414     } else if (__isFractionLike(aNumber)) {
   414     } else if (__isFractionLike(aNumber)) {
   415 	OBJ t = __FractionInstPtr(aNumber)->f_numerator;
   415         OBJ t = __FractionInstPtr(aNumber)->f_numerator;
   416 
   416 
   417 	if (myValue == 0) {
   417         if (myValue == 0) {
   418 	    RETURN(__mkSmallInteger(0));
   418             RETURN(__mkSmallInteger(0));
   419 	}
   419         }
   420 
   420 
   421 	if (__isSmallInteger(t)) {
   421         if (__isSmallInteger(t)) {
   422 	    INT num = __intVal(t);
   422             INT num = __intVal(t);
   423 	    t = __FractionInstPtr(aNumber)->f_denominator;
   423             t = __FractionInstPtr(aNumber)->f_denominator;
   424 	    if (__isSmallInteger(t)) {
   424             if (__isSmallInteger(t)) {
   425 		INT prod = myValue * num;
   425                 INT prod = myValue * num;
   426 		if (prod / myValue == num) { // check for overflow
   426                 if (prod / myValue == num) { // check for overflow
   427 		    INT den = __intVal(t);
   427                     INT den = __intVal(t);
   428 		    INT quo = prod / den;
   428                     INT quo = prod / den;
   429 		    if (quo * den == prod) {        // check for integer result
   429                     if (quo * den == prod) {        // check for integer result
   430 			RETURN ( __mkSmallInteger(quo) );
   430                         RETURN ( __mkSmallInteger(quo) );
   431 		    }
   431                     }
   432 		}
   432                 }
   433 	    }
   433             }
   434 	}
   434         }
   435     }
   435     }
   436 #endif /* not __SCHTEAM__ */
   436 #endif /* not __SCHTEAM__ */
   437 %}.
   437 %}.
   438     ^ aNumber productFromInteger:self
   438     ^ aNumber productFromInteger:self
   439 
   439 
   440     "
   440     "
   441 	3 * (1/2)
   441         3 * (1/2)
   442 	6 * (1/2)
   442         6 * (1/2)
   443 	6 * (-1/2)
   443         6 * (-1/2)
   444    "
   444    "
   445 !
   445 !
   446 
   446 
   447 + aNumber
   447 + aNumber
   448     "return the sum of the receiver's value and the argument's value"
   448     "return the sum of the receiver's value and the argument's value"
   461      * (see the message send at the bottom)
   461      * (see the message send at the bottom)
   462      */
   462      */
   463 
   463 
   464     if (__isSmallInteger(aNumber)) {
   464     if (__isSmallInteger(aNumber)) {
   465 # ifdef _ADD_IO_IO
   465 # ifdef _ADD_IO_IO
   466 	RETURN ( _ADD_IO_IO(self, aNumber) );
   466         RETURN ( _ADD_IO_IO(self, aNumber) );
   467 # else
   467 # else
   468 	REGISTER INT sum;
   468         REGISTER INT sum;
   469 
   469 
   470 	sum =  __intVal(self) + __intVal(aNumber);
   470         sum =  __intVal(self) + __intVal(aNumber);
   471 	if (__ISVALIDINTEGER(sum)) {
   471         if (__ISVALIDINTEGER(sum)) {
   472 	    RETURN ( __mkSmallInteger(sum) );
   472             RETURN ( __mkSmallInteger(sum) );
   473 	}
   473         }
   474 	RETURN ( __MKLARGEINT(sum) );
   474         RETURN ( __MKLARGEINT(sum) );
   475 # endif
   475 # endif
   476     }
   476     }
   477     if (__isFloatLike(aNumber)) {
   477     if (__isFloatLike(aNumber)) {
   478 	OBJ newFloat;
   478         OBJ newFloat;
   479 	double val = (double)__intVal(self) + __floatVal(aNumber);
   479         double val = (double)__intVal(self) + __floatVal(aNumber);
   480 
   480 
   481 	__qMKFLOAT(newFloat, val);
   481         __qMKFLOAT(newFloat, val);
   482 	RETURN ( newFloat );
   482         RETURN ( newFloat );
   483     }
   483     }
   484     if (__isShortFloat(aNumber)) {
   484     if (__isShortFloat(aNumber)) {
   485 	OBJ newFloat;
   485         OBJ newFloat;
   486 	float val = (float)__intVal(self) + __shortFloatVal(aNumber);
   486         float val = (float)__intVal(self) + __shortFloatVal(aNumber);
   487 
   487 
   488 	__qMKSFLOAT(newFloat, val);
   488         __qMKSFLOAT(newFloat, val);
   489 	RETURN ( newFloat );
   489         RETURN ( newFloat );
   490     }
   490     }
   491 #endif /* not __SCHTEAM__ */
   491 #endif /* not __SCHTEAM__ */
   492 %}.
   492 %}.
   493     ^ aNumber sumFromInteger:self
   493     ^ aNumber sumFromInteger:self
   494 !
   494 !
   510      * (see the message send at the bottom)
   510      * (see the message send at the bottom)
   511      */
   511      */
   512 
   512 
   513     if (__isSmallInteger(aNumber)) {
   513     if (__isSmallInteger(aNumber)) {
   514 # ifdef _SUB_IO_IO
   514 # ifdef _SUB_IO_IO
   515 	RETURN ( _SUB_IO_IO(self, aNumber) );
   515         RETURN ( _SUB_IO_IO(self, aNumber) );
   516 # else
   516 # else
   517 	REGISTER INT diff =  __intVal(self) - __intVal(aNumber);
   517         REGISTER INT diff =  __intVal(self) - __intVal(aNumber);
   518 	if (__ISVALIDINTEGER(diff)) {
   518         if (__ISVALIDINTEGER(diff)) {
   519 	    RETURN ( __mkSmallInteger(diff) );
   519             RETURN ( __mkSmallInteger(diff) );
   520 	}
   520         }
   521 	RETURN ( __MKLARGEINT(diff) );
   521         RETURN ( __MKLARGEINT(diff) );
   522 # endif
   522 # endif
   523     }
   523     }
   524     if (__isFloatLike(aNumber)) {
   524     if (__isFloatLike(aNumber)) {
   525 	OBJ newFloat;
   525         OBJ newFloat;
   526 	double val = (double)__intVal(self) - __floatVal(aNumber);
   526         double val = (double)__intVal(self) - __floatVal(aNumber);
   527 
   527 
   528 	__qMKFLOAT(newFloat, val);
   528         __qMKFLOAT(newFloat, val);
   529 	RETURN ( newFloat );
   529         RETURN ( newFloat );
   530     }
   530     }
   531     if (__isShortFloat(aNumber)) {
   531     if (__isShortFloat(aNumber)) {
   532 	OBJ newFloat;
   532         OBJ newFloat;
   533 	float val = (float)__intVal(self) - __shortFloatVal(aNumber);
   533         float val = (float)__intVal(self) - __shortFloatVal(aNumber);
   534 
   534 
   535 	__qMKSFLOAT(newFloat, val);
   535         __qMKSFLOAT(newFloat, val);
   536 	RETURN ( newFloat );
   536         RETURN ( newFloat );
   537     }
   537     }
   538 #endif /* not __SCHTEAM__ */
   538 #endif /* not __SCHTEAM__ */
   539 %}.
   539 %}.
   540     ^ aNumber differenceFromInteger:self
   540     ^ aNumber differenceFromInteger:self
   541 !
   541 !
   561     INT t, val;
   561     INT t, val;
   562     double dval;
   562     double dval;
   563     INT myValue = __intVal(self);
   563     INT myValue = __intVal(self);
   564 
   564 
   565     if (__isSmallInteger(aNumber)) {
   565     if (__isSmallInteger(aNumber)) {
   566 	val = __intVal(aNumber);
   566         val = __intVal(aNumber);
   567 	if (val != 0) {
   567         if (val != 0) {
   568 	    t = myValue / val;
   568             t = myValue / val;
   569 # ifdef GOOD_OPTIMIZER
   569 # ifdef GOOD_OPTIMIZER
   570 	    if (myValue % val == 0) {
   570             if (myValue % val == 0) {
   571 # else
   571 # else
   572 	    /* this is stupid - all I want is to look for a remainder ...
   572             /* this is stupid - all I want is to look for a remainder ...
   573 	       but most compilers are too stupid and generate an extra modulus
   573                but most compilers are too stupid and generate an extra modulus
   574 	       instruction for "if (me % val)".
   574                instruction for "if (me % val)".
   575 	       Even if most divide instructions already leave the remainder in
   575                Even if most divide instructions already leave the remainder in
   576 	       some register.
   576                some register.
   577 	       Therefore I use a multiplication which is faster than a modulo
   577                Therefore I use a multiplication which is faster than a modulo
   578 	       on most machines. Hint to GNU people :-)
   578                on most machines. Hint to GNU people :-)
   579 	    */
   579             */
   580 	    if ((t * val) == myValue) {
   580             if ((t * val) == myValue) {
   581 # endif
   581 # endif
   582 		RETURN ( __mkSmallInteger(t) );
   582                 RETURN ( __mkSmallInteger(t) );
   583 	    }
   583             }
   584 	}
   584         }
   585     } else {
   585     } else {
   586 	if (__isFloatLike(aNumber)) {
   586         if (__isFloatLike(aNumber)) {
   587 	    dval = __floatVal(aNumber);
   587             dval = __floatVal(aNumber);
   588 	    if (dval != 0.0) {
   588             if (dval != 0.0) {
   589 		OBJ newFloat;
   589                 OBJ newFloat;
   590 		double val = (double)myValue / dval;
   590                 double val = (double)myValue / dval;
   591 
   591 
   592 		__qMKFLOAT(newFloat, val);
   592                 __qMKFLOAT(newFloat, val);
   593 		RETURN ( newFloat );
   593                 RETURN ( newFloat );
   594 	    }
   594             }
   595 	}
   595         }
   596     }
   596     }
   597 #endif /* not __SCHTEAM__ */
   597 #endif /* not __SCHTEAM__ */
   598 %}.
   598 %}.
   599     aNumber isInteger ifTrue:[
   599     aNumber isInteger ifTrue:[
   600 	aNumber == 0 ifTrue:[
   600         aNumber == 0 ifTrue:[
   601 	    ^ ZeroDivide raiseRequestWith:thisContext.
   601             ^ ZeroDivide raiseRequestWith:thisContext.
   602 	].
   602         ].
   603 	^ Fraction numerator:self denominator:aNumber
   603         ^ Fraction numerator:self denominator:aNumber
   604     ].
   604     ].
   605     ^ aNumber quotientFromInteger:self
   605     ^ aNumber quotientFromInteger:self
   606 
   606 
   607     "
   607     "
   608      8 / 4
   608      8 / 4
   621     "return the integer part of the quotient of the receiver's value
   621     "return the integer part of the quotient of the receiver's value
   622      and the argument's value.
   622      and the argument's value.
   623      The result is truncated toward negative infinity
   623      The result is truncated toward negative infinity
   624      and will be negative, if the operands signs differ.
   624      and will be negative, if the operands signs differ.
   625      The following is always true:
   625      The following is always true:
   626 	(receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
   626         (receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
   627 
   627 
   628      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
   628      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
   629      Especially surprising:
   629      Especially surprising (because of truncation toward negative infinity):
   630 	-1 // 10 -> -1 (because -(1/10) is truncated towards next smaller integer, which is -1.
   630         -1 // 10 -> -1 (because -(1/10) is truncated towards next smaller integer, which is -1.
   631 	-10 // 3 -> -4 (because -(10/3) is truncated towards next smaller integer, which is -4.
   631         -10 // 3 -> -4 (because -(10/3) is truncated towards next smaller integer, which is -4.
   632 
   632 
   633      See #quo: which returns -2 in the above case and #rem: which is the corresponding remainder."
   633      See #quo: which truncates toward zero and returns -2 in the above case 
       
   634      and #rem: which is the corresponding remainder."
   634 
   635 
   635 %{  /* NOCONTEXT */
   636 %{  /* NOCONTEXT */
   636 #ifdef __SCHTEAM__
   637 #ifdef __SCHTEAM__
   637     return context._RETURN( self.quotientTruncated( aNumber ));
   638     return context._RETURN( self.quotientTruncated( aNumber ));
   638 #else
   639 #else
   648 
   649 
   649     INT divisor, rslt;
   650     INT divisor, rslt;
   650     INT dividend = __intVal(self);
   651     INT dividend = __intVal(self);
   651 
   652 
   652     if (__isSmallInteger(aNumber)) {
   653     if (__isSmallInteger(aNumber)) {
   653 	divisor = __intVal(aNumber);
   654         divisor = __intVal(aNumber);
   654 	if (divisor != 0) {
   655         if (divisor != 0) {
   655 	    rslt = dividend / divisor;
   656             rslt = dividend / divisor;
   656 	    /*
   657             /*
   657 	     * Optimized to speed up positive result
   658              * Optimized to speed up positive result
   658 	     */
   659              */
   659 	    if (rslt <= 0) {
   660             if (rslt <= 0) {
   660 		if (rslt == 0) {
   661                 if (rslt == 0) {
   661 		    if ((dividend ^ divisor) < 0) {
   662                     if ((dividend ^ divisor) < 0) {
   662 			/*
   663                         /*
   663 			 * result (negative) has been truncated toward 0.
   664                          * result (negative) has been truncated toward 0.
   664 			 * Return -1, because we truncate toward negative inf.
   665                          * Return -1, because we truncate toward negative inf.
   665 			 */
   666                          */
   666 			 rslt = -1;
   667                          rslt = -1;
   667 		    }
   668                     }
   668 		} else {
   669                 } else {
   669 		    /*
   670                     /*
   670 		     * If result (negative) has been truncated toward 0,
   671                      * If result (negative) has been truncated toward 0,
   671 		     * subtract 1, because we truncate toward negative inf.
   672                      * subtract 1, because we truncate toward negative inf.
   672 		     */
   673                      */
   673 		    if (divisor > 0) {
   674                     if (divisor > 0) {
   674 			if (rslt * divisor > dividend) {
   675                         if (rslt * divisor > dividend) {
   675 			    rslt--;
   676                             rslt--;
   676 			}
   677                         }
   677 		    } else {
   678                     } else {
   678 			if (rslt * divisor < dividend) {
   679                         if (rslt * divisor < dividend) {
   679 			    rslt--;
   680                             rslt--;
   680 			}
   681                         }
   681 		    }
   682                     }
   682 		}
   683                 }
   683 	    }
   684             }
   684 	    RETURN ( __mkSmallInteger(rslt) );
   685             RETURN ( __mkSmallInteger(rslt) );
   685 	}
   686         }
   686     } else {
   687     } else {
   687 	if (__isFractionLike(aNumber)) {
   688         if (__isFractionLike(aNumber)) {
   688 	    OBJ t = __FractionInstPtr(aNumber)->f_numerator;
   689             OBJ t = __FractionInstPtr(aNumber)->f_numerator;
   689 	    if (__isSmallInteger(t)) {
   690             if (__isSmallInteger(t)) {
   690 		INT num = __intVal(t);
   691                 INT num = __intVal(t);
   691 		t = __FractionInstPtr(aNumber)->f_denominator;
   692                 t = __FractionInstPtr(aNumber)->f_denominator;
   692 		if (__isSmallInteger(t)) {
   693                 if (__isSmallInteger(t)) {
   693 		    INT den = __intVal(t);
   694                     INT den = __intVal(t);
   694 		    INT prod;
   695                     INT prod;
   695 #if 0 && defined(__GNUC__) // supported from GCC 5
   696 #if 0 && defined(__GNUC__) // supported from GCC 5
   696 		    if (!__builtin_mul_overflow(myself, den, &prod)) {
   697                     if (!__builtin_mul_overflow(myself, den, &prod)) {
   697 			goto out;   // overflow, try harder...
   698                         goto out;   // overflow, try harder...
   698 		    }
   699                     }
   699 #else
   700 #else
   700 		    prod = dividend * den;
   701                     prod = dividend * den;
   701 		    // make sure, that no overflow occurred
   702                     // make sure, that no overflow occurred
   702 		    if (prod / den != dividend) {
   703                     if (prod / den != dividend) {
   703 			goto out;   // overflow, try harder...
   704                         goto out;   // overflow, try harder...
   704 		    }
   705                     }
   705 #endif
   706 #endif
   706 		    rslt = prod / num;
   707                     rslt = prod / num;
   707 
   708 
   708 		    /*
   709                     /*
   709 		     * Optimized to speed up positive result
   710                      * Optimized to speed up positive result
   710 		     */
   711                      */
   711 		    if (rslt <= 0) {
   712                     if (rslt <= 0) {
   712 			if (rslt == 0) {
   713                         if (rslt == 0) {
   713 			    if ((dividend ^ num) < 0) {
   714                             if ((dividend ^ num) < 0) {
   714 				/*
   715                                 /*
   715 				 * result (negative) has been truncated toward 0.
   716                                  * result (negative) has been truncated toward 0.
   716 				 * Return -1, because we truncate toward negative inf.
   717                                  * Return -1, because we truncate toward negative inf.
   717 				 */
   718                                  */
   718 				 rslt = -1;
   719                                  rslt = -1;
   719 			    }
   720                             }
   720 			} else {
   721                         } else {
   721 			    /*
   722                             /*
   722 			     * If result (negative) has been truncated toward 0,
   723                              * If result (negative) has been truncated toward 0,
   723 			     * subtract 1, because we truncate toward negative inf.
   724                              * subtract 1, because we truncate toward negative inf.
   724 			     */
   725                              */
   725 			    if (num > 0) {
   726                             if (num > 0) {
   726 				if (rslt * num > prod) rslt--;
   727                                 if (rslt * num > prod) rslt--;
   727 			    } else {
   728                             } else {
   728 				if (rslt * num < prod) rslt--;
   729                                 if (rslt * num < prod) rslt--;
   729 			    }
   730                             }
   730 			}
   731                         }
   731 		    }
   732                     }
   732 		    RETURN ( __mkSmallInteger(rslt) );
   733                     RETURN ( __mkSmallInteger(rslt) );
   733 		}
   734                 }
   734 	    }
   735             }
   735 	}
   736         }
   736     }
   737     }
   737 out:;
   738 out:;
   738 #endif /* not __SCHTEAM__ */
   739 #endif /* not __SCHTEAM__ */
   739 %}.
   740 %}.
   740     (aNumber = 0) ifTrue:[
   741     (aNumber = 0) ifTrue:[
   741 	^ ZeroDivide raiseRequestWith:thisContext.
   742         ^ ZeroDivide raiseRequestWith:thisContext.
   742     ].
   743     ].
   743     ^ aNumber integerQuotientFromInteger:self
   744     ^ aNumber integerQuotientFromInteger:self
   744 
   745 
   745     "
   746     "
   746      9 // 4     ~~ 2 ifTrue:[self halt].
   747      9 // 4     ~~ 2 ifTrue:[self halt].
   777      negative infinity.
   778      negative infinity.
   778      m < |aNumber| AND there is an integer k with (k * aNumber + m) = self
   779      m < |aNumber| AND there is an integer k with (k * aNumber + m) = self
   779 
   780 
   780      The returned remainder has the same sign as aNumber.
   781      The returned remainder has the same sign as aNumber.
   781      The following is always true:
   782      The following is always true:
   782 	(receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
   783         (receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
   783 
   784 
   784      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
   785      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
   785      Especially surprising:
   786      Especially surprising:
   786 	-1 \\ 10 -> 9  (because -(1/10) is truncated towards next smaller integer, which is -1,
   787         -1 \\ 10 -> 9  (because -(1/10) is truncated towards next smaller integer, which is -1,
   787 			and -1 multiplied by 10 gives -10, so we have to add 9 to get the original -1).
   788                         and -1 multiplied by 10 gives -10, so we have to add 9 to get the original -1).
   788 	-10 \\ 3 -> 2 (because -(10/3) is truncated towards next smaller integer, which is -4,
   789         -10 \\ 3 -> 2 (because -(10/3) is truncated towards next smaller integer, which is -4,
   789 			and -4 * 4 gives -12, so we need to add 2 to get the original -10.
   790                         and -4 * 4 gives -12, so we need to add 2 to get the original -10.
   790 
   791 
   791      See #rem: which is the corresponding remainder for division via #quo:.
   792      See #rem: which is the corresponding remainder for division via #quo:.
   792 
   793 
   793      Redefined here for speed."
   794      Redefined here for speed."
   794 
   795 
   807      */
   808      */
   808 
   809 
   809     INT dividend, divisor, rem;
   810     INT dividend, divisor, rem;
   810 
   811 
   811     if (__isSmallInteger(aNumber)
   812     if (__isSmallInteger(aNumber)
   812 	&& (divisor = __intVal(aNumber)) != 0) {
   813         && (divisor = __intVal(aNumber)) != 0) {
   813 	/*
   814         /*
   814 	 * Note that the sign of something modulo a negative number is undefined
   815          * Note that the sign of something modulo a negative number is undefined
   815 	 * in C!
   816          * in C!
   816 	 */
   817          */
   817 	dividend = __intVal(self);
   818         dividend = __intVal(self);
   818 	rem = dividend % divisor;
   819         rem = dividend % divisor;
   819 	if (rem) {
   820         if (rem) {
   820 	    if ((rem ^ divisor) < 0) {
   821             if ((rem ^ divisor) < 0) {
   821 		/* sign of remainder is different from sign of divisor */
   822                 /* sign of remainder is different from sign of divisor */
   822 		rem = -rem;
   823                 rem = -rem;
   823 	    }
   824             }
   824 	    if ((dividend ^ divisor) < 0) {
   825             if ((dividend ^ divisor) < 0) {
   825 		/* different signs, so division would have returned a
   826                 /* different signs, so division would have returned a
   826 		 * negative number.
   827                  * negative number.
   827 		 * C rounds toward zero, this code will simulate
   828                  * C rounds toward zero, this code will simulate
   828 		 * rounding towards negative infinity.
   829                  * rounding towards negative infinity.
   829 		 */
   830                  */
   830 		rem = divisor - rem;
   831                 rem = divisor - rem;
   831 	    }
   832             }
   832 	}
   833         }
   833 	RETURN ( __mkSmallInteger(rem) );
   834         RETURN ( __mkSmallInteger(rem) );
   834     }
   835     }
   835 #endif /* not __SCHTEAM__ */
   836 #endif /* not __SCHTEAM__ */
   836 %}.
   837 %}.
   837     (aNumber = 0) ifTrue:[
   838     (aNumber = 0) ifTrue:[
   838 	^ ZeroDivide raiseRequestWith:thisContext.
   839         ^ ZeroDivide raiseRequestWith:thisContext.
   839     ].
   840     ].
   840     ^ aNumber moduloFromInteger:self
   841     ^ aNumber moduloFromInteger:self
   841 
   842 
   842     "
   843     "
   843      9 \\ 4  == 1 ifFalse:[self halt].
   844      9 \\ 4  == 1 ifFalse:[self halt].
   861     return context._RETURN( self.abs());
   862     return context._RETURN( self.abs());
   862 #else
   863 #else
   863     INT val = __intVal(self);
   864     INT val = __intVal(self);
   864 
   865 
   865     if (val >= 0) {
   866     if (val >= 0) {
   866 	RETURN (self);
   867         RETURN (self);
   867     }
   868     }
   868     if (val != _MIN_INT) {
   869     if (val != _MIN_INT) {
   869 	RETURN ( __mkSmallInteger(-val) );
   870         RETURN ( __mkSmallInteger(-val) );
   870     }
   871     }
   871     /* only reached for minVal */
   872     /* only reached for minVal */
   872     RETURN( __MKLARGEINT(-_MIN_INT));
   873     RETURN( __MKLARGEINT(-_MIN_INT));
   873 #endif
   874 #endif
   874 %}.
   875 %}.
   898 quo:aNumber
   899 quo:aNumber
   899     "return the integer part of the quotient of the receiver's value
   900     "return the integer part of the quotient of the receiver's value
   900      and the argument's value. The result is truncated towards zero
   901      and the argument's value. The result is truncated towards zero
   901      and negative, if the operands signs differ..
   902      and negative, if the operands signs differ..
   902      The following is always true:
   903      The following is always true:
   903 	(receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
   904         (receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
   904      For positive results, this is the same as #//,
   905      For positive results, this is the same as #//,
   905      for negative results, the remainder is ignored.
   906      for negative results, the remainder is ignored.
   906      I.e.: '9 // 4 = 2' and '-9 // 4 = -3'
   907      I.e.: '9 // 4 = 2' and '-9 // 4 = -3'
   907      in contrast: '9 quo: 4 = 2' and '-9 quo: 4 = -2'"
   908      in contrast: '9 quo: 4 = 2' and '-9 quo: 4 = -2'"
   908 
   909 
   909 %{  /* NOCONTEXT */
   910 %{  /* NOCONTEXT */
   910 #ifdef __SCHTEAM__
   911 #ifdef __SCHTEAM__
   911     return context._RETURN( self.quotient(aNumber));
   912     return context._RETURN( self.quotient(aNumber));
   912 #else
   913 #else
   913     if (__isSmallInteger(aNumber)) {
   914     if (__isSmallInteger(aNumber)) {
   914 	INT val = __intVal(aNumber);
   915         INT val = __intVal(aNumber);
   915 	if (val != 0) {
   916         if (val != 0) {
   916 	    RETURN ( __mkSmallInteger(__intVal(self) / val) );
   917             RETURN ( __mkSmallInteger(__intVal(self) / val) );
   917 	}
   918         }
   918     } else {
   919     } else {
   919 	if (__isFractionLike(aNumber)) {
   920         if (__isFractionLike(aNumber)) {
   920 	    OBJ t = __FractionInstPtr(aNumber)->f_numerator;
   921             OBJ t = __FractionInstPtr(aNumber)->f_numerator;
   921 	    if (__isSmallInteger(t)) {
   922             if (__isSmallInteger(t)) {
   922 		INT num = __intVal(t);
   923                 INT num = __intVal(t);
   923 		t = __FractionInstPtr(aNumber)->f_denominator;
   924                 t = __FractionInstPtr(aNumber)->f_denominator;
   924 		if (__isSmallInteger(t)) {
   925                 if (__isSmallInteger(t)) {
   925 		    INT den = __intVal(t);
   926                     INT den = __intVal(t);
   926 		    INT myself = __intVal(self);
   927                     INT myself = __intVal(self);
   927 		    INT prod;
   928                     INT prod;
   928 #if 0 && defined(__GNUC__) // supported from GCC 5
   929 #if 0 && defined(__GNUC__) // supported from GCC 5
   929 		    if (__builtin_mul_overflow(myself, den, &prod)) {
   930                     if (__builtin_mul_overflow(myself, den, &prod)) {
   930 			RETURN ( __mkSmallInteger(prod / num ));
   931                         RETURN ( __mkSmallInteger(prod / num ));
   931 		    }
   932                     }
   932 #else
   933 #else
   933 		    prod = myself * den;
   934                     prod = myself * den;
   934 		    // make sure, that no overflow occurred
   935                     // make sure, that no overflow occurred
   935 		    if (prod / den == myself) {
   936                     if (prod / den == myself) {
   936 			RETURN ( __mkSmallInteger(prod / num ));
   937                         RETURN ( __mkSmallInteger(prod / num ));
   937 		    }
   938                     }
   938 #endif
   939 #endif
   939 		}
   940                 }
   940 	    }
   941             }
   941 	}
   942         }
   942     }
   943     }
   943 #endif /* not __SCHTEAM__ */
   944 #endif /* not __SCHTEAM__ */
   944 %}.
   945 %}.
   945     (aNumber = 0) ifTrue:[
   946     (aNumber = 0) ifTrue:[
   946 	^ ZeroDivide raiseRequestWith:thisContext.
   947         ^ ZeroDivide raiseRequestWith:thisContext.
   947     ].
   948     ].
   948     ^ self retry:#quo: coercing:aNumber
   949     ^ self retry:#quo: coercing:aNumber
   949 
   950 
   950     "
   951     "
   951      9 // 4
   952      9 // 4
   971 #ifdef __SCHTEAM__
   972 #ifdef __SCHTEAM__
   972     return context._RETURN( self.bitAnd(anInteger));
   973     return context._RETURN( self.bitAnd(anInteger));
   973 #else
   974 #else
   974     /* anding the tags doesn't change it */
   975     /* anding the tags doesn't change it */
   975     if (__isSmallInteger(anInteger)) {
   976     if (__isSmallInteger(anInteger)) {
   976 	RETURN ( ((OBJ) ((INT)self & (INT)anInteger)) );
   977         RETURN ( ((OBJ) ((INT)self & (INT)anInteger)) );
   977     }
   978     }
   978 #endif /* not __SCHTEAM__ */
   979 #endif /* not __SCHTEAM__ */
   979 %}.
   980 %}.
   980     anInteger class == LargeInteger ifTrue:[
   981     anInteger class == LargeInteger ifTrue:[
   981 	^ anInteger bitAnd:self
   982         ^ anInteger bitAnd:self
   982     ].
   983     ].
   983     ^ self retry:#bitAnd: coercing:anInteger
   984     ^ self retry:#bitAnd: coercing:anInteger
   984 
   985 
   985     "(2r001010100 bitAnd:2r00001111) radixPrintStringRadix:2"
   986     "(2r001010100 bitAnd:2r00001111) radixPrintStringRadix:2"
   986 !
   987 !
   996 #ifdef __SCHTEAM__
   997 #ifdef __SCHTEAM__
   997     return context._RETURN( self.bitClear(anInteger));
   998     return context._RETURN( self.bitClear(anInteger));
   998 #else
   999 #else
   999     /* anding the tags doesn't change it */
  1000     /* anding the tags doesn't change it */
  1000     if (__isSmallInteger(anInteger)) {
  1001     if (__isSmallInteger(anInteger)) {
  1001 	RETURN ( ((OBJ) (((INT)self & ~(INT)anInteger) | TAG_INT)) );
  1002         RETURN ( ((OBJ) (((INT)self & ~(INT)anInteger) | TAG_INT)) );
  1002     }
  1003     }
  1003 #endif /* not __SCHTEAM__ */
  1004 #endif /* not __SCHTEAM__ */
  1004 %}.
  1005 %}.
  1005     ^ self retry:#bitClear: coercing:anInteger
  1006     ^ self retry:#bitClear: coercing:anInteger
  1006 
  1007 
  1048 
  1049 
  1049     unsigned INT _self = __intVal(self);
  1050     unsigned INT _self = __intVal(self);
  1050 
  1051 
  1051     _cnt = 0;
  1052     _cnt = 0;
  1052     while (_self) {
  1053     while (_self) {
  1053 	_cnt++;
  1054         _cnt++;
  1054 	_self = _self & (_self - 1);
  1055         _self = _self & (_self - 1);
  1055     }
  1056     }
  1056 # else
  1057 # else
  1057 
  1058 
  1058 #  ifdef ALGORITHM_2
  1059 #  ifdef ALGORITHM_2
  1059     // seems to be faster on the average (and has better worst case)
  1060     // seems to be faster on the average (and has better worst case)
  1061     static unsigned char table[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
  1062     static unsigned char table[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
  1062     unsigned INT _self = __intVal(self);
  1063     unsigned INT _self = __intVal(self);
  1063 
  1064 
  1064     _cnt = 0;
  1065     _cnt = 0;
  1065     while (_self) {
  1066     while (_self) {
  1066 	_cnt += table[ _self & 0x0F ];
  1067         _cnt += table[ _self & 0x0F ];
  1067 	_self >>= 4;
  1068         _self >>= 4;
  1068     }
  1069     }
  1069 #  else
  1070 #  else
  1070 
  1071 
  1071 #   ifdef ALGORIHTM_3
  1072 #   ifdef ALGORIHTM_3
  1072     // the fastest, but hard (impossible) to understand (google for fastest bit count)
  1073     // the fastest, but hard (impossible) to understand (google for fastest bit count)
  1099 #     if __POINTER_SIZE__ == 8
  1100 #     if __POINTER_SIZE__ == 8
  1100     unsigned INT _v;
  1101     unsigned INT _v;
  1101 
  1102 
  1102 #    define _POPCNT(__op)                      \
  1103 #    define _POPCNT(__op)                      \
  1103     ({                                          \
  1104     ({                                          \
  1104 	INT __rslt;                             \
  1105         INT __rslt;                             \
  1105 	asm("xor     %%rax,%%rax        \n      \
  1106         asm("xor     %%rax,%%rax        \n      \
  1106 	     popcnt %1,%%rax           \n      \
  1107              popcnt %1,%%rax           \n      \
  1107 			"  : "=a" (__rslt)      \
  1108                         "  : "=a" (__rslt)      \
  1108 			   : "g" ((INT)(__op))    \
  1109                            : "g" ((INT)(__op))    \
  1109 			   : "cc");             \
  1110                            : "cc");             \
  1110 	(OBJ)__rslt;                            \
  1111         (OBJ)__rslt;                            \
  1111      })
  1112      })
  1112 
  1113 
  1113     _v = (INT)self;
  1114     _v = (INT)self;
  1114     _cnt = _POPCNT(_v);
  1115     _cnt = _POPCNT(_v);
  1115     _cnt--; // one too many due to tag
  1116     _cnt--; // one too many due to tag
  1116 #     else
  1117 #     else
  1117 #    define _POPCNT(__op)                      \
  1118 #    define _POPCNT(__op)                      \
  1118     ({                                          \
  1119     ({                                          \
  1119 	INT __rslt;                             \
  1120         INT __rslt;                             \
  1120 	asm("xor     %%eax,%%eax        \n      \
  1121         asm("xor     %%eax,%%eax        \n      \
  1121 	     popcnt  %1,%%eax           \n      \
  1122              popcnt  %1,%%eax           \n      \
  1122 			"  : "=a" (__rslt)      \
  1123                         "  : "=a" (__rslt)      \
  1123 			   : "g" ((INT)(__v))   \
  1124                            : "g" ((INT)(__v))   \
  1124 			   : "cc");             \
  1125                            : "cc");             \
  1125 	(OBJ)__rslt;                            \
  1126         (OBJ)__rslt;                            \
  1126      })
  1127      })
  1127 
  1128 
  1128     _v = (INT)self;
  1129     _v = (INT)self;
  1129     _cnt = _POPCNT(_v);
  1130     _cnt = _POPCNT(_v);
  1130     _cnt--; // one too many due to tag
  1131     _cnt--; // one too many due to tag
  1142     ^ super bitCount.
  1143     ^ super bitCount.
  1143 
  1144 
  1144     "
  1145     "
  1145 
  1146 
  1146      1 to:1000000 do:[:n |
  1147      1 to:1000000 do:[:n |
  1147 	self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
  1148         self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
  1148      ].
  1149      ].
  1149 
  1150 
  1150      #( 16r00000000
  1151      #( 16r00000000
  1151 	16r00010000 16r00100000 16r01000000 16r10000000
  1152         16r00010000 16r00100000 16r01000000 16r10000000
  1152 	16r00020000 16r00200000 16r02000000 16r20000000
  1153         16r00020000 16r00200000 16r02000000 16r20000000
  1153 	16r00040000 16r00400000 16r04000000 16r40000000
  1154         16r00040000 16r00400000 16r04000000 16r40000000
  1154 	16r00080000 16r00800000 16r08000000 16r80000000
  1155         16r00080000 16r00800000 16r08000000 16r80000000
  1155 
  1156 
  1156 	16rFFFFFFFF 16r7FFFFFFF 16r3FFFFFFF 16r1FFFFFFF
  1157         16rFFFFFFFF 16r7FFFFFFF 16r3FFFFFFF 16r1FFFFFFF
  1157 	16rEEEEEEEE 16r7EEEEEEE 16r3EEEEEEE 16r1EEEEEEE
  1158         16rEEEEEEEE 16r7EEEEEEE 16r3EEEEEEE 16r1EEEEEEE
  1158 	16rDDDDDDDD 16r7DDDDDDD 16r3DDDDDDD 16r1DDDDDDD
  1159         16rDDDDDDDD 16r7DDDDDDD 16r3DDDDDDD 16r1DDDDDDD
  1159 	16rCCCCCCCC 16r7CCCCCCC 16r3CCCCCCC 16r1CCCCCCC
  1160         16rCCCCCCCC 16r7CCCCCCC 16r3CCCCCCC 16r1CCCCCCC
  1160 
  1161 
  1161 	16r8000000000010000 16r8000000000100000 16r8000000001000000 16r8000000010000000
  1162         16r8000000000010000 16r8000000000100000 16r8000000001000000 16r8000000010000000
  1162 	16r8000000000020000 16r8000000000200000 16r8000000002000000 16r8000000020000000
  1163         16r8000000000020000 16r8000000000200000 16r8000000002000000 16r8000000020000000
  1163 	16r8000000000040000 16r8000000000400000 16r8000000004000000 16r8000000040000000
  1164         16r8000000000040000 16r8000000000400000 16r8000000004000000 16r8000000040000000
  1164 	16r8000000000080000 16r8000000000800000 16r8000000008000000 16r8000000080000000
  1165         16r8000000000080000 16r8000000000800000 16r8000000008000000 16r8000000080000000
  1165 
  1166 
  1166 	16r80000000FFFFFFFF 16r800000007FFFFFFF 16r800000003FFFFFFF 16r800000001FFFFFFF
  1167         16r80000000FFFFFFFF 16r800000007FFFFFFF 16r800000003FFFFFFF 16r800000001FFFFFFF
  1167 	16r80000000EEEEEEEE 16r800000007EEEEEEE 16r800000003EEEEEEE 16r800000001EEEEEEE
  1168         16r80000000EEEEEEEE 16r800000007EEEEEEE 16r800000003EEEEEEE 16r800000001EEEEEEE
  1168 	16r80000000DDDDDDDD 16r800000007DDDDDDD 16r800000003DDDDDDD 16r800000001DDDDDDD
  1169         16r80000000DDDDDDDD 16r800000007DDDDDDD 16r800000003DDDDDDD 16r800000001DDDDDDD
  1169 	16r80000000CCCCCCCC 16r800000007CCCCCCC 16r800000003CCCCCCC 16r800000001CCCCCCC
  1170         16r80000000CCCCCCCC 16r800000007CCCCCCC 16r800000003CCCCCCC 16r800000001CCCCCCC
  1170 
  1171 
  1171 	16rFFFFFFFFFFFFFFFF 16r7FFFFFFFFFFFFFFF 16r3FFFFFFFFFFFFFFF 16r1FFFFFFFFFFFFFFF
  1172         16rFFFFFFFFFFFFFFFF 16r7FFFFFFFFFFFFFFF 16r3FFFFFFFFFFFFFFF 16r1FFFFFFFFFFFFFFF
  1172      ) do:[:n |
  1173      ) do:[:n |
  1173 	self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
  1174         self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
  1174      ]
  1175      ]
  1175 
  1176 
  1176      1 to:10000000 do:[:n |
  1177      1 to:10000000 do:[:n |
  1177 	(n bitCount)
  1178         (n bitCount)
  1178      ]
  1179      ]
  1179     "
  1180     "
  1180 
  1181 
  1181     "Modified: / 09-01-2012 / 19:12:41 / cg"
  1182     "Modified: / 09-01-2012 / 19:12:41 / cg"
  1182 !
  1183 !
  1233 #ifdef __SCHTEAM__
  1234 #ifdef __SCHTEAM__
  1234     return context._RETURN( self.bitOr( anInteger ));
  1235     return context._RETURN( self.bitOr( anInteger ));
  1235 #else
  1236 #else
  1236     /* oring the tags doesn't change it */
  1237     /* oring the tags doesn't change it */
  1237     if (__isSmallInteger(anInteger)) {
  1238     if (__isSmallInteger(anInteger)) {
  1238 	RETURN ( ((OBJ) ((INT)self | (INT)anInteger)) );
  1239         RETURN ( ((OBJ) ((INT)self | (INT)anInteger)) );
  1239     }
  1240     }
  1240 #endif /* not __SCHTEAM__ */
  1241 #endif /* not __SCHTEAM__ */
  1241 %}.
  1242 %}.
  1242     ^ self retry:#bitOr: coercing:anInteger
  1243     ^ self retry:#bitOr: coercing:anInteger
  1243 
  1244 
  1282     // swap 2-byte long pairs
  1283     // swap 2-byte long pairs
  1283     v = ((v >> 16) & 0x0000FFFF) | ((v & 0x0000FFFF) << 16);
  1284     v = ((v >> 16) & 0x0000FFFF) | ((v & 0x0000FFFF) << 16);
  1284 # endif
  1285 # endif
  1285 
  1286 
  1286     if (v <= _MAX_INT) {
  1287     if (v <= _MAX_INT) {
  1287 	RETURN ( __mkSmallInteger(v) );
  1288         RETURN ( __mkSmallInteger(v) );
  1288     }
  1289     }
  1289     RETURN (__MKUINT(v));
  1290     RETURN (__MKUINT(v));
  1290 #endif /* not __SCHTEAM__ */
  1291 #endif /* not __SCHTEAM__ */
  1291 %}.
  1292 %}.
  1292     ^ super bitReversed
  1293     ^ super bitReversed
  1315     v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
  1316     v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
  1316     // swap bytes
  1317     // swap bytes
  1317     v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
  1318     v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
  1318 
  1319 
  1319     if (v <= _MAX_INT) {
  1320     if (v <= _MAX_INT) {
  1320 	RETURN ( __mkSmallInteger(v) );
  1321         RETURN ( __mkSmallInteger(v) );
  1321     }
  1322     }
  1322     RETURN (__MKUINT(v));
  1323     RETURN (__MKUINT(v));
  1323 #endif /* not __SCHTEAM__ */
  1324 #endif /* not __SCHTEAM__ */
  1324 %}.
  1325 %}.
  1325     ^ super bitReversed16
  1326     ^ super bitReversed16
  1350     v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
  1351     v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
  1351     // swap 2-byte long pairs
  1352     // swap 2-byte long pairs
  1352     v = ((v >> 16) & 0x0000FFFF) | ((v & 0x0000FFFF) << 16);
  1353     v = ((v >> 16) & 0x0000FFFF) | ((v & 0x0000FFFF) << 16);
  1353 
  1354 
  1354     if (v <= _MAX_INT) {
  1355     if (v <= _MAX_INT) {
  1355 	RETURN ( __mkSmallInteger(v) );
  1356         RETURN ( __mkSmallInteger(v) );
  1356     }
  1357     }
  1357     RETURN (__MKUINT(v));
  1358     RETURN (__MKUINT(v));
  1358 #endif /* not __SCHTEAM__ */
  1359 #endif /* not __SCHTEAM__ */
  1359 %}.
  1360 %}.
  1360     ^ super bitReversed32
  1361     ^ super bitReversed32
  1381     v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
  1382     v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
  1382     // swap nibbles ...
  1383     // swap nibbles ...
  1383     v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
  1384     v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
  1384 
  1385 
  1385     if (v <= _MAX_INT) {
  1386     if (v <= _MAX_INT) {
  1386 	RETURN ( __mkSmallInteger(v) );
  1387         RETURN ( __mkSmallInteger(v) );
  1387     }
  1388     }
  1388     RETURN (__MKUINT(v));
  1389     RETURN (__MKUINT(v));
  1389 #endif /* not __SCHTEAM__ */
  1390 #endif /* not __SCHTEAM__ */
  1390 %}.
  1391 %}.
  1391     ^ super bitReversed8
  1392     ^ super bitReversed8
  1400 
  1401 
  1401 bitShift:shiftCount
  1402 bitShift:shiftCount
  1402     "return the value of the receiver shifted by shiftCount bits;
  1403     "return the value of the receiver shifted by shiftCount bits;
  1403      leftShift if shiftCount > 0; rightShift otherwise.
  1404      leftShift if shiftCount > 0; rightShift otherwise.
  1404      Notice: the result of bitShift: on negative receivers is not
  1405      Notice: the result of bitShift: on negative receivers is not
  1405 	     defined in the language standard (since the implementation
  1406              defined in the language standard (since the implementation
  1406 	     is free to choose any internal representation for integers).
  1407              is free to choose any internal representation for integers).
  1407 	     However, ST/X preserves the sign."
  1408              However, ST/X preserves the sign."
  1408 
  1409 
  1409 %{  /* NOCONTEXT */
  1410 %{  /* NOCONTEXT */
  1410 #ifdef __SCHTEAM__
  1411 #ifdef __SCHTEAM__
  1411     return context._RETURN( self.bitShift( shiftCount ));
  1412     return context._RETURN( self.bitShift( shiftCount ));
  1412 #else
  1413 #else
  1413     INT bits, count;
  1414     INT bits, count;
  1414 
  1415 
  1415     if (__isSmallInteger(shiftCount)) {
  1416     if (__isSmallInteger(shiftCount)) {
  1416 	bits = __intVal(self);
  1417         bits = __intVal(self);
  1417 	if (bits == 0) {
  1418         if (bits == 0) {
  1418 	    RETURN (self);
  1419             RETURN (self);
  1419 	}
  1420         }
  1420 	count = __intVal(shiftCount);
  1421         count = __intVal(shiftCount);
  1421 
  1422 
  1422 	if (count > 0) {
  1423         if (count > 0) {
  1423 	    INT sign = 1;
  1424             INT sign = 1;
  1424 	    if (bits < 0) {
  1425             if (bits < 0) {
  1425 		bits = -bits;
  1426                 bits = -bits;
  1426 		sign = -1;
  1427                 sign = -1;
  1427 	    }
  1428             }
  1428 	    /*
  1429             /*
  1429 	     * a left shift
  1430              * a left shift
  1430 	     */
  1431              */
  1431 # if defined(USE_LONGLONG_FOR_SHIFT)
  1432 # if defined(USE_LONGLONG_FOR_SHIFT)
  1432 	    if (count <= N_INT_BITS) {
  1433             if (count <= N_INT_BITS) {
  1433 		unsigned LONGLONG result;
  1434                 unsigned LONGLONG result;
  1434 
  1435 
  1435 		result = (unsigned LONGLONG)bits;
  1436                 result = (unsigned LONGLONG)bits;
  1436 		result <<= count;
  1437                 result <<= count;
  1437 		if (result <= _MAX_INT) {
  1438                 if (result <= _MAX_INT) {
  1438 		    if (sign < 0) {
  1439                     if (sign < 0) {
  1439 			RETURN ( __MKINT(-result) );
  1440                         RETURN ( __MKINT(-result) );
  1440 		    }
  1441                     }
  1441 		    RETURN ( __mkSmallInteger(result) );
  1442                     RETURN ( __mkSmallInteger(result) );
  1442 		}
  1443                 }
  1443 		{
  1444                 {
  1444 		    RETURN (__MKLARGEINT64(sign, (INT)(result >> 32), (INT)(result & 0xFFFFFFFF)));
  1445                     RETURN (__MKLARGEINT64(sign, (INT)(result >> 32), (INT)(result & 0xFFFFFFFF)));
  1445 		}
  1446                 }
  1446 	    }
  1447             }
  1447 # else
  1448 # else
  1448 	    /*
  1449             /*
  1449 	     * check for overflow
  1450              * check for overflow
  1450 	     */
  1451              */
  1451 	    if (count < (N_INT_BITS-1)) {
  1452             if (count < (N_INT_BITS-1)) {
  1452 		if (! (bits >> (N_INT_BITS - 1 - count))) {
  1453                 if (! (bits >> (N_INT_BITS - 1 - count))) {
  1453 		    INT result = bits << count;
  1454                     INT result = bits << count;
  1454 
  1455 
  1455 		    if (sign < 0) {
  1456                     if (sign < 0) {
  1456 			RETURN ( __MKINT(-result) );
  1457                         RETURN ( __MKINT(-result) );
  1457 		    }
  1458                     }
  1458 		    RETURN ( __mkSmallInteger(result) );
  1459                     RETURN ( __mkSmallInteger(result) );
  1459 		}
  1460                 }
  1460 		/*
  1461                 /*
  1461 		 * so, there is an overflow ...
  1462                  * so, there is an overflow ...
  1462 		 * handle it as largeInteger
  1463                  * handle it as largeInteger
  1463 		 */
  1464                  */
  1464 		/* FALL THROUGH */
  1465                 /* FALL THROUGH */
  1465 	    }
  1466             }
  1466 # endif
  1467 # endif
  1467 	} else {
  1468         } else {
  1468 	    if (count == 0) {
  1469             if (count == 0) {
  1469 		RETURN (self);
  1470                 RETURN (self);
  1470 	    }
  1471             }
  1471 
  1472 
  1472 	    /*
  1473             /*
  1473 	     * right shifts cannot overflow
  1474              * right shifts cannot overflow
  1474 	     *
  1475              *
  1475 	     * some machines ignore shifts bigger than
  1476              * some machines ignore shifts bigger than
  1476 	     * the number of bits in an int ...
  1477              * the number of bits in an int ...
  1477 	     */
  1478              */
  1478 	    count = -count;
  1479             count = -count;
  1479 	    if (count > (N_INT_BITS-1)) {
  1480             if (count > (N_INT_BITS-1)) {
  1480 		RETURN (__mkSmallInteger(0));
  1481                 RETURN (__mkSmallInteger(0));
  1481 	    }
  1482             }
  1482 
  1483 
  1483 	    RETURN ( __mkSmallInteger(bits >> count) );
  1484             RETURN ( __mkSmallInteger(bits >> count) );
  1484 	}
  1485         }
  1485     }
  1486     }
  1486 #endif /* not __SCHTEAM__ */
  1487 #endif /* not __SCHTEAM__ */
  1487 %}.
  1488 %}.
  1488     (shiftCount isMemberOf:SmallInteger) ifTrue:[
  1489     (shiftCount isMemberOf:SmallInteger) ifTrue:[
  1489 	^ (LargeInteger value:self) bitShift:shiftCount
  1490         ^ (LargeInteger value:self) bitShift:shiftCount
  1490     ].
  1491     ].
  1491     ^ self bitShift:shiftCount asInteger   "/ is this a good idea ?
  1492     ^ self bitShift:shiftCount asInteger   "/ is this a good idea ?
  1492 !
  1493 !
  1493 
  1494 
  1494 bitTest:aMask
  1495 bitTest:aMask
  1497      is non-0, false otherwise."
  1498      is non-0, false otherwise."
  1498 
  1499 
  1499 %{  /* NOCONTEXT */
  1500 %{  /* NOCONTEXT */
  1500 #ifdef __SCHTEAM__
  1501 #ifdef __SCHTEAM__
  1501     return context._RETURN(
  1502     return context._RETURN(
  1502 	    ( self.bitAnd( aMask ) == STInteger._0 )
  1503             ( self.bitAnd( aMask ) == STInteger._0 )
  1503 	    ? STObject.False : STObject.True );
  1504             ? STObject.False : STObject.True );
  1504     /* NOTREACHED */
  1505     /* NOTREACHED */
  1505 #else
  1506 #else
  1506     /* and all bits except tag */
  1507     /* and all bits except tag */
  1507     if (__isSmallInteger(aMask)) {
  1508     if (__isSmallInteger(aMask)) {
  1508 	RETURN ( ((INT)self & ((INT)aMask & ~TAG_MASK)) ? true : false );
  1509         RETURN ( ((INT)self & ((INT)aMask & ~TAG_MASK)) ? true : false );
  1509     }
  1510     }
  1510 #endif /* not __SCHTEAM__ */
  1511 #endif /* not __SCHTEAM__ */
  1511 %}.
  1512 %}.
  1512     aMask class == LargeInteger ifTrue:[
  1513     aMask class == LargeInteger ifTrue:[
  1513 	^ (aMask bitAnd:self) ~~ 0
  1514         ^ (aMask bitAnd:self) ~~ 0
  1514     ].
  1515     ].
  1515     ^ self retry:#bitTest: coercing:aMask
  1516     ^ self retry:#bitTest: coercing:aMask
  1516 
  1517 
  1517     "
  1518     "
  1518      2r10001 bitTest:2r00001
  1519      2r10001 bitTest:2r00001
  1532 #ifdef __SCHTEAM__
  1533 #ifdef __SCHTEAM__
  1533     return context._RETURN( self.bitXor( anInteger ));
  1534     return context._RETURN( self.bitXor( anInteger ));
  1534 #else
  1535 #else
  1535     /* xoring the tags turns it off - or it in again */
  1536     /* xoring the tags turns it off - or it in again */
  1536     if (__isSmallInteger(anInteger)) {
  1537     if (__isSmallInteger(anInteger)) {
  1537 	RETURN ( (OBJ)( ((INT)self ^ (INT)anInteger) | TAG_INT) );
  1538         RETURN ( (OBJ)( ((INT)self ^ (INT)anInteger) | TAG_INT) );
  1538     }
  1539     }
  1539 #endif /* not __SCHTEAM__ */
  1540 #endif /* not __SCHTEAM__ */
  1540 %}.
  1541 %}.
  1541     ^ self retry:#bitXor: coercing:anInteger
  1542     ^ self retry:#bitXor: coercing:anInteger
  1542 !
  1543 !
  1547      Returns 0 if no bit is set."
  1548      Returns 0 if no bit is set."
  1548 
  1549 
  1549 %{  /* NOCONTEXT */
  1550 %{  /* NOCONTEXT */
  1550 #ifdef __SCHTEAM__
  1551 #ifdef __SCHTEAM__
  1551     {
  1552     {
  1552 	long bits = self.longValue();
  1553         long bits = self.longValue();
  1553 	int bitNr = 0;
  1554         int bitNr = 0;
  1554 
  1555 
  1555 	if (bits != 0) {
  1556         if (bits != 0) {
  1556 	    if ((bits & 0xFFFFFFFF00000000L) != 0) {
  1557             if ((bits & 0xFFFFFFFF00000000L) != 0) {
  1557 		bitNr += 32; bits >>= 32;
  1558                 bitNr += 32; bits >>= 32;
  1558 	    }
  1559             }
  1559 	    if ((bits & 0xFFFF0000L) != 0) {
  1560             if ((bits & 0xFFFF0000L) != 0) {
  1560 		bitNr += 16; bits >>= 16;
  1561                 bitNr += 16; bits >>= 16;
  1561 	    }
  1562             }
  1562 	    if ((bits & 0xFF00) != 0) {
  1563             if ((bits & 0xFF00) != 0) {
  1563 		bitNr += 8; bits >>= 8;
  1564                 bitNr += 8; bits >>= 8;
  1564 	    }
  1565             }
  1565 	    if ((bits & 0xF0) != 0) {
  1566             if ((bits & 0xF0) != 0) {
  1566 		bitNr += 4; bits >>= 4;
  1567                 bitNr += 4; bits >>= 4;
  1567 	    }
  1568             }
  1568 	    if ((bits & 0xC) != 0) {
  1569             if ((bits & 0xC) != 0) {
  1569 		bitNr += 2; bits >>= 2;
  1570                 bitNr += 2; bits >>= 2;
  1570 	    }
  1571             }
  1571 	    if ((bits & 0x2) != 0) {
  1572             if ((bits & 0x2) != 0) {
  1572 		bitNr += 1; bits >>= 1;
  1573                 bitNr += 1; bits >>= 1;
  1573 	    }
  1574             }
  1574 	    bitNr += 1;
  1575             bitNr += 1;
  1575 	}
  1576         }
  1576 	return context._RETURN( STInteger._new(bitNr) );
  1577         return context._RETURN( STInteger._new(bitNr) );
  1577     }
  1578     }
  1578     /* NOTREACHED */
  1579     /* NOTREACHED */
  1579 #else
  1580 #else
  1580     unsigned INT bits;
  1581     unsigned INT bits;
  1581     int index;
  1582     int index;
  1582 
  1583 
  1583     bits = __intVal(self);
  1584     bits = __intVal(self);
  1584     if (bits == 0) {
  1585     if (bits == 0) {
  1585 	RETURN ( __mkSmallInteger(0) );
  1586         RETURN ( __mkSmallInteger(0) );
  1586     }
  1587     }
  1587 
  1588 
  1588 # ifdef __BSR
  1589 # ifdef __BSR
  1589     /*
  1590     /*
  1590      * so much for CISC CPUS:
  1591      * so much for CISC CPUS:
  1596 
  1597 
  1597     index = 0;
  1598     index = 0;
  1598 
  1599 
  1599 #  if __POINTER_SIZE__ == 8
  1600 #  if __POINTER_SIZE__ == 8
  1600     if (bits & 0xFFFFFFFF00000000L) {
  1601     if (bits & 0xFFFFFFFF00000000L) {
  1601 	index += 32; bits >>= 32;
  1602         index += 32; bits >>= 32;
  1602     }
  1603     }
  1603 #  endif
  1604 #  endif
  1604     if (bits & 0xFFFF0000L) {
  1605     if (bits & 0xFFFF0000L) {
  1605 	index += 16; bits >>= 16;
  1606         index += 16; bits >>= 16;
  1606     }
  1607     }
  1607     if (bits & 0xFF00) {
  1608     if (bits & 0xFF00) {
  1608 	index += 8; bits >>= 8;
  1609         index += 8; bits >>= 8;
  1609     }
  1610     }
  1610     if (bits & 0xF0) {
  1611     if (bits & 0xF0) {
  1611 	index += 4; bits >>= 4;
  1612         index += 4; bits >>= 4;
  1612     }
  1613     }
  1613     if (bits & 0xC) {
  1614     if (bits & 0xC) {
  1614 	index += 2; bits >>= 2;
  1615         index += 2; bits >>= 2;
  1615     }
  1616     }
  1616     if (bits & 0x2) {
  1617     if (bits & 0x2) {
  1617 	index += 1; bits >>= 1;
  1618         index += 1; bits >>= 1;
  1618     }
  1619     }
  1619 # endif /* no BSR instruction */
  1620 # endif /* no BSR instruction */
  1620 
  1621 
  1621     RETURN ( __mkSmallInteger(index+1) );
  1622     RETURN ( __mkSmallInteger(index+1) );
  1622 #endif /* not __SCHTEAM__ */
  1623 #endif /* not __SCHTEAM__ */
  1630      2r100 highBit
  1631      2r100 highBit
  1631      2r1000 highBit
  1632      2r1000 highBit
  1632      2r100000000000 highBit
  1633      2r100000000000 highBit
  1633 
  1634 
  1634      ((0 to:64) collect:[:s | 1 bitShift:s])
  1635      ((0 to:64) collect:[:s | 1 bitShift:s])
  1635 	collect:[:n | n highBit]
  1636         collect:[:n | n highBit]
  1636 
  1637 
  1637      (((0 to:64) collect:[:s | 1 bitShift:s])
  1638      (((0 to:64) collect:[:s | 1 bitShift:s])
  1638 	collect:[:n | n highBit]) = (1 to:65)
  1639         collect:[:n | n highBit]) = (1 to:65)
  1639     "
  1640     "
  1640 
  1641 
  1641     "
  1642     "
  1642      Time millisecondsToRun:[
  1643      Time millisecondsToRun:[
  1643 	1000000 timesRepeat:[
  1644         1000000 timesRepeat:[
  1644 	    2r1 highBit
  1645             2r1 highBit
  1645 	]
  1646         ]
  1646      ]
  1647      ]
  1647     "
  1648     "
  1648     "
  1649     "
  1649      Time millisecondsToRun:[
  1650      Time millisecondsToRun:[
  1650 	1000000 timesRepeat:[
  1651         1000000 timesRepeat:[
  1651 	    2r1111 highBit
  1652             2r1111 highBit
  1652 	]
  1653         ]
  1653      ]
  1654      ]
  1654     "
  1655     "
  1655     "
  1656     "
  1656      Time millisecondsToRun:[
  1657      Time millisecondsToRun:[
  1657 	1000000 timesRepeat:[
  1658         1000000 timesRepeat:[
  1658 	    2r11111111111111 highBit
  1659             2r11111111111111 highBit
  1659 	]
  1660         ]
  1660      ]
  1661      ]
  1661     "
  1662     "
  1662     "
  1663     "
  1663      Time millisecondsToRun:[
  1664      Time millisecondsToRun:[
  1664 	1000000 timesRepeat:[
  1665         1000000 timesRepeat:[
  1665 	    2r11111111111111111111111111 highBit
  1666             2r11111111111111111111111111 highBit
  1666 	]
  1667         ]
  1667      ]
  1668      ]
  1668     "
  1669     "
  1669 
  1670 
  1670     "
  1671     "
  1671      2r000100 highBit
  1672      2r000100 highBit
  1685 #ifdef __SCHTEAM__
  1686 #ifdef __SCHTEAM__
  1686     long bits = self.longValue();
  1687     long bits = self.longValue();
  1687     int index = 0;
  1688     int index = 0;
  1688 
  1689 
  1689     if (bits != 0) {
  1690     if (bits != 0) {
  1690 	if ((bits & 0xFFFFFFFFL)==0) {
  1691         if ((bits & 0xFFFFFFFFL)==0) {
  1691 	    index += 32; bits >>= 32;
  1692             index += 32; bits >>= 32;
  1692 	}
  1693         }
  1693 	if ((bits & 0xFFFFL)==0) {
  1694         if ((bits & 0xFFFFL)==0) {
  1694 	    index += 16; bits >>= 16;
  1695             index += 16; bits >>= 16;
  1695 	}
  1696         }
  1696 	if ((bits & 0xFFL)==0) {
  1697         if ((bits & 0xFFL)==0) {
  1697 	    index += 8; bits >>= 8;
  1698             index += 8; bits >>= 8;
  1698 	}
  1699         }
  1699 	if ((bits & 0xFL)==0) {
  1700         if ((bits & 0xFL)==0) {
  1700 	    index += 4; bits >>= 4;
  1701             index += 4; bits >>= 4;
  1701 	}
  1702         }
  1702 	if ((bits & 0x3L)==0) {
  1703         if ((bits & 0x3L)==0) {
  1703 	    index += 2; bits >>= 2;
  1704             index += 2; bits >>= 2;
  1704 	}
  1705         }
  1705 	if ((bits & 0x1L)==0) {
  1706         if ((bits & 0x1L)==0) {
  1706 	    index += 1;
  1707             index += 1;
  1707 	}
  1708         }
  1708     }
  1709     }
  1709     return __c__._RETURN( STInteger._qnew( index ) );
  1710     return __c__._RETURN( STInteger._qnew( index ) );
  1710 #else
  1711 #else
  1711     unsigned INT bits;
  1712     unsigned INT bits;
  1712     int index;
  1713     int index;
  1713 
  1714 
  1714     bits = __intVal(self);
  1715     bits = __intVal(self);
  1715     if (bits == 0) {
  1716     if (bits == 0) {
  1716 	RETURN ( __mkSmallInteger(0) );
  1717         RETURN ( __mkSmallInteger(0) );
  1717     }
  1718     }
  1718 
  1719 
  1719 # ifdef __BSF
  1720 # ifdef __BSF
  1720     /*
  1721     /*
  1721      * so much for CISC CPUS:
  1722      * so much for CISC CPUS:
  1729 
  1730 
  1730     index = 1;
  1731     index = 1;
  1731 
  1732 
  1732 #  if __POINTER_SIZE__ == 8
  1733 #  if __POINTER_SIZE__ == 8
  1733     if ((bits<<32) == 0) {
  1734     if ((bits<<32) == 0) {
  1734 	index += 32; bits >>= 32;
  1735         index += 32; bits >>= 32;
  1735     }
  1736     }
  1736 #  endif
  1737 #  endif
  1737 
  1738 
  1738     if ((bits & 0xFFFF)==0) {
  1739     if ((bits & 0xFFFF)==0) {
  1739 	index += 16; bits >>= 16;
  1740         index += 16; bits >>= 16;
  1740     }
  1741     }
  1741     if ((bits & 0xFF)==0) {
  1742     if ((bits & 0xFF)==0) {
  1742 	index += 8; bits >>= 8;
  1743         index += 8; bits >>= 8;
  1743     }
  1744     }
  1744     if ((bits & 0xF)==0) {
  1745     if ((bits & 0xF)==0) {
  1745 	index += 4; bits >>= 4;
  1746         index += 4; bits >>= 4;
  1746     }
  1747     }
  1747     if ((bits & 0x3)==0) {
  1748     if ((bits & 0x3)==0) {
  1748 	index += 2; bits >>= 2;
  1749         index += 2; bits >>= 2;
  1749     }
  1750     }
  1750     if ((bits & 0x1)==0) {
  1751     if ((bits & 0x1)==0) {
  1751 	index += 1;
  1752         index += 1;
  1752     }
  1753     }
  1753 # endif
  1754 # endif
  1754 
  1755 
  1755     RETURN ( __mkSmallInteger(index) );
  1756     RETURN ( __mkSmallInteger(index) );
  1756 #endif /* not __SCHTEAM__ */
  1757 #endif /* not __SCHTEAM__ */
  1770      16r1000 lowBit
  1771      16r1000 lowBit
  1771      16r1000000 lowBit
  1772      16r1000000 lowBit
  1772      16r1000000000000000 lowBit
  1773      16r1000000000000000 lowBit
  1773 
  1774 
  1774      Time millisecondsToRun:[
  1775      Time millisecondsToRun:[
  1775 	1000000 timesRepeat:[
  1776         1000000 timesRepeat:[
  1776 	    2r1000 lowBit
  1777             2r1000 lowBit
  1777 	]
  1778         ]
  1778      ]
  1779      ]
  1779 
  1780 
  1780      Time millisecondsToRun:[
  1781      Time millisecondsToRun:[
  1781 	1000000 timesRepeat:[
  1782         1000000 timesRepeat:[
  1782 	    2r11110000000 lowBit
  1783             2r11110000000 lowBit
  1783 	]
  1784         ]
  1784      ]
  1785      ]
  1785 
  1786 
  1786      Time millisecondsToRun:[
  1787      Time millisecondsToRun:[
  1787 	1000000 timesRepeat:[
  1788         1000000 timesRepeat:[
  1788 	    2r1000000000000 lowBit
  1789             2r1000000000000 lowBit
  1789 	]
  1790         ]
  1790      ]
  1791      ]
  1791 
  1792 
  1792      Time millisecondsToRun:[
  1793      Time millisecondsToRun:[
  1793 	1000000 timesRepeat:[
  1794         1000000 timesRepeat:[
  1794 	    2r1000000000000000000000000000 lowBit
  1795             2r1000000000000000000000000000 lowBit
  1795 	]
  1796         ]
  1796      ]
  1797      ]
  1797     "
  1798     "
  1798 !
  1799 !
  1799 
  1800 
  1800 rightShift:shiftCount
  1801 rightShift:shiftCount
  1801     "return the value of the receiver shifted by shiftCount bits;
  1802     "return the value of the receiver shifted by shiftCount bits;
  1802      right shift if shiftCount > 0; left shift  otherwise.
  1803      right shift if shiftCount > 0; left shift  otherwise.
  1803      Notice: the result of bitShift: on negative receivers is not
  1804      Notice: the result of bitShift: on negative receivers is not
  1804 	     defined in the language standard (since the implementation
  1805              defined in the language standard (since the implementation
  1805 	     is free to choose any internal representation for integers).
  1806              is free to choose any internal representation for integers).
  1806 	     However, ST/X preserves the sign."
  1807              However, ST/X preserves the sign."
  1807 
  1808 
  1808 %{  /* NOCONTEXT */
  1809 %{  /* NOCONTEXT */
  1809 #ifdef __SCHTEAM__
  1810 #ifdef __SCHTEAM__
  1810 #else
  1811 #else
  1811     INT bits, count;
  1812     INT bits, count;
  1812 
  1813 
  1813     if (__isSmallInteger(shiftCount)) {
  1814     if (__isSmallInteger(shiftCount)) {
  1814 	bits = __intVal(self);
  1815         bits = __intVal(self);
  1815 	if (bits == 0) {
  1816         if (bits == 0) {
  1816 	    RETURN (self);
  1817             RETURN (self);
  1817 	}
  1818         }
  1818 
  1819 
  1819 	count = __intVal(shiftCount);
  1820         count = __intVal(shiftCount);
  1820 
  1821 
  1821 	if (count < 0) {
  1822         if (count < 0) {
  1822 	    /*
  1823             /*
  1823 	     * a left shift
  1824              * a left shift
  1824 	     */
  1825              */
  1825 	    count = -count;
  1826             count = -count;
  1826 # if defined(USE_LONGLONG_FOR_SHIFT)
  1827 # if defined(USE_LONGLONG_FOR_SHIFT)
  1827 	    if (count <= N_INT_BITS) {
  1828             if (count <= N_INT_BITS) {
  1828 		unsigned LONGLONG result;
  1829                 unsigned LONGLONG result;
  1829 
  1830 
  1830 		result = (unsigned LONGLONG)bits;
  1831                 result = (unsigned LONGLONG)bits;
  1831 		result <<= count;
  1832                 result <<= count;
  1832 		if (result <= _MAX_INT) {
  1833                 if (result <= _MAX_INT) {
  1833 		    RETURN ( __mkSmallInteger(result) );
  1834                     RETURN ( __mkSmallInteger(result) );
  1834 		}
  1835                 }
  1835 		{
  1836                 {
  1836 		    RETURN (__MKLARGEINT64(1, (INT)(result >> 32), (INT)(result & 0xFFFFFFFF)));
  1837                     RETURN (__MKLARGEINT64(1, (INT)(result >> 32), (INT)(result & 0xFFFFFFFF)));
  1837 		}
  1838                 }
  1838 	    }
  1839             }
  1839 # else
  1840 # else
  1840 	    /*
  1841             /*
  1841 	     * check for overflow
  1842              * check for overflow
  1842 	     */
  1843              */
  1843 	    if (count < (N_INT_BITS-1)) {
  1844             if (count < (N_INT_BITS-1)) {
  1844 		if (! (bits >> (N_INT_BITS - 1 - count))) {
  1845                 if (! (bits >> (N_INT_BITS - 1 - count))) {
  1845 		    RETURN ( __mkSmallInteger(bits << count) );
  1846                     RETURN ( __mkSmallInteger(bits << count) );
  1846 		}
  1847                 }
  1847 		/*
  1848                 /*
  1848 		 * so, there is an overflow ...
  1849                  * so, there is an overflow ...
  1849 		 * handle it as largeInteger
  1850                  * handle it as largeInteger
  1850 		 */
  1851                  */
  1851 		/* FALL THROUGH */
  1852                 /* FALL THROUGH */
  1852 	    }
  1853             }
  1853 # endif
  1854 # endif
  1854 	} else {
  1855         } else {
  1855 	    if (count == 0) {
  1856             if (count == 0) {
  1856 		RETURN (self);
  1857                 RETURN (self);
  1857 	    }
  1858             }
  1858 
  1859 
  1859 	    /*
  1860             /*
  1860 	     * right shifts cannot overflow
  1861              * right shifts cannot overflow
  1861 	     *
  1862              *
  1862 	     * some machines ignore shifts bigger than
  1863              * some machines ignore shifts bigger than
  1863 	     * the number of bits in an int ...
  1864              * the number of bits in an int ...
  1864 	     */
  1865              */
  1865 	    if (count > (N_INT_BITS-1)) {
  1866             if (count > (N_INT_BITS-1)) {
  1866 		RETURN (__mkSmallInteger(0));
  1867                 RETURN (__mkSmallInteger(0));
  1867 	    }
  1868             }
  1868 
  1869 
  1869 	    RETURN ( __mkSmallInteger(bits >> count) );
  1870             RETURN ( __mkSmallInteger(bits >> count) );
  1870 	}
  1871         }
  1871     }
  1872     }
  1872 #endif /* not __SCHTEAM__ */
  1873 #endif /* not __SCHTEAM__ */
  1873 %}.
  1874 %}.
  1874     (shiftCount isMemberOf:SmallInteger) ifTrue:[
  1875     (shiftCount isMemberOf:SmallInteger) ifTrue:[
  1875 	^ (LargeInteger value:self) rightShift:shiftCount
  1876         ^ (LargeInteger value:self) rightShift:shiftCount
  1876     ].
  1877     ].
  1877     ^ self rightShift:shiftCount asInteger   "/ is this a good idea ?
  1878     ^ self rightShift:shiftCount asInteger   "/ is this a good idea ?
  1878 
  1879 
  1879 
  1880 
  1880     "
  1881     "
  1881 	16 rightShift:2
  1882         16 rightShift:2
  1882 	 4 rightShift:-2
  1883          4 rightShift:-2
  1883     "
  1884     "
  1884 ! !
  1885 ! !
  1885 
  1886 
  1886 !SmallInteger methodsFor:'bit operators - indexed'!
  1887 !SmallInteger methodsFor:'bit operators - indexed'!
  1887 
  1888 
  1888 bitAt:anIntegerIndex
  1889 bitAt:anIntegerIndex
  1889     "return the value of the index's bit (index starts at 1) as 0 or 1.
  1890     "return the value of the index's bit (index starts at 1) as 0 or 1.
  1890      Notice: the result of bitAt: on negative receivers is not
  1891      Notice: the result of bitAt: on negative receivers is not
  1891 	     defined in the language standard (since the implementation
  1892              defined in the language standard (since the implementation
  1892 	     is free to choose any internal representation for integers)"
  1893              is free to choose any internal representation for integers)"
  1893 
  1894 
  1894 %{  /* NOCONTEXT */
  1895 %{  /* NOCONTEXT */
  1895 #ifdef __SCHTEAM__
  1896 #ifdef __SCHTEAM__
  1896     return context._RETURN( self.bitAt(anIntegerIndex));
  1897     return context._RETURN( self.bitAt(anIntegerIndex));
  1897 #else
  1898 #else
  1898     if (__isSmallInteger(anIntegerIndex)) {
  1899     if (__isSmallInteger(anIntegerIndex)) {
  1899 	INT idx = __smallIntegerVal(anIntegerIndex);
  1900         INT idx = __smallIntegerVal(anIntegerIndex);
  1900 	if (idx > 0) {
  1901         if (idx > 0) {
  1901 	    if (idx > N_INT_BITS) {
  1902             if (idx > N_INT_BITS) {
  1902 		RETURN(__mkSmallInteger(0));
  1903                 RETURN(__mkSmallInteger(0));
  1903 	    }
  1904             }
  1904 	    RETURN((__smallIntegerVal(self) & ((INT)1 << (idx-1))) ? __mkSmallInteger(1) : __mkSmallInteger(0));
  1905             RETURN((__smallIntegerVal(self) & ((INT)1 << (idx-1))) ? __mkSmallInteger(1) : __mkSmallInteger(0));
  1905 	}
  1906         }
  1906     }
  1907     }
  1907 #endif /* not __SCHTEAM__ */
  1908 #endif /* not __SCHTEAM__ */
  1908 %}.
  1909 %}.
  1909 
  1910 
  1910     ^ SubscriptOutOfBoundsError
  1911     ^ SubscriptOutOfBoundsError
  1911 	    raiseRequestWith:anIntegerIndex
  1912             raiseRequestWith:anIntegerIndex
  1912 	    errorString:'index out of bounds'
  1913             errorString:'index out of bounds'
  1913 
  1914 
  1914     "
  1915     "
  1915      16r000000001 bitAt:0 -> error
  1916      16r000000001 bitAt:0 -> error
  1916      16r000000001 bitAt:1
  1917      16r000000001 bitAt:1
  1917      16r000000001 bitAt:2
  1918      16r000000001 bitAt:2
  1927 
  1928 
  1928 " Smalltalk implementation:
  1929 " Smalltalk implementation:
  1929     |mask|
  1930     |mask|
  1930 
  1931 
  1931     anIntegerIndex <= 0 ifTrue:[
  1932     anIntegerIndex <= 0 ifTrue:[
  1932 	^ SubscriptOutOfBoundsSignal
  1933         ^ SubscriptOutOfBoundsSignal
  1933 		raiseRequestWith:anIntegerIndex
  1934                 raiseRequestWith:anIntegerIndex
  1934 		errorString:'index out of bounds'
  1935                 errorString:'index out of bounds'
  1935     ].
  1936     ].
  1936     (anIntegerIndex > SmallInteger maxBits) ifTrue:[^ 0].
  1937     (anIntegerIndex > SmallInteger maxBits) ifTrue:[^ 0].
  1937     mask := 1 bitShift:(anIntegerIndex - 1).
  1938     mask := 1 bitShift:(anIntegerIndex - 1).
  1938     ((self bitAnd:mask) == 0) ifTrue:[^ 0].
  1939     ((self bitAnd:mask) == 0) ifTrue:[^ 0].
  1939     ^ 1
  1940     ^ 1
  1947      but a new number is returned. Should be named #withBitCleared:"
  1948      but a new number is returned. Should be named #withBitCleared:"
  1948 
  1949 
  1949 %{  /* NOCONTEXT */
  1950 %{  /* NOCONTEXT */
  1950 #ifndef __SCHTEAM__
  1951 #ifndef __SCHTEAM__
  1951     if (__isSmallInteger(anInteger)) {
  1952     if (__isSmallInteger(anInteger)) {
  1952 	int index = __intVal(anInteger);
  1953         int index = __intVal(anInteger);
  1953 
  1954 
  1954 	if (index > 0) {
  1955         if (index > 0) {
  1955 # if __POINTER_SIZE__ == 8
  1956 # if __POINTER_SIZE__ == 8
  1956 	    if (index <= 62)
  1957             if (index <= 62)
  1957 # else
  1958 # else
  1958 	    if (index <= 30)
  1959             if (index <= 30)
  1959 # endif
  1960 # endif
  1960 	    {
  1961             {
  1961 		INT mask = __MASKSMALLINT( ((INT)1 << (index-1)));
  1962                 INT mask = __MASKSMALLINT( ((INT)1 << (index-1)));
  1962 
  1963 
  1963 		RETURN ( ((OBJ) ((INT)self & ~(INT)mask)) );
  1964                 RETURN ( ((OBJ) ((INT)self & ~(INT)mask)) );
  1964 	    }
  1965             }
  1965 	    RETURN (self);  /* nothing to do ... */
  1966             RETURN (self);  /* nothing to do ... */
  1966 	}
  1967         }
  1967     }
  1968     }
  1968 #endif /* not __SCHTEAM__ */
  1969 #endif /* not __SCHTEAM__ */
  1969 %}.
  1970 %}.
  1970     ^ super clearBit:anInteger
  1971     ^ super clearBit:anInteger
  1971 
  1972 
  1995      but a new number is returned. Should be named #withBitInverted:"
  1996      but a new number is returned. Should be named #withBitInverted:"
  1996 
  1997 
  1997 %{  /* NOCONTEXT */
  1998 %{  /* NOCONTEXT */
  1998 #ifndef __SCHTEAM__
  1999 #ifndef __SCHTEAM__
  1999     if (__isSmallInteger(anInteger)) {
  2000     if (__isSmallInteger(anInteger)) {
  2000 	int index = __intVal(anInteger);
  2001         int index = __intVal(anInteger);
  2001 
  2002 
  2002 	if (index > 0) {
  2003         if (index > 0) {
  2003 # if __POINTER_SIZE__ == 8
  2004 # if __POINTER_SIZE__ == 8
  2004 	    if (index <= 62)
  2005             if (index <= 62)
  2005 # else
  2006 # else
  2006 	    if (index <= 30)
  2007             if (index <= 30)
  2007 # endif
  2008 # endif
  2008 	    {
  2009             {
  2009 		INT mask = __MASKSMALLINT((INT)1 << (index-1));
  2010                 INT mask = __MASKSMALLINT((INT)1 << (index-1));
  2010 
  2011 
  2011 		RETURN ( ((OBJ) ((INT)self ^ (INT)mask)) );
  2012                 RETURN ( ((OBJ) ((INT)self ^ (INT)mask)) );
  2012 	    }
  2013             }
  2013 	}
  2014         }
  2014     }
  2015     }
  2015 #endif /* not __SCHTEAM__ */
  2016 #endif /* not __SCHTEAM__ */
  2016 %}.
  2017 %}.
  2017     ^ super invertBit:anInteger
  2018     ^ super invertBit:anInteger
  2018 
  2019 
  2037      but a new number is returned. Should be named #withBitSet:"
  2038      but a new number is returned. Should be named #withBitSet:"
  2038 
  2039 
  2039 %{  /* NOCONTEXT */
  2040 %{  /* NOCONTEXT */
  2040 #ifndef __SCHTEAM__
  2041 #ifndef __SCHTEAM__
  2041     if (__isSmallInteger(anInteger)) {
  2042     if (__isSmallInteger(anInteger)) {
  2042 	int index = __intVal(anInteger);
  2043         int index = __intVal(anInteger);
  2043 
  2044 
  2044 	if (index > 0) {
  2045         if (index > 0) {
  2045 # if __POINTER_SIZE__ == 8
  2046 # if __POINTER_SIZE__ == 8
  2046 	    if (index <= 62)
  2047             if (index <= 62)
  2047 # else
  2048 # else
  2048 	    if (index <= 30)
  2049             if (index <= 30)
  2049 # endif
  2050 # endif
  2050 	    {
  2051             {
  2051 		INT mask = __MASKSMALLINT((INT)1 << (index-1));
  2052                 INT mask = __MASKSMALLINT((INT)1 << (index-1));
  2052 
  2053 
  2053 		RETURN ( ((OBJ) ((INT)self | (INT)mask)) );
  2054                 RETURN ( ((OBJ) ((INT)self | (INT)mask)) );
  2054 	    }
  2055             }
  2055 	}
  2056         }
  2056     }
  2057     }
  2057 #endif /* not __SCHTEAM__ */
  2058 #endif /* not __SCHTEAM__ */
  2058 %}.
  2059 %}.
  2059     ^ super setBit:anInteger
  2060     ^ super setBit:anInteger
  2060 
  2061 
  2076 byteSwapped
  2077 byteSwapped
  2077     "lsb -> msb;
  2078     "lsb -> msb;
  2078      i.e. a.b.c.d -> d.c.b.a"
  2079      i.e. a.b.c.d -> d.c.b.a"
  2079 
  2080 
  2080     SmallInteger maxBytes == 8 ifTrue:[
  2081     SmallInteger maxBytes == 8 ifTrue:[
  2081 	^ self byteSwapped64
  2082         ^ self byteSwapped64
  2082     ] ifFalse:[
  2083     ] ifFalse:[
  2083 	^ self byteSwapped32
  2084         ^ self byteSwapped32
  2084     ].
  2085     ].
  2085 
  2086 
  2086     "
  2087     "
  2087      16r11223344 byteSwapped hexPrintString
  2088      16r11223344 byteSwapped hexPrintString
  2088      16r44332211 byteSwapped hexPrintString
  2089      16r44332211 byteSwapped hexPrintString
  2129 
  2130 
  2130 #  if defined(USE_BSWAP) && defined(__BORLANDC__)
  2131 #  if defined(USE_BSWAP) && defined(__BORLANDC__)
  2131 #   define HAVE_BSWAP
  2132 #   define HAVE_BSWAP
  2132 
  2133 
  2133     _asm {
  2134     _asm {
  2134 	mov eax, v
  2135         mov eax, v
  2135 	bswap eax
  2136         bswap eax
  2136 	mov swapped, eax
  2137         mov swapped, eax
  2137     };
  2138     };
  2138 #  endif
  2139 #  endif
  2139 #  if defined(USE_BSWAP) && defined(__VISUALC__)
  2140 #  if defined(USE_BSWAP) && defined(__VISUALC__)
  2140 #   define HAVE_BSWAP
  2141 #   define HAVE_BSWAP
  2141 
  2142 
  2142     _asm {
  2143     _asm {
  2143 	mov eax, v
  2144         mov eax, v
  2144 	xchg al, ah
  2145         xchg al, ah
  2145 	rol eax, 16
  2146         rol eax, 16
  2146 	xchg al, ah
  2147         xchg al, ah
  2147 	mov swapped, eax
  2148         mov swapped, eax
  2148     };
  2149     };
  2149 #  endif
  2150 #  endif
  2150 #  if defined(USE_BSWAP) && defined(__GNUC__)
  2151 #  if defined(USE_BSWAP) && defined(__GNUC__)
  2151 #   define HAVE_BSWAP
  2152 #   define HAVE_BSWAP
  2152 
  2153 
  2153     asm("movl %1, %%eax \n\
  2154     asm("movl %1, %%eax \n\
  2154 	 bswap %%eax    \n\
  2155          bswap %%eax    \n\
  2155 	 movl %%eax, %0 \n\
  2156          movl %%eax, %0 \n\
  2156 	"
  2157         "
  2157 	: "=rm"  (swapped)
  2158         : "=rm"  (swapped)
  2158 	: "rm"   (v));
  2159         : "rm"   (v));
  2159 #  endif
  2160 #  endif
  2160 # endif /* __POINTER_SIZE__ == 4 */
  2161 # endif /* __POINTER_SIZE__ == 4 */
  2161 
  2162 
  2162 # if __POINTER_SIZE__ == 8
  2163 # if __POINTER_SIZE__ == 8
  2163     v &= 0xFFFFFFFF;
  2164     v &= 0xFFFFFFFF;
  2164 
  2165 
  2165 #  if defined(__x86_64__) && defined(__GNUC__) && !defined(__CLANG__)
  2166 #  if defined(__x86_64__) && defined(__GNUC__) && !defined(__CLANG__)
  2166 #   define HAVE_BSWAP
  2167 #   define HAVE_BSWAP
  2167 
  2168 
  2168     asm("movq %1, %%rax \n\
  2169     asm("movq %1, %%rax \n\
  2169 	 bswap %%eax    \n\
  2170          bswap %%eax    \n\
  2170 	 movq %%rax, %0 \n\
  2171          movq %%rax, %0 \n\
  2171 	"
  2172         "
  2172 	: "=rm"  (swapped)
  2173         : "=rm"  (swapped)
  2173 	: "rm"   (v));
  2174         : "rm"   (v));
  2174 #  endif
  2175 #  endif
  2175 # endif
  2176 # endif
  2176 
  2177 
  2177 # ifndef HAVE_BSWAP
  2178 # ifndef HAVE_BSWAP
  2178     swapped = ((v>>24) | ((v>>8)&0xFF00) | ((v & 0xFF00)<<8) | ((v & 0xFF)<<24));
  2179     swapped = ((v>>24) | ((v>>8)&0xFF00) | ((v & 0xFF00)<<8) | ((v & 0xFF)<<24));
  2212     //   xxxxxxxx 00000000 00000000 00000000 -> 00000000 00000000 00000000 xxxxxxxx
  2213     //   xxxxxxxx 00000000 00000000 00000000 -> 00000000 00000000 00000000 xxxxxxxx
  2213     //            xxxxxxxx                                        xxxxxxxx
  2214     //            xxxxxxxx                                        xxxxxxxx
  2214     //                     xxxxxxxx                      xxxxxxxx
  2215     //                     xxxxxxxx                      xxxxxxxx
  2215     //                              xxxxxxxx    xxxxxxxx
  2216     //                              xxxxxxxx    xxxxxxxx
  2216     swapped =  (v>>56) | ((v>>40)&0xFF00) | ((v>>24) & 0xFF0000) | ((v>>8) & 0xFF000000)
  2217     swapped =  (v>>56) | ((v>>40)&0xFF00) | ((v>>24) & 0xFF0000) | ((v>>8) & 0xFF000000)
  2217 		| ((v & 0xFF000000)<<8) | ((v & 0x00FF0000)<<24) | ((v & 0x0000FF00)<<40)
  2218                 | ((v & 0xFF000000)<<8) | ((v & 0x00FF0000)<<24) | ((v & 0x0000FF00)<<40)
  2218 		| ((v & 0xFF)<<56);
  2219                 | ((v & 0xFF)<<56);
  2219 # endif
  2220 # endif
  2220     RETURN(__MKUINT( swapped ));
  2221     RETURN(__MKUINT( swapped ));
  2221 #endif /* not __SCHTEAM__ */
  2222 #endif /* not __SCHTEAM__ */
  2222 %}.
  2223 %}.
  2223     ^ super byteSwapped64
  2224     ^ super byteSwapped64
  2236 %{  /* NOCONTEXT */
  2237 %{  /* NOCONTEXT */
  2237 #ifdef __SCHTEAM__
  2238 #ifdef __SCHTEAM__
  2238     int idx0Based = index.intValue() - 1;
  2239     int idx0Based = index.intValue() - 1;
  2239 
  2240 
  2240     if (idx0Based <= 7) {
  2241     if (idx0Based <= 7) {
  2241 	long myVal = self.longValue();
  2242         long myVal = self.longValue();
  2242 	if (myVal < 0) {
  2243         if (myVal < 0) {
  2243 	    myVal = -myVal;
  2244             myVal = -myVal;
  2244 	}
  2245         }
  2245 	int byteVal = (int)((myVal >> (idx0Based * 8)) & 0xFF);
  2246         int byteVal = (int)((myVal >> (idx0Based * 8)) & 0xFF);
  2246 	return __c__._RETURN( STInteger._qnew(byteVal) );
  2247         return __c__._RETURN( STInteger._qnew(byteVal) );
  2247     }
  2248     }
  2248     if (idx0Based > 0) {
  2249     if (idx0Based > 0) {
  2249 	return __c__._RETURN( STInteger._0 );
  2250         return __c__._RETURN( STInteger._0 );
  2250     }
  2251     }
  2251 #else
  2252 #else
  2252     REGISTER INT val;
  2253     REGISTER INT val;
  2253     INT idx;
  2254     INT idx;
  2254 
  2255 
  2255     if (__isSmallInteger(index)) {
  2256     if (__isSmallInteger(index)) {
  2256 	val = __intVal(self);
  2257         val = __intVal(self);
  2257 	if (val < 0)
  2258         if (val < 0)
  2258 	    val = -val;
  2259             val = -val;
  2259 	switch (idx = __intVal(index)) {
  2260         switch (idx = __intVal(index)) {
  2260 	    case 1:
  2261             case 1:
  2261 		break;
  2262                 break;
  2262 	    case 2:
  2263             case 2:
  2263 		val = (val >> 8);
  2264                 val = (val >> 8);
  2264 		break;
  2265                 break;
  2265 	    case 3:
  2266             case 3:
  2266 		val = (val >> 16);
  2267                 val = (val >> 16);
  2267 		break;
  2268                 break;
  2268 	    case 4:
  2269             case 4:
  2269 		val = (val >> 24);
  2270                 val = (val >> 24);
  2270 		break;
  2271                 break;
  2271 # if __POINTER_SIZE__ == 8
  2272 # if __POINTER_SIZE__ == 8
  2272 	    case 5:
  2273             case 5:
  2273 		val = (val >> 32);
  2274                 val = (val >> 32);
  2274 		break;
  2275                 break;
  2275 	    case 6:
  2276             case 6:
  2276 		val = (val >> 40);
  2277                 val = (val >> 40);
  2277 		break;
  2278                 break;
  2278 	    case 7:
  2279             case 7:
  2279 		val = (val >> 48);
  2280                 val = (val >> 48);
  2280 		break;
  2281                 break;
  2281 	    case 8:
  2282             case 8:
  2282 		val = (val >> 56);
  2283                 val = (val >> 56);
  2283 		break;
  2284                 break;
  2284 # endif
  2285 # endif
  2285 	    default:
  2286             default:
  2286 		if (idx < 1)
  2287                 if (idx < 1)
  2287 		    goto bad;   /* sorry */
  2288                     goto bad;   /* sorry */
  2288 		RETURN (__mkSmallInteger(0));
  2289                 RETURN (__mkSmallInteger(0));
  2289 	}
  2290         }
  2290 	RETURN ( __mkSmallInteger( val & 0xFF) );
  2291         RETURN ( __mkSmallInteger( val & 0xFF) );
  2291     }
  2292     }
  2292   bad: ;
  2293   bad: ;
  2293 #endif /* not __SCHTEAM__ */
  2294 #endif /* not __SCHTEAM__ */
  2294 %}.
  2295 %}.
  2295     index > 0 ifFalse:[
  2296     index > 0 ifFalse:[
  2296 	"
  2297         "
  2297 	 index less than 1 - not allowed
  2298          index less than 1 - not allowed
  2298 	"
  2299         "
  2299 	^ self primitiveFailed
  2300         ^ self primitiveFailed
  2300     ].
  2301     ].
  2301     ^ 0
  2302     ^ 0
  2302 
  2303 
  2303     "
  2304     "
  2304      (16r12345678 digitAt:1) printStringRadix:16
  2305      (16r12345678 digitAt:1) printStringRadix:16
  2318 #ifdef __SCHTEAM__
  2319 #ifdef __SCHTEAM__
  2319     int idx0Based = index.intValue() - 1;
  2320     int idx0Based = index.intValue() - 1;
  2320     long myVal = self.longValue();
  2321     long myVal = self.longValue();
  2321 
  2322 
  2322     if (idx0Based <= 7) {
  2323     if (idx0Based <= 7) {
  2323 	int byteVal = (int)((myVal >> (idx0Based * 8)) & 0xFF);
  2324         int byteVal = (int)((myVal >> (idx0Based * 8)) & 0xFF);
  2324 	return __c__._RETURN( STInteger._qnew(byteVal) );
  2325         return __c__._RETURN( STInteger._qnew(byteVal) );
  2325     }
  2326     }
  2326     if (idx0Based > 0) {
  2327     if (idx0Based > 0) {
  2327 	if (myVal < 0) {
  2328         if (myVal < 0) {
  2328 	    return __c__._RETURN( STInteger._M1 );
  2329             return __c__._RETURN( STInteger._M1 );
  2329 	} else {
  2330         } else {
  2330 	    return __c__._RETURN( STInteger._0 );
  2331             return __c__._RETURN( STInteger._0 );
  2331 	}
  2332         }
  2332     }
  2333     }
  2333 #else
  2334 #else
  2334     REGISTER INT val;
  2335     REGISTER INT val;
  2335     INT idx;
  2336     INT idx;
  2336 
  2337 
  2337     if (__isSmallInteger(index)) {
  2338     if (__isSmallInteger(index)) {
  2338 	val = __intVal(self);
  2339         val = __intVal(self);
  2339 	switch (idx = __intVal(index)) {
  2340         switch (idx = __intVal(index)) {
  2340 	    case 1:
  2341             case 1:
  2341 		break;
  2342                 break;
  2342 	    case 2:
  2343             case 2:
  2343 		val = (val >> 8);
  2344                 val = (val >> 8);
  2344 		break;
  2345                 break;
  2345 	    case 3:
  2346             case 3:
  2346 		val = (val >> 16);
  2347                 val = (val >> 16);
  2347 		break;
  2348                 break;
  2348 	    case 4:
  2349             case 4:
  2349 		val = (val >> 24);
  2350                 val = (val >> 24);
  2350 		break;
  2351                 break;
  2351 # if __POINTER_SIZE__ == 8
  2352 # if __POINTER_SIZE__ == 8
  2352 	    case 5:
  2353             case 5:
  2353 		val = (val >> 32);
  2354                 val = (val >> 32);
  2354 		break;
  2355                 break;
  2355 	    case 6:
  2356             case 6:
  2356 		val = (val >> 40);
  2357                 val = (val >> 40);
  2357 		break;
  2358                 break;
  2358 	    case 7:
  2359             case 7:
  2359 		val = (val >> 48);
  2360                 val = (val >> 48);
  2360 		break;
  2361                 break;
  2361 	    case 8:
  2362             case 8:
  2362 		val = (val >> 56);
  2363                 val = (val >> 56);
  2363 		break;
  2364                 break;
  2364 # endif
  2365 # endif
  2365 	    default:
  2366             default:
  2366 		if (idx < 1)
  2367                 if (idx < 1)
  2367 		    goto bad;   /* sorry */
  2368                     goto bad;   /* sorry */
  2368 		if (val < 0) {
  2369                 if (val < 0) {
  2369 		    RETURN (__mkSmallInteger(0xFF));
  2370                     RETURN (__mkSmallInteger(0xFF));
  2370 		}
  2371                 }
  2371 		RETURN (__mkSmallInteger(0));
  2372                 RETURN (__mkSmallInteger(0));
  2372 	}
  2373         }
  2373 	RETURN ( __mkSmallInteger( val & 0xFF) );
  2374         RETURN ( __mkSmallInteger( val & 0xFF) );
  2374     }
  2375     }
  2375   bad: ;
  2376   bad: ;
  2376 #endif /* not __SCHTEAM__ */
  2377 #endif /* not __SCHTEAM__ */
  2377 %}.
  2378 %}.
  2378     index > 0 ifFalse:[
  2379     index > 0 ifFalse:[
  2379 	"
  2380         "
  2380 	 index less than 1 - not allowed
  2381          index less than 1 - not allowed
  2381 	"
  2382         "
  2382 	^ self primitiveFailed
  2383         ^ self primitiveFailed
  2383     ].
  2384     ].
  2384     ^ 0
  2385     ^ 0
  2385 
  2386 
  2386     "
  2387     "
  2387      (10 digitByteAt:1) printStringRadix:16
  2388      (10 digitByteAt:1) printStringRadix:16
  2409      could have simply created a 4-byte largeinteger and normalize it.
  2410      could have simply created a 4-byte largeinteger and normalize it.
  2410      The code below does the normalize right away, avoiding the
  2411      The code below does the normalize right away, avoiding the
  2411      overhead of producing any intermediate byte-arrays (and the scanning)
  2412      overhead of producing any intermediate byte-arrays (and the scanning)
  2412     "
  2413     "
  2413     self == 0 ifTrue: [
  2414     self == 0 ifTrue: [
  2414 	^ ByteArray with:0.
  2415         ^ ByteArray with:0.
  2415     ].
  2416     ].
  2416 
  2417 
  2417     self < 0 ifTrue: [
  2418     self < 0 ifTrue: [
  2418 	absValue := self negated
  2419         absValue := self negated
  2419     ] ifFalse: [
  2420     ] ifFalse: [
  2420 	absValue := self.
  2421         absValue := self.
  2421     ].
  2422     ].
  2422 
  2423 
  2423     b1 := absValue bitAnd:16rFF.
  2424     b1 := absValue bitAnd:16rFF.
  2424     absValue := absValue bitShift:-8.
  2425     absValue := absValue bitShift:-8.
  2425     absValue == 0 ifTrue:[
  2426     absValue == 0 ifTrue:[
  2426 	digitByteArray := ByteArray with:b1
  2427         digitByteArray := ByteArray with:b1
  2427     ] ifFalse:[
  2428     ] ifFalse:[
  2428 	b2 := absValue bitAnd:16rFF.
  2429         b2 := absValue bitAnd:16rFF.
  2429 	absValue := absValue bitShift:-8.
  2430         absValue := absValue bitShift:-8.
  2430 	absValue == 0 ifTrue:[
  2431         absValue == 0 ifTrue:[
  2431 	    digitByteArray := ByteArray with:b1 with:b2
  2432             digitByteArray := ByteArray with:b1 with:b2
  2432 	] ifFalse:[
  2433         ] ifFalse:[
  2433 	    b3 := absValue bitAnd:16rFF.
  2434             b3 := absValue bitAnd:16rFF.
  2434 	    absValue := absValue bitShift:-8.
  2435             absValue := absValue bitShift:-8.
  2435 	    absValue == 0 ifTrue:[
  2436             absValue == 0 ifTrue:[
  2436 		digitByteArray := ByteArray with:b1 with:b2 with:b3
  2437                 digitByteArray := ByteArray with:b1 with:b2 with:b3
  2437 	    ] ifFalse:[
  2438             ] ifFalse:[
  2438 		b4 := absValue bitAnd:16rFF.
  2439                 b4 := absValue bitAnd:16rFF.
  2439 		absValue := absValue bitShift:-8.
  2440                 absValue := absValue bitShift:-8.
  2440 		absValue == 0 ifTrue:[
  2441                 absValue == 0 ifTrue:[
  2441 		    digitByteArray := ByteArray with:b1 with:b2 with:b3 with:b4
  2442                     digitByteArray := ByteArray with:b1 with:b2 with:b3 with:b4
  2442 		] ifFalse:[
  2443                 ] ifFalse:[
  2443 		    b5 := absValue bitAnd:16rFF.
  2444                     b5 := absValue bitAnd:16rFF.
  2444 		    absValue := absValue bitShift:-8.
  2445                     absValue := absValue bitShift:-8.
  2445 		    absValue == 0 ifTrue:[
  2446                     absValue == 0 ifTrue:[
  2446 			digitByteArray := ByteArray new:5.
  2447                         digitByteArray := ByteArray new:5.
  2447 			digitByteArray at:1 put:b1.
  2448                         digitByteArray at:1 put:b1.
  2448 			digitByteArray at:2 put:b2.
  2449                         digitByteArray at:2 put:b2.
  2449 			digitByteArray at:3 put:b3.
  2450                         digitByteArray at:3 put:b3.
  2450 			digitByteArray at:4 put:b4.
  2451                         digitByteArray at:4 put:b4.
  2451 			digitByteArray at:5 put:b5.
  2452                         digitByteArray at:5 put:b5.
  2452 		    ] ifFalse:[
  2453                     ] ifFalse:[
  2453 			b6 := absValue bitAnd:16rFF.
  2454                         b6 := absValue bitAnd:16rFF.
  2454 			absValue := absValue bitShift:-8.
  2455                         absValue := absValue bitShift:-8.
  2455 			absValue == 0 ifTrue:[
  2456                         absValue == 0 ifTrue:[
  2456 			    digitByteArray := ByteArray new:6.
  2457                             digitByteArray := ByteArray new:6.
  2457 			    digitByteArray at:1 put:b1.
  2458                             digitByteArray at:1 put:b1.
  2458 			    digitByteArray at:2 put:b2.
  2459                             digitByteArray at:2 put:b2.
  2459 			    digitByteArray at:3 put:b3.
  2460                             digitByteArray at:3 put:b3.
  2460 			    digitByteArray at:4 put:b4.
  2461                             digitByteArray at:4 put:b4.
  2461 			    digitByteArray at:5 put:b5.
  2462                             digitByteArray at:5 put:b5.
  2462 			    digitByteArray at:6 put:b6.
  2463                             digitByteArray at:6 put:b6.
  2463 			] ifFalse:[
  2464                         ] ifFalse:[
  2464 			    b7 := absValue bitAnd:16rFF.
  2465                             b7 := absValue bitAnd:16rFF.
  2465 			    absValue := absValue bitShift:-8.
  2466                             absValue := absValue bitShift:-8.
  2466 			    absValue == 0 ifTrue:[
  2467                             absValue == 0 ifTrue:[
  2467 				digitByteArray := ByteArray new:7.
  2468                                 digitByteArray := ByteArray new:7.
  2468 				digitByteArray at:1 put:b1.
  2469                                 digitByteArray at:1 put:b1.
  2469 				digitByteArray at:2 put:b2.
  2470                                 digitByteArray at:2 put:b2.
  2470 				digitByteArray at:3 put:b3.
  2471                                 digitByteArray at:3 put:b3.
  2471 				digitByteArray at:4 put:b4.
  2472                                 digitByteArray at:4 put:b4.
  2472 				digitByteArray at:5 put:b5.
  2473                                 digitByteArray at:5 put:b5.
  2473 				digitByteArray at:6 put:b6.
  2474                                 digitByteArray at:6 put:b6.
  2474 				digitByteArray at:7 put:b7.
  2475                                 digitByteArray at:7 put:b7.
  2475 			    ] ifFalse:[
  2476                             ] ifFalse:[
  2476 				digitByteArray := ByteArray new:8.
  2477                                 digitByteArray := ByteArray new:8.
  2477 				digitByteArray at:1 put:b1.
  2478                                 digitByteArray at:1 put:b1.
  2478 				digitByteArray at:2 put:b2.
  2479                                 digitByteArray at:2 put:b2.
  2479 				digitByteArray at:3 put:b3.
  2480                                 digitByteArray at:3 put:b3.
  2480 				digitByteArray at:4 put:b4.
  2481                                 digitByteArray at:4 put:b4.
  2481 				digitByteArray at:5 put:b5.
  2482                                 digitByteArray at:5 put:b5.
  2482 				digitByteArray at:6 put:b6.
  2483                                 digitByteArray at:6 put:b6.
  2483 				digitByteArray at:7 put:b7.
  2484                                 digitByteArray at:7 put:b7.
  2484 				digitByteArray at:8 put:absValue.
  2485                                 digitByteArray at:8 put:absValue.
  2485 			    ]
  2486                             ]
  2486 			]
  2487                         ]
  2487 		    ]
  2488                     ]
  2488 		]
  2489                 ]
  2489 	    ]
  2490             ]
  2490 	]
  2491         ]
  2491     ].
  2492     ].
  2492 
  2493 
  2493     ^ digitByteArray
  2494     ^ digitByteArray
  2494 
  2495 
  2495     "
  2496     "
  2517      could have simply created a 4-byte largeinteger and normalize it.
  2518      could have simply created a 4-byte largeinteger and normalize it.
  2518      The code below does the normalize right away, avoiding the
  2519      The code below does the normalize right away, avoiding the
  2519      overhead of producing any intermediate byte-arrays (and the scanning)
  2520      overhead of producing any intermediate byte-arrays (and the scanning)
  2520     "
  2521     "
  2521     self == 0 ifTrue: [
  2522     self == 0 ifTrue: [
  2522 	^ ByteArray with:0.
  2523         ^ ByteArray with:0.
  2523     ].
  2524     ].
  2524 
  2525 
  2525     self < 0 ifTrue: [
  2526     self < 0 ifTrue: [
  2526 	absValue := self negated
  2527         absValue := self negated
  2527     ] ifFalse: [
  2528     ] ifFalse: [
  2528 	absValue := self.
  2529         absValue := self.
  2529     ].
  2530     ].
  2530 
  2531 
  2531     b1 := absValue bitAnd:16rFF.
  2532     b1 := absValue bitAnd:16rFF.
  2532     absValue := absValue bitShift:-8.
  2533     absValue := absValue bitShift:-8.
  2533     absValue == 0 ifTrue:[
  2534     absValue == 0 ifTrue:[
  2534 	digitByteArray := ByteArray with:b1
  2535         digitByteArray := ByteArray with:b1
  2535     ] ifFalse:[
  2536     ] ifFalse:[
  2536 	b2 := absValue bitAnd:16rFF.
  2537         b2 := absValue bitAnd:16rFF.
  2537 	absValue := absValue bitShift:-8.
  2538         absValue := absValue bitShift:-8.
  2538 	absValue == 0 ifTrue:[
  2539         absValue == 0 ifTrue:[
  2539 	    digitByteArray := ByteArray with:b2 with:b1
  2540             digitByteArray := ByteArray with:b2 with:b1
  2540 	] ifFalse:[
  2541         ] ifFalse:[
  2541 	    b3 := absValue bitAnd:16rFF.
  2542             b3 := absValue bitAnd:16rFF.
  2542 	    absValue := absValue bitShift:-8.
  2543             absValue := absValue bitShift:-8.
  2543 	    absValue == 0 ifTrue:[
  2544             absValue == 0 ifTrue:[
  2544 		digitByteArray := ByteArray with:b3 with:b2 with:b1
  2545                 digitByteArray := ByteArray with:b3 with:b2 with:b1
  2545 	    ] ifFalse:[
  2546             ] ifFalse:[
  2546 		b4 := absValue bitAnd:16rFF.
  2547                 b4 := absValue bitAnd:16rFF.
  2547 		absValue := absValue bitShift:-8.
  2548                 absValue := absValue bitShift:-8.
  2548 		absValue == 0 ifTrue:[
  2549                 absValue == 0 ifTrue:[
  2549 		    digitByteArray := ByteArray with:b4 with:b3 with:b2 with:b1
  2550                     digitByteArray := ByteArray with:b4 with:b3 with:b2 with:b1
  2550 		] ifFalse:[
  2551                 ] ifFalse:[
  2551 		    b5 := absValue bitAnd:16rFF.
  2552                     b5 := absValue bitAnd:16rFF.
  2552 		    absValue := absValue bitShift:-8.
  2553                     absValue := absValue bitShift:-8.
  2553 		    absValue == 0 ifTrue:[
  2554                     absValue == 0 ifTrue:[
  2554 			digitByteArray := ByteArray new:5.
  2555                         digitByteArray := ByteArray new:5.
  2555 			digitByteArray at:1 put:b5.
  2556                         digitByteArray at:1 put:b5.
  2556 			digitByteArray at:2 put:b4.
  2557                         digitByteArray at:2 put:b4.
  2557 			digitByteArray at:3 put:b3.
  2558                         digitByteArray at:3 put:b3.
  2558 			digitByteArray at:4 put:b2.
  2559                         digitByteArray at:4 put:b2.
  2559 			digitByteArray at:5 put:b1.
  2560                         digitByteArray at:5 put:b1.
  2560 		    ] ifFalse:[
  2561                     ] ifFalse:[
  2561 			b6 := absValue bitAnd:16rFF.
  2562                         b6 := absValue bitAnd:16rFF.
  2562 			absValue := absValue bitShift:-8.
  2563                         absValue := absValue bitShift:-8.
  2563 			absValue == 0 ifTrue:[
  2564                         absValue == 0 ifTrue:[
  2564 			    digitByteArray := ByteArray new:6.
  2565                             digitByteArray := ByteArray new:6.
  2565 			    digitByteArray at:1 put:b6.
  2566                             digitByteArray at:1 put:b6.
  2566 			    digitByteArray at:2 put:b5.
  2567                             digitByteArray at:2 put:b5.
  2567 			    digitByteArray at:3 put:b4.
  2568                             digitByteArray at:3 put:b4.
  2568 			    digitByteArray at:4 put:b3.
  2569                             digitByteArray at:4 put:b3.
  2569 			    digitByteArray at:5 put:b2.
  2570                             digitByteArray at:5 put:b2.
  2570 			    digitByteArray at:6 put:b1.
  2571                             digitByteArray at:6 put:b1.
  2571 			] ifFalse:[
  2572                         ] ifFalse:[
  2572 			    b7 := absValue bitAnd:16rFF.
  2573                             b7 := absValue bitAnd:16rFF.
  2573 			    absValue := absValue bitShift:-8.
  2574                             absValue := absValue bitShift:-8.
  2574 			    absValue == 0 ifTrue:[
  2575                             absValue == 0 ifTrue:[
  2575 				digitByteArray := ByteArray new:7.
  2576                                 digitByteArray := ByteArray new:7.
  2576 				digitByteArray at:1 put:b7.
  2577                                 digitByteArray at:1 put:b7.
  2577 				digitByteArray at:2 put:b6.
  2578                                 digitByteArray at:2 put:b6.
  2578 				digitByteArray at:3 put:b5.
  2579                                 digitByteArray at:3 put:b5.
  2579 				digitByteArray at:4 put:b4.
  2580                                 digitByteArray at:4 put:b4.
  2580 				digitByteArray at:5 put:b3.
  2581                                 digitByteArray at:5 put:b3.
  2581 				digitByteArray at:6 put:b2.
  2582                                 digitByteArray at:6 put:b2.
  2582 				digitByteArray at:7 put:b1.
  2583                                 digitByteArray at:7 put:b1.
  2583 			    ] ifFalse:[
  2584                             ] ifFalse:[
  2584 				digitByteArray := ByteArray new:8.
  2585                                 digitByteArray := ByteArray new:8.
  2585 				digitByteArray at:1 put:absValue.
  2586                                 digitByteArray at:1 put:absValue.
  2586 				digitByteArray at:2 put:b7.
  2587                                 digitByteArray at:2 put:b7.
  2587 				digitByteArray at:3 put:b6.
  2588                                 digitByteArray at:3 put:b6.
  2588 				digitByteArray at:4 put:b5.
  2589                                 digitByteArray at:4 put:b5.
  2589 				digitByteArray at:5 put:b4.
  2590                                 digitByteArray at:5 put:b4.
  2590 				digitByteArray at:6 put:b3.
  2591                                 digitByteArray at:6 put:b3.
  2591 				digitByteArray at:7 put:b2.
  2592                                 digitByteArray at:7 put:b2.
  2592 				digitByteArray at:8 put:b1.
  2593                                 digitByteArray at:8 put:b1.
  2593 			    ]
  2594                             ]
  2594 			]
  2595                         ]
  2595 		    ]
  2596                     ]
  2596 		]
  2597                 ]
  2597 	    ]
  2598             ]
  2598 	]
  2599         ]
  2599     ].
  2600     ].
  2600 
  2601 
  2601     ^ digitByteArray
  2602     ^ digitByteArray
  2602 
  2603 
  2603     "
  2604     "
  2617     long val = self.longValue();
  2618     long val = self.longValue();
  2618     int offs = 0;
  2619     int offs = 0;
  2619 
  2620 
  2620     if (val < 0) val = -val;
  2621     if (val < 0) val = -val;
  2621     if ((val & 0xFFFFFFFF00000000L) != 0) {
  2622     if ((val & 0xFFFFFFFF00000000L) != 0) {
  2622 	val >>= 32;
  2623         val >>= 32;
  2623 	offs = 4;
  2624         offs = 4;
  2624     }
  2625     }
  2625     if ((val & 0xFFFF0000) != 0) {
  2626     if ((val & 0xFFFF0000) != 0) {
  2626 	if ((val & 0xFF000000) != 0) {
  2627         if ((val & 0xFF000000) != 0) {
  2627 	    offs += 4;
  2628             offs += 4;
  2628 	} else {
  2629         } else {
  2629 	    offs += 3;
  2630             offs += 3;
  2630 	}
  2631         }
  2631     } else {
  2632     } else {
  2632 	if ((val & 0x0000FF00)!= 0) {
  2633         if ((val & 0x0000FF00)!= 0) {
  2633 	    offs += 2;
  2634             offs += 2;
  2634 	} else {
  2635         } else {
  2635 	    offs += 1;
  2636             offs += 1;
  2636 	}
  2637         }
  2637     }
  2638     }
  2638     return __c__._RETURN( STInteger._qnew(offs) );
  2639     return __c__._RETURN( STInteger._qnew(offs) );
  2639 #else
  2640 #else
  2640     INT val = __intVal(self);
  2641     INT val = __intVal(self);
  2641     int offs = 0;
  2642     int offs = 0;
  2642 
  2643 
  2643     if (val < 0) {
  2644     if (val < 0) {
  2644 	val = -val;
  2645         val = -val;
  2645     }
  2646     }
  2646 # if __POINTER_SIZE__ == 8
  2647 # if __POINTER_SIZE__ == 8
  2647     if (val & 0xFFFFFFFF00000000L) {
  2648     if (val & 0xFFFFFFFF00000000L) {
  2648 	val >>= 32;
  2649         val >>= 32;
  2649 	offs = 4;
  2650         offs = 4;
  2650     }
  2651     }
  2651 # endif
  2652 # endif
  2652 
  2653 
  2653     if (val & 0xFFFF0000) {
  2654     if (val & 0xFFFF0000) {
  2654 	if (val & 0xFF000000) {
  2655         if (val & 0xFF000000) {
  2655 	    RETURN ( __mkSmallInteger(4+offs));
  2656             RETURN ( __mkSmallInteger(4+offs));
  2656 	} else {
  2657         } else {
  2657 	    RETURN ( __mkSmallInteger(3+offs));
  2658             RETURN ( __mkSmallInteger(3+offs));
  2658 	}
  2659         }
  2659     } else {
  2660     } else {
  2660 	if (val & 0x0000FF00) {
  2661         if (val & 0x0000FF00) {
  2661 	    RETURN ( __mkSmallInteger(2+offs));
  2662             RETURN ( __mkSmallInteger(2+offs));
  2662 	} else {
  2663         } else {
  2663 	    RETURN ( __mkSmallInteger(1+offs));
  2664             RETURN ( __mkSmallInteger(1+offs));
  2664 	}
  2665         }
  2665     }
  2666     }
  2666 #endif /* not SCHTEAM */
  2667 #endif /* not SCHTEAM */
  2667 %}.
  2668 %}.
  2668     ^ self abs highBit - 1 // 8 + 1
  2669     ^ self abs highBit - 1 // 8 + 1
  2669 
  2670 
  2695 %{  /* NOCONTEXT */
  2696 %{  /* NOCONTEXT */
  2696 #ifndef __SCHTEAM__
  2697 #ifndef __SCHTEAM__
  2697     unsigned INT v = __intVal(self);
  2698     unsigned INT v = __intVal(self);
  2698 
  2699 
  2699     if ((INT)v >= 0) {
  2700     if ((INT)v >= 0) {
  2700 	unsigned INT swapped;
  2701         unsigned INT swapped;
  2701 
  2702 
  2702 # if __POINTER_SIZE__ == 8
  2703 # if __POINTER_SIZE__ == 8
  2703 	swapped = ((v >> 8) & 0x00FF00FF00FF00FF) | ((v & 0x00FF00FF00FF00FF) << 8);
  2704         swapped = ((v >> 8) & 0x00FF00FF00FF00FF) | ((v & 0x00FF00FF00FF00FF) << 8);
  2704 # else
  2705 # else
  2705 	swapped = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
  2706         swapped = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
  2706 # endif /* __POINTER_SIZE__ */
  2707 # endif /* __POINTER_SIZE__ */
  2707 
  2708 
  2708 	//if (__ISVALIDINTEGER(swapped)) {   // sorry, but this does not work here if (INT)swapped would be negative
  2709         //if (__ISVALIDINTEGER(swapped)) {   // sorry, but this does not work here if (INT)swapped would be negative
  2709 	if (swapped <= _MAX_INT) {
  2710         if (swapped <= _MAX_INT) {
  2710 	    RETURN ( __mkSmallInteger(swapped) );
  2711             RETURN ( __mkSmallInteger(swapped) );
  2711 	}
  2712         }
  2712 	RETURN (__MKUINT(swapped));
  2713         RETURN (__MKUINT(swapped));
  2713     }
  2714     }
  2714 #endif
  2715 #endif
  2715 %}.
  2716 %}.
  2716     ^ super swapBytes
  2717     ^ super swapBytes
  2717 
  2718 
  2866 %{  /* NOCONTEXT */
  2867 %{  /* NOCONTEXT */
  2867 #ifndef __SCHTEAM__
  2868 #ifndef __SCHTEAM__
  2868     INT i = __intVal(self);
  2869     INT i = __intVal(self);
  2869 
  2870 
  2870     if (i & 0x800000L) {
  2871     if (i & 0x800000L) {
  2871 	i = i | ~((INT)0xFFFFFF);
  2872         i = i | ~((INT)0xFFFFFF);
  2872     } else {
  2873     } else {
  2873 	i = i & 0x7FFFFF;
  2874         i = i & 0x7FFFFF;
  2874     }
  2875     }
  2875 
  2876 
  2876     RETURN (__mkSmallInteger(i));
  2877     RETURN (__mkSmallInteger(i));
  2877 #endif
  2878 #endif
  2878 %}.
  2879 %}.
  2892 %{  /* NOCONTEXT */
  2893 %{  /* NOCONTEXT */
  2893 #ifndef __SCHTEAM__
  2894 #ifndef __SCHTEAM__
  2894     INT i = __intVal(self);
  2895     INT i = __intVal(self);
  2895 
  2896 
  2896     if (i & 0x80) {
  2897     if (i & 0x80) {
  2897 	i = i | ~((INT)0xFF);
  2898         i = i | ~((INT)0xFF);
  2898     } else {
  2899     } else {
  2899 	i = i & 0x7F;
  2900         i = i & 0x7F;
  2900     }
  2901     }
  2901 
  2902 
  2902     RETURN (__mkSmallInteger(i));
  2903     RETURN (__mkSmallInteger(i));
  2903 #endif
  2904 #endif
  2904 %}.
  2905 %}.
  2918 %{  /* NOCONTEXT */
  2919 %{  /* NOCONTEXT */
  2919 #ifndef __SCHTEAM__
  2920 #ifndef __SCHTEAM__
  2920     INT i = __intVal(self);
  2921     INT i = __intVal(self);
  2921 
  2922 
  2922     if (i & 0x80000000L) {
  2923     if (i & 0x80000000L) {
  2923 	i = i | ~((INT)0xFFFFFFFF);
  2924         i = i | ~((INT)0xFFFFFFFF);
  2924     } else {
  2925     } else {
  2925 	i = i & 0x7FFFFFFFL;
  2926         i = i & 0x7FFFFFFFL;
  2926     }
  2927     }
  2927 
  2928 
  2928     RETURN (__MKINT(i));
  2929     RETURN (__MKINT(i));
  2929 #endif
  2930 #endif
  2930 %}.
  2931 %}.
  2944 %{  /* NOCONTEXT */
  2945 %{  /* NOCONTEXT */
  2945 #ifndef __SCHTEAM__
  2946 #ifndef __SCHTEAM__
  2946     INT i = __intVal(self);
  2947     INT i = __intVal(self);
  2947 
  2948 
  2948     if (i & 0x8000) {
  2949     if (i & 0x8000) {
  2949 	i = i | ~((INT)0xFFFF);
  2950         i = i | ~((INT)0xFFFF);
  2950     } else {
  2951     } else {
  2951 	i = i & 0x7FFF;
  2952         i = i & 0x7FFF;
  2952     }
  2953     }
  2953 
  2954 
  2954     RETURN (__mkSmallInteger(i));
  2955     RETURN (__mkSmallInteger(i));
  2955 #endif
  2956 #endif
  2956 %}.
  2957 %}.
  2972 #ifdef __SCHTEAM__
  2973 #ifdef __SCHTEAM__
  2973     return context._RETURN( self.ltP( aNumber ));
  2974     return context._RETURN( self.ltP( aNumber ));
  2974 #else
  2975 #else
  2975     if (__isSmallInteger(aNumber)) {
  2976     if (__isSmallInteger(aNumber)) {
  2976 # ifdef POSITIVE_ADDRESSES
  2977 # ifdef POSITIVE_ADDRESSES
  2977 	RETURN ( (__intVal(self) < __intVal(aNumber)) ? true : false );
  2978         RETURN ( (__intVal(self) < __intVal(aNumber)) ? true : false );
  2978 # else
  2979 # else
  2979 	/* tag bit does not change ordering */
  2980         /* tag bit does not change ordering */
  2980 	RETURN ( ((INT)self < (INT)aNumber) ? true : false );
  2981         RETURN ( ((INT)self < (INT)aNumber) ? true : false );
  2981 # endif
  2982 # endif
  2982     }
  2983     }
  2983     if (__isFloatLike(aNumber)) {
  2984     if (__isFloatLike(aNumber)) {
  2984 	RETURN ( ((double)__intVal(self) < __floatVal(aNumber)) ? true : false );
  2985         RETURN ( ((double)__intVal(self) < __floatVal(aNumber)) ? true : false );
  2985     }
  2986     }
  2986 #endif /* not __SCHTEAM__ */
  2987 #endif /* not __SCHTEAM__ */
  2987 %}.
  2988 %}.
  2988     ^ aNumber lessFromInteger:self
  2989     ^ aNumber lessFromInteger:self
  2989     "^ self retry:#< coercing:aNumber"
  2990     "^ self retry:#< coercing:aNumber"
  2997     return context._RETURN( self.leP( aNumber ));
  2998     return context._RETURN( self.leP( aNumber ));
  2998 #else
  2999 #else
  2999 
  3000 
  3000     if (__isSmallInteger(aNumber)) {
  3001     if (__isSmallInteger(aNumber)) {
  3001 # ifdef POSITIVE_ADDRESSES
  3002 # ifdef POSITIVE_ADDRESSES
  3002 	RETURN ( (__intVal(self) <= __intVal(aNumber)) ? true : false );
  3003         RETURN ( (__intVal(self) <= __intVal(aNumber)) ? true : false );
  3003 # else
  3004 # else
  3004 	/* tag bit does not change ordering */
  3005         /* tag bit does not change ordering */
  3005 	RETURN ( ((INT)self <= (INT)aNumber) ? true : false );
  3006         RETURN ( ((INT)self <= (INT)aNumber) ? true : false );
  3006 # endif
  3007 # endif
  3007     }
  3008     }
  3008     if (__isFloatLike(aNumber)) {
  3009     if (__isFloatLike(aNumber)) {
  3009 	RETURN ( ((double)__intVal(self) <= __floatVal(aNumber)) ? true : false );
  3010         RETURN ( ((double)__intVal(self) <= __floatVal(aNumber)) ? true : false );
  3010     }
  3011     }
  3011 #endif /* not __SCHTEAM__ */
  3012 #endif /* not __SCHTEAM__ */
  3012 %}.
  3013 %}.
  3013     ^ (self > aNumber) not
  3014     ^ (self > aNumber) not
  3014 
  3015 
  3020      as the receiver, false otherwise"
  3021      as the receiver, false otherwise"
  3021 
  3022 
  3022 %{  /* NOCONTEXT */
  3023 %{  /* NOCONTEXT */
  3023 #ifdef __SCHTEAM__
  3024 #ifdef __SCHTEAM__
  3024     if (aNumber.isNumber()) {
  3025     if (aNumber.isNumber()) {
  3025 	return context._RETURN( aNumber.eqvP( self.longValue() ));
  3026         return context._RETURN( aNumber.eqvP( self.longValue() ));
  3026     }
  3027     }
  3027 #else
  3028 #else
  3028 
  3029 
  3029     if (aNumber == self) {
  3030     if (aNumber == self) {
  3030 	RETURN ( true );
  3031         RETURN ( true );
  3031     }
  3032     }
  3032     if (! __isNonNilObject(aNumber)) {
  3033     if (! __isNonNilObject(aNumber)) {
  3033 	/* a smallint or nil */
  3034         /* a smallint or nil */
  3034 	RETURN ( false );
  3035         RETURN ( false );
  3035     }
  3036     }
  3036 
  3037 
  3037     if (__qIsFloatLike(aNumber)) {
  3038     if (__qIsFloatLike(aNumber)) {
  3038 	RETURN ( ((double)__intVal(self) == __floatVal(aNumber)) ? true : false );
  3039         RETURN ( ((double)__intVal(self) == __floatVal(aNumber)) ? true : false );
  3039     }
  3040     }
  3040     if (__qIsShortFloat(aNumber)) {
  3041     if (__qIsShortFloat(aNumber)) {
  3041 	RETURN ( ((double)__intVal(self) == __shortFloatVal(aNumber)) ? true : false );
  3042         RETURN ( ((double)__intVal(self) == __shortFloatVal(aNumber)) ? true : false );
  3042     }
  3043     }
  3043 #endif /* not __SCHTEAM__ */
  3044 #endif /* not __SCHTEAM__ */
  3044 %}.
  3045 %}.
  3045     ^ aNumber equalFromInteger:self
  3046     ^ aNumber equalFromInteger:self
  3046 !
  3047 !
  3053     return context._RETURN( self.gtP( aNumber ));
  3054     return context._RETURN( self.gtP( aNumber ));
  3054 #else
  3055 #else
  3055 
  3056 
  3056     if (__isSmallInteger(aNumber)) {
  3057     if (__isSmallInteger(aNumber)) {
  3057 # ifdef POSITIVE_ADDRESSES
  3058 # ifdef POSITIVE_ADDRESSES
  3058 	RETURN ( (__intVal(self) > __intVal(aNumber)) ? true : false );
  3059         RETURN ( (__intVal(self) > __intVal(aNumber)) ? true : false );
  3059 # else
  3060 # else
  3060 	/* tag bit does not change ordering */
  3061         /* tag bit does not change ordering */
  3061 	RETURN ( ((INT)self > (INT)aNumber) ? true : false );
  3062         RETURN ( ((INT)self > (INT)aNumber) ? true : false );
  3062 # endif
  3063 # endif
  3063     }
  3064     }
  3064     if (__isFloatLike(aNumber)) {
  3065     if (__isFloatLike(aNumber)) {
  3065 	RETURN ( ((double)__intVal(self) > __floatVal(aNumber)) ? true : false );
  3066         RETURN ( ((double)__intVal(self) > __floatVal(aNumber)) ? true : false );
  3066     }
  3067     }
  3067 #endif /* not __SCHTEAM__ */
  3068 #endif /* not __SCHTEAM__ */
  3068 %}.
  3069 %}.
  3069     ^ (aNumber < self)
  3070     ^ (aNumber < self)
  3070 
  3071 
  3079     return context._RETURN( self.geP( aNumber ));
  3080     return context._RETURN( self.geP( aNumber ));
  3080 #else
  3081 #else
  3081 
  3082 
  3082     if (__isSmallInteger(aNumber)) {
  3083     if (__isSmallInteger(aNumber)) {
  3083 # ifdef POSITIVE_ADDRESSES
  3084 # ifdef POSITIVE_ADDRESSES
  3084 	RETURN ( (__intVal(self) >= __intVal(aNumber)) ? true : false );
  3085         RETURN ( (__intVal(self) >= __intVal(aNumber)) ? true : false );
  3085 # else
  3086 # else
  3086 	/* tag bit does not change ordering */
  3087         /* tag bit does not change ordering */
  3087 	RETURN ( ((INT)self >= (INT)aNumber) ? true : false );
  3088         RETURN ( ((INT)self >= (INT)aNumber) ? true : false );
  3088 # endif
  3089 # endif
  3089     }
  3090     }
  3090     if (__isFloatLike(aNumber)) {
  3091     if (__isFloatLike(aNumber)) {
  3091 	RETURN ( ((double)__intVal(self) >= __floatVal(aNumber)) ? true : false );
  3092         RETURN ( ((double)__intVal(self) >= __floatVal(aNumber)) ? true : false );
  3092     }
  3093     }
  3093 #endif /* not __SCHTEAM__ */
  3094 #endif /* not __SCHTEAM__ */
  3094 %}.
  3095 %}.
  3095     ^ (self < aNumber) not
  3096     ^ (self < aNumber) not
  3096 
  3097 
  3110     |low|
  3111     |low|
  3111 
  3112 
  3112     low := self bitAnd: 16r3FFF.
  3113     low := self bitAnd: 16r3FFF.
  3113     ^ (9741 * low
  3114     ^ (9741 * low
  3114       + ((9741 * (self bitShift: -14) + (101 * low) bitAnd: 16383) * 16384))
  3115       + ((9741 * (self bitShift: -14) + (101 * low) bitAnd: 16383) * 16384))
  3115 	bitAnd: 16r0FFFFFFF
  3116         bitAnd: 16r0FFFFFFF
  3116 
  3117 
  3117     "
  3118     "
  3118      1 hashMultiply
  3119      1 hashMultiply
  3119      2 hashMultiply
  3120      2 hashMultiply
  3120      3 hashMultiply
  3121      3 hashMultiply
  3137 %{  /* NOCONTEXT */
  3138 %{  /* NOCONTEXT */
  3138 #ifndef __SCHTEAM__
  3139 #ifndef __SCHTEAM__
  3139 
  3140 
  3140     if (__isSmallInteger(aNumber)) {
  3141     if (__isSmallInteger(aNumber)) {
  3141 # if TAG_INT == 1
  3142 # if TAG_INT == 1
  3142 	/* tag bit does not change ordering */
  3143         /* tag bit does not change ordering */
  3143 	if ((INT)(self) > (INT)(aNumber))
  3144         if ((INT)(self) > (INT)(aNumber))
  3144 # else
  3145 # else
  3145 	if (__intVal(self) > __intVal(aNumber))
  3146         if (__intVal(self) > __intVal(aNumber))
  3146 # endif
  3147 # endif
  3147 	{
  3148         {
  3148 	    RETURN ( self );
  3149             RETURN ( self );
  3149 	}
  3150         }
  3150 	RETURN ( aNumber );
  3151         RETURN ( aNumber );
  3151     }
  3152     }
  3152     if (__isFloatLike(aNumber)) {
  3153     if (__isFloatLike(aNumber)) {
  3153 	if ( (double)__intVal(self) > __floatVal(aNumber) ) {
  3154         if ( (double)__intVal(self) > __floatVal(aNumber) ) {
  3154 	    RETURN ( self );
  3155             RETURN ( self );
  3155 	}
  3156         }
  3156 	RETURN ( aNumber );
  3157         RETURN ( aNumber );
  3157     }
  3158     }
  3158 #endif /* not __SCHTEAM__ */
  3159 #endif /* not __SCHTEAM__ */
  3159 %}.
  3160 %}.
  3160     "/ fallback for non-smallInteger argument
  3161     "/ fallback for non-smallInteger argument
  3161 
  3162 
  3169 %{  /* NOCONTEXT */
  3170 %{  /* NOCONTEXT */
  3170 #ifndef __SCHTEAM__
  3171 #ifndef __SCHTEAM__
  3171 
  3172 
  3172     if (__isSmallInteger(aNumber)) {
  3173     if (__isSmallInteger(aNumber)) {
  3173 # if TAG_INT == 1
  3174 # if TAG_INT == 1
  3174 	/* tag bit does not change ordering */
  3175         /* tag bit does not change ordering */
  3175 	if ((INT)(self) < (INT)(aNumber))
  3176         if ((INT)(self) < (INT)(aNumber))
  3176 # else
  3177 # else
  3177 	if (__intVal(self) < __intVal(aNumber))
  3178         if (__intVal(self) < __intVal(aNumber))
  3178 # endif
  3179 # endif
  3179 	{
  3180         {
  3180 	    RETURN ( self );
  3181             RETURN ( self );
  3181 	}
  3182         }
  3182 	RETURN ( aNumber );
  3183         RETURN ( aNumber );
  3183     }
  3184     }
  3184     if (__isFloatLike(aNumber)) {
  3185     if (__isFloatLike(aNumber)) {
  3185 	if ( (double)__intVal(self) < __floatVal(aNumber) ) {
  3186         if ( (double)__intVal(self) < __floatVal(aNumber) ) {
  3186 	    RETURN ( self );
  3187             RETURN ( self );
  3187 	}
  3188         }
  3188 	RETURN ( aNumber );
  3189         RETURN ( aNumber );
  3189     }
  3190     }
  3190 #endif /* not __SCHTEAM__ */
  3191 #endif /* not __SCHTEAM__ */
  3191 %}.
  3192 %}.
  3192     "/ fallback for non-smallInteger argument
  3193     "/ fallback for non-smallInteger argument
  3193 
  3194 
  3199     "return true, if the arguments value is not equal to mine"
  3200     "return true, if the arguments value is not equal to mine"
  3200 
  3201 
  3201 %{  /* NOCONTEXT */
  3202 %{  /* NOCONTEXT */
  3202 #ifdef __SCHTEAM__
  3203 #ifdef __SCHTEAM__
  3203     if (aNumber.isNumber()) {
  3204     if (aNumber.isNumber()) {
  3204 	return context._RETURN( (aNumber.isEqv( self.longValue() )) ? STObject.False : STObject.True);
  3205         return context._RETURN( (aNumber.isEqv( self.longValue() )) ? STObject.False : STObject.True);
  3205 	/* NOTREACHED */
  3206         /* NOTREACHED */
  3206     }
  3207     }
  3207 #else
  3208 #else
  3208 
  3209 
  3209     if (aNumber == self) {
  3210     if (aNumber == self) {
  3210 	RETURN ( false );
  3211         RETURN ( false );
  3211     }
  3212     }
  3212     if (! __isNonNilObject(aNumber)) {
  3213     if (! __isNonNilObject(aNumber)) {
  3213 	/* a smallint or nil */
  3214         /* a smallint or nil */
  3214 	RETURN ( true );
  3215         RETURN ( true );
  3215     }
  3216     }
  3216 
  3217 
  3217     if (__qIsFloatLike(aNumber)) {
  3218     if (__qIsFloatLike(aNumber)) {
  3218 	RETURN ( ((double)__intVal(self) != __floatVal(aNumber)) ? true : false );
  3219         RETURN ( ((double)__intVal(self) != __floatVal(aNumber)) ? true : false );
  3219     }
  3220     }
  3220     if (__qIsShortFloat(aNumber)) {
  3221     if (__qIsShortFloat(aNumber)) {
  3221 	RETURN ( ((double)__intVal(self) != __shortFloatVal(aNumber)) ? true : false );
  3222         RETURN ( ((double)__intVal(self) != __shortFloatVal(aNumber)) ? true : false );
  3222     }
  3223     }
  3223 #endif /* not __SCHTEAM__ */
  3224 #endif /* not __SCHTEAM__ */
  3224 %}.
  3225 %}.
  3225     ^ (self = aNumber) not
  3226     ^ (self = aNumber) not
  3226 ! !
  3227 ! !
  3267     REGISTER INT tmp;
  3268     REGISTER INT tmp;
  3268     static struct inlineCache blockVal = __ILC0(0);
  3269     static struct inlineCache blockVal = __ILC0(0);
  3269 
  3270 
  3270     tmp = __intVal(self);
  3271     tmp = __intVal(self);
  3271     if (tmp > 0) {
  3272     if (tmp > 0) {
  3272 	if (__isBlockLike(aBlock)
  3273         if (__isBlockLike(aBlock)
  3273 	 && (__BlockInstPtr(aBlock)->b_nargs == __mkSmallInteger(0))) {
  3274          && (__BlockInstPtr(aBlock)->b_nargs == __mkSmallInteger(0))) {
  3274 	    {
  3275             {
  3275 		REGISTER OBJFUNC codeVal;
  3276                 REGISTER OBJFUNC codeVal;
  3276 
  3277 
  3277 		/*
  3278                 /*
  3278 		 * specially tuned version for compiled blocks,
  3279                  * specially tuned version for compiled blocks,
  3279 		 * (the most common case)
  3280                  * (the most common case)
  3280 		 */
  3281                  */
  3281 		if (((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil)
  3282                 if (((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil)
  3282 # ifdef PARANOIA
  3283 # ifdef PARANOIA
  3283 		 && (! ((INT)(__BlockInstPtr(aBlock)->b_flags) & __MASKSMALLINT(F_DYNAMIC)))
  3284                  && (! ((INT)(__BlockInstPtr(aBlock)->b_flags) & __MASKSMALLINT(F_DYNAMIC)))
  3284 # endif
  3285 # endif
  3285 		) {
  3286                 ) {
  3286 
  3287 
  3287 # ifdef NEW_BLOCK_CALL
  3288 # ifdef NEW_BLOCK_CALL
  3288 
  3289 
  3289 #                   define BLOCK_ARG  aBlock
  3290 #                   define BLOCK_ARG  aBlock
  3290 
  3291 
  3291 # else
  3292 # else
  3292 
  3293 
  3293 #                   define BLOCK_ARG  rHome
  3294 #                   define BLOCK_ARG  rHome
  3294 		    REGISTER OBJ rHome;
  3295                     REGISTER OBJ rHome;
  3295 
  3296 
  3296 		    /*
  3297                     /*
  3297 		     * home on stack - no need to refetch
  3298                      * home on stack - no need to refetch
  3298 		     */
  3299                      */
  3299 		    rHome = __BlockInstPtr(aBlock)->b_home;
  3300                     rHome = __BlockInstPtr(aBlock)->b_home;
  3300 		    if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE))
  3301                     if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE))
  3301 # endif
  3302 # endif
  3302 		    {
  3303                     {
  3303 # ifdef __UNROLL_LOOPS__
  3304 # ifdef __UNROLL_LOOPS__
  3304 
  3305 
  3305 			/*
  3306                         /*
  3306 			 * you are not supposed to program like this - I know what I do
  3307                          * you are not supposed to program like this - I know what I do
  3307 			 */
  3308                          */
  3308 			while (tmp > 8) {
  3309                         while (tmp > 8) {
  3309 			    if (InterruptPending != nil) goto interrupted0;
  3310                             if (InterruptPending != nil) goto interrupted0;
  3310 	continue0:
  3311         continue0:
  3311 			    (*codeVal)(BLOCK_ARG);
  3312                             (*codeVal)(BLOCK_ARG);
  3312 			    if (InterruptPending != nil) goto interrupted1;
  3313                             if (InterruptPending != nil) goto interrupted1;
  3313 	continue1:
  3314         continue1:
  3314 			    (*codeVal)(BLOCK_ARG);
  3315                             (*codeVal)(BLOCK_ARG);
  3315 			    if (InterruptPending != nil) goto interrupted2;
  3316                             if (InterruptPending != nil) goto interrupted2;
  3316 	continue2:
  3317         continue2:
  3317 			    (*codeVal)(BLOCK_ARG);
  3318                             (*codeVal)(BLOCK_ARG);
  3318 			    if (InterruptPending != nil) goto interrupted3;
  3319                             if (InterruptPending != nil) goto interrupted3;
  3319 	continue3:
  3320         continue3:
  3320 			    (*codeVal)(BLOCK_ARG);
  3321                             (*codeVal)(BLOCK_ARG);
  3321 			    if (InterruptPending != nil) goto interrupted4;
  3322                             if (InterruptPending != nil) goto interrupted4;
  3322 	continue4:
  3323         continue4:
  3323 			    (*codeVal)(BLOCK_ARG);
  3324                             (*codeVal)(BLOCK_ARG);
  3324 			    if (InterruptPending != nil) goto interrupted5;
  3325                             if (InterruptPending != nil) goto interrupted5;
  3325 	continue5:
  3326         continue5:
  3326 			    (*codeVal)(BLOCK_ARG);
  3327                             (*codeVal)(BLOCK_ARG);
  3327 			    if (InterruptPending != nil) goto interrupted6;
  3328                             if (InterruptPending != nil) goto interrupted6;
  3328 	continue6:
  3329         continue6:
  3329 			    (*codeVal)(BLOCK_ARG);
  3330                             (*codeVal)(BLOCK_ARG);
  3330 			    if (InterruptPending != nil) goto interrupted7;
  3331                             if (InterruptPending != nil) goto interrupted7;
  3331 	continue7:
  3332         continue7:
  3332 			    (*codeVal)(BLOCK_ARG);
  3333                             (*codeVal)(BLOCK_ARG);
  3333 			    tmp -= 8;
  3334                             tmp -= 8;
  3334 			}
  3335                         }
  3335 # endif /* __UNROLL_LOOPS__ */
  3336 # endif /* __UNROLL_LOOPS__ */
  3336 			do {
  3337                         do {
  3337 			    if (InterruptPending != nil) goto interruptedX;
  3338                             if (InterruptPending != nil) goto interruptedX;
  3338 	continueX:
  3339         continueX:
  3339 			    (*codeVal)(BLOCK_ARG);
  3340                             (*codeVal)(BLOCK_ARG);
  3340 			} while(--tmp);
  3341                         } while(--tmp);
  3341 
  3342 
  3342 			RETURN (self);
  3343                         RETURN (self);
  3343 			if (0) {
  3344                         if (0) {
  3344 # ifdef __UNROLL_LOOPS__
  3345 # ifdef __UNROLL_LOOPS__
  3345 			    interrupted0:
  3346                             interrupted0:
  3346 						__interruptL(@line); goto continue0;
  3347                                                 __interruptL(@line); goto continue0;
  3347 			    interrupted1:
  3348                             interrupted1:
  3348 						__interruptL(@line); goto continue1;
  3349                                                 __interruptL(@line); goto continue1;
  3349 			    interrupted2:
  3350                             interrupted2:
  3350 						__interruptL(@line); goto continue2;
  3351                                                 __interruptL(@line); goto continue2;
  3351 			    interrupted3:
  3352                             interrupted3:
  3352 						__interruptL(@line); goto continue3;
  3353                                                 __interruptL(@line); goto continue3;
  3353 			    interrupted4:
  3354                             interrupted4:
  3354 						__interruptL(@line); goto continue4;
  3355                                                 __interruptL(@line); goto continue4;
  3355 			    interrupted5:
  3356                             interrupted5:
  3356 						__interruptL(@line); goto continue5;
  3357                                                 __interruptL(@line); goto continue5;
  3357 			    interrupted6:
  3358                             interrupted6:
  3358 						__interruptL(@line); goto continue6;
  3359                                                 __interruptL(@line); goto continue6;
  3359 			    interrupted7:
  3360                             interrupted7:
  3360 						__interruptL(@line); goto continue7;
  3361                                                 __interruptL(@line); goto continue7;
  3361 # endif /* __UNROLL_LOOPS__ */
  3362 # endif /* __UNROLL_LOOPS__ */
  3362 			    interruptedX:
  3363                             interruptedX:
  3363 						__interruptL(@line); goto continueX;
  3364                                                 __interruptL(@line); goto continueX;
  3364 			}
  3365                         }
  3365 		    }
  3366                     }
  3366 		}
  3367                 }
  3367 	    }
  3368             }
  3368 
  3369 
  3369 #           undef BLOCK_ARG
  3370 #           undef BLOCK_ARG
  3370 
  3371 
  3371 # ifdef NEW_BLOCK_CALL
  3372 # ifdef NEW_BLOCK_CALL
  3372 #           define BLOCK_ARG  aBlock
  3373 #           define BLOCK_ARG  aBlock
  3374 # else
  3375 # else
  3375 #           define BLOCK_ARG  (__BlockInstPtr(aBlock)->b_home)
  3376 #           define BLOCK_ARG  (__BlockInstPtr(aBlock)->b_home)
  3376 #           define IBLOCK_ARG (__BlockInstPtr(aBlock)->b_home)
  3377 #           define IBLOCK_ARG (__BlockInstPtr(aBlock)->b_home)
  3377 # endif
  3378 # endif
  3378 
  3379 
  3379 	    /*
  3380             /*
  3380 	     * sorry - must check for the blocks code within the loops;
  3381              * sorry - must check for the blocks code within the loops;
  3381 	     * it could be recompiled or flushed (in the interrupt)
  3382              * it could be recompiled or flushed (in the interrupt)
  3382 	     */
  3383              */
  3383 	    do {
  3384             do {
  3384 		REGISTER OBJFUNC codeVal;
  3385                 REGISTER OBJFUNC codeVal;
  3385 
  3386 
  3386 		if ((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) {
  3387                 if ((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) {
  3387 		    /*
  3388                     /*
  3388 		     * arg is a compiled block with code -
  3389                      * arg is a compiled block with code -
  3389 		     * directly call it without going through Block>>value
  3390                      * directly call it without going through Block>>value
  3390 		     * however, if there is an interrupt, refetch the code pointer.
  3391                      * however, if there is an interrupt, refetch the code pointer.
  3391 		     */
  3392                      */
  3392 		    /* stay here, while no interrupts are pending ... */
  3393                     /* stay here, while no interrupts are pending ... */
  3393 		    do {
  3394                     do {
  3394 			(*codeVal)(BLOCK_ARG);
  3395                         (*codeVal)(BLOCK_ARG);
  3395 			if (InterruptPending != nil) goto outerLoop;
  3396                         if (InterruptPending != nil) goto outerLoop;
  3396 		    } while (--tmp);
  3397                     } while (--tmp);
  3397 		    RETURN (self);
  3398                     RETURN (self);
  3398 		} else {
  3399                 } else {
  3399 		    if (InterruptPending != nil) __interruptL(@line);
  3400                     if (InterruptPending != nil) __interruptL(@line);
  3400 
  3401 
  3401 		    if (__BlockInstPtr(aBlock)->b_bytecodes != nil) {
  3402                     if (__BlockInstPtr(aBlock)->b_bytecodes != nil) {
  3402 			/*
  3403                         /*
  3403 			 * arg is a compiled block with bytecode -
  3404                          * arg is a compiled block with bytecode -
  3404 			 * directly call interpreter without going through Block>>value
  3405                          * directly call interpreter without going through Block>>value
  3405 			 */
  3406                          */
  3406 			__interpret(aBlock, 0, nil, IBLOCK_ARG, nil, nil);
  3407                         __interpret(aBlock, 0, nil, IBLOCK_ARG, nil, nil);
  3407 		    } else {
  3408                     } else {
  3408 			/*
  3409                         /*
  3409 			 * arg is something else - call it with #value
  3410                          * arg is something else - call it with #value
  3410 			 */
  3411                          */
  3411 			(*blockVal.ilc_func)(aBlock, @symbol(value), nil, &blockVal);
  3412                         (*blockVal.ilc_func)(aBlock, @symbol(value), nil, &blockVal);
  3412 		    }
  3413                     }
  3413 		}
  3414                 }
  3414     outerLoop: ;
  3415     outerLoop: ;
  3415 	    } while (--tmp);
  3416             } while (--tmp);
  3416 
  3417 
  3417 #           undef BLOCK_ARG
  3418 #           undef BLOCK_ARG
  3418 #           undef IBLOCK_ARG
  3419 #           undef IBLOCK_ARG
  3419 
  3420 
  3420 	    RETURN (self);
  3421             RETURN (self);
  3421 	}
  3422         }
  3422 
  3423 
  3423 	/*
  3424         /*
  3424 	 * not a block-like thingy - call it with #value
  3425          * not a block-like thingy - call it with #value
  3425 	 */
  3426          */
  3426 	do {
  3427         do {
  3427 	    if (InterruptPending != nil) __interruptL(@line);
  3428             if (InterruptPending != nil) __interruptL(@line);
  3428 	    (*blockVal.ilc_func)(aBlock, @symbol(value), nil, &blockVal);
  3429             (*blockVal.ilc_func)(aBlock, @symbol(value), nil, &blockVal);
  3429 	} while(--tmp);
  3430         } while(--tmp);
  3430 	RETURN (self);
  3431         RETURN (self);
  3431     }
  3432     }
  3432 #endif
  3433 #endif
  3433 %}.
  3434 %}.
  3434     ^ super timesRepeat:aBlock
  3435     ^ super timesRepeat:aBlock
  3435 
  3436 
  3450     REGISTER INT tmp, step;
  3451     REGISTER INT tmp, step;
  3451     REGISTER INT final;
  3452     REGISTER INT final;
  3452     static struct inlineCache blockVal = __ILC1(0);
  3453     static struct inlineCache blockVal = __ILC1(0);
  3453 
  3454 
  3454     if (__bothSmallInteger(incr, stop)) {
  3455     if (__bothSmallInteger(incr, stop)) {
  3455 	tmp = __intVal(self);
  3456         tmp = __intVal(self);
  3456 	final = __intVal(stop);
  3457         final = __intVal(stop);
  3457 	step = __intVal(incr);
  3458         step = __intVal(incr);
  3458 
  3459 
  3459 	if (__isBlockLike(aBlock)
  3460         if (__isBlockLike(aBlock)
  3460 	 && (__BlockInstPtr(aBlock)->b_nargs == __mkSmallInteger(1))) {
  3461          && (__BlockInstPtr(aBlock)->b_nargs == __mkSmallInteger(1))) {
  3461 	    {
  3462             {
  3462 		REGISTER OBJFUNC codeVal;
  3463                 REGISTER OBJFUNC codeVal;
  3463 
  3464 
  3464 		/*
  3465                 /*
  3465 		 * specially tuned version for static compiled blocks, called with
  3466                  * specially tuned version for static compiled blocks, called with
  3466 		 * home on the stack (the most common case)
  3467                  * home on the stack (the most common case)
  3467 		 */
  3468                  */
  3468 		if (((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil)
  3469                 if (((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil)
  3469 # ifdef PARANOIA
  3470 # ifdef PARANOIA
  3470 		 && (! ((INT)(__BlockInstPtr(aBlock)->b_flags) & __MASKSMALLINT(F_DYNAMIC)))
  3471                  && (! ((INT)(__BlockInstPtr(aBlock)->b_flags) & __MASKSMALLINT(F_DYNAMIC)))
  3471 # endif
  3472 # endif
  3472 		) {
  3473                 ) {
  3473 
  3474 
  3474 # ifdef NEW_BLOCK_CALL
  3475 # ifdef NEW_BLOCK_CALL
  3475 
  3476 
  3476 #                   define BLOCK_ARG  aBlock
  3477 #                   define BLOCK_ARG  aBlock
  3477 
  3478 
  3478 # else
  3479 # else
  3479 
  3480 
  3480 #                   define BLOCK_ARG  rHome
  3481 #                   define BLOCK_ARG  rHome
  3481 		    REGISTER OBJ rHome;
  3482                     REGISTER OBJ rHome;
  3482 		    rHome = __BlockInstPtr(aBlock)->b_home;
  3483                     rHome = __BlockInstPtr(aBlock)->b_home;
  3483 		    if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE))
  3484                     if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE))
  3484 
  3485 
  3485 # endif
  3486 # endif
  3486 		    {
  3487                     {
  3487 			if (step < 0) {
  3488                         if (step < 0) {
  3488 			    if (step == -1) {
  3489                             if (step == -1) {
  3489 				while (tmp >= final) {
  3490                                 while (tmp >= final) {
  3490 				    if (InterruptPending != nil) __interruptL(@line);
  3491                                     if (InterruptPending != nil) __interruptL(@line);
  3491 				    (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3492                                     (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3492 				    tmp--;
  3493                                     tmp--;
  3493 				}
  3494                                 }
  3494 			    } else {
  3495                             } else {
  3495 				while (tmp >= final) {
  3496                                 while (tmp >= final) {
  3496 				    if (InterruptPending != nil) __interruptL(@line);
  3497                                     if (InterruptPending != nil) __interruptL(@line);
  3497 				    (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3498                                     (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3498 				    tmp += step;
  3499                                     tmp += step;
  3499 				}
  3500                                 }
  3500 			    }
  3501                             }
  3501 			} else {
  3502                         } else {
  3502 			    if (step == 1) {
  3503                             if (step == 1) {
  3503 				while (tmp <= final) {
  3504                                 while (tmp <= final) {
  3504 				    if (InterruptPending != nil) __interruptL(@line);
  3505                                     if (InterruptPending != nil) __interruptL(@line);
  3505 				    (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3506                                     (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3506 				    tmp++;
  3507                                     tmp++;
  3507 				}
  3508                                 }
  3508 			    } else {
  3509                             } else {
  3509 				while (tmp <= final) {
  3510                                 while (tmp <= final) {
  3510 				    if (InterruptPending != nil) __interruptL(@line);
  3511                                     if (InterruptPending != nil) __interruptL(@line);
  3511 				    (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3512                                     (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3512 				    tmp += step;
  3513                                     tmp += step;
  3513 				}
  3514                                 }
  3514 			    }
  3515                             }
  3515 			}
  3516                         }
  3516 			RETURN (self);
  3517                         RETURN (self);
  3517 		    }
  3518                     }
  3518 		}
  3519                 }
  3519 	    }
  3520             }
  3520 
  3521 
  3521 	    /*
  3522             /*
  3522 	     * sorry - must check for the blocks code within the loops;
  3523              * sorry - must check for the blocks code within the loops;
  3523 	     * it could be recompiled or flushed (in the interrupt)
  3524              * it could be recompiled or flushed (in the interrupt)
  3524 	     */
  3525              */
  3525 
  3526 
  3526 #           undef BLOCK_ARG
  3527 #           undef BLOCK_ARG
  3527 
  3528 
  3528 # ifdef NEW_BLOCK_CALL
  3529 # ifdef NEW_BLOCK_CALL
  3529 #           define BLOCK_ARG  aBlock
  3530 #           define BLOCK_ARG  aBlock
  3531 # else
  3532 # else
  3532 #           define BLOCK_ARG  (__BlockInstPtr(aBlock)->b_home)
  3533 #           define BLOCK_ARG  (__BlockInstPtr(aBlock)->b_home)
  3533 #           define IBLOCK_ARG (__BlockInstPtr(aBlock)->b_home)
  3534 #           define IBLOCK_ARG (__BlockInstPtr(aBlock)->b_home)
  3534 # endif
  3535 # endif
  3535 
  3536 
  3536 	    if (step < 0) {
  3537             if (step < 0) {
  3537 		while (tmp >= final) {
  3538                 while (tmp >= final) {
  3538 		    REGISTER OBJFUNC codeVal;
  3539                     REGISTER OBJFUNC codeVal;
  3539 
  3540 
  3540 		    if (InterruptPending != nil) __interruptL(@line);
  3541                     if (InterruptPending != nil) __interruptL(@line);
  3541 
  3542 
  3542 		    if ((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) {
  3543                     if ((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) {
  3543 			/*
  3544                         /*
  3544 			 * arg is a compiled block with code -
  3545                          * arg is a compiled block with code -
  3545 			 * directly call it without going through Block>>value
  3546                          * directly call it without going through Block>>value
  3546 			 */
  3547                          */
  3547 			(*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3548                         (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3548 		    } else {
  3549                     } else {
  3549 			if (__BlockInstPtr(aBlock)->b_bytecodes != nil) {
  3550                         if (__BlockInstPtr(aBlock)->b_bytecodes != nil) {
  3550 			    /*
  3551                             /*
  3551 			     * arg is a compiled block with bytecode -
  3552                              * arg is a compiled block with bytecode -
  3552 			     * directly call interpreter without going through Block>>value
  3553                              * directly call interpreter without going through Block>>value
  3553 			     */
  3554                              */
  3554 # ifdef PASS_ARG_POINTER
  3555 # ifdef PASS_ARG_POINTER
  3555 			    {
  3556                             {
  3556 				OBJ idx;
  3557                                 OBJ idx;
  3557 
  3558 
  3558 				idx = __mkSmallInteger(tmp);
  3559                                 idx = __mkSmallInteger(tmp);
  3559 				__interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &idx);
  3560                                 __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &idx);
  3560 			    }
  3561                             }
  3561 # else
  3562 # else
  3562 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, __mkSmallInteger(tmp));
  3563                             __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, __mkSmallInteger(tmp));
  3563 # endif
  3564 # endif
  3564 
  3565 
  3565 			} else {
  3566                         } else {
  3566 			    /*
  3567                             /*
  3567 			     * arg is something else - call it with #value
  3568                              * arg is something else - call it with #value
  3568 			     */
  3569                              */
  3569 			    (*blockVal.ilc_func)(aBlock, @symbol(value:), nil, &blockVal, __mkSmallInteger(tmp));
  3570                             (*blockVal.ilc_func)(aBlock, @symbol(value:), nil, &blockVal, __mkSmallInteger(tmp));
  3570 			}
  3571                         }
  3571 		    }
  3572                     }
  3572 		    tmp += step;
  3573                     tmp += step;
  3573 		}
  3574                 }
  3574 	    } else {
  3575             } else {
  3575 		while (tmp <= final) {
  3576                 while (tmp <= final) {
  3576 		    REGISTER OBJFUNC codeVal;
  3577                     REGISTER OBJFUNC codeVal;
  3577 
  3578 
  3578 		    if (InterruptPending != nil) __interruptL(@line);
  3579                     if (InterruptPending != nil) __interruptL(@line);
  3579 
  3580 
  3580 		    if ((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) {
  3581                     if ((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) {
  3581 			/*
  3582                         /*
  3582 			 * arg is a compiled block with code -
  3583                          * arg is a compiled block with code -
  3583 			 * directly call it without going through Block>>value
  3584                          * directly call it without going through Block>>value
  3584 			 */
  3585                          */
  3585 			(*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3586                         (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3586 		    } else {
  3587                     } else {
  3587 			if (__BlockInstPtr(aBlock)->b_bytecodes != nil) {
  3588                         if (__BlockInstPtr(aBlock)->b_bytecodes != nil) {
  3588 			    /*
  3589                             /*
  3589 			     * arg is a compiled block with bytecode -
  3590                              * arg is a compiled block with bytecode -
  3590 			     * directly call interpreter without going through Block>>value
  3591                              * directly call interpreter without going through Block>>value
  3591 			     */
  3592                              */
  3592 # ifdef PASS_ARG_POINTER
  3593 # ifdef PASS_ARG_POINTER
  3593 			    {
  3594                             {
  3594 				OBJ idx;
  3595                                 OBJ idx;
  3595 
  3596 
  3596 				idx = __mkSmallInteger(tmp);
  3597                                 idx = __mkSmallInteger(tmp);
  3597 				__interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &idx);
  3598                                 __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &idx);
  3598 			    }
  3599                             }
  3599 # else
  3600 # else
  3600 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, __mkSmallInteger(tmp));
  3601                             __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, __mkSmallInteger(tmp));
  3601 # endif
  3602 # endif
  3602 
  3603 
  3603 			} else {
  3604                         } else {
  3604 			    /*
  3605                             /*
  3605 			     * arg is something else - call it with #value:
  3606                              * arg is something else - call it with #value:
  3606 			     */
  3607                              */
  3607 			    (*blockVal.ilc_func)(aBlock, @symbol(value:), nil, &blockVal, __mkSmallInteger(tmp));
  3608                             (*blockVal.ilc_func)(aBlock, @symbol(value:), nil, &blockVal, __mkSmallInteger(tmp));
  3608 			}
  3609                         }
  3609 		    }
  3610                     }
  3610 		    tmp += step;
  3611                     tmp += step;
  3611 		}
  3612                 }
  3612 	    }
  3613             }
  3613 
  3614 
  3614 #           undef BLOCK_ARG
  3615 #           undef BLOCK_ARG
  3615 #           undef IBLOCK_ARG
  3616 #           undef IBLOCK_ARG
  3616 
  3617 
  3617 	} else {
  3618         } else {
  3618 	    /*
  3619             /*
  3619 	     * arg is something else - call it with #value:
  3620              * arg is something else - call it with #value:
  3620 	     */
  3621              */
  3621 	    if (step < 0) {
  3622             if (step < 0) {
  3622 		while (tmp >= final) {
  3623                 while (tmp >= final) {
  3623 		    if (InterruptPending != nil) __interruptL(@line);
  3624                     if (InterruptPending != nil) __interruptL(@line);
  3624 
  3625 
  3625 		    (*blockVal.ilc_func)(aBlock,
  3626                     (*blockVal.ilc_func)(aBlock,
  3626 					 @symbol(value:),
  3627                                          @symbol(value:),
  3627 					 nil, &blockVal,
  3628                                          nil, &blockVal,
  3628 					 __mkSmallInteger(tmp));
  3629                                          __mkSmallInteger(tmp));
  3629 		    tmp += step;
  3630                     tmp += step;
  3630 		}
  3631                 }
  3631 	    } else {
  3632             } else {
  3632 		while (tmp <= final) {
  3633                 while (tmp <= final) {
  3633 		    if (InterruptPending != nil) __interruptL(@line);
  3634                     if (InterruptPending != nil) __interruptL(@line);
  3634 
  3635 
  3635 		    (*blockVal.ilc_func)(aBlock,
  3636                     (*blockVal.ilc_func)(aBlock,
  3636 					 @symbol(value:),
  3637                                          @symbol(value:),
  3637 					 nil, &blockVal,
  3638                                          nil, &blockVal,
  3638 					 __mkSmallInteger(tmp));
  3639                                          __mkSmallInteger(tmp));
  3639 		    tmp += step;
  3640                     tmp += step;
  3640 		}
  3641                 }
  3641 	    }
  3642             }
  3642 	}
  3643         }
  3643 	RETURN ( self );
  3644         RETURN ( self );
  3644     }
  3645     }
  3645 #endif
  3646 #endif
  3646 %}.
  3647 %}.
  3647     "/
  3648     "/
  3648     "/ arrive here if stop is not a smallInteger
  3649     "/ arrive here if stop is not a smallInteger
  3665     REGISTER INT tmp;
  3666     REGISTER INT tmp;
  3666     INT final;
  3667     INT final;
  3667     static struct inlineCache blockVal = __ILC1(0);
  3668     static struct inlineCache blockVal = __ILC1(0);
  3668 
  3669 
  3669     if (__isSmallInteger(stop)) {
  3670     if (__isSmallInteger(stop)) {
  3670 	tmp = __intVal(self);
  3671         tmp = __intVal(self);
  3671 	final = __intVal(stop);
  3672         final = __intVal(stop);
  3672 
  3673 
  3673 	if (__isBlockLike(aBlock)
  3674         if (__isBlockLike(aBlock)
  3674 	 && (__BlockInstPtr(aBlock)->b_nargs == __mkSmallInteger(1))) {
  3675          && (__BlockInstPtr(aBlock)->b_nargs == __mkSmallInteger(1))) {
  3675 	    {
  3676             {
  3676 		/*
  3677                 /*
  3677 		 * specially tuned version for the most common case,
  3678                  * specially tuned version for the most common case,
  3678 		 * where called with home on the stack
  3679                  * where called with home on the stack
  3679 		 */
  3680                  */
  3680 		REGISTER OBJFUNC codeVal;
  3681                 REGISTER OBJFUNC codeVal;
  3681 
  3682 
  3682 		if ((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) {
  3683                 if ((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) {
  3683 
  3684 
  3684 # ifdef NEW_BLOCK_CALL
  3685 # ifdef NEW_BLOCK_CALL
  3685 
  3686 
  3686 #                   define BLOCK_ARG  aBlock
  3687 #                   define BLOCK_ARG  aBlock
  3687 
  3688 
  3688 # else
  3689 # else
  3689 
  3690 
  3690 #                   define BLOCK_ARG  rHome
  3691 #                   define BLOCK_ARG  rHome
  3691 		    REGISTER OBJ rHome;
  3692                     REGISTER OBJ rHome;
  3692 		    rHome = __BlockInstPtr(aBlock)->b_home;
  3693                     rHome = __BlockInstPtr(aBlock)->b_home;
  3693 		    if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE))
  3694                     if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE))
  3694 # endif
  3695 # endif
  3695 		    {
  3696                     {
  3696 
  3697 
  3697 # ifdef PARANOIA
  3698 # ifdef PARANOIA
  3698 			if (! ((INT)(__BlockInstPtr(aBlock)->b_flags) & __MASKSMALLINT(F_DYNAMIC)))
  3699                         if (! ((INT)(__BlockInstPtr(aBlock)->b_flags) & __MASKSMALLINT(F_DYNAMIC)))
  3699 # endif
  3700 # endif
  3700 			{
  3701                         {
  3701 			    /*
  3702                             /*
  3702 			     * static compiled blocks ...
  3703                              * static compiled blocks ...
  3703 			     */
  3704                              */
  3704 # ifdef __UNROLL_LOOPS__
  3705 # ifdef __UNROLL_LOOPS__
  3705 			    /*
  3706                             /*
  3706 			     * The following code is designed to run as fast as possible;
  3707                              * The following code is designed to run as fast as possible;
  3707 			     *  - taken branches only if interrupts are pending
  3708                              *  - taken branches only if interrupts are pending
  3708 			     *  - only forward branches (which are usually predicted as not taken)
  3709                              *  - only forward branches (which are usually predicted as not taken)
  3709 			     *  - unrolled the loop
  3710                              *  - unrolled the loop
  3710 			     *
  3711                              *
  3711 			     * you are not supposed to program like this - I know what I do
  3712                              * you are not supposed to program like this - I know what I do
  3712 			     */
  3713                              */
  3713 #  if TAG_INT==1
  3714 #  if TAG_INT==1
  3714 			    INT t8 = (INT)(__mkSmallInteger(tmp+8));
  3715                             INT t8 = (INT)(__mkSmallInteger(tmp+8));
  3715 			    tmp = (INT)(__mkSmallInteger(tmp));
  3716                             tmp = (INT)(__mkSmallInteger(tmp));
  3716 			    final = (INT)(__mkSmallInteger(final));
  3717                             final = (INT)(__mkSmallInteger(final));
  3717 #  else
  3718 #  else
  3718 			    INT t8 = tmp+8;
  3719                             INT t8 = tmp+8;
  3719 #  endif
  3720 #  endif
  3720 
  3721 
  3721 			    for (;;) {
  3722                             for (;;) {
  3722 
  3723 
  3723 				while (t8 <= final) {
  3724                                 while (t8 <= final) {
  3724 #  if TAG_INT==1
  3725 #  if TAG_INT==1
  3725 				    t8 += (INT)(__MASKSMALLINT(8));
  3726                                     t8 += (INT)(__MASKSMALLINT(8));
  3726 #  else
  3727 #  else
  3727 				    t8 += 8;
  3728                                     t8 += 8;
  3728 #  endif
  3729 #  endif
  3729 				    if (InterruptPending != nil) goto interrupted0;
  3730                                     if (InterruptPending != nil) goto interrupted0;
  3730 	continue0:
  3731         continue0:
  3731 #  if TAG_INT==1
  3732 #  if TAG_INT==1
  3732 				    (*codeVal)(BLOCK_ARG, tmp);
  3733                                     (*codeVal)(BLOCK_ARG, tmp);
  3733 #  else
  3734 #  else
  3734 				    (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3735                                     (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3735 #  endif
  3736 #  endif
  3736 				    if (InterruptPending != nil) goto interrupted1;
  3737                                     if (InterruptPending != nil) goto interrupted1;
  3737 	continue1:
  3738         continue1:
  3738 #  if TAG_INT==1
  3739 #  if TAG_INT==1
  3739 				    (*codeVal)(BLOCK_ARG, tmp+(INT)(__MASKSMALLINT(1)) );
  3740                                     (*codeVal)(BLOCK_ARG, tmp+(INT)(__MASKSMALLINT(1)) );
  3740 #  else
  3741 #  else
  3741 				    (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp+1));
  3742                                     (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp+1));
  3742 #  endif
  3743 #  endif
  3743 				    if (InterruptPending != nil) goto interrupted2;
  3744                                     if (InterruptPending != nil) goto interrupted2;
  3744 	continue2:
  3745         continue2:
  3745 #  if TAG_INT==1
  3746 #  if TAG_INT==1
  3746 				    (*codeVal)(BLOCK_ARG, tmp+(INT)(__MASKSMALLINT(2)) );
  3747                                     (*codeVal)(BLOCK_ARG, tmp+(INT)(__MASKSMALLINT(2)) );
  3747 #  else
  3748 #  else
  3748 				    (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp+2));
  3749                                     (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp+2));
  3749 #  endif
  3750 #  endif
  3750 				    if (InterruptPending != nil) goto interrupted3;
  3751                                     if (InterruptPending != nil) goto interrupted3;
  3751 	continue3:
  3752         continue3:
  3752 #  if TAG_INT==1
  3753 #  if TAG_INT==1
  3753 				    (*codeVal)(BLOCK_ARG, tmp+(INT)(__MASKSMALLINT(3)) );
  3754                                     (*codeVal)(BLOCK_ARG, tmp+(INT)(__MASKSMALLINT(3)) );
  3754 #  else
  3755 #  else
  3755 				    (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp+3));
  3756                                     (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp+3));
  3756 #  endif
  3757 #  endif
  3757 				    if (InterruptPending != nil) goto interrupted4;
  3758                                     if (InterruptPending != nil) goto interrupted4;
  3758 	continue4:
  3759         continue4:
  3759 #  if TAG_INT==1
  3760 #  if TAG_INT==1
  3760 				    (*codeVal)(BLOCK_ARG, tmp+(INT)(__MASKSMALLINT(4)) );
  3761                                     (*codeVal)(BLOCK_ARG, tmp+(INT)(__MASKSMALLINT(4)) );
  3761 #  else
  3762 #  else
  3762 				    (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp+4));
  3763                                     (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp+4));
  3763 #  endif
  3764 #  endif
  3764 				    if (InterruptPending != nil) goto interrupted5;
  3765                                     if (InterruptPending != nil) goto interrupted5;
  3765 	continue5:
  3766         continue5:
  3766 #  if TAG_INT==1
  3767 #  if TAG_INT==1
  3767 				    (*codeVal)(BLOCK_ARG, tmp+(INT)(__MASKSMALLINT(5)) );
  3768                                     (*codeVal)(BLOCK_ARG, tmp+(INT)(__MASKSMALLINT(5)) );
  3768 #  else
  3769 #  else
  3769 				    (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp+5));
  3770                                     (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp+5));
  3770 #  endif
  3771 #  endif
  3771 				    if (InterruptPending != nil) goto interrupted6;
  3772                                     if (InterruptPending != nil) goto interrupted6;
  3772 	continue6:
  3773         continue6:
  3773 #  if TAG_INT==1
  3774 #  if TAG_INT==1
  3774 				    (*codeVal)(BLOCK_ARG, tmp+(INT)(__MASKSMALLINT(6)) );
  3775                                     (*codeVal)(BLOCK_ARG, tmp+(INT)(__MASKSMALLINT(6)) );
  3775 #  else
  3776 #  else
  3776 				    (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp+6));
  3777                                     (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp+6));
  3777 #  endif
  3778 #  endif
  3778 				    if (InterruptPending != nil) goto interrupted7;
  3779                                     if (InterruptPending != nil) goto interrupted7;
  3779 	continue7:
  3780         continue7:
  3780 #  if TAG_INT==1
  3781 #  if TAG_INT==1
  3781 				    (*codeVal)(BLOCK_ARG, tmp+(INT)(__MASKSMALLINT(7)) );
  3782                                     (*codeVal)(BLOCK_ARG, tmp+(INT)(__MASKSMALLINT(7)) );
  3782 #  else
  3783 #  else
  3783 				    (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp+7));
  3784                                     (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp+7));
  3784 #  endif
  3785 #  endif
  3785 
  3786 
  3786 #  if TAG_INT==1
  3787 #  if TAG_INT==1
  3787 				    tmp += (INT)(__MASKSMALLINT(8));
  3788                                     tmp += (INT)(__MASKSMALLINT(8));
  3788 #  else
  3789 #  else
  3789 				    tmp += 8;
  3790                                     tmp += 8;
  3790 #  endif
  3791 #  endif
  3791 				}
  3792                                 }
  3792 				while (tmp <= final) {
  3793                                 while (tmp <= final) {
  3793 				    if (InterruptPending != nil) goto interruptedX;
  3794                                     if (InterruptPending != nil) goto interruptedX;
  3794 	continueX:
  3795         continueX:
  3795 #  if TAG_INT==1
  3796 #  if TAG_INT==1
  3796 				    (*codeVal)(BLOCK_ARG, tmp);
  3797                                     (*codeVal)(BLOCK_ARG, tmp);
  3797 				    tmp += (INT)(__MASKSMALLINT(1));
  3798                                     tmp += (INT)(__MASKSMALLINT(1));
  3798 #  else
  3799 #  else
  3799 				    (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3800                                     (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3800 				    tmp++;
  3801                                     tmp++;
  3801 #  endif
  3802 #  endif
  3802 				}
  3803                                 }
  3803 				RETURN (self);
  3804                                 RETURN (self);
  3804 
  3805 
  3805 				if (0) {
  3806                                 if (0) {
  3806 				    /*
  3807                                     /*
  3807 				     * no discussion about those gotos ...
  3808                                      * no discussion about those gotos ...
  3808 				     * ... its better for your CPU's pipelines
  3809                                      * ... its better for your CPU's pipelines
  3809 				     * (if you dont understand why, just dont argue).
  3810                                      * (if you dont understand why, just dont argue).
  3810 				     */
  3811                                      */
  3811 				    interrupted7:
  3812                                     interrupted7:
  3812 						    __interruptL(@line); goto continue7;
  3813                                                     __interruptL(@line); goto continue7;
  3813 				    interrupted6:
  3814                                     interrupted6:
  3814 						    __interruptL(@line); goto continue6;
  3815                                                     __interruptL(@line); goto continue6;
  3815 				    interrupted5:
  3816                                     interrupted5:
  3816 						    __interruptL(@line); goto continue5;
  3817                                                     __interruptL(@line); goto continue5;
  3817 				    interrupted4:
  3818                                     interrupted4:
  3818 						    __interruptL(@line); goto continue4;
  3819                                                     __interruptL(@line); goto continue4;
  3819 				    interrupted3:
  3820                                     interrupted3:
  3820 						    __interruptL(@line); goto continue3;
  3821                                                     __interruptL(@line); goto continue3;
  3821 				    interrupted2:
  3822                                     interrupted2:
  3822 						    __interruptL(@line); goto continue2;
  3823                                                     __interruptL(@line); goto continue2;
  3823 				    interrupted1:
  3824                                     interrupted1:
  3824 						    __interruptL(@line); goto continue1;
  3825                                                     __interruptL(@line); goto continue1;
  3825 				    interrupted0:
  3826                                     interrupted0:
  3826 						    __interruptL(@line); goto continue0;
  3827                                                     __interruptL(@line); goto continue0;
  3827 				    interruptedX:
  3828                                     interruptedX:
  3828 						    __interruptL(@line); goto continueX;
  3829                                                     __interruptL(@line); goto continueX;
  3829 				}
  3830                                 }
  3830 			    }
  3831                             }
  3831 # else
  3832 # else
  3832 			    while (tmp <= final) {
  3833                             while (tmp <= final) {
  3833 				if (InterruptPending != nil) __interruptL(@line);
  3834                                 if (InterruptPending != nil) __interruptL(@line);
  3834 				(*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3835                                 (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3835 				tmp ++;
  3836                                 tmp ++;
  3836 			    }
  3837                             }
  3837 			    RETURN (self);
  3838                             RETURN (self);
  3838 # endif /* __UNROLL_LOOPS__ */
  3839 # endif /* __UNROLL_LOOPS__ */
  3839 			}
  3840                         }
  3840 
  3841 
  3841 			/*
  3842                         /*
  3842 			 * mhmh - seems to be a block with dynamic code
  3843                          * mhmh - seems to be a block with dynamic code
  3843 			 * must refetch, to allow dynamic recompilation or code flush.
  3844                          * must refetch, to allow dynamic recompilation or code flush.
  3844 			 */
  3845                          */
  3845 			while (tmp <= final) {
  3846                         while (tmp <= final) {
  3846 			    if (InterruptPending != nil) __interruptL(@line);
  3847                             if (InterruptPending != nil) __interruptL(@line);
  3847 			    if ((codeVal = __BlockInstPtr(aBlock)->b_code) == (OBJFUNC)nil) break;
  3848                             if ((codeVal = __BlockInstPtr(aBlock)->b_code) == (OBJFUNC)nil) break;
  3848 			    (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3849                             (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3849 			    tmp ++;
  3850                             tmp ++;
  3850 			}
  3851                         }
  3851 
  3852 
  3852 			if (tmp > final) {
  3853                         if (tmp > final) {
  3853 			    RETURN (self);
  3854                             RETURN (self);
  3854 			}
  3855                         }
  3855 		    }
  3856                     }
  3856 		}
  3857                 }
  3857 	    }
  3858             }
  3858 
  3859 
  3859 #           undef BLOCK_ARG
  3860 #           undef BLOCK_ARG
  3860 
  3861 
  3861 # ifdef NEW_BLOCK_CALL
  3862 # ifdef NEW_BLOCK_CALL
  3862 #           define BLOCK_ARG  aBlock
  3863 #           define BLOCK_ARG  aBlock
  3864 # else
  3865 # else
  3865 #           define BLOCK_ARG  (__BlockInstPtr(aBlock)->b_home)
  3866 #           define BLOCK_ARG  (__BlockInstPtr(aBlock)->b_home)
  3866 #           define IBLOCK_ARG (__BlockInstPtr(aBlock)->b_home)
  3867 #           define IBLOCK_ARG (__BlockInstPtr(aBlock)->b_home)
  3867 # endif
  3868 # endif
  3868 
  3869 
  3869 	    /*
  3870             /*
  3870 	     * sorry - must check for the blocks code within the loops;
  3871              * sorry - must check for the blocks code within the loops;
  3871 	     * it could be recompiled or flushed (in the interrupt)
  3872              * it could be recompiled or flushed (in the interrupt)
  3872 	     */
  3873              */
  3873 	    while (tmp <= final) {
  3874             while (tmp <= final) {
  3874 		REGISTER OBJFUNC codeVal;
  3875                 REGISTER OBJFUNC codeVal;
  3875 
  3876 
  3876 		if ((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) {
  3877                 if ((codeVal = __BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) {
  3877 		    /*
  3878                     /*
  3878 		     * arg is a compiled block with code -
  3879                      * arg is a compiled block with code -
  3879 		     * directly call it without going through Block>>value
  3880                      * directly call it without going through Block>>value
  3880 		     */
  3881                      */
  3881 
  3882 
  3882 		    /* stay here, while no interrupts are pending ... */
  3883                     /* stay here, while no interrupts are pending ... */
  3883 		    do {
  3884                     do {
  3884 			(*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3885                         (*codeVal)(BLOCK_ARG, __mkSmallInteger(tmp));
  3885 			if (InterruptPending != nil) goto outerLoop;
  3886                         if (InterruptPending != nil) goto outerLoop;
  3886 			tmp++;
  3887                         tmp++;
  3887 		    } while (tmp <= final);
  3888                     } while (tmp <= final);
  3888 		    RETURN (self);
  3889                     RETURN (self);
  3889 		} else {
  3890                 } else {
  3890 		    if (InterruptPending != nil) __interruptL(@line);
  3891                     if (InterruptPending != nil) __interruptL(@line);
  3891 
  3892 
  3892 		    if (__BlockInstPtr(aBlock)->b_bytecodes != nil) {
  3893                     if (__BlockInstPtr(aBlock)->b_bytecodes != nil) {
  3893 			/*
  3894                         /*
  3894 			 * arg is a compiled block with bytecode -
  3895                          * arg is a compiled block with bytecode -
  3895 			 * directly call interpreter without going through Block>>value
  3896                          * directly call interpreter without going through Block>>value
  3896 			 */
  3897                          */
  3897 # ifdef PASS_ARG_POINTER
  3898 # ifdef PASS_ARG_POINTER
  3898 			{
  3899                         {
  3899 			    OBJ idx;
  3900                             OBJ idx;
  3900 
  3901 
  3901 			    idx = __mkSmallInteger(tmp);
  3902                             idx = __mkSmallInteger(tmp);
  3902 			    __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &idx);
  3903                             __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, &idx);
  3903 			}
  3904                         }
  3904 # else
  3905 # else
  3905 			__interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, __mkSmallInteger(tmp));
  3906                         __interpret(aBlock, 1, nil, IBLOCK_ARG, nil, nil, __mkSmallInteger(tmp));
  3906 # endif
  3907 # endif
  3907 
  3908 
  3908 		    } else {
  3909                     } else {
  3909 			/*
  3910                         /*
  3910 			 * arg is something else - call it with #value:
  3911                          * arg is something else - call it with #value:
  3911 			 */
  3912                          */
  3912 			(*blockVal.ilc_func)(aBlock, @symbol(value:), nil, &blockVal, __mkSmallInteger(tmp));
  3913                         (*blockVal.ilc_func)(aBlock, @symbol(value:), nil, &blockVal, __mkSmallInteger(tmp));
  3913 		    }
  3914                     }
  3914 		}
  3915                 }
  3915 	    outerLoop: ;
  3916             outerLoop: ;
  3916 		tmp++;
  3917                 tmp++;
  3917 	    }
  3918             }
  3918 
  3919 
  3919 #           undef BLOCK_ARG
  3920 #           undef BLOCK_ARG
  3920 #           undef IBLOCK_ARG
  3921 #           undef IBLOCK_ARG
  3921 
  3922 
  3922 	    RETURN (self);
  3923             RETURN (self);
  3923 	}
  3924         }
  3924 	/*
  3925         /*
  3925 	 * arg is something else - call it with #value:
  3926          * arg is something else - call it with #value:
  3926 	 */
  3927          */
  3927 	while (tmp <= final) {
  3928         while (tmp <= final) {
  3928 	    if (InterruptPending != nil) __interruptL(@line);
  3929             if (InterruptPending != nil) __interruptL(@line);
  3929 
  3930 
  3930 	    (*blockVal.ilc_func)(aBlock,
  3931             (*blockVal.ilc_func)(aBlock,
  3931 					 @symbol(value:),
  3932                                          @symbol(value:),
  3932 					 nil, &blockVal,
  3933                                          nil, &blockVal,
  3933 					 __mkSmallInteger(tmp));
  3934                                          __mkSmallInteger(tmp));
  3934 	    tmp++;
  3935             tmp++;
  3935 	}
  3936         }
  3936 	RETURN ( self );
  3937         RETURN ( self );
  3937     }
  3938     }
  3938 #endif /* not __SCHTEAM__ */
  3939 #endif /* not __SCHTEAM__ */
  3939 %}.
  3940 %}.
  3940 
  3941 
  3941     "/
  3942     "/
  3952 !SmallInteger methodsFor:'misc math'!
  3953 !SmallInteger methodsFor:'misc math'!
  3953 
  3954 
  3954 bernoulli
  3955 bernoulli
  3955     "returns the nth Bernoulli number.
  3956     "returns the nth Bernoulli number.
  3956      The series runs this:
  3957      The series runs this:
  3957 	 1/6, 1/30, 1/42, 1/30, 5/66, 691/2730, etc
  3958          1/6, 1/30, 1/42, 1/30, 5/66, 691/2730, etc
  3958      Uses a table of the first 20 bernoulli numbers.
  3959      Uses a table of the first 20 bernoulli numbers.
  3959      So bernoulli(42) will fail for now.
  3960      So bernoulli(42) will fail for now.
  3960      Used with taylor series for tan"
  3961      Used with taylor series for tan"
  3961 
  3962 
  3962     |table p|
  3963     |table p|
  3963 
  3964 
  3964     table := #(
  3965     table := #(
  3965 		(1 6)
  3966                 (1 6)
  3966 		(-1 30)
  3967                 (-1 30)
  3967 		(1 42)
  3968                 (1 42)
  3968 		(-1 30)
  3969                 (-1 30)
  3969 		(5 66)
  3970                 (5 66)
  3970 		(-691 2730)
  3971                 (-691 2730)
  3971 		(7 6)
  3972                 (7 6)
  3972 		(-3617 510)
  3973                 (-3617 510)
  3973 		(43867 798)
  3974                 (43867 798)
  3974 		(-174611 330)
  3975                 (-174611 330)
  3975 		(854513 138)
  3976                 (854513 138)
  3976 		(-236364091 2730)
  3977                 (-236364091 2730)
  3977 		(8553103 6)
  3978                 (8553103 6)
  3978 		(-23749461029 870)
  3979                 (-23749461029 870)
  3979 		(8615841276005 14322)
  3980                 (8615841276005 14322)
  3980 		(-7709321041217 510)
  3981                 (-7709321041217 510)
  3981 		(2577687858367 6)
  3982                 (2577687858367 6)
  3982 		(-26315271553053477373 1919190)
  3983                 (-26315271553053477373 1919190)
  3983 		(2929993913841559 6)
  3984                 (2929993913841559 6)
  3984 		(-261082718496449122051 13530)
  3985                 (-261082718496449122051 13530)
  3985 	      ).
  3986               ).
  3986 
  3987 
  3987     self even ifTrue:[
  3988     self even ifTrue:[
  3988 	self == 0 ifTrue:[^1].
  3989         self == 0 ifTrue:[^1].
  3989 	p := table at:(self / 2).
  3990         p := table at:(self / 2).
  3990 	^ Fraction numerator:(p first) denominator:(p second).
  3991         ^ Fraction numerator:(p first) denominator:(p second).
  3991     ].
  3992     ].
  3992     self == 1 ifTrue:[ ^ (1 / 2) ].
  3993     self == 1 ifTrue:[ ^ (1 / 2) ].
  3993     ^ 0.
  3994     ^ 0.
  3994 
  3995 
  3995     "
  3996     "
  4008     "
  4009     "
  4009 !
  4010 !
  4010 
  4011 
  4011 divMod:aNumber
  4012 divMod:aNumber
  4012     "return an array filled with
  4013     "return an array filled with
  4013 	(self // aNumber) and (self \\ aNumber).
  4014         (self // aNumber) and (self \\ aNumber).
  4014      The returned remainder has the same sign as aNumber.
  4015      The returned remainder has the same sign as aNumber.
  4015      The following is always true:
  4016      The following is always true:
  4016 	(receiver // something) * something + (receiver \\ something) = receiver
  4017         (receiver // something) * something + (receiver \\ something) = receiver
  4017 
  4018 
  4018      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
  4019      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
  4019      Especially surprising:
  4020      Especially surprising:
  4020 	-1 \\ 10 -> 9  (because -(1/10) is truncated towards next smaller integer, which is -1,
  4021         -1 \\ 10 -> 9  (because -(1/10) is truncated towards next smaller integer, which is -1,
  4021 			and -1 multiplied by 10 gives -10, so we have to add 9 to get the original -1).
  4022                         and -1 multiplied by 10 gives -10, so we have to add 9 to get the original -1).
  4022 	-10 \\ 3 -> 2 (because -(10/3) is truncated towards next smaller integer, which is -4,
  4023         -10 \\ 3 -> 2 (because -(10/3) is truncated towards next smaller integer, which is -4,
  4023 			and -4 * 4 gives -12, so we need to add 2 to get the original -10.
  4024                         and -4 * 4 gives -12, so we need to add 2 to get the original -10.
  4024 
  4025 
  4025      This is redefined here for more performance"
  4026      This is redefined here for more performance"
  4026 
  4027 
  4027 %{  /* NOCONTEXT */
  4028 %{  /* NOCONTEXT */
  4028 #ifndef __SCHTEAM__
  4029 #ifndef __SCHTEAM__
  4029     INT val, div, mod, mySelf;
  4030     INT val, div, mod, mySelf;
  4030 
  4031 
  4031     if (__isSmallInteger(aNumber)
  4032     if (__isSmallInteger(aNumber)
  4032      && ((val = __intVal(aNumber)) > 0)
  4033      && ((val = __intVal(aNumber)) > 0)
  4033      && ((mySelf = __intVal(self)) >= 0)) {
  4034      && ((mySelf = __intVal(self)) >= 0)) {
  4034 	div = mySelf / val;
  4035         div = mySelf / val;
  4035 	mod = mySelf % val;
  4036         mod = mySelf % val;
  4036 
  4037 
  4037 	RETURN (__ARRAY_WITH2( __mkSmallInteger(div), __mkSmallInteger(mod)));
  4038         RETURN (__ARRAY_WITH2( __mkSmallInteger(div), __mkSmallInteger(mod)));
  4038     }
  4039     }
  4039 #endif
  4040 #endif
  4040 %}.
  4041 %}.
  4041     ^ super divMod:aNumber
  4042     ^ super divMod:aNumber
  4042 
  4043 
  4076      some code. (thanx to MessageTally)"
  4077      some code. (thanx to MessageTally)"
  4077 
  4078 
  4078 %{  /* NOCONTEXT */
  4079 %{  /* NOCONTEXT */
  4079 #ifndef __SCHTEAM__
  4080 #ifndef __SCHTEAM__
  4080     if (__isSmallInteger(anInteger)) {
  4081     if (__isSmallInteger(anInteger)) {
  4081 	INT orgArg, ttt, selfInt, orgSelfInt, temp;
  4082         INT orgArg, ttt, selfInt, orgSelfInt, temp;
  4082 
  4083 
  4083 	ttt = orgArg = __intVal(anInteger);
  4084         ttt = orgArg = __intVal(anInteger);
  4084 	if (ttt) {
  4085         if (ttt) {
  4085 	    selfInt = orgSelfInt = __intVal(self);
  4086             selfInt = orgSelfInt = __intVal(self);
  4086 	    while (ttt != 0) {
  4087             while (ttt != 0) {
  4087 		temp = selfInt % ttt;
  4088                 temp = selfInt % ttt;
  4088 		selfInt = ttt;
  4089                 selfInt = ttt;
  4089 		ttt = temp;
  4090                 ttt = temp;
  4090 	    }
  4091             }
  4091 	    /*
  4092             /*
  4092 	     * since its not defined in C, what the sign of
  4093              * since its not defined in C, what the sign of
  4093 	     * a modulus result is when the arg is negative,
  4094              * a modulus result is when the arg is negative,
  4094 	     * change it explicitely here ...
  4095              * change it explicitely here ...
  4095 	     */
  4096              */
  4096 	    if (orgArg < 0) {
  4097             if (orgArg < 0) {
  4097 		/* result should be negative */
  4098                 /* result should be negative */
  4098 		if (orgSelfInt > 0) selfInt = -selfInt;
  4099                 if (orgSelfInt > 0) selfInt = -selfInt;
  4099 	    } else {
  4100             } else {
  4100 		/* result should be positive */
  4101                 /* result should be positive */
  4101 		if (orgSelfInt < 0) selfInt = -selfInt;
  4102                 if (orgSelfInt < 0) selfInt = -selfInt;
  4102 	    }
  4103             }
  4103 	    RETURN ( __mkSmallInteger(selfInt) );
  4104             RETURN ( __mkSmallInteger(selfInt) );
  4104 	}
  4105         }
  4105     }
  4106     }
  4106 #endif
  4107 #endif
  4107 %}.
  4108 %}.
  4108     ^ super gcd:anInteger
  4109     ^ super gcd:anInteger
  4109 !
  4110 !
  4123      to print a number/and for conversion to a LargeInteger.
  4124      to print a number/and for conversion to a LargeInteger.
  4124      Implemented that way, to allow for tiny systems (PDAs) without a Float class
  4125      Implemented that way, to allow for tiny systems (PDAs) without a Float class
  4125      (i.e. without log)."
  4126      (i.e. without log)."
  4126 
  4127 
  4127     self > 0 ifTrue:[
  4128     self > 0 ifTrue:[
  4128 	self < 10000 ifTrue:[
  4129         self < 10000 ifTrue:[
  4129 	    self < 10 ifTrue:[^ 0].
  4130             self < 10 ifTrue:[^ 0].
  4130 	    self < 100 ifTrue:[^ 1].
  4131             self < 100 ifTrue:[^ 1].
  4131 	    self < 1000 ifTrue:[^ 2].
  4132             self < 1000 ifTrue:[^ 2].
  4132 	    ^ 3
  4133             ^ 3
  4133 	].
  4134         ].
  4134 	self < 100000000 ifTrue:[
  4135         self < 100000000 ifTrue:[
  4135 	    self < 100000 ifTrue:[^ 4].
  4136             self < 100000 ifTrue:[^ 4].
  4136 	    self < 1000000 ifTrue:[^ 5].
  4137             self < 1000000 ifTrue:[^ 5].
  4137 	    self < 10000000 ifTrue:[^ 6].
  4138             self < 10000000 ifTrue:[^ 6].
  4138 	    ^ 7
  4139             ^ 7
  4139 	].
  4140         ].
  4140 	self < 1000000000 ifTrue:[^ 8].
  4141         self < 1000000000 ifTrue:[^ 8].
  4141 	SmallInteger maxBytes == 4 ifTrue:[
  4142         SmallInteger maxBytes == 4 ifTrue:[
  4142 	    "/ on a 32 bit machine, SmallInt cannot be larger
  4143             "/ on a 32 bit machine, SmallInt cannot be larger
  4143 	    ^ 9
  4144             ^ 9
  4144 	].
  4145         ].
  4145 
  4146 
  4146 	"/ 64 bit machine
  4147         "/ 64 bit machine
  4147 	self < 100000000000000 ifTrue:[
  4148         self < 100000000000000 ifTrue:[
  4148 	    self < 10000000000 ifTrue:[^ 9].
  4149             self < 10000000000 ifTrue:[^ 9].
  4149 	    self < 100000000000 ifTrue:[^ 10].
  4150             self < 100000000000 ifTrue:[^ 10].
  4150 	    self < 1000000000000 ifTrue:[^ 11].
  4151             self < 1000000000000 ifTrue:[^ 11].
  4151 	    self < 10000000000000 ifTrue:[^ 12].
  4152             self < 10000000000000 ifTrue:[^ 12].
  4152 	    ^ 13
  4153             ^ 13
  4153 	].
  4154         ].
  4154 	self < 1000000000000000 ifTrue:[^ 14].
  4155         self < 1000000000000000 ifTrue:[^ 14].
  4155 	self < 10000000000000000 ifTrue:[^ 15].
  4156         self < 10000000000000000 ifTrue:[^ 15].
  4156 	self < 100000000000000000 ifTrue:[^ 16].
  4157         self < 100000000000000000 ifTrue:[^ 16].
  4157 	self < 1000000000000000000 ifTrue:[^ 17].
  4158         self < 1000000000000000000 ifTrue:[^ 17].
  4158 	^ 18.
  4159         ^ 18.
  4159     ].
  4160     ].
  4160 
  4161 
  4161     ^ self class
  4162     ^ self class
  4162 	raise:#domainErrorSignal
  4163         raise:#domainErrorSignal
  4163 	receiver:self
  4164         receiver:self
  4164 	selector:#intlog10
  4165         selector:#intlog10
  4165 	arguments:#()
  4166         arguments:#()
  4166 	errorString:'logarithm of negative integer'
  4167         errorString:'logarithm of negative integer'
  4167 
  4168 
  4168     "
  4169     "
  4169       99 intlog10
  4170       99 intlog10
  4170       100 intlog10
  4171       100 intlog10
  4171       101 intlog10
  4172       101 intlog10
  4197     INT _100s = 0, _10s = 0, _1s = 0;
  4198     INT _100s = 0, _10s = 0, _1s = 0;
  4198     INT b = __intVal(self);
  4199     INT b = __intVal(self);
  4199     unsigned INT rslt;
  4200     unsigned INT rslt;
  4200 
  4201 
  4201     if (b <= 99999999) {
  4202     if (b <= 99999999) {
  4202 	if (b <= 255) {
  4203         if (b <= 255) {
  4203 	    // the most common case: convert bytes
  4204             // the most common case: convert bytes
  4204 	    for (i=7; i>=0; i--) {
  4205             for (i=7; i>=0; i--) {
  4205 		if (_100s >= 5)       _100s += 3;
  4206                 if (_100s >= 5)       _100s += 3;
  4206 		if (_10s >= 5)        _10s += 3;
  4207                 if (_10s >= 5)        _10s += 3;
  4207 		if (_1s >= 5)         _1s += 3;
  4208                 if (_1s >= 5)         _1s += 3;
  4208 
  4209 
  4209 		_100s    =    (_100s<<1)       | (_10s >> 3 & 1);       _100s &= 0xF;
  4210                 _100s    =    (_100s<<1)       | (_10s >> 3 & 1);       _100s &= 0xF;
  4210 		_10s     =    (_10s<<1)        | (_1s >> 3 & 1);        _10s &= 0xF;
  4211                 _10s     =    (_10s<<1)        | (_1s >> 3 & 1);        _10s &= 0xF;
  4211 		_1s      =    (_1s<<1)         | (b >> 7 & 1);          _1s &= 0xF;
  4212                 _1s      =    (_1s<<1)         | (b >> 7 & 1);          _1s &= 0xF;
  4212 		b <<= 1;
  4213                 b <<= 1;
  4213 	    }
  4214             }
  4214 	    rslt = (_100s<<8) | (_10s<<4) | _1s;
  4215             rslt = (_100s<<8) | (_10s<<4) | _1s;
  4215 	    RETURN (__MKSMALLINT( rslt) );
  4216             RETURN (__MKSMALLINT( rslt) );
  4216 	}
  4217         }
  4217 
  4218 
  4218 	for (i=26; i>=0; i--) {
  4219         for (i=26; i>=0; i--) {
  4219 	    if (_10000000s >= 5)  _10000000s += 3;
  4220             if (_10000000s >= 5)  _10000000s += 3;
  4220 	    if (_1000000s >= 5)   _1000000s += 3;
  4221             if (_1000000s >= 5)   _1000000s += 3;
  4221 	    if (_100000s >= 5)    _100000s += 3;
  4222             if (_100000s >= 5)    _100000s += 3;
  4222 	    if (_10000s >= 5)     _10000s += 3;
  4223             if (_10000s >= 5)     _10000s += 3;
  4223 	    if (_1000s >= 5)      _1000s += 3;
  4224             if (_1000s >= 5)      _1000s += 3;
  4224 	    if (_100s >= 5)       _100s += 3;
  4225             if (_100s >= 5)       _100s += 3;
  4225 	    if (_10s >= 5)        _10s += 3;
  4226             if (_10s >= 5)        _10s += 3;
  4226 	    if (_1s >= 5)         _1s += 3;
  4227             if (_1s >= 5)         _1s += 3;
  4227 
  4228 
  4228 	    _10000000s =  (_10000000s<<1)  | (_1000000s >> 3 & 1);  _10000000s &= 0xF;
  4229             _10000000s =  (_10000000s<<1)  | (_1000000s >> 3 & 1);  _10000000s &= 0xF;
  4229 	    _1000000s =   (_1000000s<<1)   | (_100000s >> 3 & 1);   _1000000s &= 0xF;
  4230             _1000000s =   (_1000000s<<1)   | (_100000s >> 3 & 1);   _1000000s &= 0xF;
  4230 	    _100000s =    (_100000s<<1)    | (_10000s >> 3 & 1);    _100000s &= 0xF;
  4231             _100000s =    (_100000s<<1)    | (_10000s >> 3 & 1);    _100000s &= 0xF;
  4231 	    _10000s  =    (_10000s<<1)     | (_1000s >> 3 & 1);     _10000s &= 0xF;
  4232             _10000s  =    (_10000s<<1)     | (_1000s >> 3 & 1);     _10000s &= 0xF;
  4232 	    _1000s   =    (_1000s<<1)      | (_100s >> 3 & 1);      _1000s &= 0xF;
  4233             _1000s   =    (_1000s<<1)      | (_100s >> 3 & 1);      _1000s &= 0xF;
  4233 	    _100s    =    (_100s<<1)       | (_10s >> 3 & 1);       _100s &= 0xF;
  4234             _100s    =    (_100s<<1)       | (_10s >> 3 & 1);       _100s &= 0xF;
  4234 	    _10s     =    (_10s<<1)        | (_1s >> 3 & 1);        _10s &= 0xF;
  4235             _10s     =    (_10s<<1)        | (_1s >> 3 & 1);        _10s &= 0xF;
  4235 	    _1s      =    (_1s<<1)         | (b >> 26 & 1);         _1s &= 0xF;
  4236             _1s      =    (_1s<<1)         | (b >> 26 & 1);         _1s &= 0xF;
  4236 	    b <<= 1;
  4237             b <<= 1;
  4237 	}
  4238         }
  4238 
  4239 
  4239 	rslt = (_10000000s<<28)
  4240         rslt = (_10000000s<<28)
  4240 	       | (_1000000s<<24) | (_100000s<<20) | (_10000s<<16)
  4241                | (_1000000s<<24) | (_100000s<<20) | (_10000s<<16)
  4241 	       | (_1000s<<12) | (_100s<<8) | (_10s<<4) | _1s;
  4242                | (_1000s<<12) | (_100s<<8) | (_10s<<4) | _1s;
  4242 	RETURN (__MKUINT( rslt) );
  4243         RETURN (__MKUINT( rslt) );
  4243     }
  4244     }
  4244 #endif
  4245 #endif
  4245 %}.
  4246 %}.
  4246     ^ super asBCD.
  4247     ^ super asBCD.
  4247 
  4248 
  4276      The base argument should be between 2 and 36."
  4277      The base argument should be between 2 and 36."
  4277 
  4278 
  4278     |absBase|
  4279     |absBase|
  4279 
  4280 
  4280     (base isInteger and:[absBase := base abs. absBase between:2 and:36]) ifTrue:[
  4281     (base isInteger and:[absBase := base abs. absBase between:2 and:36]) ifTrue:[
  4281 	showRadix ifTrue:[
  4282         showRadix ifTrue:[
  4282 	    absBase printOn:aStream.
  4283             absBase printOn:aStream.
  4283 	    aStream nextPut:$r.
  4284             aStream nextPut:$r.
  4284 	].
  4285         ].
  4285 	aStream nextPutAll:(self printStringRadix:base)
  4286         aStream nextPutAll:(self printStringRadix:base)
  4286     ] ifFalse:[
  4287     ] ifFalse:[
  4287 	super printOn:aStream base:base showRadix:true.
  4288         super printOn:aStream base:base showRadix:true.
  4288     ].
  4289     ].
  4289 
  4290 
  4290     "Created: / 07-09-2001 / 13:54:40 / cg"
  4291     "Created: / 07-09-2001 / 13:54:40 / cg"
  4291     "Modified: / 02-08-2010 / 12:25:20 / cg"
  4292     "Modified: / 02-08-2010 / 12:25:20 / cg"
  4292 !
  4293 !
  4307     OBJ newString = nil;
  4308     OBJ newString = nil;
  4308     INT myValue;
  4309     INT myValue;
  4309     int negative = 0;
  4310     int negative = 0;
  4310 
  4311 
  4311     if (self == __MKSMALLINT(0)) {
  4312     if (self == __MKSMALLINT(0)) {
  4312 	RETURN (@global(ZeroString));
  4313         RETURN (@global(ZeroString));
  4313 //        RETURN (__MKSTRING_L("0", 1));
  4314 //        RETURN (__MKSTRING_L("0", 1));
  4314     }
  4315     }
  4315     myValue = __intVal(self);
  4316     myValue = __intVal(self);
  4316     if (myValue < 0) {
  4317     if (myValue < 0) {
  4317 	negative = 1;
  4318         negative = 1;
  4318 	myValue = -myValue;
  4319         myValue = -myValue;
  4319     }
  4320     }
  4320     cp = buffer + sizeof(buffer) - 1;
  4321     cp = buffer + sizeof(buffer) - 1;
  4321     *cp-- = '\0';
  4322     *cp-- = '\0';
  4322     for ( ; myValue != 0; cp--) {
  4323     for ( ; myValue != 0; cp--) {
  4323 	*cp = '0' + (myValue % 10);
  4324         *cp = '0' + (myValue % 10);
  4324 	myValue /= 10;
  4325         myValue /= 10;
  4325     }
  4326     }
  4326     if (negative) {
  4327     if (negative) {
  4327 	*cp-- = '-';
  4328         *cp-- = '-';
  4328     }
  4329     }
  4329     newString = __MKSTRING_L(cp+1, (buffer + sizeof(buffer) - 2 - cp));
  4330     newString = __MKSTRING_L(cp+1, (buffer + sizeof(buffer) - 2 - cp));
  4330     if (newString != nil) {
  4331     if (newString != nil) {
  4331 	RETURN (newString);
  4332         RETURN (newString);
  4332     }
  4333     }
  4333 #endif /* not __SCHTEAM__ */
  4334 #endif /* not __SCHTEAM__ */
  4334 %}.
  4335 %}.
  4335     "/ only arrive here,
  4336     "/ only arrive here,
  4336     "/  when having memory problems (i.e. no space for string) ...
  4337     "/  when having memory problems (i.e. no space for string) ...
  4362     int __base = base.intValue().abs();
  4363     int __base = base.intValue().abs();
  4363     long myValue = self.longValue();
  4364     long myValue = self.longValue();
  4364     java.lang.String __s;
  4365     java.lang.String __s;
  4365 
  4366 
  4366     switch (__base) {
  4367     switch (__base) {
  4367 	case 2:
  4368         case 2:
  4368 	    __s = java.lang.Long.toBinaryString(myValue);
  4369             __s = java.lang.Long.toBinaryString(myValue);
  4369 	    break;
  4370             break;
  4370 
  4371 
  4371 	case 8:
  4372         case 8:
  4372 	    __s = java.lang.Long.toOctalString(myValue);
  4373             __s = java.lang.Long.toOctalString(myValue);
  4373 	    break;
  4374             break;
  4374 
  4375 
  4375 	case 10:
  4376         case 10:
  4376 	    __s = java.lang.Long.toString(myValue);
  4377             __s = java.lang.Long.toString(myValue);
  4377 	    break;
  4378             break;
  4378 
  4379 
  4379 	case 16:
  4380         case 16:
  4380 	    __s = java.lang.Long.toHexString(myValue);
  4381             __s = java.lang.Long.toHexString(myValue);
  4381 	    break;
  4382             break;
  4382 
  4383 
  4383 	default:
  4384         default:
  4384 	{
  4385         {
  4385 	    boolean negative = false;
  4386             boolean negative = false;
  4386 	    __s = "";
  4387             __s = "";
  4387 
  4388 
  4388 	    if ((__base > 36) || (__base < 2)) {
  4389             if ((__base > 36) || (__base < 2)) {
  4389 		throw new SmalltalkError("invalid base: ", base);
  4390                 throw new SmalltalkError("invalid base: ", base);
  4390 	    }
  4391             }
  4391 	    if (myValue < 0) {
  4392             if (myValue < 0) {
  4392 		negative = true;
  4393                 negative = true;
  4393 		myValue = -myValue;
  4394                 myValue = -myValue;
  4394 	    }
  4395             }
  4395 	    while (myValue != 0) {
  4396             while (myValue != 0) {
  4396 		int digit;
  4397                 int digit;
  4397 		char ch;
  4398                 char ch;
  4398 
  4399 
  4399 		digit = (int)(myValue % __base);
  4400                 digit = (int)(myValue % __base);
  4400 		if (digit <= 9) {
  4401                 if (digit <= 9) {
  4401 		    ch = (char)('0' + digit);
  4402                     ch = (char)('0' + digit);
  4402 		} else {
  4403                 } else {
  4403 		    ch = (char)('A' + digit - 10);
  4404                     ch = (char)('A' + digit - 10);
  4404 		}
  4405                 }
  4405 		__s = ch + __s;
  4406                 __s = ch + __s;
  4406 		myValue = myValue / __base;
  4407                 myValue = myValue / __base;
  4407 	    }
  4408             }
  4408 	    if (negative) {
  4409             if (negative) {
  4409 		__s = "-" + __s;
  4410                 __s = "-" + __s;
  4410 	    }
  4411             }
  4411 	    break;
  4412             break;
  4412 	}
  4413         }
  4413     }
  4414     }
  4414     return context._RETURN( new STString( __s ));
  4415     return context._RETURN( new STString( __s ));
  4415 #else
  4416 #else
  4416     static char ucDigits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  4417     static char ucDigits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  4417     static char lcDigits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
  4418     static char lcDigits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
  4418 
  4419 
  4419     if (__isSmallInteger(base)) {
  4420     if (__isSmallInteger(base)) {
  4420 	char *digits;
  4421         char *digits;
  4421 	INT __base;
  4422         INT __base;
  4422 
  4423 
  4423 	if (self == __MKSMALLINT(0)) {
  4424         if (self == __MKSMALLINT(0)) {
  4424 	    RETURN (@global(ZeroString));
  4425             RETURN (@global(ZeroString));
  4425 	}
  4426         }
  4426 	__base = __intVal(base);
  4427         __base = __intVal(base);
  4427 	if (__base < 0) {
  4428         if (__base < 0) {
  4428 	    __base = - __base;
  4429             __base = - __base;
  4429 	    digits = lcDigits;
  4430             digits = lcDigits;
  4430 	} else {
  4431         } else {
  4431 	    digits = ucDigits;
  4432             digits = ucDigits;
  4432 	}
  4433         }
  4433 
  4434 
  4434 	if ((__base < sizeof(ucDigits)) && (__base > 1)) {
  4435         if ((__base < sizeof(ucDigits)) && (__base > 1)) {
  4435 	    char buffer[64+5];  /* for 64bit machines, base 2, plus sign, plus 0-byte */
  4436             char buffer[64+5];  /* for 64bit machines, base 2, plus sign, plus 0-byte */
  4436 	    char *cp;
  4437             char *cp;
  4437 	    OBJ newString;
  4438             OBJ newString;
  4438 	    int negative = 0;
  4439             int negative = 0;
  4439 	    INT myValue = __intVal(self);
  4440             INT myValue = __intVal(self);
  4440 
  4441 
  4441 	    if (myValue < 0) {
  4442             if (myValue < 0) {
  4442 		negative = 1;
  4443                 negative = 1;
  4443 		myValue = -myValue;
  4444                 myValue = -myValue;
  4444 	    }
  4445             }
  4445 	    cp = buffer + sizeof(buffer) - 1;
  4446             cp = buffer + sizeof(buffer) - 1;
  4446 	    *cp-- = '\0';
  4447             *cp-- = '\0';
  4447 	    for (; myValue != 0; cp--) {
  4448             for (; myValue != 0; cp--) {
  4448 		*cp = digits[myValue % __base];
  4449                 *cp = digits[myValue % __base];
  4449 		myValue /= __base;
  4450                 myValue /= __base;
  4450 	    }
  4451             }
  4451 	    if (negative) {
  4452             if (negative) {
  4452 		*cp-- = '-';
  4453                 *cp-- = '-';
  4453 	    }
  4454             }
  4454 	    newString = __MKSTRING_L(cp+1, (buffer + sizeof(buffer) - 2 - cp));
  4455             newString = __MKSTRING_L(cp+1, (buffer + sizeof(buffer) - 2 - cp));
  4455 	    if (newString != nil) {
  4456             if (newString != nil) {
  4456 		RETURN (newString);
  4457                 RETURN (newString);
  4457 	    }
  4458             }
  4458 	}
  4459         }
  4459     }
  4460     }
  4460 #endif /* not __SCHTEAM__ */
  4461 #endif /* not __SCHTEAM__ */
  4461 %}.
  4462 %}.
  4462     "/ arrive here, for bad base,
  4463     "/ arrive here, for bad base,
  4463     "/ or when having memory problems (i.e. no space for string) ...
  4464     "/ or when having memory problems (i.e. no space for string) ...
  4535     char buffer[256];
  4536     char buffer[256];
  4536     OBJ s;
  4537     OBJ s;
  4537     int len;
  4538     int len;
  4538 
  4539 
  4539     if (__isStringLike(formatString)) {
  4540     if (__isStringLike(formatString)) {
  4540 	/*
  4541         /*
  4541 	 * actually only needed on sparc: since thisContext is
  4542          * actually only needed on sparc: since thisContext is
  4542 	 * in a global register, which gets destroyed by printf,
  4543          * in a global register, which gets destroyed by printf,
  4543 	 * manually save it here - very stupid ...
  4544          * manually save it here - very stupid ...
  4544 	 */
  4545          */
  4545 	__BEGIN_PROTECT_REGISTERS__
  4546         __BEGIN_PROTECT_REGISTERS__
  4546 
  4547 
  4547 	len = snprintf(buffer, sizeof(buffer), __stringVal(formatString), __intVal(self));
  4548         len = snprintf(buffer, sizeof(buffer), __stringVal(formatString), __intVal(self));
  4548 
  4549 
  4549 	__END_PROTECT_REGISTERS__
  4550         __END_PROTECT_REGISTERS__
  4550 
  4551 
  4551 	if (len < 0) goto fail;
  4552         if (len < 0) goto fail;
  4552 
  4553 
  4553 	s = __MKSTRING_L(buffer, len);
  4554         s = __MKSTRING_L(buffer, len);
  4554 	if (s != nil) {
  4555         if (s != nil) {
  4555 	    RETURN (s);
  4556             RETURN (s);
  4556 	}
  4557         }
  4557     }
  4558     }
  4558 fail: ;
  4559 fail: ;
  4559 #endif /* not __SCHTEAM__ */
  4560 #endif /* not __SCHTEAM__ */
  4560 %}.
  4561 %}.
  4561     self primitiveFailed
  4562     self primitiveFailed
  4562 
  4563 
  4563     "
  4564     "
  4564 	123 printfPrintString:'%%d -> %d'
  4565         123 printfPrintString:'%%d -> %d'
  4565 	123 printfPrintString:'%%6d -> %6d'
  4566         123 printfPrintString:'%%6d -> %6d'
  4566 	123 printfPrintString:'%%x -> %x'
  4567         123 printfPrintString:'%%x -> %x'
  4567 	123 printfPrintString:'%%4x -> %4x'
  4568         123 printfPrintString:'%%4x -> %4x'
  4568 	123 printfPrintString:'%%04x -> %04x'
  4569         123 printfPrintString:'%%04x -> %04x'
  4569     "
  4570     "
  4570 ! !
  4571 ! !
  4571 
  4572 
  4572 !SmallInteger methodsFor:'private'!
  4573 !SmallInteger methodsFor:'private'!
  4573 
  4574 
  4579 
  4580 
  4580     |absVal|
  4581     |absVal|
  4581 
  4582 
  4582     absVal := self abs.
  4583     absVal := self abs.
  4583     aNumber < 0 ifTrue:[
  4584     aNumber < 0 ifTrue:[
  4584 	^ absVal negated
  4585         ^ absVal negated
  4585     ].
  4586     ].
  4586     aNumber == 0 ifTrue:[^ 0].
  4587     aNumber == 0 ifTrue:[^ 0].
  4587     ^ absVal
  4588     ^ absVal
  4588 
  4589 
  4589     "
  4590     "
  4651      and can therefore speed things up by not going through LargeIntegers."
  4652      and can therefore speed things up by not going through LargeIntegers."
  4652 
  4653 
  4653 %{  /* NOCONTEXT */
  4654 %{  /* NOCONTEXT */
  4654 #ifdef __SCHTEAM__
  4655 #ifdef __SCHTEAM__
  4655     {
  4656     {
  4656 	long myValue = self.longValue();
  4657         long myValue = self.longValue();
  4657 	long otherValue = aNumber.longValue();
  4658         long otherValue = aNumber.longValue();
  4658 	long sum = myValue + otherValue;
  4659         long sum = myValue + otherValue;
  4659 	return context._RETURN( STInteger._new(sum) );
  4660         return context._RETURN( STInteger._new(sum) );
  4660     }
  4661     }
  4661     /* NOT REACHED */
  4662     /* NOT REACHED */
  4662 #else
  4663 #else
  4663     if (__isSmallInteger(aNumber)) {
  4664     if (__isSmallInteger(aNumber)) {
  4664 	INT sum;
  4665         INT sum;
  4665 
  4666 
  4666 	sum =  __intVal(self) + __intVal(aNumber);
  4667         sum =  __intVal(self) + __intVal(aNumber);
  4667 	if (!__ISVALIDINTEGER(sum)) {
  4668         if (!__ISVALIDINTEGER(sum)) {
  4668 	    /* keep the sign */
  4669             /* keep the sign */
  4669 	    sum %= _MAX_INT;
  4670             sum %= _MAX_INT;
  4670 	}
  4671         }
  4671 	RETURN ( __mkSmallInteger(sum));
  4672         RETURN ( __mkSmallInteger(sum));
  4672     }
  4673     }
  4673 #endif
  4674 #endif
  4674 %}.
  4675 %}.
  4675     self primitiveFailed
  4676     self primitiveFailed
  4676 
  4677 
  4677     "
  4678     "
  4678 	5 plus:-1
  4679         5 plus:-1
  4679 	5 plus:1
  4680         5 plus:1
  4680 	1 plus:-5
  4681         1 plus:-5
  4681 	self maxVal plus:1
  4682         self maxVal plus:1
  4682 	self maxVal + 1
  4683         self maxVal + 1
  4683     "
  4684     "
  4684 !
  4685 !
  4685 
  4686 
  4686 subtract:aNumber
  4687 subtract:aNumber
  4687     "return the difference of the receiver and the argument, as SmallInteger.
  4688     "return the difference of the receiver and the argument, as SmallInteger.
  4692      and can therefore speed things up by not going through LargeIntegers."
  4693      and can therefore speed things up by not going through LargeIntegers."
  4693 
  4694 
  4694 %{  /* NOCONTEXT */
  4695 %{  /* NOCONTEXT */
  4695 #ifdef __SCHTEAM__
  4696 #ifdef __SCHTEAM__
  4696     {
  4697     {
  4697 	long myValue = self.longValue();
  4698         long myValue = self.longValue();
  4698 	long otherValue = aNumber.longValue();
  4699         long otherValue = aNumber.longValue();
  4699 	long diference = myValue - otherValue;
  4700         long diference = myValue - otherValue;
  4700 	return context._RETURN( STInteger._new(diference) );
  4701         return context._RETURN( STInteger._new(diference) );
  4701     }
  4702     }
  4702     /* NOT REACHED */
  4703     /* NOT REACHED */
  4703 #else
  4704 #else
  4704 
  4705 
  4705     if (__isSmallInteger(aNumber)) {
  4706     if (__isSmallInteger(aNumber)) {
  4706 	INT diff;
  4707         INT diff;
  4707 
  4708 
  4708 	diff = __intVal(self) - __intVal(aNumber);
  4709         diff = __intVal(self) - __intVal(aNumber);
  4709 	if (!__ISVALIDINTEGER(diff)) {
  4710         if (!__ISVALIDINTEGER(diff)) {
  4710 	    /* keep the sign */
  4711             /* keep the sign */
  4711 	    diff %= _MAX_INT;
  4712             diff %= _MAX_INT;
  4712 	}
  4713         }
  4713 	RETURN ( __mkSmallInteger(diff));
  4714         RETURN ( __mkSmallInteger(diff));
  4714     }
  4715     }
  4715 #endif
  4716 #endif
  4716 %}.
  4717 %}.
  4717     self primitiveFailed
  4718     self primitiveFailed
  4718 
  4719 
  4719     "
  4720     "
  4720 	-1 subtract:5
  4721         -1 subtract:5
  4721 	5 subtract:1
  4722         5 subtract:1
  4722 	1 subtract:-5
  4723         1 subtract:-5
  4723 	self minVal subtract:1
  4724         self minVal subtract:1
  4724 	self minVal - 1
  4725         self minVal - 1
  4725     "
  4726     "
  4726 !
  4727 !
  4727 
  4728 
  4728 times:aNumber
  4729 times:aNumber
  4729     "return the product of the receiver and the argument, as SmallInteger.
  4730     "return the product of the receiver and the argument, as SmallInteger.
  4734      and can therefore speed things up by not going through LargeIntegers."
  4735      and can therefore speed things up by not going through LargeIntegers."
  4735 
  4736 
  4736 %{  /* NOCONTEXT */
  4737 %{  /* NOCONTEXT */
  4737 #ifdef __SCHTEAM__
  4738 #ifdef __SCHTEAM__
  4738     {
  4739     {
  4739 	long myValue = self.longValue();
  4740         long myValue = self.longValue();
  4740 	long otherValue = aNumber.longValue();
  4741         long otherValue = aNumber.longValue();
  4741 	long product = myValue * otherValue;
  4742         long product = myValue * otherValue;
  4742 	return context._RETURN( STInteger._new(product) );
  4743         return context._RETURN( STInteger._new(product) );
  4743     }
  4744     }
  4744     /* NOT REACHED */
  4745     /* NOT REACHED */
  4745 #else
  4746 #else
  4746     INT myValue, otherValue;
  4747     INT myValue, otherValue;
  4747     unsigned INT productLow, productHi;
  4748     unsigned INT productLow, productHi;
  4766 # if defined(__i386__) && defined(__GNUC__) && (__GNUC__ >= 2)
  4767 # if defined(__i386__) && defined(__GNUC__) && (__GNUC__ >= 2)
  4767 #  define USE_LONGLONG_FOR_MUL
  4768 #  define USE_LONGLONG_FOR_MUL
  4768 # endif
  4769 # endif
  4769 
  4770 
  4770     if (__isSmallInteger(aNumber)) {
  4771     if (__isSmallInteger(aNumber)) {
  4771 	myValue = __intVal(self);
  4772         myValue = __intVal(self);
  4772 	otherValue = __intVal(aNumber);
  4773         otherValue = __intVal(aNumber);
  4773 
  4774 
  4774 # if defined(USE_LONGLONG_FOR_MUL)
  4775 # if defined(USE_LONGLONG_FOR_MUL)
  4775 	{
  4776         {
  4776 #  if defined(__alpha__) && !defined(__alpha64__)
  4777 #  if defined(__alpha__) && !defined(__alpha64__)
  4777 #   define LONGLONG      INT64
  4778 #   define LONGLONG      INT64
  4778 #  else
  4779 #  else
  4779 #   define LONGLONG      long long
  4780 #   define LONGLONG      long long
  4780 #  endif
  4781 #  endif
  4781 	    LONGLONG product;
  4782             LONGLONG product;
  4782 
  4783 
  4783 	    product = (LONGLONG)myValue * (LONGLONG)otherValue;
  4784             product = (LONGLONG)myValue * (LONGLONG)otherValue;
  4784 	    if (product < 0) {
  4785             if (product < 0) {
  4785 		RETURN ( __mkSmallInteger(-(INT)(-product & _MAX_INT)));
  4786                 RETURN ( __mkSmallInteger(-(INT)(-product & _MAX_INT)));
  4786 	    }
  4787             }
  4787 	    RETURN ( __mkSmallInteger((INT)(product & _MAX_INT)));
  4788             RETURN ( __mkSmallInteger((INT)(product & _MAX_INT)));
  4788 	}
  4789         }
  4789 # else /* no long-long */
  4790 # else /* no long-long */
  4790 	negative = 1;
  4791         negative = 1;
  4791 	if (myValue < 0) {
  4792         if (myValue < 0) {
  4792 	    negative = -1;
  4793             negative = -1;
  4793 	    myValue = -myValue;
  4794             myValue = -myValue;
  4794 	}
  4795         }
  4795 	if (otherValue < 0) {
  4796         if (otherValue < 0) {
  4796 	    negative = -negative;
  4797             negative = -negative;
  4797 	    otherValue = -otherValue;
  4798             otherValue = -otherValue;
  4798 	}
  4799         }
  4799 
  4800 
  4800 #  if defined(__GNUC__) && defined(__mc68k__)
  4801 #  if defined(__GNUC__) && defined(__mc68k__)
  4801 	asm ("mulu%.l %3,%1:%0"
  4802         asm ("mulu%.l %3,%1:%0"
  4802 		: "=d"  ((unsigned long)(productLow)),
  4803                 : "=d"  ((unsigned long)(productLow)),
  4803 		  "=d"  ((unsigned long)(productHi))
  4804                   "=d"  ((unsigned long)(productHi))
  4804 		: "%0"  ((unsigned long)(myValue)),
  4805                 : "%0"  ((unsigned long)(myValue)),
  4805 		  "dmi" ((unsigned long)(otherValue)));
  4806                   "dmi" ((unsigned long)(otherValue)));
  4806 #  else
  4807 #  else
  4807 #   if defined (__GNUC__) && defined(__x86__)
  4808 #   if defined (__GNUC__) && defined(__x86__)
  4808 	asm ("mull %3"
  4809         asm ("mull %3"
  4809 		: "=a"  ((unsigned long)(productLow)),
  4810                 : "=a"  ((unsigned long)(productLow)),
  4810 		  "=d"  ((unsigned long)(productHi))
  4811                   "=d"  ((unsigned long)(productHi))
  4811 		: "%0"  ((unsigned long)(myValue)),
  4812                 : "%0"  ((unsigned long)(myValue)),
  4812 		  "rm"  ((unsigned long)(otherValue)));
  4813                   "rm"  ((unsigned long)(otherValue)));
  4813 #   else
  4814 #   else
  4814 #    if defined(__win32__) && defined(__BORLANDC__)
  4815 #    if defined(__win32__) && defined(__BORLANDC__)
  4815 	asm {
  4816         asm {
  4816 	    mov   eax, myValue
  4817             mov   eax, myValue
  4817 	    mov   edx, otherValue
  4818             mov   edx, otherValue
  4818 	    mul   edx
  4819             mul   edx
  4819 	    mov   productLow, eax
  4820             mov   productLow, eax
  4820 	    mov   productHi, edx
  4821             mov   productHi, edx
  4821 	}
  4822         }
  4822 #    else /* generic */
  4823 #    else /* generic */
  4823 	{
  4824         {
  4824 	    unsigned INT pHH, pHL, pLH, pLL;
  4825             unsigned INT pHH, pHL, pLH, pLL;
  4825 	    unsigned INT low1, low2, hi1, hi2;
  4826             unsigned INT low1, low2, hi1, hi2;
  4826 	    unsigned INT t;
  4827             unsigned INT t;
  4827 
  4828 
  4828 	    /* unsigned multiply myValue * otherValue -> productHi, productLow
  4829             /* unsigned multiply myValue * otherValue -> productHi, productLow
  4829 	     *
  4830              *
  4830 	     * this is too slow:
  4831              * this is too slow:
  4831 	     * since most machines can do 32*32 to 64 bit multiply,
  4832              * since most machines can do 32*32 to 64 bit multiply,
  4832 	     * (or at least 32*32 with Overflow check)
  4833              * (or at least 32*32 with Overflow check)
  4833 	     * - need more assembler (inline) functions here
  4834              * - need more assembler (inline) functions here
  4834 	     */
  4835              */
  4835 #     if __POINTER_SIZE__ == 8
  4836 #     if __POINTER_SIZE__ == 8
  4836 	    low1 = low32Bits((unsigned INT)myValue);
  4837             low1 = low32Bits((unsigned INT)myValue);
  4837 	    hi1 = hi32Bits((unsigned INT)myValue);
  4838             hi1 = hi32Bits((unsigned INT)myValue);
  4838 	    low2 = low32Bits((unsigned INT)otherValue);
  4839             low2 = low32Bits((unsigned INT)otherValue);
  4839 	    hi2 = hi32Bits((unsigned INT)otherValue);
  4840             hi2 = hi32Bits((unsigned INT)otherValue);
  4840 #      undef LLMASK
  4841 #      undef LLMASK
  4841 #      define LLMASK 0xC000000000000000LL
  4842 #      define LLMASK 0xC000000000000000LL
  4842 #     else
  4843 #     else
  4843 	    low1 = low16Bits((unsigned INT)myValue);
  4844             low1 = low16Bits((unsigned INT)myValue);
  4844 	    hi1 = hi16Bits((unsigned INT)myValue);
  4845             hi1 = hi16Bits((unsigned INT)myValue);
  4845 	    low2 = low16Bits((unsigned INT)otherValue);
  4846             low2 = low16Bits((unsigned INT)otherValue);
  4846 	    hi2 = hi16Bits((unsigned INT)otherValue);
  4847             hi2 = hi16Bits((unsigned INT)otherValue);
  4847 #      define LLMASK 0xC0000000
  4848 #      define LLMASK 0xC0000000
  4848 #     endif
  4849 #     endif
  4849 
  4850 
  4850 	    pLH = low1 * hi2;
  4851             pLH = low1 * hi2;
  4851 	    pHL = hi1 * low2;
  4852             pHL = hi1 * low2;
  4852 	    pLL = low1 * low2;
  4853             pLL = low1 * low2;
  4853 	    pHH = hi1 * hi2;
  4854             pHH = hi1 * hi2;
  4854 
  4855 
  4855 	    /*
  4856             /*
  4856 	     * the common case ...
  4857              * the common case ...
  4857 	     */
  4858              */
  4858 	    if ((pHL == 0)
  4859             if ((pHL == 0)
  4859 	     && (pLH == 0)
  4860              && (pLH == 0)
  4860 	     && (pHH == 0)
  4861              && (pHH == 0)
  4861 	     && ((pLL & LLMASK) == 0)) {
  4862              && ((pLL & LLMASK) == 0)) {
  4862 		if (negative < 0) {
  4863                 if (negative < 0) {
  4863 		    RETURN ( __mkSmallInteger(- ((INT)pLL)) );
  4864                     RETURN ( __mkSmallInteger(- ((INT)pLL)) );
  4864 		}
  4865                 }
  4865 		RETURN ( __mkSmallInteger((INT)pLL) );
  4866                 RETURN ( __mkSmallInteger((INT)pLL) );
  4866 	    }
  4867             }
  4867 
  4868 
  4868 	    /*
  4869             /*
  4869 	     *   pHH |--------|--------|
  4870              *   pHH |--------|--------|
  4870 	     *   pLH          |--------|--------|
  4871              *   pLH          |--------|--------|
  4871 	     *   pHL          |--------|--------|
  4872              *   pHL          |--------|--------|
  4872 	     *   pLL                   |--------|--------|
  4873              *   pLL                   |--------|--------|
  4873 	     */
  4874              */
  4874 
  4875 
  4875 #     if __POINTER_SIZE__ == 8
  4876 #     if __POINTER_SIZE__ == 8
  4876 	    t = low32Bits(pLH) + low32Bits(pHL) + hi32Bits(pLL);
  4877             t = low32Bits(pLH) + low32Bits(pHL) + hi32Bits(pLL);
  4877 	    productLow = (t << 32) + low32Bits(pLL);
  4878             productLow = (t << 32) + low32Bits(pLL);
  4878 	    productHi = pHH + hi32Bits(t) + hi32Bits(pHL) + hi32Bits(pLH);
  4879             productHi = pHH + hi32Bits(t) + hi32Bits(pHL) + hi32Bits(pLH);
  4879 #     else
  4880 #     else
  4880 	    t = low16Bits(pLH) + low16Bits(pHL) + hi16Bits(pLL);
  4881             t = low16Bits(pLH) + low16Bits(pHL) + hi16Bits(pLL);
  4881 	    productLow = (t << 16) + low16Bits(pLL);
  4882             productLow = (t << 16) + low16Bits(pLL);
  4882 	    productHi = pHH + hi16Bits(t) + hi16Bits(pHL) + hi16Bits(pLH);
  4883             productHi = pHH + hi16Bits(t) + hi16Bits(pHL) + hi16Bits(pLH);
  4883 #     endif
  4884 #     endif
  4884 	}
  4885         }
  4885 #    endif /* ! __win32__ */
  4886 #    endif /* ! __win32__ */
  4886 #   endif /* ! (__GNUC__ && __x86__) */
  4887 #   endif /* ! (__GNUC__ && __x86__) */
  4887 #  endif /* ! (__GNUC__ && __mc68k__) */
  4888 #  endif /* ! (__GNUC__ && __mc68k__) */
  4888 
  4889 
  4889 	if (negative < 0) {
  4890         if (negative < 0) {
  4890 	    RETURN ( __mkSmallInteger(-(INT)(productLow & _MAX_INT)));
  4891             RETURN ( __mkSmallInteger(-(INT)(productLow & _MAX_INT)));
  4891 	}
  4892         }
  4892 	RETURN ( __mkSmallInteger((INT)(productLow & _MAX_INT)));
  4893         RETURN ( __mkSmallInteger((INT)(productLow & _MAX_INT)));
  4893 # endif /* ! USE_LONGLONG */
  4894 # endif /* ! USE_LONGLONG */
  4894     }
  4895     }
  4895 #endif /* not __SCHTEAM__ */
  4896 #endif /* not __SCHTEAM__ */
  4896 %}.
  4897 %}.
  4897 
  4898 
  4898     self primitiveFailed
  4899     self primitiveFailed
  4899 
  4900 
  4900     "
  4901     "
  4901 	5 times:-1
  4902         5 times:-1
  4902 	5 times:1
  4903         5 times:1
  4903 	self maxVal-1 times:2
  4904         self maxVal-1 times:2
  4904 	self maxVal-1 times:-2
  4905         self maxVal-1 times:-2
  4905 	self maxVal-1 * 2  bitAnd:16r3fffffff
  4906         self maxVal-1 * 2  bitAnd:16r3fffffff
  4906     "
  4907     "
  4907 ! !
  4908 ! !
  4908 
  4909 
  4909 !SmallInteger methodsFor:'special modulo bit operators'!
  4910 !SmallInteger methodsFor:'special modulo bit operators'!
  4910 
  4911 
  4944 
  4945 
  4945     unsigned INT bits;
  4946     unsigned INT bits;
  4946     int count;
  4947     int count;
  4947 
  4948 
  4948     if (__isSmallInteger(shiftCount)) {
  4949     if (__isSmallInteger(shiftCount)) {
  4949 	count = __intVal(shiftCount);
  4950         count = __intVal(shiftCount);
  4950 	count = count % 32;
  4951         count = count % 32;
  4951 
  4952 
  4952 	bits = __intVal(self);
  4953         bits = __intVal(self);
  4953 	if (count > 0) {
  4954         if (count > 0) {
  4954 	    bits = (bits << count) | (bits >> (32-count));
  4955             bits = (bits << count) | (bits >> (32-count));
  4955 	} else {
  4956         } else {
  4956 	    bits = (bits >> (-count)) | (bits << (32-(-count)));
  4957             bits = (bits >> (-count)) | (bits << (32-(-count)));
  4957 	}
  4958         }
  4958 # if __POINTER_SIZE__ == 8
  4959 # if __POINTER_SIZE__ == 8
  4959 	bits &= 0xFFFFFFFFL;
  4960         bits &= 0xFFFFFFFFL;
  4960 # endif
  4961 # endif
  4961 	RETURN (__MKUINT(bits));
  4962         RETURN (__MKUINT(bits));
  4962     }
  4963     }
  4963 #endif
  4964 #endif
  4964 %}.
  4965 %}.
  4965     ^ self primitiveFailed
  4966     ^ self primitiveFailed
  4966 
  4967 
  4990 #ifndef __SCHTEAM__
  4991 #ifndef __SCHTEAM__
  4991 
  4992 
  4992     INT bits, count;
  4993     INT bits, count;
  4993 
  4994 
  4994     if (__isSmallInteger(shiftCount)) {
  4995     if (__isSmallInteger(shiftCount)) {
  4995 	count = __intVal(shiftCount);
  4996         count = __intVal(shiftCount);
  4996 	if (count >= 32) {
  4997         if (count >= 32) {
  4997 	    RETURN (__mkSmallInteger(0));
  4998             RETURN (__mkSmallInteger(0));
  4998 	}
  4999         }
  4999 
  5000 
  5000 	bits = __intVal(self);
  5001         bits = __intVal(self);
  5001 	if (count > 0) {
  5002         if (count > 0) {
  5002 	    bits = bits << count;
  5003             bits = bits << count;
  5003 	} else {
  5004         } else {
  5004 	    bits = bits >> (-count);
  5005             bits = bits >> (-count);
  5005 	}
  5006         }
  5006 # if __POINTER_SIZE__ == 8
  5007 # if __POINTER_SIZE__ == 8
  5007 	bits &= 0xFFFFFFFFL;
  5008         bits &= 0xFFFFFFFFL;
  5008 # endif
  5009 # endif
  5009 	RETURN (__MKINT(bits));
  5010         RETURN (__MKINT(bits));
  5010     }
  5011     }
  5011 #endif
  5012 #endif
  5012 %}.
  5013 %}.
  5013     ^ self primitiveFailed
  5014     ^ self primitiveFailed
  5014 
  5015 
  5058 
  5059 
  5059     unsigned INT bits;
  5060     unsigned INT bits;
  5060     INT count;
  5061     INT count;
  5061 
  5062 
  5062     if (__isSmallInteger(shiftCount)) {
  5063     if (__isSmallInteger(shiftCount)) {
  5063 	count = __intVal(shiftCount);
  5064         count = __intVal(shiftCount);
  5064 	if (count >= 32) {
  5065         if (count >= 32) {
  5065 	    RETURN (__mkSmallInteger(0));
  5066             RETURN (__mkSmallInteger(0));
  5066 	}
  5067         }
  5067 
  5068 
  5068 	bits = __intVal(self);
  5069         bits = __intVal(self);
  5069 	if (count > 0) {
  5070         if (count > 0) {
  5070 	    bits = bits << count;
  5071             bits = bits << count;
  5071 	} else {
  5072         } else {
  5072 	    bits = bits >> (-count);
  5073             bits = bits >> (-count);
  5073 	}
  5074         }
  5074 # if __POINTER_SIZE__ == 8
  5075 # if __POINTER_SIZE__ == 8
  5075 	bits &= 0xFFFFFFFFL;
  5076         bits &= 0xFFFFFFFFL;
  5076 # endif
  5077 # endif
  5077 	RETURN (__MKUINT(bits));
  5078         RETURN (__MKUINT(bits));
  5078     }
  5079     }
  5079 #endif
  5080 #endif
  5080 %}.
  5081 %}.
  5081     ^ self primitiveFailed
  5082     ^ self primitiveFailed
  5082 
  5083 
  5100      - reimplemented here for speed"
  5101      - reimplemented here for speed"
  5101 
  5102 
  5102 %{  /* NOCONTEXT */
  5103 %{  /* NOCONTEXT */
  5103 #ifdef __SCHTEAM__
  5104 #ifdef __SCHTEAM__
  5104     if (STObject.bothSmallInteger(min, max)) {
  5105     if (STObject.bothSmallInteger(min, max)) {
  5105 	long myVal = ((STInteger)self).longValue();
  5106         long myVal = ((STInteger)self).longValue();
  5106 
  5107 
  5107 	if (myVal >= ((STInteger)min).longValue()) {
  5108         if (myVal >= ((STInteger)min).longValue()) {
  5108 	    if (myVal <= ((STInteger)max).longValue()) {
  5109             if (myVal <= ((STInteger)max).longValue()) {
  5109 		return __c__._RETURN_true();
  5110                 return __c__._RETURN_true();
  5110 	    }
  5111             }
  5111 	}
  5112         }
  5112 	return __c__._RETURN_false();
  5113         return __c__._RETURN_false();
  5113     }
  5114     }
  5114 #else /* not SCHTEAM */
  5115 #else /* not SCHTEAM */
  5115     if (__bothSmallInteger(min, max)) {
  5116     if (__bothSmallInteger(min, max)) {
  5116 # if TAG_INT == 1
  5117 # if TAG_INT == 1
  5117 	// tag bit does not change the magnitude order
  5118         // tag bit does not change the magnitude order
  5118 	if ((INT)self < (INT)(min)) {
  5119         if ((INT)self < (INT)(min)) {
  5119 	     RETURN ( false );
  5120              RETURN ( false );
  5120 	}
  5121         }
  5121 	if ((INT)self > (INT)(max)) {
  5122         if ((INT)self > (INT)(max)) {
  5122 	     RETURN ( false );
  5123              RETURN ( false );
  5123 	}
  5124         }
  5124 	RETURN ( true );
  5125         RETURN ( true );
  5125 # else
  5126 # else
  5126 	REGISTER INT selfVal;
  5127         REGISTER INT selfVal;
  5127 
  5128 
  5128 	selfVal = __intVal(self);
  5129         selfVal = __intVal(self);
  5129 	if (selfVal < __intVal(min)) {
  5130         if (selfVal < __intVal(min)) {
  5130 	     RETURN ( false );
  5131              RETURN ( false );
  5131 	}
  5132         }
  5132 	if (selfVal > __intVal(max)) {
  5133         if (selfVal > __intVal(max)) {
  5133 	     RETURN ( false );
  5134              RETURN ( false );
  5134 	}
  5135         }
  5135 	RETURN ( true );
  5136         RETURN ( true );
  5136 # endif
  5137 # endif
  5137     }
  5138     }
  5138 #endif /* not SCHTEAM */
  5139 #endif /* not SCHTEAM */
  5139 %}.
  5140 %}.
  5140     (self < min) ifTrue:[^ false].
  5141     (self < min) ifTrue:[^ false].
  5282 #endif
  5283 #endif
  5283 %}.
  5284 %}.
  5284     ^ super parityOdd
  5285     ^ super parityOdd
  5285 
  5286 
  5286     "
  5287     "
  5287 	self assert:
  5288         self assert:
  5288 	 (((0 to:255) collect:[:i | i parityOdd ifTrue:1 ifFalse:0])
  5289          (((0 to:255) collect:[:i | i parityOdd ifTrue:1 ifFalse:0])
  5289 	    asByteArray collect:[:c | c + $0 asciiValue]) asString
  5290             asByteArray collect:[:c | c + $0 asciiValue]) asString
  5290 	 =
  5291          =
  5291 	    '0110100110010110100101100110100110010110011010010110100110010110100101100110100101101001100101100110100110010110100101100110100110010110011010010110100110010110011010011001011010010110011010010110100110010110100101100110100110010110011010010110100110010110'
  5292             '0110100110010110100101100110100110010110011010010110100110010110100101100110100101101001100101100110100110010110100101100110100110010110011010010110100110010110011010011001011010010110011010010110100110010110100101100110100110010110011010010110100110010110'
  5292 
  5293 
  5293 	self assert:(16r0FFFFFFF parityOdd = 16r0FFFFFFF bitCount odd).
  5294         self assert:(16r0FFFFFFF parityOdd = 16r0FFFFFFF bitCount odd).
  5294 	self assert:(16r1FFFFFFF parityOdd = 16r1FFFFFFF bitCount odd).
  5295         self assert:(16r1FFFFFFF parityOdd = 16r1FFFFFFF bitCount odd).
  5295 	self assert:(16r3FFFFFFF parityOdd = 16r3FFFFFFF bitCount odd).
  5296         self assert:(16r3FFFFFFF parityOdd = 16r3FFFFFFF bitCount odd).
  5296 	self assert:(16r7FFFFFFF parityOdd = 16r7FFFFFFF bitCount odd).
  5297         self assert:(16r7FFFFFFF parityOdd = 16r7FFFFFFF bitCount odd).
  5297 	self assert:(16rFFFFFFFF parityOdd = 16rFFFFFFFF bitCount odd).
  5298         self assert:(16rFFFFFFFF parityOdd = 16rFFFFFFFF bitCount odd).
  5298 	self assert:(16r3FFFFFFFFFFFFFFF parityOdd = 16r3FFFFFFFFFFFFFFF bitCount odd).
  5299         self assert:(16r3FFFFFFFFFFFFFFF parityOdd = 16r3FFFFFFFFFFFFFFF bitCount odd).
  5299 	self assert:(16r7FFFFFFFFFFFFFFF parityOdd = 16r7FFFFFFFFFFFFFFF bitCount odd).
  5300         self assert:(16r7FFFFFFFFFFFFFFF parityOdd = 16r7FFFFFFFFFFFFFFF bitCount odd).
  5300 	self assert:(16rFFFFFFFFFFFFFFFF parityOdd = 16rFFFFFFFFFFFFFFFF bitCount odd).
  5301         self assert:(16rFFFFFFFFFFFFFFFF parityOdd = 16rFFFFFFFFFFFFFFFF bitCount odd).
  5301     "
  5302     "
  5302 
  5303 
  5303     "Modified (comment): / 09-01-2012 / 19:55:37 / cg"
  5304     "Modified (comment): / 09-01-2012 / 19:55:37 / cg"
  5304 !
  5305 !
  5305 
  5306