X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/b0d623f7f2ae71ed96e60569f61f9a9a27016e80..440d4c6cfad24426bfddca7518f16c17f4e443f7:/libkern/zlib/adler32.c diff --git a/libkern/zlib/adler32.c b/libkern/zlib/adler32.c index c94fde187..00214cd2e 100644 --- a/libkern/zlib/adler32.c +++ b/libkern/zlib/adler32.c @@ -32,6 +32,7 @@ /* @(#) $Id$ */ + #define ZLIB_INTERNAL #if KERNEL #include @@ -39,6 +40,11 @@ #include "zlib.h" #endif /* KERNEL */ +#if defined __x86_64__ || defined __i386__ || defined _ARM_ARCH_6 +#include // For uintptr_t. + extern uLong adler32_vec(uLong adler, uLong sum2, const Bytef *buf, uInt len); +#endif + #define BASE 65521UL /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ @@ -124,6 +130,23 @@ uLong ZEXPORT adler32(adler, buf, len) return adler | (sum2 << 16); } +#if defined __x86_64__ || defined __i386__ || defined _ARM_ARCH_6 + + if (len>=32000) { /* use vector code only if len is sufficiently large to compensate registers save/restore */ + /* align buf to 16-byte boundary */ + while (((uintptr_t)buf)&15) { /* not on a 16-byte boundary */ + len--; + adler += *buf++; + sum2 += adler; + if (adler >= BASE) adler -= BASE; + MOD4(sum2); /* only added so many BASE's */ + } + + return adler32_vec(adler, sum2, buf, len); // x86_64 or i386 (up to SSE3) or armv6 or up + } + +#endif // defined __x86_64__ || defined __i386__ || defined _ARM_ARCH_6 + /* do length NMAX blocks -- requires just one modulo operation */ while (len >= NMAX) { len -= NMAX;