SmallInteger.st
changeset 14632 6fe0dc1d5377
parent 14540 84fc4b759ad8
child 14693 d65d6d900457
child 18011 deb0c3355881
equal deleted inserted replaced
14631:501217c542a5 14632:6fe0dc1d5377
   211 #if defined(__i386__) && defined(__GNUC__) && (__GNUC__ >= 2)
   211 #if defined(__i386__) && defined(__GNUC__) && (__GNUC__ >= 2)
   212 # define USE_LONGLONG_FOR_MUL
   212 # define USE_LONGLONG_FOR_MUL
   213 #endif
   213 #endif
   214 
   214 
   215     if (__isSmallInteger(aNumber)) {
   215     if (__isSmallInteger(aNumber)) {
   216         myValue = __intVal(self);
   216 	myValue = __intVal(self);
   217         otherValue = __intVal(aNumber);
   217 	otherValue = __intVal(aNumber);
   218 
   218 
   219 #if defined(USE_LONGLONG_FOR_MUL)
   219 #if defined(USE_LONGLONG_FOR_MUL)
   220         {
   220 	{
   221 # if defined(__alpha__) && !defined(__alpha64__)
   221 # if defined(__alpha__) && !defined(__alpha64__)
   222 #  define LONGLONG      INT64
   222 #  define LONGLONG      INT64
   223 # else
   223 # else
   224 #  define LONGLONG      long long
   224 #  define LONGLONG      long long
   225 # endif
   225 # endif
   226             LONGLONG product;
   226 	    LONGLONG product;
   227 
   227 
   228             product = (LONGLONG)myValue * (LONGLONG)otherValue;
   228 	    product = (LONGLONG)myValue * (LONGLONG)otherValue;
   229             if ((product >= (LONGLONG)_MIN_INT)
   229 	    if ((product >= (LONGLONG)_MIN_INT)
   230              && (product <= (LONGLONG)_MAX_INT)) {
   230 	     && (product <= (LONGLONG)_MAX_INT)) {
   231                 RETURN ( __mkSmallInteger((INT)product) );
   231 		RETURN ( __mkSmallInteger((INT)product) );
   232             }
   232 	    }
   233             if (product < 0) {
   233 	    if (product < 0) {
   234                 negative = -1;
   234 		negative = -1;
   235                 product = -product;
   235 		product = -product;
   236             } else {
   236 	    } else {
   237                 negative = 1;
   237 		negative = 1;
   238             }
   238 	    }
   239             productHi = product >> 32;
   239 	    productHi = product >> 32;
   240             productLow = product & 0xFFFFFFFFL;
   240 	    productLow = product & 0xFFFFFFFFL;
   241         }
   241 	}
   242 #else /* no long-long */
   242 #else /* no long-long */
   243         negative = 1;
   243 	negative = 1;
   244         if (myValue < 0) {
   244 	if (myValue < 0) {
   245             negative = -1;
   245 	    negative = -1;
   246             myValue = -myValue;
   246 	    myValue = -myValue;
   247         }
   247 	}
   248         if (otherValue < 0) {
   248 	if (otherValue < 0) {
   249             negative = -negative;
   249 	    negative = -negative;
   250             otherValue = -otherValue;
   250 	    otherValue = -otherValue;
   251         }
   251 	}
   252 
   252 
   253 # if defined(__GNUC__) && defined(__mc68k__)
   253 # if defined(__GNUC__) && defined(__mc68k__)
   254         asm ("mulu%.l %3,%1:%0"
   254 	asm ("mulu%.l %3,%1:%0"
   255                 : "=d"  ((unsigned long)(productLow)),
   255 		: "=d"  ((unsigned long)(productLow)),
   256                   "=d"  ((unsigned long)(productHi))
   256 		  "=d"  ((unsigned long)(productHi))
   257                 : "%0"  ((unsigned long)(myValue)),
   257 		: "%0"  ((unsigned long)(myValue)),
   258                   "dmi" ((unsigned long)(otherValue)));
   258 		  "dmi" ((unsigned long)(otherValue)));
   259 # else
   259 # else
   260 #  if defined (__GNUC__) && defined(__i386__)
   260 #  if defined (__GNUC__) && defined(__i386__)
   261         asm ("mull %3"
   261 	asm ("mull %3"
   262                 : "=a"  ((unsigned long)(productLow)),
   262 		: "=a"  ((unsigned long)(productLow)),
   263                   "=d"  ((unsigned long)(productHi))
   263 		  "=d"  ((unsigned long)(productHi))
   264                 : "%0"  ((unsigned long)(myValue)),
   264 		: "%0"  ((unsigned long)(myValue)),
   265                   "rm"  ((unsigned long)(otherValue)));
   265 		  "rm"  ((unsigned long)(otherValue)));
   266 #  else
   266 #  else
   267 #   if defined(WIN32) && defined(__BORLANDC__)
   267 #   if defined(WIN32) && defined(__BORLANDC__)
   268         asm {
   268 	asm {
   269             mov   eax, myValue
   269 	    mov   eax, myValue
   270             mov   edx, otherValue
   270 	    mov   edx, otherValue
   271             mul   edx
   271 	    mul   edx
   272             mov   productLow, eax
   272 	    mov   productLow, eax
   273             mov   productHi, edx
   273 	    mov   productHi, edx
   274         }
   274 	}
   275 #   else /* generic */
   275 #   else /* generic */
   276         {
   276 	{
   277             unsigned INT pHH, pHL, pLH, pLL;
   277 	    unsigned INT pHH, pHL, pLH, pLL;
   278             unsigned INT low1, low2, hi1, hi2;
   278 	    unsigned INT low1, low2, hi1, hi2;
   279             unsigned INT t;
   279 	    unsigned INT t;
   280 
   280 
   281             /* unsigned multiply myValue * otherValue -> productHi, productLow
   281 	    /* unsigned multiply myValue * otherValue -> productHi, productLow
   282              *
   282 	     *
   283              * this is too slow:
   283 	     * this is too slow:
   284              * since most machines can do 32*32 to 64 bit multiply,
   284 	     * since most machines can do 32*32 to 64 bit multiply,
   285              * (or at least 32*32 with Overflow check)
   285 	     * (or at least 32*32 with Overflow check)
   286              * - need more assembler (inline) functions here
   286 	     * - need more assembler (inline) functions here
   287              */
   287 	     */
   288 #    if __POINTER_SIZE__ == 8
   288 #    if __POINTER_SIZE__ == 8
   289             low1 = low32Bits((unsigned INT)myValue);
   289 	    low1 = low32Bits((unsigned INT)myValue);
   290             hi1 = hi32Bits((unsigned INT)myValue);
   290 	    hi1 = hi32Bits((unsigned INT)myValue);
   291             low2 = low32Bits((unsigned INT)otherValue);
   291 	    low2 = low32Bits((unsigned INT)otherValue);
   292             hi2 = hi32Bits((unsigned INT)otherValue);
   292 	    hi2 = hi32Bits((unsigned INT)otherValue);
   293 #     define LLMASK 0xC000000000000000L
   293 #     define LLMASK 0xC000000000000000L
   294 #    else
   294 #    else
   295             low1 = low16Bits((unsigned INT)myValue);
   295 	    low1 = low16Bits((unsigned INT)myValue);
   296             hi1 = hi16Bits((unsigned INT)myValue);
   296 	    hi1 = hi16Bits((unsigned INT)myValue);
   297             low2 = low16Bits((unsigned INT)otherValue);
   297 	    low2 = low16Bits((unsigned INT)otherValue);
   298             hi2 = hi16Bits((unsigned INT)otherValue);
   298 	    hi2 = hi16Bits((unsigned INT)otherValue);
   299 #     define LLMASK 0xC0000000
   299 #     define LLMASK 0xC0000000
   300 #    endif
   300 #    endif
   301 
   301 
   302             pLH = low1 * hi2;
   302 	    pLH = low1 * hi2;
   303             pHL = hi1 * low2;
   303 	    pHL = hi1 * low2;
   304             pLL = low1 * low2;
   304 	    pLL = low1 * low2;
   305             pHH = hi1 * hi2;
   305 	    pHH = hi1 * hi2;
   306 
   306 
   307             /*
   307 	    /*
   308              * the common case ...
   308 	     * the common case ...
   309              */
   309 	     */
   310             if ((pHL == 0)
   310 	    if ((pHL == 0)
   311              && (pLH == 0)
   311 	     && (pLH == 0)
   312              && (pHH == 0)
   312 	     && (pHH == 0)
   313              && ((pLL & LLMASK) == 0)) {
   313 	     && ((pLL & LLMASK) == 0)) {
   314                 if (negative < 0) {
   314 		if (negative < 0) {
   315                     RETURN ( __mkSmallInteger(- ((INT)pLL)) );
   315 		    RETURN ( __mkSmallInteger(- ((INT)pLL)) );
   316                 }
   316 		}
   317                 RETURN ( __mkSmallInteger((INT)pLL) );
   317 		RETURN ( __mkSmallInteger((INT)pLL) );
   318             }
   318 	    }
   319 
   319 
   320             /*
   320 	    /*
   321              *   pHH |--------|--------|
   321 	     *   pHH |--------|--------|
   322              *   pLH          |--------|--------|
   322 	     *   pLH          |--------|--------|
   323              *   pHL          |--------|--------|
   323 	     *   pHL          |--------|--------|
   324              *   pLL                   |--------|--------|
   324 	     *   pLL                   |--------|--------|
   325              */
   325 	     */
   326 
   326 
   327 #    if __POINTER_SIZE__ == 8
   327 #    if __POINTER_SIZE__ == 8
   328             t = low32Bits(pLH) + low32Bits(pHL) + hi32Bits(pLL);
   328 	    t = low32Bits(pLH) + low32Bits(pHL) + hi32Bits(pLL);
   329             productLow = (t << 32) + low32Bits(pLL);
   329 	    productLow = (t << 32) + low32Bits(pLL);
   330             productHi = pHH + hi32Bits(t) + hi32Bits(pHL) + hi32Bits(pLH);
   330 	    productHi = pHH + hi32Bits(t) + hi32Bits(pHL) + hi32Bits(pLH);
   331 #    else
   331 #    else
   332             t = low16Bits(pLH) + low16Bits(pHL) + hi16Bits(pLL);
   332 	    t = low16Bits(pLH) + low16Bits(pHL) + hi16Bits(pLL);
   333             productLow = (t << 16) + low16Bits(pLL);
   333 	    productLow = (t << 16) + low16Bits(pLL);
   334             productHi = pHH + hi16Bits(t) + hi16Bits(pHL) + hi16Bits(pLH);
   334 	    productHi = pHH + hi16Bits(t) + hi16Bits(pHL) + hi16Bits(pLH);
   335 #    endif
   335 #    endif
   336         }
   336 	}
   337 #   endif /* ! WIN32 */
   337 #   endif /* ! WIN32 */
   338 #  endif /* ! (__GNUC__ && __i386__) */
   338 #  endif /* ! (__GNUC__ && __i386__) */
   339 # endif /* ! (__GNUC__ && __mc68k__) */
   339 # endif /* ! (__GNUC__ && __mc68k__) */
   340 
   340 
   341         if (productHi == 0) {
   341 	if (productHi == 0) {
   342             if (negative < 0) {
   342 	    if (negative < 0) {
   343                 if (productLow <= -(_MIN_INT)) {
   343 		if (productLow <= -(_MIN_INT)) {
   344                     RETURN ( __mkSmallInteger(-((INT)productLow)) );
   344 		    RETURN ( __mkSmallInteger(-((INT)productLow)) );
   345                 }
   345 		}
   346             } else {
   346 	    } else {
   347                 if (productLow <= _MAX_INT) {
   347 		if (productLow <= _MAX_INT) {
   348                     RETURN ( __mkSmallInteger(productLow) );
   348 		    RETURN ( __mkSmallInteger(productLow) );
   349                 }
   349 		}
   350             }
   350 	    }
   351         }
   351 	}
   352 #endif /* ! USE_LONGLONG */
   352 #endif /* ! USE_LONGLONG */
   353 
   353 
   354 #if __POINTER_SIZE__ == 8
   354 #if __POINTER_SIZE__ == 8
   355         RETURN (__MKLARGEINT128(negative, productLow, productHi));
   355 	RETURN (__MKLARGEINT128(negative, productLow, productHi));
   356 #else
   356 #else
   357         RETURN (__MKLARGEINT64(negative, productLow, productHi));
   357 	RETURN (__MKLARGEINT64(negative, productLow, productHi));
   358 #endif
   358 #endif
   359     } else if (__isFloatLike(aNumber)) {
   359     } else if (__isFloatLike(aNumber)) {
   360         OBJ newFloat;
   360 	OBJ newFloat;
   361         double val = (double)__intVal(self) * __floatVal(aNumber);
   361 	double val = (double)__intVal(self) * __floatVal(aNumber);
   362 
   362 
   363         __qMKFLOAT(newFloat, val);
   363 	__qMKFLOAT(newFloat, val);
   364         RETURN ( newFloat );
   364 	RETURN ( newFloat );
   365     } else if (__isShortFloat(aNumber)) {
   365     } else if (__isShortFloat(aNumber)) {
   366         OBJ newFloat;
   366 	OBJ newFloat;
   367         float val = (float)__intVal(self) * __shortFloatVal(aNumber);
   367 	float val = (float)__intVal(self) * __shortFloatVal(aNumber);
   368 
   368 
   369         __qMKSFLOAT(newFloat, val);
   369 	__qMKSFLOAT(newFloat, val);
   370         RETURN ( newFloat );
   370 	RETURN ( newFloat );
   371     }
   371     }
   372 %}.
   372 %}.
   373     ^ aNumber productFromInteger:self
   373     ^ aNumber productFromInteger:self
   374 !
   374 !
   375 
   375 
   543      and the arguments value. The result is truncated toward negative infinity
   543      and the arguments value. The result is truncated toward negative infinity
   544      and negative, if the operands signs differ.
   544      and negative, if the operands signs differ.
   545      Be careful with negative results: 9 // 4 = 2,
   545      Be careful with negative results: 9 // 4 = 2,
   546      while -9 // 4 = -3.
   546      while -9 // 4 = -3.
   547      The following is always true:
   547      The following is always true:
   548         (receiver // aNumber) * aNumber + (receiver \\ aNUmber) = receiver
   548 	(receiver // aNumber) * aNumber + (receiver \\ aNUmber) = receiver
   549      See #quo: which returns -2 in the latter."
   549      See #quo: which returns -2 in the latter."
   550 
   550 
   551 %{  /* NOCONTEXT */
   551 %{  /* NOCONTEXT */
   552 
   552 
   553     /*
   553     /*
   561      */
   561      */
   562 
   562 
   563     INT dividend, divisor, rslt;
   563     INT dividend, divisor, rslt;
   564 
   564 
   565     if (__isSmallInteger(aNumber)) {
   565     if (__isSmallInteger(aNumber)) {
   566         divisor = __intVal(aNumber);
   566 	divisor = __intVal(aNumber);
   567         if (divisor != 0) {
   567 	if (divisor != 0) {
   568             dividend = __intVal(self);
   568 	    dividend = __intVal(self);
   569             rslt = dividend / divisor;
   569 	    rslt = dividend / divisor;
   570             /*
   570 	    /*
   571              * Optimized to speed up positive result
   571 	     * Optimized to speed up positive result
   572              */
   572 	     */
   573             if (rslt <= 0) {
   573 	    if (rslt <= 0) {
   574                 if (rslt == 0) {
   574 		if (rslt == 0) {
   575                     if ((dividend ^ divisor) < 0) {
   575 		    if ((dividend ^ divisor) < 0) {
   576                         /*
   576 			/*
   577                          * result (negative) has been truncated toward 0.
   577 			 * result (negative) has been truncated toward 0.
   578                          * Return -1, because we truncate toward negative inf.
   578 			 * Return -1, because we truncate toward negative inf.
   579                          */
   579 			 */
   580                          rslt = -1;
   580 			 rslt = -1;
   581                     }
   581 		    }
   582                 } else {
   582 		} else {
   583                     /*
   583 		    /*
   584                      * If result (negative) has been truncated toward 0,
   584 		     * If result (negative) has been truncated toward 0,
   585                      * subtract 1, because we truncate toward negative inf.
   585 		     * subtract 1, because we truncate toward negative inf.
   586                      */
   586 		     */
   587                     if (divisor > 0) {
   587 		    if (divisor > 0) {
   588                         if (rslt * divisor > dividend) {
   588 			if (rslt * divisor > dividend) {
   589                             rslt--;
   589 			    rslt--;
   590                         }
   590 			}
   591                     } else {
   591 		    } else {
   592                         if (rslt * divisor < dividend) {
   592 			if (rslt * divisor < dividend) {
   593                             rslt--;
   593 			    rslt--;
   594                         }
   594 			}
   595                     }
   595 		    }
   596                 }
   596 		}
   597             }
   597 	    }
   598             RETURN ( __mkSmallInteger(rslt) );
   598 	    RETURN ( __mkSmallInteger(rslt) );
   599         }
   599 	}
   600     } else {
   600     } else {
   601         if (__isFraction(aNumber)) {
   601 	if (__isFraction(aNumber)) {
   602             OBJ t;
   602 	    OBJ t;
   603             INT num, den;
   603 	    INT num, den;
   604 
   604 
   605             t = __FractionInstPtr(aNumber)->f_numerator;
   605 	    t = __FractionInstPtr(aNumber)->f_numerator;
   606             if (__isSmallInteger(t)) {
   606 	    if (__isSmallInteger(t)) {
   607                 num = __intVal(t);
   607 		num = __intVal(t);
   608                 t = __FractionInstPtr(aNumber)->f_denominator;
   608 		t = __FractionInstPtr(aNumber)->f_denominator;
   609                 if (__isSmallInteger(t)) {
   609 		if (__isSmallInteger(t)) {
   610                     den = __intVal(t);
   610 		    den = __intVal(t);
   611                     RETURN ( __mkSmallInteger(__intVal(self) * den / num ));
   611 		    RETURN ( __mkSmallInteger(__intVal(self) * den / num ));
   612                 }
   612 		}
   613             }
   613 	    }
   614         }
   614 	}
   615     }
   615     }
   616 %}.
   616 %}.
   617     (aNumber = 0) ifTrue:[
   617     (aNumber = 0) ifTrue:[
   618         ^ ZeroDivide raiseRequestWith:thisContext.
   618 	^ ZeroDivide raiseRequestWith:thisContext.
   619     ].
   619     ].
   620     ^ aNumber integerQuotientFromInteger:self
   620     ^ aNumber integerQuotientFromInteger:self
   621 
   621 
   622     "
   622     "
   623      9 // 4     ~~ 2 ifTrue:[self halt].
   623      9 // 4     ~~ 2 ifTrue:[self halt].
   642 \\ aNumber
   642 \\ aNumber
   643     "Answer the integer remainder m defined by division with truncation toward
   643     "Answer the integer remainder m defined by division with truncation toward
   644      negative infinity. The remainder has the same sign as aNumber.
   644      negative infinity. The remainder has the same sign as aNumber.
   645      m < |aNumber| AND there is an integer k with (k * aNumber + m) = self
   645      m < |aNumber| AND there is an integer k with (k * aNumber + m) = self
   646      The following is always true:
   646      The following is always true:
   647         (receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
   647 	(receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
   648      Compare with #rem:
   648      Compare with #rem:
   649 
   649 
   650      Redefined for speed."
   650      Redefined for speed."
   651 
   651 
   652 %{  /* NOCONTEXT */
   652 %{  /* NOCONTEXT */
   662      */
   662      */
   663 
   663 
   664     INT dividend, divisor, rem;
   664     INT dividend, divisor, rem;
   665 
   665 
   666     if (__isSmallInteger(aNumber)
   666     if (__isSmallInteger(aNumber)
   667         && (divisor = __intVal(aNumber)) != 0) {
   667 	&& (divisor = __intVal(aNumber)) != 0) {
   668         /*
   668 	/*
   669          * Note that the sign of something modulo a negative number is undefined
   669 	 * Note that the sign of something modulo a negative number is undefined
   670          * in C!
   670 	 * in C!
   671          */
   671 	 */
   672         dividend = __intVal(self);
   672 	dividend = __intVal(self);
   673         rem = dividend % divisor;
   673 	rem = dividend % divisor;
   674         if (rem) {
   674 	if (rem) {
   675             if ((rem ^ divisor) < 0) {
   675 	    if ((rem ^ divisor) < 0) {
   676                 /* sign of remainder is different from sign of divisor */
   676 		/* sign of remainder is different from sign of divisor */
   677                 rem = -rem;
   677 		rem = -rem;
   678             }
   678 	    }
   679             if ((dividend ^ divisor) < 0) {
   679 	    if ((dividend ^ divisor) < 0) {
   680                 /* different signs, so division would have returned a
   680 		/* different signs, so division would have returned a
   681                  * negative number.
   681 		 * negative number.
   682                  * C rounds toward zero, this code will simulate
   682 		 * C rounds toward zero, this code will simulate
   683                  * rounding towards negative infinity.
   683 		 * rounding towards negative infinity.
   684                  */
   684 		 */
   685                 rem = divisor - rem;
   685 		rem = divisor - rem;
   686             }
   686 	    }
   687         }
   687 	}
   688         RETURN ( __mkSmallInteger(rem) );
   688 	RETURN ( __mkSmallInteger(rem) );
   689     }
   689     }
   690 %}.
   690 %}.
   691     (aNumber = 0) ifTrue:[
   691     (aNumber = 0) ifTrue:[
   692         ^ ZeroDivide raiseRequestWith:thisContext.
   692 	^ ZeroDivide raiseRequestWith:thisContext.
   693     ].
   693     ].
   694     ^ aNumber moduloFromInteger:self
   694     ^ aNumber moduloFromInteger:self
   695 
   695 
   696     "
   696     "
   697      9 \\ 4  == 1 ifFalse:[self halt].
   697      9 \\ 4  == 1 ifFalse:[self halt].
   816 !
   816 !
   817 
   817 
   818 bitAt:anIntegerIndex
   818 bitAt:anIntegerIndex
   819     "return the value of the index's bit (index starts at 1) as 0 or 1.
   819     "return the value of the index's bit (index starts at 1) as 0 or 1.
   820      Notice: the result of bitAt: on negative receivers is not
   820      Notice: the result of bitAt: on negative receivers is not
   821              defined in the language standard (since the implementation
   821 	     defined in the language standard (since the implementation
   822              is free to choose any internal representation for integers)"
   822 	     is free to choose any internal representation for integers)"
   823 
   823 
   824 %{  /* NOCONTEXT */
   824 %{  /* NOCONTEXT */
   825 
   825 
   826     if (__isSmallInteger(anIntegerIndex)) {
   826     if (__isSmallInteger(anIntegerIndex)) {
   827         INT idx = __smallIntegerVal(anIntegerIndex);
   827 	INT idx = __smallIntegerVal(anIntegerIndex);
   828         if (idx > 0) {
   828 	if (idx > 0) {
   829             if (idx > N_INT_BITS) {
   829 	    if (idx > N_INT_BITS) {
   830                 RETURN(__mkSmallInteger(0));
   830 		RETURN(__mkSmallInteger(0));
   831             }
   831 	    }
   832             RETURN((__smallIntegerVal(self) & (1 << (idx-1))) ? __mkSmallInteger(1) : __mkSmallInteger(0));
   832 	    RETURN((__smallIntegerVal(self) & (1 << (idx-1))) ? __mkSmallInteger(1) : __mkSmallInteger(0));
   833         }
   833 	}
   834     }
   834     }
   835 %}.
   835 %}.
   836 
   836 
   837     ^ SubscriptOutOfBoundsSignal
   837     ^ SubscriptOutOfBoundsSignal
   838             raiseRequestWith:anIntegerIndex
   838 	    raiseRequestWith:anIntegerIndex
   839             errorString:'index out of bounds'
   839 	    errorString:'index out of bounds'
   840 
   840 
   841     "
   841     "
   842      16r00000001 bitAt:0
   842      16r00000001 bitAt:0
   843      16r00000001 bitAt:1
   843      16r00000001 bitAt:1
   844      16r00000001 bitAt:2
   844      16r00000001 bitAt:2
   854 
   854 
   855 " Smalltalk implementation:
   855 " Smalltalk implementation:
   856     |mask|
   856     |mask|
   857 
   857 
   858     anIntegerIndex <= 0 ifTrue:[
   858     anIntegerIndex <= 0 ifTrue:[
   859         ^ SubscriptOutOfBoundsSignal
   859 	^ SubscriptOutOfBoundsSignal
   860                 raiseRequestWith:anIntegerIndex
   860 		raiseRequestWith:anIntegerIndex
   861                 errorString:'index out of bounds'
   861 		errorString:'index out of bounds'
   862     ].
   862     ].
   863     (anIntegerIndex > SmallInteger maxBits) ifTrue:[^ 0].
   863     (anIntegerIndex > SmallInteger maxBits) ifTrue:[^ 0].
   864     mask := 1 bitShift:(anIntegerIndex - 1).
   864     mask := 1 bitShift:(anIntegerIndex - 1).
   865     ((self bitAnd:mask) == 0) ifTrue:[^ 0].
   865     ((self bitAnd:mask) == 0) ifTrue:[^ 0].
   866     ^ 1
   866     ^ 1
   898 #ifdef ALGORITHM_1
   898 #ifdef ALGORITHM_1
   899     // old k&r code; might be better if only one or two bits are set
   899     // old k&r code; might be better if only one or two bits are set
   900 
   900 
   901     _cnt = 0;
   901     _cnt = 0;
   902     while (_self) {
   902     while (_self) {
   903         _cnt++;
   903 	_cnt++;
   904         _self = _self & (_self - 1);
   904 	_self = _self & (_self - 1);
   905     }
   905     }
   906 #else
   906 #else
   907 # ifdef ALGORITHM_2
   907 # ifdef ALGORITHM_2
   908     // seems to be faster on the average (and has better worst case)
   908     // seems to be faster on the average (and has better worst case)
   909 
   909 
   910     static unsigned char table[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
   910     static unsigned char table[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
   911 
   911 
   912     _cnt = 0;
   912     _cnt = 0;
   913     while (_self) {
   913     while (_self) {
   914         _cnt += table[ _self & 0x0F ];
   914 	_cnt += table[ _self & 0x0F ];
   915         _self >>= 4;
   915 	_self >>= 4;
   916     }
   916     }
   917 # else
   917 # else
   918 #  ifdef ALGORIHTM_3
   918 #  ifdef ALGORIHTM_3
   919     // the fastest, but hard (impossible) to understand (google for fastest bit count)
   919     // the fastest, but hard (impossible) to understand (google for fastest bit count)
   920 #   if __POINTER_SIZE__ == 8
   920 #   if __POINTER_SIZE__ == 8
   946     RETURN ( __MKSMALLINT(_cnt));
   946     RETURN ( __MKSMALLINT(_cnt));
   947 %}
   947 %}
   948 
   948 
   949     "
   949     "
   950      1 to:1000000 do:[:n |
   950      1 to:1000000 do:[:n |
   951         self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
   951 	self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
   952      ].
   952      ].
   953 
   953 
   954      #( 
   954      #(
   955         16r00010000 16r00100000 16r01000000 16r10000000
   955 	16r00010000 16r00100000 16r01000000 16r10000000
   956         16r00020000 16r00200000 16r02000000 16r20000000
   956 	16r00020000 16r00200000 16r02000000 16r20000000
   957         16r00040000 16r00400000 16r04000000 16r40000000
   957 	16r00040000 16r00400000 16r04000000 16r40000000
   958         16r00080000 16r00800000 16r08000000 16r80000000
   958 	16r00080000 16r00800000 16r08000000 16r80000000
   959 
   959 
   960         16rFFFFFFFF 16r7FFFFFFF 16r3FFFFFFF 16r1FFFFFFF
   960 	16rFFFFFFFF 16r7FFFFFFF 16r3FFFFFFF 16r1FFFFFFF
   961         16rEEEEEEEE 16r7EEEEEEE 16r3EEEEEEE 16r1EEEEEEE
   961 	16rEEEEEEEE 16r7EEEEEEE 16r3EEEEEEE 16r1EEEEEEE
   962         16rDDDDDDDD 16r7DDDDDDD 16r3DDDDDDD 16r1DDDDDDD
   962 	16rDDDDDDDD 16r7DDDDDDD 16r3DDDDDDD 16r1DDDDDDD
   963         16rCCCCCCCC 16r7CCCCCCC 16r3CCCCCCC 16r1CCCCCCC
   963 	16rCCCCCCCC 16r7CCCCCCC 16r3CCCCCCC 16r1CCCCCCC
   964      ) do:[:n |
   964      ) do:[:n |
   965         self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
   965 	self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
   966      ]
   966      ]
   967 
   967 
   968      1 to:10000000 do:[:n |
   968      1 to:10000000 do:[:n |
   969         (n bitCount)
   969 	(n bitCount)
   970      ]
   970      ]
   971     "
   971     "
   972 
   972 
   973     "Modified: / 09-01-2012 / 19:12:41 / cg"
   973     "Modified: / 09-01-2012 / 19:12:41 / cg"
   974 !
   974 !
  1089 
  1089 
  1090 %{  /* NOCONTEXT */
  1090 %{  /* NOCONTEXT */
  1091 
  1091 
  1092     /* and all bits except tag */
  1092     /* and all bits except tag */
  1093     if (__isSmallInteger(aMask)) {
  1093     if (__isSmallInteger(aMask)) {
  1094         RETURN ( ((INT)self & ((INT)aMask & ~TAG_MASK)) ? true : false );
  1094 	RETURN ( ((INT)self & ((INT)aMask & ~TAG_MASK)) ? true : false );
  1095     }
  1095     }
  1096 %}.
  1096 %}.
  1097     aMask class == LargeInteger ifTrue:[
  1097     aMask class == LargeInteger ifTrue:[
  1098         ^ (aMask bitAnd:self) ~~ 0
  1098 	^ (aMask bitAnd:self) ~~ 0
  1099     ].
  1099     ].
  1100     ^ self retry:#bitTest: coercing:aMask
  1100     ^ self retry:#bitTest: coercing:aMask
  1101 
  1101 
  1102     "
  1102     "
  1103      2r10001 bitTest:2r00001  
  1103      2r10001 bitTest:2r00001
  1104      2r10001 bitTest:2r00010  
  1104      2r10001 bitTest:2r00010
  1105      2r10001 bitTest:2r00100  
  1105      2r10001 bitTest:2r00100
  1106      2r10001 bitTest:2r01000  
  1106      2r10001 bitTest:2r01000
  1107      2r10001 bitTest:2r10000  
  1107      2r10001 bitTest:2r10000
  1108      2r10001 bitTest:2r10001  
  1108      2r10001 bitTest:2r10001
  1109      2r10001 bitTest:2r10010  
  1109      2r10001 bitTest:2r10010
  1110     "
  1110     "
  1111 !
  1111 !
  1112 
  1112 
  1113 bitXor:anInteger
  1113 bitXor:anInteger
  1114     "return the bitwise-exclusive-or of the receiver and the argument, anInteger"
  1114     "return the bitwise-exclusive-or of the receiver and the argument, anInteger"
  1179     unsigned INT bits;
  1179     unsigned INT bits;
  1180     int index;
  1180     int index;
  1181 
  1181 
  1182     bits = __intVal(self);
  1182     bits = __intVal(self);
  1183     if (bits == 0) {
  1183     if (bits == 0) {
  1184         RETURN ( __mkSmallInteger(0) );
  1184 	RETURN ( __mkSmallInteger(0) );
  1185     }
  1185     }
  1186 
  1186 
  1187 #ifdef __BSR              
  1187 #ifdef __BSR
  1188     /*
  1188     /*
  1189      * so much for CISC CPUS:
  1189      * so much for CISC CPUS:
  1190      * the following code is not faster on a PIII-400
  1190      * the following code is not faster on a PIII-400
  1191      * (but saves a few code-bytes, though)
  1191      * (but saves a few code-bytes, though)
  1192      */
  1192      */
  1195 
  1195 
  1196     index = 0;
  1196     index = 0;
  1197 
  1197 
  1198 # if __POINTER_SIZE__ == 8
  1198 # if __POINTER_SIZE__ == 8
  1199     if (bits & 0xFFFFFFFF00000000L) {
  1199     if (bits & 0xFFFFFFFF00000000L) {
  1200         index += 32; bits = bits >> 32;
  1200 	index += 32; bits = bits >> 32;
  1201     }
  1201     }
  1202 # endif
  1202 # endif
  1203     if (bits & 0xFFFF0000L) {
  1203     if (bits & 0xFFFF0000L) {
  1204         index += 16; bits = bits >> 16;
  1204 	index += 16; bits = bits >> 16;
  1205     }
  1205     }
  1206     if (bits & 0xFF00) {
  1206     if (bits & 0xFF00) {
  1207         index += 8; bits = bits >> 8;
  1207 	index += 8; bits = bits >> 8;
  1208     }
  1208     }
  1209     if (bits & 0xF0) {
  1209     if (bits & 0xF0) {
  1210         index += 4; bits = bits >> 4;
  1210 	index += 4; bits = bits >> 4;
  1211     }
  1211     }
  1212     if (bits & 0xC) {
  1212     if (bits & 0xC) {
  1213         index += 2; bits = bits >> 2;
  1213 	index += 2; bits = bits >> 2;
  1214     }
  1214     }
  1215     if (bits & 0x2) {
  1215     if (bits & 0x2) {
  1216         index += 1; bits = bits >> 1;
  1216 	index += 1; bits = bits >> 1;
  1217     }
  1217     }
  1218 #endif /* no BSR instruction */
  1218 #endif /* no BSR instruction */
  1219 
  1219 
  1220     RETURN ( __mkSmallInteger(index+1) );
  1220     RETURN ( __mkSmallInteger(index+1) );
  1221 %}
  1221 %}
  1226      2r100 highBit
  1226      2r100 highBit
  1227      2r1000 highBit
  1227      2r1000 highBit
  1228      2r100000000000 highBit
  1228      2r100000000000 highBit
  1229 
  1229 
  1230      ((0 to:64) collect:[:s | 1 bitShift:s])
  1230      ((0 to:64) collect:[:s | 1 bitShift:s])
  1231         collect:[:n | n highBit]
  1231 	collect:[:n | n highBit]
  1232 
  1232 
  1233      (((0 to:64) collect:[:s | 1 bitShift:s])
  1233      (((0 to:64) collect:[:s | 1 bitShift:s])
  1234         collect:[:n | n highBit]) = (1 to:65)
  1234 	collect:[:n | n highBit]) = (1 to:65)
  1235     "
  1235     "
  1236 
  1236 
  1237     "
  1237     "
  1238      Time millisecondsToRun:[
  1238      Time millisecondsToRun:[
  1239         1000000 timesRepeat:[
  1239 	1000000 timesRepeat:[
  1240             2r1 highBit
  1240 	    2r1 highBit
  1241         ]
  1241 	]
  1242      ]
  1242      ]
  1243     "
  1243     "
  1244     "
  1244     "
  1245      Time millisecondsToRun:[
  1245      Time millisecondsToRun:[
  1246         1000000 timesRepeat:[
  1246 	1000000 timesRepeat:[
  1247             2r1111 highBit
  1247 	    2r1111 highBit
  1248         ]
  1248 	]
  1249      ]
  1249      ]
  1250     "
  1250     "
  1251     "
  1251     "
  1252      Time millisecondsToRun:[
  1252      Time millisecondsToRun:[
  1253         1000000 timesRepeat:[
  1253 	1000000 timesRepeat:[
  1254             2r11111111111111 highBit
  1254 	    2r11111111111111 highBit
  1255         ]
  1255 	]
  1256      ]
  1256      ]
  1257     "
  1257     "
  1258     "
  1258     "
  1259      Time millisecondsToRun:[
  1259      Time millisecondsToRun:[
  1260         1000000 timesRepeat:[
  1260 	1000000 timesRepeat:[
  1261             2r11111111111111111111111111 highBit
  1261 	    2r11111111111111111111111111 highBit
  1262         ]
  1262 	]
  1263      ]
  1263      ]
  1264     "
  1264     "
  1265 
  1265 
  1266     "
  1266     "
  1267      2r000100 highBit
  1267      2r000100 highBit
  1411 
  1411 
  1412 rightShift:shiftCount
  1412 rightShift:shiftCount
  1413     "return the value of the receiver shifted by shiftCount bits;
  1413     "return the value of the receiver shifted by shiftCount bits;
  1414      right shift if shiftCount > 0; left shift  otherwise.
  1414      right shift if shiftCount > 0; left shift  otherwise.
  1415      Notice: the result of bitShift: on negative receivers is not
  1415      Notice: the result of bitShift: on negative receivers is not
  1416              defined in the language standard (since the implementation
  1416 	     defined in the language standard (since the implementation
  1417              is free to choose any internal representation for integers).
  1417 	     is free to choose any internal representation for integers).
  1418              However, ST/X preserves the sign."
  1418 	     However, ST/X preserves the sign."
  1419 
  1419 
  1420 %{  /* NOCONTEXT */
  1420 %{  /* NOCONTEXT */
  1421 
  1421 
  1422     INT bits, count;
  1422     INT bits, count;
  1423 
  1423 
  1424     if (__isSmallInteger(shiftCount)) {
  1424     if (__isSmallInteger(shiftCount)) {
  1425         bits = __intVal(self);
  1425 	bits = __intVal(self);
  1426         if (bits == 0) {
  1426 	if (bits == 0) {
  1427             RETURN (self);
  1427 	    RETURN (self);
  1428         }
  1428 	}
  1429 
  1429 
  1430         count = __intVal(shiftCount);
  1430 	count = __intVal(shiftCount);
  1431 
  1431 
  1432         if (count < 0) {
  1432 	if (count < 0) {
  1433             /*
  1433 	    /*
  1434              * a left shift
  1434 	     * a left shift
  1435              */
  1435 	     */
  1436             count = -count;
  1436 	    count = -count;
  1437 #if defined(USE_LONGLONG_FOR_SHIFT)
  1437 #if defined(USE_LONGLONG_FOR_SHIFT)
  1438             if (count <= N_INT_BITS) {
  1438 	    if (count <= N_INT_BITS) {
  1439                 unsigned LONGLONG result;
  1439 		unsigned LONGLONG result;
  1440 
  1440 
  1441                 result = (unsigned LONGLONG)bits;
  1441 		result = (unsigned LONGLONG)bits;
  1442                 result <<= count;
  1442 		result <<= count;
  1443                 if (result <= _MAX_INT) {
  1443 		if (result <= _MAX_INT) {
  1444                     RETURN ( __mkSmallInteger(result) );
  1444 		    RETURN ( __mkSmallInteger(result) );
  1445                 }
  1445 		}
  1446                 {
  1446 		{
  1447                     RETURN (__MKLARGEINT64(1, (INT)(result >> 32), (INT)(result & 0xFFFFFFFF)));
  1447 		    RETURN (__MKLARGEINT64(1, (INT)(result >> 32), (INT)(result & 0xFFFFFFFF)));
  1448                 }
  1448 		}
  1449             }
  1449 	    }
  1450 #else
  1450 #else
  1451             /*
  1451 	    /*
  1452              * check for overflow
  1452 	     * check for overflow
  1453              */
  1453 	     */
  1454             if (count < (N_INT_BITS-1)) {
  1454 	    if (count < (N_INT_BITS-1)) {
  1455                 if (! (bits >> (N_INT_BITS - 1 - count))) {
  1455 		if (! (bits >> (N_INT_BITS - 1 - count))) {
  1456                     RETURN ( __mkSmallInteger(bits << count) );
  1456 		    RETURN ( __mkSmallInteger(bits << count) );
  1457                 }
  1457 		}
  1458                 /*
  1458 		/*
  1459                  * so, there is an overflow ...
  1459 		 * so, there is an overflow ...
  1460                  * handle it as largeInteger
  1460 		 * handle it as largeInteger
  1461                  */
  1461 		 */
  1462                 /* FALL THROUGH */
  1462 		/* FALL THROUGH */
  1463             }
  1463 	    }
  1464 #endif
  1464 #endif
  1465         } else {
  1465 	} else {
  1466             if (count == 0) {
  1466 	    if (count == 0) {
  1467                 RETURN (self);
  1467 		RETURN (self);
  1468             }
  1468 	    }
  1469 
  1469 
  1470             /*
  1470 	    /*
  1471              * right shifts cannot overflow
  1471 	     * right shifts cannot overflow
  1472              *
  1472 	     *
  1473              * some machines ignore shifts bigger than
  1473 	     * some machines ignore shifts bigger than
  1474              * the number of bits in an int ...
  1474 	     * the number of bits in an int ...
  1475              */
  1475 	     */
  1476             if (count > (N_INT_BITS-1)) {
  1476 	    if (count > (N_INT_BITS-1)) {
  1477                 RETURN (__mkSmallInteger(0));
  1477 		RETURN (__mkSmallInteger(0));
  1478             }
  1478 	    }
  1479 
  1479 
  1480             RETURN ( __mkSmallInteger(bits >> count) );
  1480 	    RETURN ( __mkSmallInteger(bits >> count) );
  1481         }
  1481 	}
  1482     }
  1482     }
  1483 %}.
  1483 %}.
  1484     (shiftCount isMemberOf:SmallInteger) ifTrue:[
  1484     (shiftCount isMemberOf:SmallInteger) ifTrue:[
  1485         ^ (LargeInteger value:self) rightShift:shiftCount
  1485 	^ (LargeInteger value:self) rightShift:shiftCount
  1486     ].
  1486     ].
  1487     ^ self rightShift:(1 coerce:shiftCount)   "/ is this a good idea ?
  1487     ^ self rightShift:(1 coerce:shiftCount)   "/ is this a good idea ?
  1488 
  1488 
  1489 
  1489 
  1490     "
  1490     "
  1491         16 rightShift:2
  1491 	16 rightShift:2
  1492          4 rightShift:-2
  1492 	 4 rightShift:-2
  1493     "
  1493     "
  1494 !
  1494 !
  1495 
  1495 
  1496 setBit:anInteger
  1496 setBit:anInteger
  1497     "return a new integer where the specified bit is on.
  1497     "return a new integer where the specified bit is on.
  1592 
  1592 
  1593     unsigned INT bits;
  1593     unsigned INT bits;
  1594     int count;
  1594     int count;
  1595 
  1595 
  1596     if (__isSmallInteger(shiftCount)) {
  1596     if (__isSmallInteger(shiftCount)) {
  1597         count = __intVal(shiftCount);
  1597 	count = __intVal(shiftCount);
  1598         count = count % 32;
  1598 	count = count % 32;
  1599 
  1599 
  1600         bits = __intVal(self);
  1600 	bits = __intVal(self);
  1601         if (count > 0) {
  1601 	if (count > 0) {
  1602             bits = (bits << count) | (bits >> (32-count));
  1602 	    bits = (bits << count) | (bits >> (32-count));
  1603         } else {
  1603 	} else {
  1604             bits = (bits >> (-count)) | (bits << (32-(-count)));
  1604 	    bits = (bits >> (-count)) | (bits << (32-(-count)));
  1605         }
  1605 	}
  1606 #if __POINTER_SIZE__ == 8
  1606 #if __POINTER_SIZE__ == 8
  1607         bits &= 0xFFFFFFFFL;
  1607 	bits &= 0xFFFFFFFFL;
  1608 #endif
  1608 #endif
  1609         RETURN (__MKUINT(bits));
  1609 	RETURN (__MKUINT(bits));
  1610     }
  1610     }
  1611 %}.
  1611 %}.
  1612     ^ self primitiveFailed
  1612     ^ self primitiveFailed
  1613 
  1613 
  1614     "
  1614     "
  1615      128 rotate32:1
  1615      128 rotate32:1
  1616 
  1616 
  1617      1 rotate32:1   
  1617      1 rotate32:1
  1618      1 rotate32:2   
  1618      1 rotate32:2
  1619      1 rotate32:31
  1619      1 rotate32:31
  1620      1 rotate32:32
  1620      1 rotate32:32
  1621 
  1621 
  1622      1 rotate32:-1   
  1622      1 rotate32:-1
  1623      1 rotate32:-2   
  1623      1 rotate32:-2
  1624      1 rotate32:-3   
  1624      1 rotate32:-3
  1625      1 rotate32:-32   
  1625      1 rotate32:-32
  1626     "
  1626     "
  1627 !
  1627 !
  1628 
  1628 
  1629 bitShift32:shiftCount
  1629 bitShift32:shiftCount
  1630     "return the value of the receiver shifted by shiftCount bits,
  1630     "return the value of the receiver shifted by shiftCount bits,
  1740      i.e. a.b.c.d -> d.c.b.a"
  1740      i.e. a.b.c.d -> d.c.b.a"
  1741 
  1741 
  1742 %{  /* NOCONTEXT */
  1742 %{  /* NOCONTEXT */
  1743 
  1743 
  1744 #if __POINTER_SIZE__ == 4
  1744 #if __POINTER_SIZE__ == 4
  1745     unsigned int v = __intVal(self);  
  1745     unsigned int v = __intVal(self);
  1746     unsigned int swapped;  
  1746     unsigned int swapped;
  1747 
  1747 
  1748 # ifdef __BORLANDC__
  1748 # ifdef __BORLANDC__
  1749 #  ifdef USE_BSWAP
  1749 #  ifdef USE_BSWAP
  1750     _asm {
  1750     _asm {
  1751         mov eax, v 
  1751 	mov eax, v
  1752         bswap eax
  1752 	bswap eax
  1753         mov swapped, eax 
  1753 	mov swapped, eax
  1754     };
  1754     };
  1755 #  else
  1755 #  else
  1756     _asm {
  1756     _asm {
  1757         mov eax, v 
  1757 	mov eax, v
  1758         xchg al, ah
  1758 	xchg al, ah
  1759         rol eax, 16
  1759 	rol eax, 16
  1760         xchg al, ah
  1760 	xchg al, ah
  1761         mov swapped, eax 
  1761 	mov swapped, eax
  1762     };
  1762     };
  1763 #  endif
  1763 #  endif
  1764 # else
  1764 # else
  1765     swapped = ((v>>24) | ((v>>8)&0xFF00) | ((v & 0xFF00)<<8) | ((v & 0xFF)<<24));
  1765     swapped = ((v>>24) | ((v>>8)&0xFF00) | ((v & 0xFF00)<<8) | ((v & 0xFF)<<24));
  1766 # endif
  1766 # endif
  1768 #endif /* __POINTER_SIZE__ */
  1768 #endif /* __POINTER_SIZE__ */
  1769 %}.
  1769 %}.
  1770     ^ super byteSwapped
  1770     ^ super byteSwapped
  1771 
  1771 
  1772     "
  1772     "
  1773      16r11223344 byteSwapped hexPrintString  
  1773      16r11223344 byteSwapped hexPrintString
  1774      16r44332211 byteSwapped hexPrintString 
  1774      16r44332211 byteSwapped hexPrintString
  1775     "
  1775     "
  1776 
  1776 
  1777     "Created: / 09-01-2012 / 23:01:33 / cg"
  1777     "Created: / 09-01-2012 / 23:01:33 / cg"
  1778 !
  1778 !
  1779 
  1779 
  1925      could have simply created a 4-byte largeinteger and normalize it.
  1925      could have simply created a 4-byte largeinteger and normalize it.
  1926      The code below does the normalize right away, avoiding the
  1926      The code below does the normalize right away, avoiding the
  1927      overhead of producing any intermediate byte-arrays (and the scanning)
  1927      overhead of producing any intermediate byte-arrays (and the scanning)
  1928     "
  1928     "
  1929     self == 0 ifTrue: [
  1929     self == 0 ifTrue: [
  1930         ^ ByteArray with:0.
  1930 	^ ByteArray with:0.
  1931     ].
  1931     ].
  1932 
  1932 
  1933     self < 0 ifTrue: [
  1933     self < 0 ifTrue: [
  1934         absValue := self negated
  1934 	absValue := self negated
  1935     ] ifFalse: [
  1935     ] ifFalse: [
  1936         absValue := self.
  1936 	absValue := self.
  1937     ].
  1937     ].
  1938 
  1938 
  1939     b1 := absValue bitAnd:16rFF.
  1939     b1 := absValue bitAnd:16rFF.
  1940     absValue := absValue bitShift:-8.
  1940     absValue := absValue bitShift:-8.
  1941     absValue == 0 ifTrue:[
  1941     absValue == 0 ifTrue:[
  1942         digitByteArray := ByteArray with:b1
  1942 	digitByteArray := ByteArray with:b1
  1943     ] ifFalse:[
  1943     ] ifFalse:[
  1944         b2 := absValue bitAnd:16rFF.
  1944 	b2 := absValue bitAnd:16rFF.
  1945         absValue := absValue bitShift:-8.
  1945 	absValue := absValue bitShift:-8.
  1946         absValue == 0 ifTrue:[
  1946 	absValue == 0 ifTrue:[
  1947             digitByteArray := ByteArray with:b1 with:b2
  1947 	    digitByteArray := ByteArray with:b1 with:b2
  1948         ] ifFalse:[
  1948 	] ifFalse:[
  1949             b3 := absValue bitAnd:16rFF.
  1949 	    b3 := absValue bitAnd:16rFF.
  1950             absValue := absValue bitShift:-8.
  1950 	    absValue := absValue bitShift:-8.
  1951             absValue == 0 ifTrue:[
  1951 	    absValue == 0 ifTrue:[
  1952                 digitByteArray := ByteArray with:b1 with:b2 with:b3
  1952 		digitByteArray := ByteArray with:b1 with:b2 with:b3
  1953             ] ifFalse:[
  1953 	    ] ifFalse:[
  1954                 b4 := absValue bitAnd:16rFF.
  1954 		b4 := absValue bitAnd:16rFF.
  1955                 absValue := absValue bitShift:-8.
  1955 		absValue := absValue bitShift:-8.
  1956                 absValue == 0 ifTrue:[
  1956 		absValue == 0 ifTrue:[
  1957                     digitByteArray := ByteArray with:b1 with:b2 with:b3 with:b4
  1957 		    digitByteArray := ByteArray with:b1 with:b2 with:b3 with:b4
  1958                 ] ifFalse:[
  1958 		] ifFalse:[
  1959                     b5 := absValue bitAnd:16rFF.
  1959 		    b5 := absValue bitAnd:16rFF.
  1960                     absValue := absValue bitShift:-8.
  1960 		    absValue := absValue bitShift:-8.
  1961                     absValue == 0 ifTrue:[
  1961 		    absValue == 0 ifTrue:[
  1962                         digitByteArray := ByteArray new:5.
  1962 			digitByteArray := ByteArray new:5.
  1963                         digitByteArray at:1 put:b1.
  1963 			digitByteArray at:1 put:b1.
  1964                         digitByteArray at:2 put:b2.
  1964 			digitByteArray at:2 put:b2.
  1965                         digitByteArray at:3 put:b3.
  1965 			digitByteArray at:3 put:b3.
  1966                         digitByteArray at:4 put:b4.
  1966 			digitByteArray at:4 put:b4.
  1967                         digitByteArray at:5 put:b5.
  1967 			digitByteArray at:5 put:b5.
  1968                     ] ifFalse:[
  1968 		    ] ifFalse:[
  1969                         b6 := absValue bitAnd:16rFF.
  1969 			b6 := absValue bitAnd:16rFF.
  1970                         absValue := absValue bitShift:-8.
  1970 			absValue := absValue bitShift:-8.
  1971                         absValue == 0 ifTrue:[
  1971 			absValue == 0 ifTrue:[
  1972                             digitByteArray := ByteArray new:6.
  1972 			    digitByteArray := ByteArray new:6.
  1973                             digitByteArray at:1 put:b1.
  1973 			    digitByteArray at:1 put:b1.
  1974                             digitByteArray at:2 put:b2.
  1974 			    digitByteArray at:2 put:b2.
  1975                             digitByteArray at:3 put:b3.
  1975 			    digitByteArray at:3 put:b3.
  1976                             digitByteArray at:4 put:b4.
  1976 			    digitByteArray at:4 put:b4.
  1977                             digitByteArray at:5 put:b5.
  1977 			    digitByteArray at:5 put:b5.
  1978                             digitByteArray at:6 put:b6.
  1978 			    digitByteArray at:6 put:b6.
  1979                         ] ifFalse:[
  1979 			] ifFalse:[
  1980                             b7 := absValue bitAnd:16rFF.
  1980 			    b7 := absValue bitAnd:16rFF.
  1981                             absValue := absValue bitShift:-8.
  1981 			    absValue := absValue bitShift:-8.
  1982                             absValue == 0 ifTrue:[
  1982 			    absValue == 0 ifTrue:[
  1983                                 digitByteArray := ByteArray new:7.
  1983 				digitByteArray := ByteArray new:7.
  1984                                 digitByteArray at:1 put:b1.
  1984 				digitByteArray at:1 put:b1.
  1985                                 digitByteArray at:2 put:b2.
  1985 				digitByteArray at:2 put:b2.
  1986                                 digitByteArray at:3 put:b3.
  1986 				digitByteArray at:3 put:b3.
  1987                                 digitByteArray at:4 put:b4.
  1987 				digitByteArray at:4 put:b4.
  1988                                 digitByteArray at:5 put:b5.
  1988 				digitByteArray at:5 put:b5.
  1989                                 digitByteArray at:6 put:b6.
  1989 				digitByteArray at:6 put:b6.
  1990                                 digitByteArray at:7 put:b7.
  1990 				digitByteArray at:7 put:b7.
  1991                             ] ifFalse:[
  1991 			    ] ifFalse:[
  1992                                 digitByteArray := ByteArray new:8.
  1992 				digitByteArray := ByteArray new:8.
  1993                                 digitByteArray at:1 put:b1.
  1993 				digitByteArray at:1 put:b1.
  1994                                 digitByteArray at:2 put:b2.
  1994 				digitByteArray at:2 put:b2.
  1995                                 digitByteArray at:3 put:b3.
  1995 				digitByteArray at:3 put:b3.
  1996                                 digitByteArray at:4 put:b4.
  1996 				digitByteArray at:4 put:b4.
  1997                                 digitByteArray at:5 put:b5.
  1997 				digitByteArray at:5 put:b5.
  1998                                 digitByteArray at:6 put:b6.
  1998 				digitByteArray at:6 put:b6.
  1999                                 digitByteArray at:7 put:b7.
  1999 				digitByteArray at:7 put:b7.
  2000                                 digitByteArray at:8 put:absValue.
  2000 				digitByteArray at:8 put:absValue.
  2001                             ]
  2001 			    ]
  2002                         ]
  2002 			]
  2003                     ]
  2003 		    ]
  2004                 ]
  2004 		]
  2005             ]
  2005 	    ]
  2006         ]
  2006 	]
  2007     ].
  2007     ].
  2008 
  2008 
  2009     ^ digitByteArray
  2009     ^ digitByteArray
  2010 
  2010 
  2011     "
  2011     "
  2020      (8 bits of the absolute value per element),
  2020      (8 bits of the absolute value per element),
  2021      if msbflag = true, most significant byte is first,
  2021      if msbflag = true, most significant byte is first,
  2022      otherwise least significant byte is first"
  2022      otherwise least significant byte is first"
  2023 
  2023 
  2024     msbFlag ifTrue:[
  2024     msbFlag ifTrue:[
  2025         ^ self digitBytes reversed.  "digitBytes has been just created - reverse inplace"
  2025 	^ self digitBytes reversed.  "digitBytes has been just created - reverse inplace"
  2026     ].
  2026     ].
  2027     ^ self digitBytes
  2027     ^ self digitBytes
  2028 
  2028 
  2029     "
  2029     "
  2030       16r12 digitBytesMSB:true
  2030       16r12 digitBytesMSB:true
  2102      i.e. a.b.c.d -> b.a.d.c"
  2102      i.e. a.b.c.d -> b.a.d.c"
  2103 
  2103 
  2104 %{  /* NOCONTEXT */
  2104 %{  /* NOCONTEXT */
  2105 
  2105 
  2106 #if __POINTER_SIZE__ == 4
  2106 #if __POINTER_SIZE__ == 4
  2107     unsigned int v = __intVal(self);  
  2107     unsigned int v = __intVal(self);
  2108     unsigned int swapped;  
  2108     unsigned int swapped;
  2109 
  2109 
  2110     swapped = ((v&0xFF000000)>>8) | ((v&0xFF0000) << 8) | ((v & 0xFF00)>>8) | ((v & 0xFF)<<8);
  2110     swapped = ((v&0xFF000000)>>8) | ((v&0xFF0000) << 8) | ((v & 0xFF00)>>8) | ((v & 0xFF)<<8);
  2111     RETURN (__MKUINT(swapped));
  2111     RETURN (__MKUINT(swapped));
  2112 #endif /* __POINTER_SIZE__ */
  2112 #endif /* __POINTER_SIZE__ */
  2113 %}.
  2113 %}.
  2114     ^ super swapBytes
  2114     ^ super swapBytes
  2115 
  2115 
  2116     "
  2116     "
  2117      16r11223344 swapBytes hexPrintString  
  2117      16r11223344 swapBytes hexPrintString
  2118      16r44332211 swapBytes hexPrintString 
  2118      16r44332211 swapBytes hexPrintString
  2119     "
  2119     "
  2120 
  2120 
  2121     "Created: / 09-01-2012 / 23:01:33 / cg"
  2121     "Created: / 09-01-2012 / 23:01:33 / cg"
  2122 ! !
  2122 ! !
  2123 
  2123 
  2220 
  2220 
  2221 %{  /* NOCONTEXT */
  2221 %{  /* NOCONTEXT */
  2222     INT i = __intVal(self);
  2222     INT i = __intVal(self);
  2223 
  2223 
  2224     if (i & 0x800000) {
  2224     if (i & 0x800000) {
  2225         i = i | ~0xFFFFFFL;
  2225 	i = i | ~0xFFFFFFL;
  2226     } else {
  2226     } else {
  2227         i = i & 0x7FFFFF;
  2227 	i = i & 0x7FFFFF;
  2228     }
  2228     }
  2229 
  2229 
  2230     RETURN (__mkSmallInteger(i));
  2230     RETURN (__mkSmallInteger(i));
  2231 %}.
  2231 %}.
  2232     ^ self primitiveFailed
  2232     ^ self primitiveFailed
  2244 
  2244 
  2245 %{  /* NOCONTEXT */
  2245 %{  /* NOCONTEXT */
  2246     INT i = __intVal(self);
  2246     INT i = __intVal(self);
  2247 
  2247 
  2248     if (i & 0x80) {
  2248     if (i & 0x80) {
  2249         i = i | ~0xFFL;
  2249 	i = i | ~0xFFL;
  2250     } else {
  2250     } else {
  2251         i = i & 0x7F;
  2251 	i = i & 0x7F;
  2252     }
  2252     }
  2253 
  2253 
  2254     RETURN (__mkSmallInteger(i));
  2254     RETURN (__mkSmallInteger(i));
  2255 %}.
  2255 %}.
  2256     ^ self primitiveFailed
  2256     ^ self primitiveFailed
  2257 
  2257 
  2258     "
  2258     "
  2259      16rFF signExtendedByteValue 
  2259      16rFF signExtendedByteValue
  2260      16r80 signExtendedByteValue 
  2260      16r80 signExtendedByteValue
  2261      16r7F signExtendedByteValue 
  2261      16r7F signExtendedByteValue
  2262     "
  2262     "
  2263 !
  2263 !
  2264 
  2264 
  2265 signExtendedShortValue
  2265 signExtendedShortValue
  2266     "return a smallInteger from sign-extending the 16'th bit.
  2266     "return a smallInteger from sign-extending the 16'th bit.
  2268 
  2268 
  2269 %{  /* NOCONTEXT */
  2269 %{  /* NOCONTEXT */
  2270     INT i = __intVal(self);
  2270     INT i = __intVal(self);
  2271 
  2271 
  2272     if (i & 0x8000) {
  2272     if (i & 0x8000) {
  2273         i = i | ~0xFFFFL;
  2273 	i = i | ~0xFFFFL;
  2274     } else {
  2274     } else {
  2275         i = i & 0x7FFF;
  2275 	i = i & 0x7FFF;
  2276     }
  2276     }
  2277 
  2277 
  2278     RETURN (__mkSmallInteger(i));
  2278     RETURN (__mkSmallInteger(i));
  2279 %}.
  2279 %}.
  2280     ^ self primitiveFailed
  2280     ^ self primitiveFailed
  2281 
  2281 
  2282     "
  2282     "
  2283      16rFFFF signExtendedShortValue 
  2283      16rFFFF signExtendedShortValue
  2284      16r8000 signExtendedShortValue 
  2284      16r8000 signExtendedShortValue
  2285      16r7FFF signExtendedShortValue 
  2285      16r7FFF signExtendedShortValue
  2286     "
  2286     "
  2287 ! !
  2287 ! !
  2288 
  2288 
  2289 !SmallInteger methodsFor:'comparing'!
  2289 !SmallInteger methodsFor:'comparing'!
  2290 
  2290 
  3356      to print a number/and for conversion to a LargeInteger.
  3356      to print a number/and for conversion to a LargeInteger.
  3357      Implemented that way, to allow for tiny systems (PDAs) without a Float class
  3357      Implemented that way, to allow for tiny systems (PDAs) without a Float class
  3358      (i.e. without log)."
  3358      (i.e. without log)."
  3359 
  3359 
  3360     self <= 0 ifTrue:[
  3360     self <= 0 ifTrue:[
  3361         ^ self class
  3361 	^ self class
  3362             raise:#domainErrorSignal
  3362 	    raise:#domainErrorSignal
  3363             receiver:self
  3363 	    receiver:self
  3364             selector:#intlog10
  3364 	    selector:#intlog10
  3365             arguments:#()
  3365 	    arguments:#()
  3366             errorString:'logarithm of negative integer'
  3366 	    errorString:'logarithm of negative integer'
  3367     ].
  3367     ].
  3368     self < 10000 ifTrue:[
  3368     self < 10000 ifTrue:[
  3369         self < 10 ifTrue:[^ 0].
  3369 	self < 10 ifTrue:[^ 0].
  3370         self < 100 ifTrue:[^ 1].
  3370 	self < 100 ifTrue:[^ 1].
  3371         self < 1000 ifTrue:[^ 2].
  3371 	self < 1000 ifTrue:[^ 2].
  3372         ^ 3
  3372 	^ 3
  3373     ].
  3373     ].
  3374     self < 100000000 ifTrue:[
  3374     self < 100000000 ifTrue:[
  3375         self < 100000 ifTrue:[^ 4].
  3375 	self < 100000 ifTrue:[^ 4].
  3376         self < 1000000 ifTrue:[^ 5].
  3376 	self < 1000000 ifTrue:[^ 5].
  3377         self < 10000000 ifTrue:[^ 6].
  3377 	self < 10000000 ifTrue:[^ 6].
  3378         ^ 7
  3378 	^ 7
  3379     ].
  3379     ].
  3380     self < 1000000000 ifTrue:[^ 8].
  3380     self < 1000000000 ifTrue:[^ 8].
  3381     ^ 9
  3381     ^ 9
  3382 
  3382 
  3383     "
  3383     "
  3384       99 intlog10
  3384       99 intlog10
  3385       100 intlog10 
  3385       100 intlog10
  3386       101 intlog10        
  3386       101 intlog10
  3387       (101 log:10) floor  
  3387       (101 log:10) floor
  3388       120 intlog10
  3388       120 intlog10
  3389       -1 intlog10
  3389       -1 intlog10
  3390     "
  3390     "
  3391 ! !
  3391 ! !
  3392 
  3392 
  3409 %}.
  3409 %}.
  3410     self primitiveFailed
  3410     self primitiveFailed
  3411 
  3411 
  3412     "
  3412     "
  3413      16r7FFFFFFF + 1          2147483648
  3413      16r7FFFFFFF + 1          2147483648
  3414      16r7FFFFFFF plus32: 1    
  3414      16r7FFFFFFF plus32: 1
  3415     "
  3415     "
  3416 !
  3416 !
  3417 
  3417 
  3418 plus:aNumber
  3418 plus:aNumber
  3419     "return the sum of the receiver and the argument, as SmallInteger.
  3419     "return the sum of the receiver and the argument, as SmallInteger.
  3512 #if defined(__i386__) && defined(__GNUC__) && (__GNUC__ >= 2)
  3512 #if defined(__i386__) && defined(__GNUC__) && (__GNUC__ >= 2)
  3513 # define USE_LONGLONG_FOR_MUL
  3513 # define USE_LONGLONG_FOR_MUL
  3514 #endif
  3514 #endif
  3515 
  3515 
  3516     if (__isSmallInteger(aNumber)) {
  3516     if (__isSmallInteger(aNumber)) {
  3517         myValue = __intVal(self);
  3517 	myValue = __intVal(self);
  3518         otherValue = __intVal(aNumber);
  3518 	otherValue = __intVal(aNumber);
  3519 
  3519 
  3520 #if defined(USE_LONGLONG_FOR_MUL)
  3520 #if defined(USE_LONGLONG_FOR_MUL)
  3521         {
  3521 	{
  3522 # if defined(__alpha__) && !defined(__alpha64__)
  3522 # if defined(__alpha__) && !defined(__alpha64__)
  3523 #  define LONGLONG      INT64
  3523 #  define LONGLONG      INT64
  3524 # else
  3524 # else
  3525 #  define LONGLONG      long long
  3525 #  define LONGLONG      long long
  3526 # endif
  3526 # endif
  3527             LONGLONG product;
  3527 	    LONGLONG product;
  3528 
  3528 
  3529             product = (LONGLONG)myValue * (LONGLONG)otherValue;
  3529 	    product = (LONGLONG)myValue * (LONGLONG)otherValue;
  3530             if (product < 0) {
  3530 	    if (product < 0) {
  3531                 RETURN ( __mkSmallInteger(-(INT)(-product & _MAX_INT)));
  3531 		RETURN ( __mkSmallInteger(-(INT)(-product & _MAX_INT)));
  3532             }
  3532 	    }
  3533             RETURN ( __mkSmallInteger((INT)(product & _MAX_INT)));
  3533 	    RETURN ( __mkSmallInteger((INT)(product & _MAX_INT)));
  3534         }
  3534 	}
  3535 #else /* no long-long */
  3535 #else /* no long-long */
  3536         negative = 1;
  3536 	negative = 1;
  3537         if (myValue < 0) {
  3537 	if (myValue < 0) {
  3538             negative = -1;
  3538 	    negative = -1;
  3539             myValue = -myValue;
  3539 	    myValue = -myValue;
  3540         }
  3540 	}
  3541         if (otherValue < 0) {
  3541 	if (otherValue < 0) {
  3542             negative = -negative;
  3542 	    negative = -negative;
  3543             otherValue = -otherValue;
  3543 	    otherValue = -otherValue;
  3544         }
  3544 	}
  3545 
  3545 
  3546 # if defined(__GNUC__) && defined(__mc68k__)
  3546 # if defined(__GNUC__) && defined(__mc68k__)
  3547         asm ("mulu%.l %3,%1:%0"
  3547 	asm ("mulu%.l %3,%1:%0"
  3548                 : "=d"  ((unsigned long)(productLow)),
  3548 		: "=d"  ((unsigned long)(productLow)),
  3549                   "=d"  ((unsigned long)(productHi))
  3549 		  "=d"  ((unsigned long)(productHi))
  3550                 : "%0"  ((unsigned long)(myValue)),
  3550 		: "%0"  ((unsigned long)(myValue)),
  3551                   "dmi" ((unsigned long)(otherValue)));
  3551 		  "dmi" ((unsigned long)(otherValue)));
  3552 # else
  3552 # else
  3553 #  if defined (__GNUC__) && defined(__i386__)
  3553 #  if defined (__GNUC__) && defined(__i386__)
  3554         asm ("mull %3"
  3554 	asm ("mull %3"
  3555                 : "=a"  ((unsigned long)(productLow)),
  3555 		: "=a"  ((unsigned long)(productLow)),
  3556                   "=d"  ((unsigned long)(productHi))
  3556 		  "=d"  ((unsigned long)(productHi))
  3557                 : "%0"  ((unsigned long)(myValue)),
  3557 		: "%0"  ((unsigned long)(myValue)),
  3558                   "rm"  ((unsigned long)(otherValue)));
  3558 		  "rm"  ((unsigned long)(otherValue)));
  3559 #  else
  3559 #  else
  3560 #   if defined(WIN32) && defined(__BORLANDC__)
  3560 #   if defined(WIN32) && defined(__BORLANDC__)
  3561         asm {
  3561 	asm {
  3562             mov   eax, myValue
  3562 	    mov   eax, myValue
  3563             mov   edx, otherValue
  3563 	    mov   edx, otherValue
  3564             mul   edx
  3564 	    mul   edx
  3565             mov   productLow, eax
  3565 	    mov   productLow, eax
  3566             mov   productHi, edx
  3566 	    mov   productHi, edx
  3567         }
  3567 	}
  3568 #   else /* generic */
  3568 #   else /* generic */
  3569         {
  3569 	{
  3570             unsigned INT pHH, pHL, pLH, pLL;
  3570 	    unsigned INT pHH, pHL, pLH, pLL;
  3571             unsigned INT low1, low2, hi1, hi2;
  3571 	    unsigned INT low1, low2, hi1, hi2;
  3572             unsigned INT t;
  3572 	    unsigned INT t;
  3573 
  3573 
  3574             /* unsigned multiply myValue * otherValue -> productHi, productLow
  3574 	    /* unsigned multiply myValue * otherValue -> productHi, productLow
  3575              *
  3575 	     *
  3576              * this is too slow:
  3576 	     * this is too slow:
  3577              * since most machines can do 32*32 to 64 bit multiply,
  3577 	     * since most machines can do 32*32 to 64 bit multiply,
  3578              * (or at least 32*32 with Overflow check)
  3578 	     * (or at least 32*32 with Overflow check)
  3579              * - need more assembler (inline) functions here
  3579 	     * - need more assembler (inline) functions here
  3580              */
  3580 	     */
  3581 #    if __POINTER_SIZE__ == 8
  3581 #    if __POINTER_SIZE__ == 8
  3582             low1 = low32Bits((unsigned INT)myValue);
  3582 	    low1 = low32Bits((unsigned INT)myValue);
  3583             hi1 = hi32Bits((unsigned INT)myValue);
  3583 	    hi1 = hi32Bits((unsigned INT)myValue);
  3584             low2 = low32Bits((unsigned INT)otherValue);
  3584 	    low2 = low32Bits((unsigned INT)otherValue);
  3585             hi2 = hi32Bits((unsigned INT)otherValue);
  3585 	    hi2 = hi32Bits((unsigned INT)otherValue);
  3586 #     define LLMASK 0xC000000000000000L
  3586 #     define LLMASK 0xC000000000000000L
  3587 #    else
  3587 #    else
  3588             low1 = low16Bits((unsigned INT)myValue);
  3588 	    low1 = low16Bits((unsigned INT)myValue);
  3589             hi1 = hi16Bits((unsigned INT)myValue);
  3589 	    hi1 = hi16Bits((unsigned INT)myValue);
  3590             low2 = low16Bits((unsigned INT)otherValue);
  3590 	    low2 = low16Bits((unsigned INT)otherValue);
  3591             hi2 = hi16Bits((unsigned INT)otherValue);
  3591 	    hi2 = hi16Bits((unsigned INT)otherValue);
  3592 #     define LLMASK 0xC0000000
  3592 #     define LLMASK 0xC0000000
  3593 #    endif
  3593 #    endif
  3594 
  3594 
  3595             pLH = low1 * hi2;
  3595 	    pLH = low1 * hi2;
  3596             pHL = hi1 * low2;
  3596 	    pHL = hi1 * low2;
  3597             pLL = low1 * low2;
  3597 	    pLL = low1 * low2;
  3598             pHH = hi1 * hi2;
  3598 	    pHH = hi1 * hi2;
  3599 
  3599 
  3600             /*
  3600 	    /*
  3601              * the common case ...
  3601 	     * the common case ...
  3602              */
  3602 	     */
  3603             if ((pHL == 0)
  3603 	    if ((pHL == 0)
  3604              && (pLH == 0)
  3604 	     && (pLH == 0)
  3605              && (pHH == 0)
  3605 	     && (pHH == 0)
  3606              && ((pLL & LLMASK) == 0)) {
  3606 	     && ((pLL & LLMASK) == 0)) {
  3607                 if (negative < 0) {
  3607 		if (negative < 0) {
  3608                     RETURN ( __mkSmallInteger(- ((INT)pLL)) );
  3608 		    RETURN ( __mkSmallInteger(- ((INT)pLL)) );
  3609                 }
  3609 		}
  3610                 RETURN ( __mkSmallInteger((INT)pLL) );
  3610 		RETURN ( __mkSmallInteger((INT)pLL) );
  3611             }
  3611 	    }
  3612 
  3612 
  3613             /*
  3613 	    /*
  3614              *   pHH |--------|--------|
  3614 	     *   pHH |--------|--------|
  3615              *   pLH          |--------|--------|
  3615 	     *   pLH          |--------|--------|
  3616              *   pHL          |--------|--------|
  3616 	     *   pHL          |--------|--------|
  3617              *   pLL                   |--------|--------|
  3617 	     *   pLL                   |--------|--------|
  3618              */
  3618 	     */
  3619 
  3619 
  3620 #    if __POINTER_SIZE__ == 8
  3620 #    if __POINTER_SIZE__ == 8
  3621             t = low32Bits(pLH) + low32Bits(pHL) + hi32Bits(pLL);
  3621 	    t = low32Bits(pLH) + low32Bits(pHL) + hi32Bits(pLL);
  3622             productLow = (t << 32) + low32Bits(pLL);
  3622 	    productLow = (t << 32) + low32Bits(pLL);
  3623             productHi = pHH + hi32Bits(t) + hi32Bits(pHL) + hi32Bits(pLH);
  3623 	    productHi = pHH + hi32Bits(t) + hi32Bits(pHL) + hi32Bits(pLH);
  3624 #    else
  3624 #    else
  3625             t = low16Bits(pLH) + low16Bits(pHL) + hi16Bits(pLL);
  3625 	    t = low16Bits(pLH) + low16Bits(pHL) + hi16Bits(pLL);
  3626             productLow = (t << 16) + low16Bits(pLL);
  3626 	    productLow = (t << 16) + low16Bits(pLL);
  3627             productHi = pHH + hi16Bits(t) + hi16Bits(pHL) + hi16Bits(pLH);
  3627 	    productHi = pHH + hi16Bits(t) + hi16Bits(pHL) + hi16Bits(pLH);
  3628 #    endif
  3628 #    endif
  3629         }
  3629 	}
  3630 #   endif /* ! WIN32 */
  3630 #   endif /* ! WIN32 */
  3631 #  endif /* ! (__GNUC__ && __i386__) */
  3631 #  endif /* ! (__GNUC__ && __i386__) */
  3632 # endif /* ! (__GNUC__ && __mc68k__) */
  3632 # endif /* ! (__GNUC__ && __mc68k__) */
  3633 
  3633 
  3634         if (negative < 0) {
  3634 	if (negative < 0) {
  3635             RETURN ( __mkSmallInteger(-(INT)(productLow & _MAX_INT)));
  3635 	    RETURN ( __mkSmallInteger(-(INT)(productLow & _MAX_INT)));
  3636         }
  3636 	}
  3637         RETURN ( __mkSmallInteger((INT)(productLow & _MAX_INT)));
  3637 	RETURN ( __mkSmallInteger((INT)(productLow & _MAX_INT)));
  3638 #endif /* ! USE_LONGLONG */
  3638 #endif /* ! USE_LONGLONG */
  3639     }
  3639     }
  3640 %}.
  3640 %}.
  3641 
  3641 
  3642     self primitiveFailed
  3642     self primitiveFailed
  3643 
  3643 
  3644     "
  3644     "
  3645         5 times:-1
  3645 	5 times:-1
  3646         5 times:1
  3646 	5 times:1
  3647         self maxVal-1 times:2
  3647 	self maxVal-1 times:2
  3648         self maxVal-1 times:-2
  3648 	self maxVal-1 times:-2
  3649         self maxVal-1 * 2  bitAnd:16r3fffffff
  3649 	self maxVal-1 * 2  bitAnd:16r3fffffff
  3650     "
  3650     "
  3651 ! !
  3651 ! !
  3652 
  3652 
  3653 !SmallInteger methodsFor:'printing & storing'!
  3653 !SmallInteger methodsFor:'printing & storing'!
  3654 
  3654 
  3662     "append a string representation of the receiver in the specified numberBase to aStream
  3662     "append a string representation of the receiver in the specified numberBase to aStream
  3663      (if showRadix is true, with initial XXr)
  3663      (if showRadix is true, with initial XXr)
  3664      The base argument should be between 2 and 36."
  3664      The base argument should be between 2 and 36."
  3665 
  3665 
  3666     showRadix ifTrue:[
  3666     showRadix ifTrue:[
  3667         base printOn:aStream.
  3667 	base printOn:aStream.
  3668         aStream nextPut:$r.
  3668 	aStream nextPut:$r.
  3669     ].
  3669     ].
  3670 
  3670 
  3671     (base isInteger and:[ base between:2 and:36 ]) ifTrue:[ 
  3671     (base isInteger and:[ base between:2 and:36 ]) ifTrue:[
  3672         aStream nextPutAll:(self printStringRadix:base)
  3672 	aStream nextPutAll:(self printStringRadix:base)
  3673     ] ifFalse:[
  3673     ] ifFalse:[
  3674         super printOn:aStream base:base showRadix:false.
  3674 	super printOn:aStream base:base showRadix:false.
  3675     ].
  3675     ].
  3676 
  3676 
  3677     "Created: / 07-09-2001 / 13:54:40 / cg"
  3677     "Created: / 07-09-2001 / 13:54:40 / cg"
  3678     "Modified: / 02-08-2010 / 12:25:20 / cg"
  3678     "Modified: / 02-08-2010 / 12:25:20 / cg"
  3679 !
  3679 !
  3694     int negative = 0;
  3694     int negative = 0;
  3695     int len;
  3695     int len;
  3696 
  3696 
  3697     myValue = __intVal(self);
  3697     myValue = __intVal(self);
  3698     if (myValue == 0) {
  3698     if (myValue == 0) {
  3699         RETURN (__MKSTRING_L("0", 1));
  3699 	RETURN (__MKSTRING_L("0", 1));
  3700     }
  3700     }
  3701 #ifdef SLOW_CODE
  3701 #ifdef SLOW_CODE
  3702     /*
  3702     /*
  3703      * this takes twice as long as the code below ...
  3703      * this takes twice as long as the code below ...
  3704      * (printf is soooo slow)
  3704      * (printf is soooo slow)
  3708      * actually only needed on sparc: since thisContext is
  3708      * actually only needed on sparc: since thisContext is
  3709      * in a global register, which gets destroyed by printf,
  3709      * in a global register, which gets destroyed by printf,
  3710      * manually save it here - very stupid ...
  3710      * manually save it here - very stupid ...
  3711      */
  3711      */
  3712     __BEGIN_PROTECT_REGISTERS__
  3712     __BEGIN_PROTECT_REGISTERS__
  3713     len = snprintf(buffer, sizeof(buffer), "%ld", (long)myValue);
  3713     len = snprintf(buffer, sizeof(buffer), "%"_ld_"", (long)myValue);
  3714     __END_PROTECT_REGISTERS__
  3714     __END_PROTECT_REGISTERS__
  3715 
  3715 
  3716     if (len >= 0 && len <= sizeof(buffer)) {
  3716     if (len >= 0 && len <= sizeof(buffer)) {
  3717         newString = __MKSTRING_L(buffer, len);
  3717 	newString = __MKSTRING_L(buffer, len);
  3718     }
  3718     }
  3719 
  3719 
  3720 #else
  3720 #else
  3721     if (myValue < 0) {
  3721     if (myValue < 0) {
  3722         negative = 1;
  3722 	negative = 1;
  3723         myValue = -myValue;
  3723 	myValue = -myValue;
  3724     }
  3724     }
  3725     cp = buffer + sizeof(buffer) - 1;
  3725     cp = buffer + sizeof(buffer) - 1;
  3726     *cp-- = '\0';
  3726     *cp-- = '\0';
  3727     while (myValue != 0) {
  3727     while (myValue != 0) {
  3728         *cp = '0' + (myValue % 10);
  3728 	*cp = '0' + (myValue % 10);
  3729         myValue = myValue / 10;
  3729 	myValue = myValue / 10;
  3730         cp--;
  3730 	cp--;
  3731     }
  3731     }
  3732     if (negative) {
  3732     if (negative) {
  3733         *cp-- = '-';
  3733 	*cp-- = '-';
  3734     }
  3734     }
  3735     newString = __MKSTRING_L(cp+1, (buffer + sizeof(buffer) - 2 - cp));
  3735     newString = __MKSTRING_L(cp+1, (buffer + sizeof(buffer) - 2 - cp));
  3736 #endif
  3736 #endif
  3737     if (newString != nil) {
  3737     if (newString != nil) {
  3738         RETURN (newString);
  3738 	RETURN (newString);
  3739     }
  3739     }
  3740 %}.
  3740 %}.
  3741     "/ only arrive here,
  3741     "/ only arrive here,
  3742     "/  when having memory problems (i.e. no space for string) ...
  3742     "/  when having memory problems (i.e. no space for string) ...
  3743     ^ super printString
  3743     ^ super printString
  3761     INT myValue;
  3761     INT myValue;
  3762     int negative = 0;
  3762     int negative = 0;
  3763     INT __base;
  3763     INT __base;
  3764 
  3764 
  3765     if (__isSmallInteger(base)) {
  3765     if (__isSmallInteger(base)) {
  3766         myValue = __intVal(self);
  3766 	myValue = __intVal(self);
  3767         if (myValue == 0) {
  3767 	if (myValue == 0) {
  3768             RETURN (__MKSTRING_L("0", 1));
  3768 	    RETURN (__MKSTRING_L("0", 1));
  3769         }
  3769 	}
  3770         __base = __intVal(base);
  3770 	__base = __intVal(base);
  3771 
  3771 
  3772 #ifdef SLOW_CODE
  3772 #ifdef SLOW_CODE
  3773         switch (__base) {
  3773 	switch (__base) {
  3774             case 10:
  3774 	    case 10:
  3775                 format = "%ld";
  3775 		format = "%"_ld_"";
  3776                 break;
  3776 		break;
  3777             case 16:
  3777 	    case 16:
  3778                 format = "%lx";
  3778 		format = "%"_lx_"";
  3779                 break;
  3779 		break;
  3780             case 8:
  3780 	    case 8:
  3781                 format = "%lo";
  3781 		format = "%"_lo_"";
  3782                 break;
  3782 		break;
  3783         }
  3783 	}
  3784 
  3784 
  3785         if (format) {
  3785 	if (format) {
  3786             /*
  3786 	    /*
  3787              * actually only needed on sparc: since thisContext is
  3787 	     * actually only needed on sparc: since thisContext is
  3788              * in a global register, which gets destroyed by printf,
  3788 	     * in a global register, which gets destroyed by printf,
  3789              * manually save it here - very stupid ...
  3789 	     * manually save it here - very stupid ...
  3790              */
  3790 	     */
  3791             __BEGIN_PROTECT_REGISTERS__
  3791 	    __BEGIN_PROTECT_REGISTERS__
  3792 
  3792 
  3793             len = snprintf(buffer, sizeof(buffer), format, (long)myValue);
  3793 	    len = snprintf(buffer, sizeof(buffer), format, (long)myValue);
  3794 
  3794 
  3795             __END_PROTECT_REGISTERS__
  3795 	    __END_PROTECT_REGISTERS__
  3796 
  3796 
  3797             if (len > 0 && len <= sizeof(buffer)) {
  3797 	    if (len > 0 && len <= sizeof(buffer)) {
  3798                 newString = __MKSTRING_L(buffer, len);
  3798 		newString = __MKSTRING_L(buffer, len);
  3799                 if (newString != nil) {
  3799 		if (newString != nil) {
  3800                     RETURN (newString);
  3800 		    RETURN (newString);
  3801                 }
  3801 		}
  3802             }
  3802 	    }
  3803         }
  3803 	}
  3804 #else
  3804 #else
  3805         if ((__base <= 36) && (__base > 1)) {
  3805 	if ((__base <= 36) && (__base > 1)) {
  3806             if (myValue < 0) {
  3806 	    if (myValue < 0) {
  3807                 negative = 1;
  3807 		negative = 1;
  3808                 myValue = -myValue;
  3808 		myValue = -myValue;
  3809             }
  3809 	    }
  3810             cp = buffer + sizeof(buffer) - 1;
  3810 	    cp = buffer + sizeof(buffer) - 1;
  3811             *cp-- = '\0';
  3811 	    *cp-- = '\0';
  3812             while (myValue != 0) {
  3812 	    while (myValue != 0) {
  3813                 int digit;
  3813 		int digit;
  3814 
  3814 
  3815                 digit = myValue % __base;
  3815 		digit = myValue % __base;
  3816                 if (digit <= 9) {
  3816 		if (digit <= 9) {
  3817                     *cp = '0' + digit;
  3817 		    *cp = '0' + digit;
  3818                 } else {
  3818 		} else {
  3819                     *cp = 'A' + digit - 10;
  3819 		    *cp = 'A' + digit - 10;
  3820                 }
  3820 		}
  3821                 myValue = myValue / __base;
  3821 		myValue = myValue / __base;
  3822                 cp--;
  3822 		cp--;
  3823             }
  3823 	    }
  3824             if (negative) {
  3824 	    if (negative) {
  3825                 *cp-- = '-';
  3825 		*cp-- = '-';
  3826             }
  3826 	    }
  3827             newString = __MKSTRING_L(cp+1, (buffer + sizeof(buffer) - 2 - cp));
  3827 	    newString = __MKSTRING_L(cp+1, (buffer + sizeof(buffer) - 2 - cp));
  3828             if (newString != nil) {
  3828 	    if (newString != nil) {
  3829                 RETURN (newString);
  3829 		RETURN (newString);
  3830             }
  3830 	    }
  3831         }
  3831 	}
  3832 #endif
  3832 #endif
  3833     }
  3833     }
  3834 %}.
  3834 %}.
  3835     "/ arrive here, for bad base,
  3835     "/ arrive here, for bad base,
  3836     "/ or when having memory problems (i.e. no space for string) ...
  3836     "/ or when having memory problems (i.e. no space for string) ...
  3873      This method is NONSTANDARD and may be removed without notice;
  3873      This method is NONSTANDARD and may be removed without notice;
  3874      it is provided to allow special conversions in very special
  3874      it is provided to allow special conversions in very special
  3875      situaltions.
  3875      situaltions.
  3876      Notice that a conversion may not be portable; for example,
  3876      Notice that a conversion may not be portable; for example,
  3877      to correctly convert an int on a 64-bit alpha, a %ld is required,
  3877      to correctly convert an int on a 64-bit alpha, a %ld is required,
  3878      while other systems may be happy with a %d ...
  3878      on 64bit mingw or visualc, %lld is required,
       
  3879      while other systems may be happy with a %d.
       
  3880      (We cannot use lld unconditionally, because some (old) c compilers do not support it!!)
  3879      Use at your own risk (if at all).
  3881      Use at your own risk (if at all).
  3880      WARNNG: this goes directly to the C-printf function and may therefore me inherently unsafe.
  3882      WARNNG: this goes directly to the C-printf function and may therefore me inherently unsafe.
  3881      Please use the printf: method, which is safe as it is completely implemented in Smalltalk."
  3883      Please use the printf: method, which is safe as it is completely implemented in Smalltalk."
  3882 
  3884 
  3883 %{  /* STACK: 400 */
  3885 %{  /* STACK: 400 */
  3884     char buffer[256];
  3886     char buffer[256];
  3885     OBJ s;
  3887     OBJ s;
  3886     int len;
  3888     int len;
  3887 
  3889 
  3888     if (__isStringLike(formatString)) {
  3890     if (__isStringLike(formatString)) {
  3889         /*
  3891 	/*
  3890          * actually only needed on sparc: since thisContext is
  3892 	 * actually only needed on sparc: since thisContext is
  3891          * in a global register, which gets destroyed by printf,
  3893 	 * in a global register, which gets destroyed by printf,
  3892          * manually save it here - very stupid ...
  3894 	 * manually save it here - very stupid ...
  3893          */
  3895 	 */
  3894         __BEGIN_PROTECT_REGISTERS__
  3896 	__BEGIN_PROTECT_REGISTERS__
  3895 
  3897 
  3896         len = snprintf(buffer, sizeof(buffer), __stringVal(formatString), __intVal(self));
  3898 	len = snprintf(buffer, sizeof(buffer), __stringVal(formatString), __intVal(self));
  3897 
  3899 
  3898         __END_PROTECT_REGISTERS__
  3900 	__END_PROTECT_REGISTERS__
  3899 
  3901 
  3900         if (len < 0) goto fail;
  3902 	if (len < 0) goto fail;
  3901 
  3903 
  3902         s = __MKSTRING_L(buffer, len);
  3904 	s = __MKSTRING_L(buffer, len);
  3903         if (s != nil) {
  3905 	if (s != nil) {
  3904             RETURN (s);
  3906 	    RETURN (s);
  3905         }
  3907 	}
  3906     }
  3908     }
  3907 fail: ;
  3909 fail: ;
  3908 %}.
  3910 %}.
  3909     self primitiveFailed
  3911     self primitiveFailed
  3910 
  3912 
  3911     "
  3913     "
  3912         123 printfPrintString:'%%d -> %d'
  3914 	123 printfPrintString:'%%d -> %d'
  3913         123 printfPrintString:'%%6d -> %6d'
  3915 	123 printfPrintString:'%%6d -> %6d'
  3914         123 printfPrintString:'%%x -> %x'
  3916 	123 printfPrintString:'%%x -> %x'
  3915         123 printfPrintString:'%%4x -> %4x'
  3917 	123 printfPrintString:'%%4x -> %4x'
  3916         123 printfPrintString:'%%04x -> %04x'
  3918 	123 printfPrintString:'%%04x -> %04x'
  3917     "
  3919     "
  3918 ! !
  3920 ! !
  3919 
  3921 
  3920 !SmallInteger methodsFor:'private'!
  3922 !SmallInteger methodsFor:'private'!
  3921 
  3923 
  3988 
  3990 
  3989     "
  3991     "
  3990      0 isPowerOfTwo
  3992      0 isPowerOfTwo
  3991      1 isPowerOfTwo
  3993      1 isPowerOfTwo
  3992      2 isPowerOfTwo
  3994      2 isPowerOfTwo
  3993      3 isPowerOfTwo                   
  3995      3 isPowerOfTwo
  3994      4 isPowerOfTwo                   
  3996      4 isPowerOfTwo
  3995      16r8000000000000000 isPowerOfTwo   
  3997      16r8000000000000000 isPowerOfTwo
  3996      16r8000000000000001 isPowerOfTwo   
  3998      16r8000000000000001 isPowerOfTwo
  3997 
  3999 
  3998      10000 factorial isPowerOfTwo
  4000      10000 factorial isPowerOfTwo
  3999      |n| n := 10000 factorial. Time millisecondsToRun:[1000 timesRepeat:[ n isPowerOfTwo]] 
  4001      |n| n := 10000 factorial. Time millisecondsToRun:[1000 timesRepeat:[ n isPowerOfTwo]]
  4000     "
  4002     "
  4001 
  4003 
  4002     "Modified: / 20-06-2011 / 12:41:18 / cg"
  4004     "Modified: / 20-06-2011 / 12:41:18 / cg"
  4003 !
  4005 !
  4004 
  4006 
  4036 
  4038 
  4037 %{  /* NOCONTEXT */
  4039 %{  /* NOCONTEXT */
  4038 
  4040 
  4039     // tricky, but very fast (google for it, to understand)
  4041     // tricky, but very fast (google for it, to understand)
  4040 #if __POINTER_SIZE__ == 4
  4042 #if __POINTER_SIZE__ == 4
  4041     unsigned int v = __intVal(self);  
  4043     unsigned int v = __intVal(self);
  4042 
  4044 
  4043     v ^= v >> 16;
  4045     v ^= v >> 16;
  4044     v ^= v >> 8;
  4046     v ^= v >> 8;
  4045     v ^= v >> 4;
  4047     v ^= v >> 4;
  4046     v &= 0xf;
  4048     v &= 0xf;
  4048 #endif
  4050 #endif
  4049 %}.
  4051 %}.
  4050     ^ super parityOdd
  4052     ^ super parityOdd
  4051 
  4053 
  4052     "
  4054     "
  4053         self assert:
  4055 	self assert:
  4054          (((0 to:255) collect:[:i | i parityOdd ifTrue:1 ifFalse:0])
  4056 	 (((0 to:255) collect:[:i | i parityOdd ifTrue:1 ifFalse:0])
  4055             asByteArray collect:[:c | c + $0 asciiValue]) asString
  4057 	    asByteArray collect:[:c | c + $0 asciiValue]) asString
  4056          =
  4058 	 =
  4057             '0110100110010110100101100110100110010110011010010110100110010110100101100110100101101001100101100110100110010110100101100110100110010110011010010110100110010110011010011001011010010110011010010110100110010110100101100110100110010110011010010110100110010110'
  4059 	    '0110100110010110100101100110100110010110011010010110100110010110100101100110100101101001100101100110100110010110100101100110100110010110011010010110100110010110011010011001011010010110011010010110100110010110100101100110100110010110011010010110100110010110'
  4058 
  4060 
  4059         self assert:(16r0FFFFFFF parityOdd = 16r0FFFFFFF bitCount odd).  
  4061 	self assert:(16r0FFFFFFF parityOdd = 16r0FFFFFFF bitCount odd).
  4060         self assert:(16r1FFFFFFF parityOdd = 16r1FFFFFFF bitCount odd).
  4062 	self assert:(16r1FFFFFFF parityOdd = 16r1FFFFFFF bitCount odd).
  4061         self assert:(16r3FFFFFFF parityOdd = 16r3FFFFFFF bitCount odd).
  4063 	self assert:(16r3FFFFFFF parityOdd = 16r3FFFFFFF bitCount odd).
  4062         self assert:(16r7FFFFFFF parityOdd = 16r7FFFFFFF bitCount odd).
  4064 	self assert:(16r7FFFFFFF parityOdd = 16r7FFFFFFF bitCount odd).
  4063         self assert:(16rFFFFFFFF parityOdd = 16rFFFFFFFF bitCount odd).
  4065 	self assert:(16rFFFFFFFF parityOdd = 16rFFFFFFFF bitCount odd).
  4064     "
  4066     "
  4065 
  4067 
  4066     "Modified (comment): / 09-01-2012 / 19:55:37 / cg"
  4068     "Modified (comment): / 09-01-2012 / 19:55:37 / cg"
  4067 !
  4069 !
  4068 
  4070 
  4119 ! !
  4121 ! !
  4120 
  4122 
  4121 !SmallInteger class methodsFor:'documentation'!
  4123 !SmallInteger class methodsFor:'documentation'!
  4122 
  4124 
  4123 version
  4125 version
  4124     ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.198 2012-11-28 12:49:35 cg Exp $'
  4126     ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.199 2013-01-08 17:55:11 cg Exp $'
  4125 !
  4127 !
  4126 
  4128 
  4127 version_CVS
  4129 version_CVS
  4128     ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.198 2012-11-28 12:49:35 cg Exp $'
  4130     ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.199 2013-01-08 17:55:11 cg Exp $'
  4129 ! !
  4131 ! !