#REFACTORING
authorClaus Gittinger <cg@exept.de>
Tue, 17 Nov 2015 11:31:37 +0100
changeset 18897 562b990d5773
parent 18895 223497b63b36
child 18898 0dc54d84ac92
#REFACTORING many comments added: #bitReversed #bitReversed16 #bitReversed32 #bitReversed8
SmallInteger.st
--- a/SmallInteger.st	Fri Nov 13 21:00:19 2015 +0100
+++ b/SmallInteger.st	Tue Nov 17 11:31:37 2015 +0100
@@ -963,6 +963,7 @@
 ! !
 
 
+
 !SmallInteger methodsFor:'bit operators'!
 
 bitAnd:anInteger
@@ -1043,7 +1044,9 @@
 
 bitClear:anInteger
     "return the bitwise-and of the receiver and the complement of the argument, anInteger,
-     returning the receiver with bits of the argument cleared."
+     returning the receiver with bits of the argument cleared.
+     The method's name may be misleading: the receiver is not changed,
+     but a new number is returned. Should be named #withBitCleared:"
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
@@ -1051,7 +1054,7 @@
 #else
     /* anding the tags doesn't change it */
     if (__isSmallInteger(anInteger)) {
-	RETURN ( ((OBJ) (((INT)self & ~(INT)anInteger) | TAG_INT)) );
+        RETURN ( ((OBJ) (((INT)self & ~(INT)anInteger) | TAG_INT)) );
     }
 #endif /* not __SCHTEAM__ */
 %}.
