*** empty log message ***
authorClaus Gittinger <cg@exept.de>
Sun, 17 Mar 2019 18:35:19 +0100
changeset 4876 0ad921aed93f
parent 4875 0ad684e3ac77
child 4877 70700688e4e4
*** empty log message ***
CRC32Stream.st
--- a/CRC32Stream.st	Sun Mar 17 18:18:27 2019 +0100
+++ b/CRC32Stream.st	Sun Mar 17 18:35:19 2019 +0100
@@ -31,32 +31,43 @@
 
 !CRC32Stream primitiveDefinitions!
 %{
+#if defined(__x86__) || defined(__x86_64__)
 
-/*
- * includes, defines, structure definitions
- * and typedefs come here.
- */
-#ifdef __LP64__
-inline uint64_t _mm_crc32_u64(uint64_t crc, uint64_t value) {
+# if defined(__GNUC__)
+#  pragma GCC push_options
+#  pragma GCC target ("arch=core-avx2")
+#  define HAS_CRC
+# endif
+
+# if defined(__clang__)
+#  define HAS_CRC
+# endif
+
+#ifdef HAS_CRC
+
+# ifdef __LP64__
+static inline uint64_t __crc32_u64(uint64_t crc, uint64_t value) {
   asm("crc32q %[value], %[crc]\n" : [crc] "+r" (crc) : [value] "rm" (value));
   return crc;
 }
-#endif
+# endif
 
-inline uint32_t _mm_crc32_u32(uint32_t crc, uint32_t value) {
+static inline uint32_t __crc32_u32(uint32_t crc, uint32_t value) {
   asm("crc32l %[value], %[crc]\n" : [crc] "+r" (crc) : [value] "rm" (value));
   return crc;
 }
 
-inline uint32_t _mm_crc32_u16(uint32_t crc, uint16_t value) {
+static inline uint32_t __crc32_u16(uint32_t crc, uint16_t value) {
   asm("crc32w %[value], %[crc]\n" : [crc] "+r" (crc) : [value] "rm" (value));
   return crc;
 }
 
-inline uint32_t _mm_crc32_u8(uint32_t crc, uint8_t value) {
+static inline uint32_t __crc32_u8(uint32_t crc, uint8_t value) {
   asm("crc32b %[value], %[crc]\n" : [crc] "+r" (crc) : [value] "rm" (value));
   return crc;
 }
+# endif // HAS_CRC
+#endif // x86 or x86_64
 %}
 ! !
 
@@ -85,37 +96,37 @@
     Standard CRC method as defined by ISO 3309 [ISO-3309] or ITU-T V.42 [ITU-T-V42].
     The default CRC polynomial employed is
 
-        x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
-        (or 16r04C11DB7)
+	x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
+	(or 16r04C11DB7)
 
-    You can also create an instace performing the Castagnoli CRC-32C 
+    You can also create an instace performing the Castagnoli CRC-32C
     (used in iSCSI & SCTP [RFC3720], G.hn payload, SSE4.2):
 
-        self newCrc32c
+	self newCrc32c
 
-        poly: 16r1edc6f41
-        = x32 + x28 + x27 + x26 + x25 + x23 + x22 + x20 + x19 + x18 + x14 + x13 + x11 + x10 + x9 + x8 + x6 + 1
+	poly: 16r1edc6f41
+	= x32 + x28 + x27 + x26 + x25 + x23 + x22 + x20 + x19 + x18 + x14 + x13 + x11 + x10 + x9 + x8 + x6 + 1
 
-    Notice that this CRC is also used with PNG images; 
+    Notice that this CRC is also used with PNG images;
     therefore, its performance directly affects png image processing (png write speed).
 
     throughput:
-        235 Mb/s on MacBook Pro (2.6Ghz I7)
-        157 Mb/s on a 2.5Ghz 64X2 Athlon 4800+ (64bit)
-        150 Mb/s on 2Ghz Duo
+	235 Mb/s on MacBook Pro (2.6Ghz I7)
+	157 Mb/s on a 2.5Ghz 64X2 Athlon 4800+ (64bit)
+	150 Mb/s on 2Ghz Duo
      new:
-        500 Mb/s for castagnoli on MacBook Pro (2.6Ghz I7)
+	500 Mb/s for castagnoli on MacBook Pro (2.6Ghz I7)
 
     [author:]
-        Stefan Vogel (stefan@zwerg)
+	Stefan Vogel (stefan@zwerg)
 
     [instance variables:]
 
     [class variables:]
 
     [see also:]
-        SHA1Stream
-        MD5Stream
+	SHA1Stream
+	MD5Stream
 
 "
 !
@@ -124,261 +135,111 @@
 "
 
   expect 60C1D0A0
-                                                                [exBegin]
+								[exBegin]
     self information:(CRC32Stream hashValueOf:'resume') hexPrintString
-                                                                [exEnd]
+								[exEnd]
 
   expect 16r60C1D0A0
-                                                                [exBegin]
+								[exBegin]
     self information:(CRC32Stream new
-                            nextPut:$r;
-                            nextPut:$e;
-                            nextPut:$s;
-                            nextPut:$u;
-                            nextPut:$m;
-                            nextPut:$e;
-                            hashValue) hexPrintString
-                                                                [exEnd]
+			    nextPut:$r;
+			    nextPut:$e;
+			    nextPut:$s;
+			    nextPut:$u;
+			    nextPut:$m;
+			    nextPut:$e;
+			    hashValue) hexPrintString
+								[exEnd]
 
   expect 16r70E46888:
-                                                                [exBegin]
+								[exBegin]
     self information:(CRC32Stream hashValueOf:#[1 2 3 4 5 6 7]) hexPrintString
-                                                                [exEnd]
+								[exEnd]
 
   expect 16r8CD04C73:
-                                                                [exBegin]
+								[exBegin]
     self information:((CRC32Stream hashValueOf:#[16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
-             16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
-             16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
-             16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF]) hexPrintString)
-                                                                [exEnd]
+	     16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
+	     16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF
+	     16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF 16rFF]) hexPrintString)
+								[exEnd]
 
   timing throughput:
