# HG changeset patch # User Claus Gittinger # Date 1553374464 -3600 # Node ID 98825b2502d853153e6f48333d00fa703b661ad5 # Parent 0e400da677276b0ad45a30fb33d71f67c0e81575 fix for borland diff -r 0e400da67727 -r 98825b2502d8 CRC32Stream.st --- a/CRC32Stream.st Sat Mar 23 21:49:56 2019 +0100 +++ b/CRC32Stream.st Sat Mar 23 21:54:24 2019 +0100 @@ -43,35 +43,39 @@ # ifdef __LP64__ # define uint64_t __uint64__ # endif - typedef unsigned int uint32_t; - typedef unsigned short uint16_t; - typedef unsigned char uint8_t; + // typedef unsigned int uint32_t; + // typedef unsigned short uint16_t; + // typedef unsigned char uint8_t; # endif -#ifdef HAS_CRC +# ifdef HAS_CRC -# if __POINTER_SIZE__ == 8 +# if __POINTER_SIZE__ == 8 static inline __uint64__ __crc32_u64(__uint64__ crc, __uint64__ value) { asm("crc32q %[value], %[crc]\n" : [crc] "+r" (crc) : [value] "rm" (value)); return crc; } -# endif +# endif -static inline uint32_t __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; } -static inline uint32_t __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; } -static inline uint32_t __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 %} @@ -141,55 +145,55 @@ " 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] + [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/1024) asFloat; showCR:' Mb'. Transcript show:(n*50/1024/1024 / t); showCR:' Mb/s' - [exEnd] + [exEnd] 500Mb/s (on MacBook Pro 2012 / 2.6Ghz I7) - [exBegin] + [exBegin] |hashStream s n t l| hashStream := CRC32Stream newCastagnoli. @@ -197,17 +201,17 @@ s := '12345678901234567890123456789012345678901234567890'. l := s size. 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:(l*n/1024/1024) asFloat; showCR:' Mb'. Transcript show:(n*l/1024/1024 / t); showCR:' Mb/s' - [exEnd] + [exEnd] the real speed is shown with longer inputs... - [exBegin] + [exBegin] |hashStream n t l s| hashStream := CRC32Stream newCastagnoli. @@ -215,42 +219,42 @@ s := '1234567890' ,* 10000. l := s size. t := Time millisecondsToRun:[ - n timesRepeat:[ - hashStream nextPutAll:s - ]. - ]. + n timesRepeat:[ + hashStream nextPutAll:s + ]. + ]. t := (t / 1000) asFloat. Transcript show:'crc32:'; showCR: hashStream hashValue hexPrintString. Transcript show:t; show:' seconds for '; show:(l*n/1024/1024) asFloat; showCR:' Mb'. Transcript show:(n*l/1024/1024 / t); showCR:' Mb/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] " ! ! @@ -427,7 +431,6 @@ and works only for the castagnoli polynom" %{ /* NOCONTEXT */ -#define HAS_CRC #if defined(HAS_CRC) int len, offs; @@ -437,109 +440,109 @@ offs = __intVal(start) - 1; if (__bothSmallInteger(count, start)) { - int objSize; - unsigned char *extPtr; + int objSize; + unsigned char *extPtr; - // the most common first - if (__isStringLike(anObject)) { - objSize = __stringSize(anObject); - extPtr = (unsigned char *)__stringVal(anObject); - } else if (__isByteArray(anObject)) { - objSize = __byteArraySize(anObject); - extPtr = (unsigned char *)__byteArrayVal(anObject); - } else if (__isExternalBytesLike(anObject)) { - OBJ sz = __externalBytesSize(anObject); + // the most common first + if (__isStringLike(anObject)) { + objSize = __stringSize(anObject); + extPtr = (unsigned char *)__stringVal(anObject); + } else if (__isByteArray(anObject)) { + objSize = __byteArraySize(anObject); + extPtr = (unsigned char *)__byteArrayVal(anObject); + } else 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; + 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; - _crc = (unsigned int) (__intVal( __INST(crc) )); - if (!__isSmallInteger(__INST(crc))) { - _crc = __unsignedLongIntVal( __INST(crc) ); - } + _crc = (unsigned int) (__intVal( __INST(crc) )); + if (!__isSmallInteger(__INST(crc))) { + _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 = ((unsigned INT *)cp)[0]; - unsigned INT w1, w2, w3; + 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 = __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]); - } - } + _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++; + 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++; - _crc = __crc32_u8(_crc, ch); - } + _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); - } + 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); - } + RETURN (count); + } } bad: ; #endif @@ -559,4 +562,3 @@ version_CVS ^ '$Header$' ! ! -