@@ -1067,36 +1070,62 @@
     "return the number of 1-bits in the receiver"
 
 %{  /* NOCONTEXT */
-#ifndef __SCHTEAM__
+#ifdef __SCHTEAM__
+    long _v1, _v2;
+    long _self = self.longValue();
+
+    _v1 = _self & 0xFFFFFFFF;
+    _v1 = _v1 - ((_v1 >> 1) & 0x55555555);
+    _v1 = (_v1 & 0x33333333) + ((_v1 >> 2) & 0x33333333);
+    _v1 = ((_v1 + (_v1 >> 4)) & 0x0F0F0F0F);
+
+    _v2 = (unsigned int)(_self >> 32);
+    _v2 = _v2 - ((_v2 >> 1) & 0x55555555);
+    _v2 = (_v2 & 0x33333333) + ((_v2 >> 2) & 0x33333333);
+    _v2 = ((_v2 + (_v2 >> 4)) & 0x0F0F0F0F);
+
+    _cnt = ((_v1 * 0x01010101) >> 24) + ((_v2 * 0x01010101) >> 24);
+    return __c__._RETURN( STInteger._qnew( _cnt ) );
+#else
     unsigned int _cnt;
-    unsigned INT _self = __intVal(self);
-
-# define ALGORIHTM_3
+
+    // popcnt is slower
+# if 0 // defined(__GNUC__) && (defined(__x86__) || defined(__x86_64__))
+#  define ALGORIHTM_4
+# else
+#  define ALGORIHTM_3
+# endif
 
 # ifdef ALGORITHM_1
     // old k&r code; might be better if only one or two bits are set
 
+    unsigned INT _self = __intVal(self);
+
     _cnt = 0;
     while (_self) {
-	_cnt++;
-	_self = _self & (_self - 1);
+        _cnt++;
+        _self = _self & (_self - 1);
     }
 # else
+
 #  ifdef ALGORITHM_2
     // seems to be faster on the average (and has better worst case)
 
     static unsigned char table[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+    unsigned INT _self = __intVal(self);
 
     _cnt = 0;
     while (_self) {
-	_cnt += table[ _self & 0x0F ];
-	_self >>= 4;
+        _cnt += table[ _self & 0x0F ];
+        _self >>= 4;
     }
 #  else
+
 #   ifdef ALGORIHTM_3
     // the fastest, but hard (impossible) to understand (google for fastest bit count)
 #    if __POINTER_SIZE__ == 8
     unsigned int _v1, _v2;
+    unsigned INT _self = __intVal(self);
 
     _v1 = _self & 0xFFFFFFFF;
     _v1 = _v1 - ((_v1 >> 1) & 0x55555555);
@@ -1116,7 +1145,45 @@
     _cnt = (_cnt * 0x01010101) >> 24;
 #    endif
 #   else
-     error error error
+
+#    ifdef ALGORIHTM_4
+     // using the popcnt instruction (x86 only); strange enough, this is slower than ALGO3
+#     if __POINTER_SIZE__ == 8
+    unsigned INT _v;
+
+#    define _POPCNT(__op)                      \
+    ({                                          \
+        INT __rslt;                             \
+        asm("xor     %%rax,%%rax        \n      \
+             popcnt %1,%%rax           \n      \
+                        "  : "=a" (__rslt)      \
+                           : "g" ((INT)(__op))    \
+                           : "cc");             \
+        (OBJ)__rslt;                            \
+     })
+
+    _v = (INT)self;
+    _cnt = _POPCNT(_v);
+    _cnt--; // one too many due to tag 
+#     else
+#    define _POPCNT(__op)                      \
+    ({                                          \
+        INT __rslt;                             \
+        asm("xor     %%eax,%%eax        \n      \
+             popcnt  %1,%%eax           \n      \
+                        "  : "=a" (__rslt)      \
+                           : "g" ((INT)(__v))   \
+                           : "cc");             \
+        (OBJ)__rslt;                            \
+     })
+
+    _v = (INT)self;
+    _cnt = _POPCNT(_v);
+    _cnt--; // one too many due to tag 
+#     endif
+#    else
+      error error error
+#    endif
 #   endif
 #  endif
 # endif
@@ -1129,25 +1196,37 @@
     "
 
      1 to:1000000 do:[:n |
-	self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
+        self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
      ].
 
-     #(
-	16r00010000 16r00100000 16r01000000 16r10000000
-	16r00020000 16r00200000 16r02000000 16r20000000
-	16r00040000 16r00400000 16r04000000 16r40000000
-	16r00080000 16r00800000 16r08000000 16r80000000
-
-	16rFFFFFFFF 16r7FFFFFFF 16r3FFFFFFF 16r1FFFFFFF
-	16rEEEEEEEE 16r7EEEEEEE 16r3EEEEEEE 16r1EEEEEEE
-	16rDDDDDDDD 16r7DDDDDDD 16r3DDDDDDD 16r1DDDDDDD
-	16rCCCCCCCC 16r7CCCCCCC 16r3CCCCCCC 16r1CCCCCCC
+     #( 16r00000000
+        16r00010000 16r00100000 16r01000000 16r10000000
+        16r00020000 16r00200000 16r02000000 16r20000000
+        16r00040000 16r00400000 16r04000000 16r40000000
+        16r00080000 16r00800000 16r08000000 16r80000000
+
+        16rFFFFFFFF 16r7FFFFFFF 16r3FFFFFFF 16r1FFFFFFF
+        16rEEEEEEEE 16r7EEEEEEE 16r3EEEEEEE 16r1EEEEEEE
+        16rDDDDDDDD 16r7DDDDDDD 16r3DDDDDDD 16r1DDDDDDD
+        16rCCCCCCCC 16r7CCCCCCC 16r3CCCCCCC 16r1CCCCCCC
+
+        16r8000000000010000 16r8000000000100000 16r8000000001000000 16r8000000010000000
+        16r8000000000020000 16r8000000000200000 16r8000000002000000 16r8000000020000000
+        16r8000000000040000 16r8000000000400000 16r8000000004000000 16r8000000040000000
+        16r8000000000080000 16r8000000000800000 16r8000000008000000 16r8000000080000000
+
+        16r80000000FFFFFFFF 16r800000007FFFFFFF 16r800000003FFFFFFF 16r800000001FFFFFFF
+        16r80000000EEEEEEEE 16r800000007EEEEEEE 16r800000003EEEEEEE 16r800000001EEEEEEE
+        16r80000000DDDDDDDD 16r800000007DDDDDDD 16r800000003DDDDDDD 16r800000001DDDDDDD
+        16r80000000CCCCCCCC 16r800000007CCCCCCC 16r800000003CCCCCCC 16r800000001CCCCCCC
+
+        16rFFFFFFFFFFFFFFFF 16r7FFFFFFFFFFFFFFF 16r3FFFFFFFFFFFFFFF 16r1FFFFFFFFFFFFFFF
      ) do:[:n |
-	self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
+        self assert:(n bitCount = ((n printStringRadix:2) occurrencesOf:$1))
      ]
 
      1 to:10000000 do:[:n |
-	(n bitCount)
+        (n bitCount)
      ]
     "
 
@@ -1155,14 +1234,18 @@
 !
 
 bitInvert
-    "return the value of the receiver with all bits inverted"
+    "return the value of the receiver with all bits inverted.
+     The method's name may be misleading: the receiver is not changed,
+     but a new number is returned. Could be named #withBitsInverted"
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
+    long _self = self.longValue();
+    return __c__._RETURN( STInteger._new( ~_self ) );
 #else
     /* invert anything except tag bits */
     RETURN ( ((OBJ) ((INT)self ^ ~TAG_MASK)) );
-#endif
+#endif /* not __SCHTEAM__ */
 %}.
     ^ super bitInvert
 !