-  230Mb/s (on MacBook Pro 2012 / 2.6Ghz I7) 
-                                                                [exBegin]
+  230Mb/s (on MacBook Pro 2012 / 2.6Ghz I7)
+								[exBegin]
     |hashStream n t|
 
     hashStream := CRC32Stream new.
     n := 2000000.
     t := Time millisecondsToRun:[
-            n timesRepeat:[
-                hashStream nextPutAll:'12345678901234567890123456789012345678901234567890'.
-            ].
-         ].
+	    n timesRepeat:[
+		hashStream nextPutAll:'12345678901234567890123456789012345678901234567890'.
+	    ].
+	 ].
     t := (t / 1000) asFloat.
     Transcript show:'crc32:'; showCR: hashStream hashValue hexPrintString.
     Transcript show:t; show:' seconds for '; show:(50*n/1024) asFloat; showCR:' Kb'.
     Transcript show:(n*50/1024 / t); showCR:' Kb/s'
-                                                                [exEnd]
+								[exEnd]
 
-  500Mb/s (on MacBook Pro 2012 / 2.6Ghz I7) 
-                                                                [exBegin]
+  500Mb/s (on MacBook Pro 2012 / 2.6Ghz I7)
+								[exBegin]
     |hashStream n t|
 
     hashStream := CRC32Stream newCastagnoli.
-    n := 4000000.
+    n := 2000000.
     t := Time millisecondsToRun:[
-            n timesRepeat:[
-                hashStream nextPutAll:'12345678901234567890123456789012345678901234567890'.
-            ].
-         ].
+	    n timesRepeat:[
+		hashStream nextPutAll:'12345678901234567890123456789012345678901234567890'.
+	    ].
+	 ].
     t := (t / 1000) asFloat.
     Transcript show:'crc32:'; showCR: hashStream hashValue hexPrintString.
     Transcript show:t; show:' seconds for '; show:(50*n/1024) asFloat; showCR:' Kb'.
     Transcript show:(n*50/1024 / t); showCR:' Kb/s'
-                                                                [exEnd]
+								[exEnd]
 
   test vectors from https://tools.ietf.org/html/rfc3720#page-217:
-  
+
   expect 0
-                                                                [exBegin]
+								[exBegin]
     self information:(CRC32Stream newCrc32c hashValueOf:'') hexPrintString
-                                                                [exEnd]
+								[exEnd]
   expect C1D04330
-                                                                [exBegin]
+								[exBegin]
     self information:(CRC32Stream newCrc32c hashValueOf:'a') hexPrintString
-                                                                [exEnd]
+								[exEnd]
   expect E3069283
-                                                                [exBegin]
+								[exBegin]
     self information:(CRC32Stream newCrc32c hashValueOf:'123456789') hexPrintString
-                                                                [exEnd]
+								[exEnd]
   expect 8A9136AA
-                                                                [exBegin]
+								[exBegin]
     self information:(CRC32Stream newCrc32c hashValueOf:(ByteArray new:32 withAll:0)) hexPrintString
-                                                                [exEnd]
+								[exEnd]
   expect 62a8ab43
-                                                                [exBegin]
+								[exBegin]
     self information:(CRC32Stream newCrc32c hashValueOf:(ByteArray new:32 withAll:16rFF)) hexPrintString
-                                                                [exEnd]
+								[exEnd]
   expect 46dd794e
-                                                                [exBegin]
+								[exBegin]
     self information:(CRC32Stream newCrc32c hashValueOf:(0 to:31) asByteArray) hexPrintString
-                                                                [exEnd]
+								[exEnd]
 
 "
 ! !
 
 !CRC32Stream class methodsFor:'instance creation'!
 