@@ -1176,9 +1259,9 @@
 #else
     /* oring the tags doesn't change it */
     if (__isSmallInteger(anInteger)) {
-	RETURN ( ((OBJ) ((INT)self | (INT)anInteger)) );
+        RETURN ( ((OBJ) ((INT)self | (INT)anInteger)) );
     }
-#endif
+#endif /* not __SCHTEAM__ */
 %}.
     ^ self retry:#bitOr: coercing:anInteger
 
@@ -1190,6 +1273,155 @@
     "
 !
 
+bitReversed
+    "swap (i.e. reverse) bits in an integer
+     i.e. a.b.c.d....x.y.z -> z.y.x...b.a.d.c."
+
+%{  /* NOCONTEXT */
+#ifndef __SCHTEAM__
+    unsigned INT v = __intVal(self);
+
+# if __POINTER_SIZE__ == 8
+    // swap odd and even bits
+    v = ((v >> 1) & 0x5555555555555555) | ((v & 0x5555555555555555) << 1);
+    // swap consecutive pairs
+    v = ((v >> 2) & 0x3333333333333333) | ((v & 0x3333333333333333) << 2);
+    // swap nibbles ... 
+    v = ((v >> 4) & 0x0F0F0F0F0F0F0F0F) | ((v & 0x0F0F0F0F0F0F0F0F) << 4);
+    // swap bytes
+    v = ((v >> 8) & 0x00FF00FF00FF00FF) | ((v & 0x00FF00FF00FF00FF) << 8);
+    // swap 2-byte pairs
+    v = ((v >> 16) & 0x0000FFFF0000FFFF) | (( v & 0x0000FFFF0000FFFF) << 16);
+    // swap 4-byte long pairs
+    v = ((v >> 32) & 0x00000000FFFFFFFF) | (( v & 0x00000000FFFFFFFF) << 32);
+# else
+    // swap odd and even bits
+    v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
+    // swap consecutive pairs
+    v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
+    // swap nibbles ... 
+    v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
+    // swap bytes
+    v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
+    // swap 2-byte long pairs
+    v = ((v >> 16) & 0x0000FFFF) | ((v & 0x0000FFFF) << 16);
+# endif
+
+    if (v <= _MAX_INT) {
+        RETURN ( __mkSmallInteger(v) );
+    }
+    RETURN (__MKUINT(v));
+#endif /* not __SCHTEAM__ */
+%}.
+    ^ super bitReversed
+    
+    "
+     2r1001 bitReversed printStringRadix:2
+     2r100111010011 bitReversed printStringRadix:2
+     -1 bitReversed printStringRadix:2
+    "
+!
+
+bitReversed16
+    "swap (i.e. reverse) the low 16 bits in an integer 
+     the high bits are ignored and clear in the result
+     i.e. xxx.a.b.c.d....x.y.z -> 000.z.y.x...b.a.d.c."
+
+%{  /* NOCONTEXT */
+#ifndef __SCHTEAM__
+    unsigned INT v = __intVal(self) & 0xFFFF;
+
+    // swap odd and even bits
+    v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
+    // swap consecutive pairs
+    v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
+    // swap nibbles ... 
+    v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
+    // swap bytes
+    v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
+
+    if (v <= _MAX_INT) {
+        RETURN ( __mkSmallInteger(v) );
+    }
+    RETURN (__MKUINT(v));
+#endif /* not __SCHTEAM__ */
+%}.
+    ^ super bitReversed16
+
+    "
+     2r1001 bitReversed16 printStringRadix:2
+     2r100111010011 bitReversed16 printStringRadix:2
+     -1 bitReversed16 printStringRadix:2
+    "
+!
+
+bitReversed32
+    "swap (i.e. reverse) the low 32 bits in an integer
+     the high bits are ignored and clear in the result
+     i.e. xxx.a.b.c.d....x.y.z -> 000.z.y.x...b.a.d.c."
+
+%{  /* NOCONTEXT */
+#ifndef __SCHTEAM__
+    unsigned INT v = __intVal(self) & 0xFFFFFFFF;
+
+    // swap odd and even bits
+    v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
+    // swap consecutive pairs
+    v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
+    // swap nibbles ... 
+    v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
+    // swap bytes
+    v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
+    // swap 2-byte long pairs
+    v = ((v >> 16) & 0x0000FFFF) | ((v & 0x0000FFFF) << 16);
+
+    if (v <= _MAX_INT) {
+        RETURN ( __mkSmallInteger(v) );
+    }
+    RETURN (__MKUINT(v));
+#endif /* not __SCHTEAM__ */
+%}.
+    ^ super bitReversed32
+
+    "
+     2r1001 bitReversed32 printStringRadix:2
+     2r100111010011 bitReversed32 printStringRadix:2
+     -1 bitReversed32 printStringRadix:2
+    "
+!
+
+bitReversed8
+    "swap (i.e. reverse) the low 8 bits in an integer 
+     the high bits are ignored and clear in the result
+     i.e. xxx.a.b.c.d....x.y.z -> 000.z.y.x...b.a.d.c."
+
+%{  /* NOCONTEXT */
+#ifndef __SCHTEAM__
+    unsigned INT v = __intVal(self) & 0xFF;
+
+    // swap odd and even bits
+    v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
+    // swap consecutive pairs
+    v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
+    // swap nibbles ... 
+    v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
+
+    if (v <= _MAX_INT) {
+        RETURN ( __mkSmallInteger(v) );
+    }
+    RETURN (__MKUINT(v));
+#endif /* not __SCHTEAM__ */
+%}.
+    ^ super bitReversed8
+
+    "
+     2r1001 bitReversed8 printStringRadix:2
+     2r10011101 bitReversed8 printStringRadix:2
+     2r111110011101 bitReversed8 printStringRadix:2
+     -1 bitReversed8 printStringRadix:2
+    "
+!
+
 bitShift:shiftCount
     "return the value of the receiver shifted by shiftCount bits;
      leftShift if shiftCount > 0; rightShift otherwise.