-castagnoli_nextPutBytes:count from:anObject startingAt:start
-    "add the hash of anObject to the computed hash so far.
-     This uses an x86 crc instruction,
-     and works only with the castagnoli polynom"
-
-%{
-#if defined(__x86__) || defined(__x86_64__)
-# if defined(__clang__) || defined(__GNUC__)
-#  pragma GCC push_options
-#  pragma GCC target ("arch=core-avx2")
-
-    if (__bothSmallInteger(count, start)) {
-        int len, offs;
-        int objSize;
-        unsigned char *extPtr;
-
-        len = __intVal(count);
-        offs = __intVal(start) - 1;
-
-        if (__isExternalBytesLike(anObject)) {
-            OBJ sz = __externalBytesSize(anObject);
-
-            extPtr = (unsigned char *)__externalBytesAddress(anObject);
-            if (__isSmallInteger(sz)) {
-                objSize = __intVal(sz);
-            } else {
-                objSize = 0; /* unknown */
-            }
-        } else {
-            int nInstVars, nInstBytes;
-            OBJ oClass = __Class(anObject);
-
-            switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
-                case BYTEARRAY:
-                case WORDARRAY:
-                case LONGARRAY:
-                case SWORDARRAY:
-                case SLONGARRAY:
-                case FLOATARRAY:
-                case DOUBLEARRAY:
-                    break;
-                default:
-                    goto bad;
-            }
-            nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
-            nInstBytes = __OBJS2BYTES__(nInstVars);
-            // nInstBytes is the number of bytes occupied by pointer instance variables
-            // subtract from size and add to byte-pointer
-            objSize = __qSize(anObject) - OHDR_SIZE - nInstBytes;
-            extPtr = (unsigned char *)__byteArrayVal(anObject)+nInstBytes;
-        }
-
-        if ((offs >= 0) && (len >= 0) && (objSize >= (len + offs))) {
-            unsigned int _crc;
-            unsigned int *_crcTable = __integerArrayVal( __INST(crcTable) );
-            unsigned char *cp = extPtr+offs;
-            unsigned int n = len;
-
-            if (__isSmallInteger(__INST(crc))) {
-                _crc = (unsigned int) (__intVal( __INST(crc) ));
-            } else {
-                _crc = __unsignedLongIntVal( __INST(crc) );
-            }
-
-#if 0
-# if __POINTER_SIZE__ == 8
-            if (((unsigned INT)cp & 7) == 0) {
-                // longword aligned
-                for ( ; n >= 8 ; n -= 8, cp += 8) {
-                    unsigned INT lWord;
-                    unsigned char _idx;
-
-                    lWord = ((unsigned INT *)cp)[0];
-                    _idx = (_crc ^ lWord) & 0xFF;
-                    _crc = _crcTable[_idx] ^ (_crc >> 8);
-                    _idx = (_crc ^ (lWord>>8)) & 0xFF;
-                    _crc = _crcTable[_idx] ^ (_crc >> 8);
-                    _idx = (_crc ^ (lWord>>16)) & 0xFF;
-                    _crc = _crcTable[_idx] ^ (_crc >> 8);
-                    _idx = (_crc ^ (lWord>>24)) & 0xFF;
-                    _crc = _crcTable[_idx] ^ (_crc >> 8);
-
-                    _idx = (_crc ^ (lWord>>32)) & 0xFF;
-                    _crc = _crcTable[_idx] ^ (_crc >> 8);
-                    _idx = (_crc ^ (lWord>>40)) & 0xFF;
-                    _crc = _crcTable[_idx] ^ (_crc >> 8);
-                    _idx = (_crc ^ (lWord>>48)) & 0xFF;
-                    _crc = _crcTable[_idx] ^ (_crc >> 8);
-                    _idx = (_crc ^ (lWord>>56)) & 0xFF;
-                    _crc = _crcTable[_idx] ^ (_crc >> 8);
-                }
-            }
-# endif // __POINTER_SIZE__ == 8          
-            if (((unsigned INT)cp & 3) == 0) {
-                // word aligned
-                for ( ; n >= 4 ; n -= 4, cp += 4) {
-                    unsigned int word;
-                    unsigned char _idx;
-
-                    word = ((unsigned int *)cp)[0];
-                    _idx = (_crc ^ word) & 0xFF;
-                    _crc = _crcTable[_idx] ^ (_crc >> 8);
-                    _idx = (_crc ^ (word>>8)) & 0xFF;
-                    _crc = _crcTable[_idx] ^ (_crc >> 8);
-                    _idx = (_crc ^ (word>>16)) & 0xFF;
-                    _crc = _crcTable[_idx] ^ (_crc >> 8);
-                    _idx = (_crc ^ (word>>24)) & 0xFF;
-                    _crc = _crcTable[_idx] ^ (_crc >> 8);
-                }
-            }
-#endif // 0
-            for ( ; n >= 4 ; n -= 4, cp += 4) {
-                unsigned char _idx;
-
-                _idx = (_crc ^ cp[0]) & 0xFF;
-                _crc = _crcTable[_idx] ^ (_crc >> 8);
-                _idx = (_crc ^ cp[1]) & 0xFF;
-                _crc = _crcTable[_idx] ^ (_crc >> 8);
-                _idx = (_crc ^ cp[2]) & 0xFF;
-                _crc = _crcTable[_idx] ^ (_crc >> 8);
-                _idx = (_crc ^ cp[3]) & 0xFF;
-                _crc = _crcTable[_idx] ^ (_crc >> 8);
-            }
-            while (n-- > 0) {
-                unsigned char ch = *cp++;
-                
-                _crc = __builtin_ia32_crc32qi(_crc, ch);
-            }
-
-            if ((__POINTER_SIZE__==8) || (_crc <= _MAX_INT)) {
-                __INST(crc) = __MKSMALLINT(_crc);
-            } else {
-                // this code fails with gcc 4.7.2:
-                // __INST(crc) = __MKUINT(_crc); __STORESELF(crc);
-                OBJ temp = __MKUINT(_crc); 
-                __INST(crc) = temp; __STORESELF(crc);
-            }
-
-            RETURN (count);
-        }
-    }
-bad: ;
-# endif
-#endif
-%}.
-    self primitiveFailed
-
-    "Created: / 17-03-2019 / 15:36:45 / Claus Gittinger"
-!
-
 generatorPolynomMSB:anInteger
     "notice, in literature, the generator polynom is usually specified as an MSB number"
-    
+
     ^ self generatorPolynom:(anInteger bitReversed32)
 
     "
        self assert:((self generatorPolynom:16r82F63B78)
-                                nextPut:'123456789';
-                                hashValue)    = 16rE3069283
+				nextPut:'123456789';
+				hashValue)    = 16rE3069283
     "
 
     "Created: / 16-03-2019 / 20:55:46 / Claus Gittinger"
@@ -386,7 +247,7 @@
 
 generatorPolynomMSB:anInteger initValue:initValueArg
     "notice, in literature, the generator polynom is usually specified as an MSB number"
-    
+
     ^ self generatorPolynom:(anInteger bitReversed32) initValue:initValueArg
 
     "Created: / 16-03-2019 / 21:11:31 / Claus Gittinger"
@@ -394,7 +255,7 @@
 
 generatorPolynomMSB:anInteger initValue:initValueArg xorOut:xorOut
     "notice, in literature, the generator polynom is usually specified as an MSB number"
-    
+
     ^ self generatorPolynom:(anInteger bitReversed32) initValue:initValueArg xorOut:xorOut
 
     "Created: / 16-03-2019 / 21:21:27 / Claus Gittinger"
@@ -412,11 +273,11 @@
 
 newCCITT
     "return an instance of the ITU-T CRC-32
-        x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1"
+	x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1"
 
     "/ 16r4C11DB7 bitReversed32 -> 16rEDB88320
-    ^ self generatorPolynomMSB:16r4C11DB7 
-           initValue:16rFFFFFFFF xorOut:16rFFFFFFFF
+    ^ self generatorPolynomMSB:16r4C11DB7
+	   initValue:16rFFFFFFFF xorOut:16rFFFFFFFF
 
     "Created: / 16-03-2019 / 23:29:39 / Claus Gittinger"
     "Modified: / 17-03-2019 / 14:07:36 / Claus Gittinger"
@@ -424,27 +285,27 @@
 
 newCastagnoli
     "return an instance of the Castagnoli CRC-32
-        x32 + x28 + x27 + x26 + x25 + x23 + x22 + x20 + x19 + x18 + x14 + x13 + x11 + x10 + x9 + x8 + x6 + 1
+	x32 + x28 + x27 + x26 + x25 + x23 + x22 + x20 + x19 + x18 + x14 + x13 + x11 + x10 + x9 + x8 + x6 + 1
      (used in iSCSI & SCTP, G.hn payload, SSE4.2)"
 
     |impl|
-    
+
     impl := (self canUseFastCRC) ifTrue:[CRC32Stream_Castagnoli] ifFalse:[self].
-    
+
     "/ 16r1edc6f41 bitReversed32 -> 16r82F63B78
-    ^ impl generatorPolynomMSB:16r1edc6f41 
-           initValue:16rFFFFFFFF xorOut:16rFFFFFFFF
+    ^ impl generatorPolynomMSB:16r1edc6f41
+	   initValue:16rFFFFFFFF xorOut:16rFFFFFFFF
 
     "
      Castagnoli crc:
        self assert:((self newCrc32c)
-                                nextPut:'123456789';
-                                hashValue) = 3808858755. '16rE3069283'
+				nextPut:'123456789';
+				hashValue) = 3808858755. '16rE3069283'
 
      default crc:
        self assert:((self new)
-                                nextPut:'123456789';
-                                hashValue) = 3421780262. '16rCBF43926'
+				nextPut:'123456789';
+				hashValue) = 3421780262. '16rCBF43926'
     "
 
     "Created: / 17-03-2019 / 14:33:54 / Claus Gittinger"
@@ -459,13 +320,13 @@
     "
      Castagnoli crc:
        self assert:((self newCrc32c)
-                                nextPut:'123456789';
-                                hashValue) = 3808858755. '16rE3069283'
+				nextPut:'123456789';
+				hashValue) = 3808858755. '16rE3069283'
 
      default crc:
        self assert:((self new)
-                                nextPut:'123456789';
-                                hashValue) = 3421780262. '16rCBF43926'
+				nextPut:'123456789';
+				hashValue) = 3421780262. '16rCBF43926'
     "
 
     "Modified (comment): / 17-05-2012 / 12:48:53 / cg"