@@ -1324,28 +1556,27 @@
 clearBit:anInteger
     "return a new integer where the specified bit is off.
      Bits are counted from 1 starting with the least significant.
-     The methods name may be misleading: the receiver is not changed,
+     The method's name may be misleading: the receiver is not changed,
      but a new number is returned. Should be named #withBitCleared:"
 
 %{  /* NOCONTEXT */
-#ifdef __SCHTEAM__
-#else
+#ifndef __SCHTEAM__
     if (__isSmallInteger(anInteger)) {
-	int index = __intVal(anInteger);
-
-	if (index > 0) {
+        int index = __intVal(anInteger);
+
+        if (index > 0) {
 # if __POINTER_SIZE__ == 8
-	    if (index <= 62)
+            if (index <= 62)
 # else
-	    if (index <= 30)
+            if (index <= 30)
 # endif
-	    {
-		INT mask = __MASKSMALLINT(1 << (index-1));
-
-		RETURN ( ((OBJ) ((INT)self & ~(INT)mask)) );
-	    }
-	    RETURN (self);  /* nothing to do ... */
-	}
+            {
+                INT mask = __MASKSMALLINT(1 << (index-1));
+
+                RETURN ( ((OBJ) ((INT)self & ~(INT)mask)) );
+            }
+            RETURN (self);  /* nothing to do ... */
+        }
     }
 #endif /* not __SCHTEAM__ */
 %}.
@@ -1507,27 +1738,26 @@
 invertBit:anInteger
     "return a new number where the specified bit is inverted.
      Bits are counted from 1 starting with the least significant.
-     The methods name may be misleading: the receiver is not changed,
+     The method's name may be misleading: the receiver is not changed,
      but a new number is returned. Should be named #withBitInverted:"
 
 %{  /* NOCONTEXT */
-#ifdef __SCHTEAM__
-#else
+#ifndef __SCHTEAM__
     if (__isSmallInteger(anInteger)) {
-	int index = __intVal(anInteger);
-
-	if (index > 0) {
+        int index = __intVal(anInteger);
+
+        if (index > 0) {
 # if __POINTER_SIZE__ == 8
-	    if (index <= 62)
+            if (index <= 62)
 # else
-	    if (index <= 30)
+            if (index <= 30)
 # endif
-	    {
-		INT mask = __MASKSMALLINT(1 << (index-1));
-
-		RETURN ( ((OBJ) ((INT)self ^ (INT)mask)) );
-	    }
-	}
+            {
+                INT mask = __MASKSMALLINT(1 << (index-1));
+
+                RETURN ( ((OBJ) ((INT)self ^ (INT)mask)) );
+            }
+        }
     }
 #endif /* not __SCHTEAM__ */
 %}.
@@ -1757,27 +1987,26 @@
 setBit:anInteger
     "return a new integer where the specified bit is on.
      Bits are counted from 1 starting with the least significant.