@@ -476,11 +337,13 @@
 
 canUseFastCRC
 %{ /* NOCONTEXT */
-#if defined(__x86__) || defined(__x86_64__)
-# if defined(__clang__) || defined(__GNUC__)
+#if defined(HAS_CRC)
+# if defined(__x86__) || defined(__x86_64__)
+#  if defined(__clang__) || defined(__GNUC__)
     extern unsigned char __cpu_hasSSE4_2;
-    
+
     RETURN (__cpu_hasSSE4_2 ? true : false);
+#  endif
 # endif
 #endif
 %}.
@@ -500,8 +363,8 @@
      set start and xorOut to 16rFFFFFFFF.
      Note: you have to set the bit-reversed value, so the LSB must be first"
 
-    self generatorPolynom:anLSBInteger 
-         initValue:16rFFFFFFFF xorOut:16rFFFFFFFF.
+    self generatorPolynom:anLSBInteger
+	 initValue:16rFFFFFFFF xorOut:16rFFFFFFFF.
 
     "Modified: / 16-03-2019 / 21:23:25 / Claus Gittinger"
     "Modified (format): / 17-03-2019 / 14:02:38 / Claus Gittinger"
@@ -512,8 +375,8 @@
      set start to initValueArg and xorOut to 16rFFFFFFFF.
      Note: you have to set the bit-reversed value, so the LSB must be first"
 
-    self generatorPolynom:anLSBInteger 
-         initValue:initValueArg xorOut:16rFFFFFFFF
+    self generatorPolynom:anLSBInteger
+	 initValue:initValueArg xorOut:16rFFFFFFFF
 
     "Created: / 16-03-2019 / 21:06:16 / Claus Gittinger"
     "Modified (format): / 17-03-2019 / 14:02:31 / Claus Gittinger"
@@ -526,7 +389,7 @@
     redefined to use the CPU's CRC instruction
 
     [author:]
-        Claus Gittinger
+	Claus Gittinger
 "
 ! !
 
@@ -538,142 +401,117 @@
      and works only for the castagnoli polynom"
 
 %{  /* NOCONTEXT */
-#if defined(__x86__) || defined(__x86_64__)
-# if defined(__clang__) || defined(__GNUC__)
-
-    int len, offs;
-
-    // fetch here, but catch non-SmallInt error later
-    len = __intVal(count);
-    offs = __intVal(start) - 1;
+#if defined(HAS_CRC)
 
     if (__bothSmallInteger(count, start)) {
-        int objSize;
-        unsigned char *extPtr;
+	int len, offs;
+	int objSize;
+	unsigned char *extPtr;
 
-        if (__isExternalBytesLike(anObject)) {
-            OBJ sz = __externalBytesSize(anObject);
+	len = __intVal(count);
+	offs = __intVal(start) - 1;
+
+	if (__isExternalBytesLike(anObject)) {
+	    OBJ sz = __externalBytesSize(anObject);
 
-            extPtr = (unsigned char *)__externalBytesAddress(anObject);
-            if (__isSmallInteger(sz)) {
-                objSize = __intVal(sz);
-            } else {
-                objSize = 0; /* unknown */
-            }
-        } else {
-            int nInstVars, nInstBytes;
-            OBJ oClass = __Class(anObject);
+	    extPtr = (unsigned char *)__externalBytesAddress(anObject);
+	    if (__isSmallInteger(sz)) {
+		objSize = __intVal(sz);
+	    } else {
+		objSize = 0; /* unknown */
+	    }
+	} else {
+	    int nInstVars, nInstBytes;
+	    OBJ oClass = __Class(anObject);
 
-            switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
-                case BYTEARRAY:
-                case WORDARRAY:
-                case LONGARRAY:
-                case SWORDARRAY:
-                case SLONGARRAY:
-                case FLOATARRAY:
-                case DOUBLEARRAY:
-                    break;
-                default:
-                    goto bad;
-            }
-            nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
-            nInstBytes = __OBJS2BYTES__(nInstVars);
-            // nInstBytes is the number of bytes occupied by pointer instance variables
-            // subtract from size and add to byte-pointer
-            objSize = __qSize(anObject) - OHDR_SIZE - nInstBytes;
-            extPtr = (unsigned char *)__byteArrayVal(anObject)+nInstBytes;
-        }
+	    switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
+		case BYTEARRAY:
+		case WORDARRAY:
+		case LONGARRAY:
+		case SWORDARRAY:
+		case SLONGARRAY:
+		case FLOATARRAY:
+		case DOUBLEARRAY:
+		    break;
+		default:
+		    goto bad;
+	    }
+	    nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
+	    nInstBytes = __OBJS2BYTES__(nInstVars);
+	    // nInstBytes is the number of bytes occupied by pointer instance variables
+	    // subtract from size and add to byte-pointer
+	    objSize = __qSize(anObject) - OHDR_SIZE - nInstBytes;
+	    extPtr = (unsigned char *)__byteArrayVal(anObject)+nInstBytes;
+	}
 