-     The methods name may be misleading: the receiver is not changed,
+     The method's name may be misleading: the receiver is not changed,
      but a new number is returned. Should be named #withBitSet:"
 
 %{  /* NOCONTEXT */
-#ifdef __SCHTEAM__
-#else
+#ifndef __SCHTEAM__
     if (__isSmallInteger(anInteger)) {
-	int index = __intVal(anInteger);
-
-	if (index > 0) {
+        int index = __intVal(anInteger);
+
+        if (index > 0) {
 # if __POINTER_SIZE__ == 8
-	    if (index <= 62)
+            if (index <= 62)
 # else
-	    if (index <= 30)
+            if (index <= 30)
 # endif
-	    {
-		INT mask = __MASKSMALLINT(1 << (index-1));
-
-		RETURN ( ((OBJ) ((INT)self | (INT)mask)) );
-	    }
-	}
+            {
+                INT mask = __MASKSMALLINT(1 << (index-1));
+
+                RETURN ( ((OBJ) ((INT)self | (INT)mask)) );
+            }
+        }
     }
 #endif /* not __SCHTEAM__ */
 %}.
@@ -1828,7 +2057,7 @@
 
     swapped = ((v>>8)&0xFF) | ((v & 0xFF)<<8);
     RETURN (__mkSmallInteger(swapped));
-#endif
+#endif /* not __SCHTEAM__ */
 %}.
     ^ super byteSwapped16
 
@@ -1938,11 +2167,11 @@
     //                     xxxxxxxx                      xxxxxxxx
     //                              xxxxxxxx    xxxxxxxx
     swapped =  (v>>56) | ((v>>40)&0xFF00) | ((v>>24) & 0xFF0000) | ((v>>8) & 0xFF000000)
-		| ((v & 0xFF000000)<<8) | ((v & 0x00FF0000)<<24) | ((v & 0x0000FF00)<<40)
-		| ((v & 0xFF)<<56);
+                | ((v & 0xFF000000)<<8) | ((v & 0x00FF0000)<<24) | ((v & 0x0000FF00)<<40)
+                | ((v & 0xFF)<<56);
 # endif
     RETURN(__MKUINT( swapped ));
-#endif
+#endif /* not __SCHTEAM__ */
 %}.
     ^ super byteSwapped64
 
@@ -2409,7 +2638,9 @@
 swapBytes
     "swap bytes pair-wise in a positive integer
      i.e. a.b.c.d -> b.a.d.c.
-
+     The name may be misleading; actually a new integer is returned,
+     and the receiver is not modified.
+     
      Redefined here for speed.
      Swapping of negative integers is undefined and therefore not supported.
      This case is handled in the superclass."
@@ -2419,19 +2650,19 @@
     unsigned INT v = __intVal(self);
 
     if ((INT)v >= 0) {
-	unsigned INT swapped;
+        unsigned INT swapped;
 
 # if __POINTER_SIZE__ == 8
-	swapped = ((v >> 8) & 0x00FF00FF00FF00FF) | ((v & 0x00FF00FF00FF00FF) << 8);
+        swapped = ((v >> 8) & 0x00FF00FF00FF00FF) | ((v & 0x00FF00FF00FF00FF) << 8);
 # else
-	swapped = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
+        swapped = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
 # endif /* __POINTER_SIZE__ */
 
-	//if (__ISVALIDINTEGER(swapped)) {   // sorry, but this does not work here if (INT)swapped would be negative
-	if (swapped <= _MAX_INT) {
-	    RETURN ( __mkSmallInteger(swapped) );
-	}
-	RETURN (__MKUINT(swapped));
+        //if (__ISVALIDINTEGER(swapped)) {   // sorry, but this does not work here if (INT)swapped would be negative
+        if (swapped <= _MAX_INT) {
+            RETURN ( __mkSmallInteger(swapped) );
+        }
+        RETURN (__MKUINT(swapped));
     }
 #endif
 %}.
@@ -2482,13 +2713,18 @@
 !SmallInteger methodsFor:'coercing & converting'!
 
 asCharacter
-    "Return a character with the receiver as ascii value"
+    "Return a character with the receiver as ascii (actually: unicode) value"
 
     ^ Character value:self
+
+    "
+     Character value:16r61
+     Character value:16r161
+    "
 !
 
 asFloat
-    "return a Float with same value as receiver.
+    "return a Float with same value as the receiver.
      Redefined for performance (machine can do it faster)"
 
 %{  /* NOCONTEXT */
@@ -2506,7 +2742,11 @@
 !
 
 asLargeInteger
-    "return a LargeInteger with same value as receiver"
+    "return a LargeInteger with same value as receiver.
+     Not for general use:
+       Notice, that this returns an unnormalized large int (i.e. a large with a smallint value),
+       which are normally not present in the system, and not handled correctly by many functions.
+       This exists only as a helper for some algorithms and converters"
 
     ^ LargeInteger value:self
 !
@@ -2531,12 +2771,12 @@
 !
 
 asUnsignedInt
-    "return an integer representing my unsigned INT
-     value. Notice, that the returned integer's size
+    "return an integer representing my unsigned INT value. 
+     Notice, that the returned integer's size
      depends heavily on the underlying INT size;
      You will get 16rFFFFFFFF on 32bit machines,
      but 16rFFFFFFFFFFFFFFFF on 64 bit machines.
-     So use this only for printing."
+     So use this only for printing or certain bit operations (emulating C semantics)."
 
 %{  /* NOCONTEXT */
     INT iVal = __intVal(self);
@@ -2687,16 +2927,16 @@
 #else
     if (__isSmallInteger(aNumber)) {
 # ifdef POSITIVE_ADDRESSES
-	RETURN ( (__intVal(self) < __intVal(aNumber)) ? true : false );
+        RETURN ( (__intVal(self) < __intVal(aNumber)) ? true : false );
 # else
-	/* tag bit does not change ordering */
-	RETURN ( ((INT)self < (INT)aNumber) ? true : false );
+        /* tag bit does not change ordering */
+        RETURN ( ((INT)self < (INT)aNumber) ? true : false );
 # endif
     }
     if (__isFloatLike(aNumber)) {
-	RETURN ( ((double)__intVal(self) < __floatVal(aNumber)) ? true : false );
+        RETURN ( ((double)__intVal(self) < __floatVal(aNumber)) ? true : false );
     }
-#endif
+#endif /* not __SCHTEAM__ */
 %}.
     ^ aNumber lessFromInteger:self
     "^ self retry:#< coercing:aNumber"
@@ -2712,16 +2952,16 @@
 
     if (__isSmallInteger(aNumber)) {
 # ifdef POSITIVE_ADDRESSES
-	RETURN ( (__intVal(self) <= __intVal(aNumber)) ? true : false );
+        RETURN ( (__intVal(self) <= __intVal(aNumber)) ? true : false );
 # else
-	/* tag bit does not change ordering */
-	RETURN ( ((INT)self <= (INT)aNumber) ? true : false );
+        /* tag bit does not change ordering */
+        RETURN ( ((INT)self <= (INT)aNumber) ? true : false );
 # endif
     }
     if (__isFloatLike(aNumber)) {
-	RETURN ( ((double)__intVal(self) <= __floatVal(aNumber)) ? true : false );
+        RETURN ( ((double)__intVal(self) <= __floatVal(aNumber)) ? true : false );
     }
-#endif
+#endif /* not __SCHTEAM__ */
 %}.
     ^ (self > aNumber) not
 
@@ -2735,25 +2975,25 @@
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
     if (aNumber.isNumber()) {
-	return context._RETURN( self.eqvP( aNumber ));
+        return context._RETURN( aNumber.eqvP( self.longValue() ));
     }
 #else
 
     if (aNumber == self) {
-	RETURN ( true );
+        RETURN ( true );
     }
     if (! __isNonNilObject(aNumber)) {
-	/* a smallint or nil */
-	RETURN ( false );
+        /* a smallint or nil */
+        RETURN ( false );
     }
 
     if (__qIsFloatLike(aNumber)) {
-	RETURN ( ((double)__intVal(self) == __floatVal(aNumber)) ? true : false );
+        RETURN ( ((double)__intVal(self) == __floatVal(aNumber)) ? true : false );
     }
     if (__qIsShortFloat(aNumber)) {
-	RETURN ( ((double)__intVal(self) == __shortFloatVal(aNumber)) ? true : false );
+        RETURN ( ((double)__intVal(self) == __shortFloatVal(aNumber)) ? true : false );
     }
-#endif
+#endif /* not __SCHTEAM__ */
 %}.
     ^ aNumber equalFromInteger:self
 !
@@ -2768,16 +3008,16 @@
 
     if (__isSmallInteger(aNumber)) {
 # ifdef POSITIVE_ADDRESSES
-	RETURN ( (__intVal(self) > __intVal(aNumber)) ? true : false );
+        RETURN ( (__intVal(self) > __intVal(aNumber)) ? true : false );
 # else
-	/* tag bit does not change ordering */
-	RETURN ( ((INT)self > (INT)aNumber) ? true : false );
+        /* tag bit does not change ordering */
+        RETURN ( ((INT)self > (INT)aNumber) ? true : false );
 # endif
     }
     if (__isFloatLike(aNumber)) {
-	RETURN ( ((double)__intVal(self) > __floatVal(aNumber)) ? true : false );
+        RETURN ( ((double)__intVal(self) > __floatVal(aNumber)) ? true : false );
     }