-        if ((offs >= 0) && (len >= 0) && (objSize >= (len + offs))) {
-            unsigned int _crc;
-            unsigned int *_crcTable = __integerArrayVal( __INST(crcTable) );
-            unsigned char *cp = extPtr+offs;
-            unsigned int n = len;
-            OBJ crcInst = __INST(crc);
-            
-            // fetch here, but catch non-SmallInt error later
-            _crc = (unsigned int) (__intVal( crcInst ));
-            if (! __isSmallInteger(crcInst)) {
-                _crc = __unsignedLongIntVal(crcInst);
-            }
+	if ((offs >= 0) && (len >= 0) && (objSize >= (len + offs))) {
+	    unsigned int _crc;
+	    unsigned int *_crcTable = __integerArrayVal( __INST(crcTable) );
+	    unsigned char *cp = extPtr+offs;
+	    unsigned int n = len;
+
+	    if (__isSmallInteger(__INST(crc))) {
+		_crc = (unsigned int) (__intVal( __INST(crc) ));
+	    } else {
+		_crc = __unsignedLongIntVal( __INST(crc) );
+	    }
 
 # if __POINTER_SIZE__ == 8
-            if (((unsigned INT)cp & 7) == 0) {
-                // longword aligned
-                for ( ; n >= 32 ; n -= 32, cp += 32) {
-                    unsigned INT w0, w1, w2, w3;
-                    
-                    w0 = ((unsigned INT *)cp)[0];
-                    w1 = ((unsigned INT *)cp)[1];
-                    w2 = ((unsigned INT *)cp)[2];
-                    w3 = ((unsigned INT *)cp)[3];
-                    _crc = _mm_crc32_u64(_crc, w0);
-                    _crc = _mm_crc32_u64(_crc, w1);
-                    _crc = _mm_crc32_u64(_crc, w2);
-                    _crc = _mm_crc32_u64(_crc, w3);
-                }
-                if (n >= 16) {
-                    _crc = _mm_crc32_u64(_crc, ((unsigned INT *)cp)[0]);
-                    _crc = _mm_crc32_u64(_crc, ((unsigned INT *)cp)[1]);
-                    n -= 16, cp += 16;
-                }
-                if (n >= 8) {
-                    _crc = _mm_crc32_u64(_crc, ((unsigned INT *)cp)[0]);
-                    n -= 8, cp += 8;
-                }
-                if (n >= 4) {
-                    _crc = _mm_crc32_u32(_crc, ((unsigned int *)cp)[0]);
-                    n -= 4, cp += 4;
-                }
-                if (n >= 2) {
-                    _crc = _mm_crc32_u16(_crc, ((unsigned short *)cp)[0]);
-                    n -= 2, cp += 2;
-                }
-                if (n >= 1) {
-                    _crc = _mm_crc32_u8(_crc, (cp)[0]);
-                }
-                __INST(crc) = __MKSMALLINT(_crc);
-                RETURN (count);
-            }
-# endif // __POINTER_SIZE__ == 8          
-            if (((unsigned INT)cp & 3) == 0) {
-                // word aligned
-                for ( ; n >= 4 ; n -= 4, cp += 4) {
-                    _crc = _mm_crc32_u32(_crc, ((unsigned int *)cp)[0]);
-                }
-            }
-            for ( ; n >= 4 ; n -= 4, cp += 4) {
-                _crc = _mm_crc32_u8(_crc, cp[0]);
-                _crc = _mm_crc32_u8(_crc, cp[1]);
-                _crc = _mm_crc32_u8(_crc, cp[2]);
-                _crc = _mm_crc32_u8(_crc, cp[3]);
-            }
-            while (n-- > 0) {
-                unsigned char ch = *cp++;
+	    if (((unsigned INT)cp & 7) == 0) {
+		// longword aligned
+		for ( ; n >= 32 ; n -= 32, cp += 32) {
+		    unsigned INT w0 = ((unsigned INT *)cp)[0];
+		    unsigned INT w1, w2, w3;
 
-                _crc = _mm_crc32_u8(_crc, ch);
-            }
-done:
-            if ((__POINTER_SIZE__==8) || (_crc <= _MAX_INT)) {
-                __INST(crc) = __MKSMALLINT(_crc);
-            } else {
-                // this code fails with gcc 4.7.2:
-                // __INST(crc) = __MKUINT(_crc); __STORESELF(crc);
-                OBJ temp = __MKUINT(_crc); 
-                __INST(crc) = temp; __STORESELF(crc);
-            }
+		    _crc = __crc32_u64(_crc, w0);
+		    w1 = ((unsigned INT *)cp)[1];
+		    _crc = __crc32_u64(_crc, w1);
+		    w2 = ((unsigned INT *)cp)[2];
+		    _crc = __crc32_u64(_crc, w2);
+		    w3 = ((unsigned INT *)cp)[3];
+		    _crc = __crc32_u64(_crc, w3);
+		}
+		for ( ; n >= 8 ; n -= 8, cp += 8) {
+		    _crc = __crc32_u64(_crc, ((unsigned INT *)cp)[0]);
+		}
+	    }
+# endif // __POINTER_SIZE__ == 8
+	    if (((unsigned INT)cp & 3) == 0) {
+		// word aligned
+		for ( ; n >= 4 ; n -= 4, cp += 4) {
+		    _crc = __crc32_u32(_crc, ((unsigned int *)cp)[0]);
+		}
+	    }
+	    for ( ; n >= 4 ; n -= 4, cp += 4) {
+		_crc = __crc32_u8(_crc, cp[0]);
+		_crc = __crc32_u8(_crc, cp[1]);
+		_crc = __crc32_u8(_crc, cp[2]);
+		_crc = __crc32_u8(_crc, cp[3]);
+	    }
+	    while (n-- > 0) {
+		unsigned char ch = *cp++;
 
-            RETURN (count);
-        }
+		_crc = __crc32_u8(_crc, ch);
+	    }
+
+	    if ((__POINTER_SIZE__==8) || (_crc <= _MAX_INT)) {
+		__INST(crc) = __MKSMALLINT(_crc);
+	    } else {
+		// this code fails with gcc 4.7.2:
+		// __INST(crc) = __MKUINT(_crc); __STORESELF(crc);
+		OBJ temp = __MKUINT(_crc);
+		__INST(crc) = temp; __STORESELF(crc);
+	    }
+
+	    RETURN (count);
+	}
     }
 bad: ;
-# endif
 #endif
 %}.
     self primitiveFailed
 
     "Created: / 17-03-2019 / 16:44:27 / Claus Gittinger"
-    "Modified: / 17-03-2019 / 18:09:03 / Claus Gittinger"
 ! !
 
 !CRC32Stream class methodsFor:'documentation'!
@@ -685,4 +523,3 @@
 version_CVS
     ^ '$Header$'
 ! !
-