-#endif
+#endif /* not __SCHTEAM__ */
 %}.
     ^ (aNumber < self)
 
@@ -2794,16 +3034,16 @@
 
     if (__isSmallInteger(aNumber)) {
 # ifdef POSITIVE_ADDRESSES
-	RETURN ( (__intVal(self) >= __intVal(aNumber)) ? true : false );
+        RETURN ( (__intVal(self) >= __intVal(aNumber)) ? true : false );
 # else
-	/* tag bit does not change ordering */
-	RETURN ( ((INT)self >= (INT)aNumber) ? true : false );
+        /* tag bit does not change ordering */
+        RETURN ( ((INT)self >= (INT)aNumber) ? true : false );
 # endif
     }
     if (__isFloatLike(aNumber)) {
-	RETURN ( ((double)__intVal(self) >= __floatVal(aNumber)) ? true : false );
+        RETURN ( ((double)__intVal(self) >= __floatVal(aNumber)) ? true : false );
     }
-#endif
+#endif /* not __SCHTEAM__ */
 %}.
     ^ (self < aNumber) not
 
@@ -2852,23 +3092,23 @@
 
     if (__isSmallInteger(aNumber)) {
 # if TAG_INT == 1
-	/* tag bit does not change ordering */
-	if ((INT)(self) > (INT)(aNumber))
+        /* tag bit does not change ordering */
+        if ((INT)(self) > (INT)(aNumber))
 # else
-	if (__intVal(self) > __intVal(aNumber))
+        if (__intVal(self) > __intVal(aNumber))
 # endif
-	{
-	    RETURN ( self );
-	}
-	RETURN ( aNumber );
+        {
+            RETURN ( self );
+        }
+        RETURN ( aNumber );
     }
     if (__isFloatLike(aNumber)) {
-	if ( (double)__intVal(self) > __floatVal(aNumber) ) {
-	    RETURN ( self );
-	}
-	RETURN ( aNumber );
+        if ( (double)__intVal(self) > __floatVal(aNumber) ) {
+            RETURN ( self );
+        }
+        RETURN ( aNumber );
     }
-#endif
+#endif /* not __SCHTEAM__ */
 %}.
     "/ fallback for non-smallInteger argument
 
@@ -2884,23 +3124,23 @@
 
     if (__isSmallInteger(aNumber)) {
 # if TAG_INT == 1
-	/* tag bit does not change ordering */
-	if ((INT)(self) < (INT)(aNumber))
+        /* tag bit does not change ordering */
+        if ((INT)(self) < (INT)(aNumber))
 # else
-	if (__intVal(self) < __intVal(aNumber))
+        if (__intVal(self) < __intVal(aNumber))
 # endif
-	{
-	    RETURN ( self );
-	}
-	RETURN ( aNumber );
+        {
+            RETURN ( self );
+        }
+        RETURN ( aNumber );
     }
     if (__isFloatLike(aNumber)) {
-	if ( (double)__intVal(self) < __floatVal(aNumber) ) {
-	    RETURN ( self );
-	}
-	RETURN ( aNumber );
+        if ( (double)__intVal(self) < __floatVal(aNumber) ) {
+            RETURN ( self );
+        }
+        RETURN ( aNumber );
     }
-#endif
+#endif /* not __SCHTEAM__ */
 %}.
     "/ fallback for non-smallInteger argument
 
@@ -2914,26 +3154,26 @@
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
     if (aNumber.isNumber()) {
-	return context._RETURN( (self.eqvP( aNumber ) == STObject.True) ? STObject.False : STObject.True);
-	/* NOTREACHED */
+        return context._RETURN( (aNumber.eqv( self.longValue() )) ? STObject.False : STObject.True);
+        /* NOTREACHED */
     }
 #else
 
     if (aNumber == self) {
-	RETURN ( false );
+        RETURN ( false );
     }
     if (! __isNonNilObject(aNumber)) {
-	/* a smallint or nil */
-	RETURN ( true );
+        /* a smallint or nil */
+        RETURN ( true );
     }
 
     if (__qIsFloatLike(aNumber)) {
-	RETURN ( ((double)__intVal(self) != __floatVal(aNumber)) ? true : false );
+        RETURN ( ((double)__intVal(self) != __floatVal(aNumber)) ? true : false );
     }
     if (__qIsShortFloat(aNumber)) {
-	RETURN ( ((double)__intVal(self) != __shortFloatVal(aNumber)) ? true : false );
+        RETURN ( ((double)__intVal(self) != __shortFloatVal(aNumber)) ? true : false );
     }
-#endif
+#endif /* not __SCHTEAM__ */
 %}.
     ^ (self = aNumber) not
 ! !
@@ -2969,7 +3209,6 @@
 ! !
 
 
-
 !SmallInteger methodsFor:'iteration'!
 
 timesRepeat:aBlock
@@ -4255,14 +4494,15 @@
 
 setSign:aNumber
     "private: for protocol completeness with LargeIntegers.
-     Returns a smallInteger with my absValue and the sign of the argument"
-
+     Returns a smallInteger with my absValue and the sign of the argument.
+     The method's name may be misleading: the receiver is not changed,
+     but a new number is returned."
 
     |absVal|
 
     absVal := self abs.
     aNumber < 0 ifTrue:[
-	^ absVal negated
+        ^ absVal negated
     ].
     aNumber == 0 ifTrue:[^ 0].
     ^ absVal
@@ -4280,7 +4520,9 @@
 sign:aNumber
     <resource: #obsolete>
     "private: for protocol completeness with LargeIntegers.
-     Returns a smallInteger with my absValue and the sign of the argument"
+     Returns a smallInteger with my absValue and the sign of the argument.
+     The method's name may be misleading: the receiver is not changed,
+     but a new number is returned."
 
     ^ self setSign:aNumber
 
@@ -4935,31 +5177,35 @@
 #ifndef __SCHTEAM__
 
     // tricky, but very fast (google for it, to understand)
-# if __POINTER_SIZE__ == 4
-    unsigned int v = __intVal(self);
-
+    unsigned INT v = __intVal(self);
+
+# if __POINTER_SIZE__ == 8
+    v ^= v >> 32;
+# endif
     v ^= v >> 16;
     v ^= v >> 8;
     v ^= v >> 4;
     v &= 0xf;
     RETURN ( ( (0x6996 >> v) & 1 ) ? true : false );
-# endif
 #endif
 %}.
     ^ super parityOdd
 
     "
-	self assert:
-	 (((0 to:255) collect:[:i | i parityOdd ifTrue:1 ifFalse:0])
-	    asByteArray collect:[:c | c + $0 asciiValue]) asString
-	 =
-	    '0110100110010110100101100110100110010110011010010110100110010110100101100110100101101001100101100110100110010110100101100110100110010110011010010110100110010110011010011001011010010110011010010110100110010110100101100110100110010110011010010110100110010110'
-
-	self assert:(16r0FFFFFFF parityOdd = 16r0FFFFFFF bitCount odd).
-	self assert:(16r1FFFFFFF parityOdd = 16r1FFFFFFF bitCount odd).
-	self assert:(16r3FFFFFFF parityOdd = 16r3FFFFFFF bitCount odd).
-	self assert:(16r7FFFFFFF parityOdd = 16r7FFFFFFF bitCount odd).
-	self assert:(16rFFFFFFFF parityOdd = 16rFFFFFFFF bitCount odd).
+        self assert:
+         (((0 to:255) collect:[:i | i parityOdd ifTrue:1 ifFalse:0])
+            asByteArray collect:[:c | c + $0 asciiValue]) asString
+         =
+            '0110100110010110100101100110100110010110011010010110100110010110100101100110100101101001100101100110100110010110100101100110100110010110011010010110100110010110011010011001011010010110011010010110100110010110100101100110100110010110011010010110100110010110'
+
+        self assert:(16r0FFFFFFF parityOdd = 16r0FFFFFFF bitCount odd).
+        self assert:(16r1FFFFFFF parityOdd = 16r1FFFFFFF bitCount odd).
+        self assert:(16r3FFFFFFF parityOdd = 16r3FFFFFFF bitCount odd).
+        self assert:(16r7FFFFFFF parityOdd = 16r7FFFFFFF bitCount odd).
+        self assert:(16rFFFFFFFF parityOdd = 16rFFFFFFFF bitCount odd).
+        self assert:(16r3FFFFFFFFFFFFFFF parityOdd = 16r3FFFFFFFFFFFFFFF bitCount odd).
+        self assert:(16r7FFFFFFFFFFFFFFF parityOdd = 16r7FFFFFFFFFFFFFFF bitCount odd).
+        self assert:(16rFFFFFFFFFFFFFFFF parityOdd = 16rFFFFFFFFFFFFFFFF bitCount odd).
     "
 
     "Modified (comment): / 09-01-2012 / 19:55:37 / cg"