#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "perlmulticore.h" /* windows perl pisses me off. 26 years since c99, and still we have broken headers */ /* this has been copied from libecb */ #if defined (_WIN32) && !defined (__MINGW32__) typedef signed short uint16_t; typedef signed int int32_t; typedef unsigned int uint32_t; #if __GNUC__ typedef unsigned long long uint64_t; #else /* _MSC_VER || __BORLANDC__ */ typedef unsigned __int64 uint64_t; #endif typedef unsigned long long uint64_t; #ifdef _WIN64 typedef uint64_t uintptr_t; typedef int64_t intptr_t; #else typedef uint32_t uintptr_t; typedef int32_t intptr_t; #endif #else #include #endif // portable impl #include "crc32csb8.c" static uint32_t (*crc32c) (uint32_t crc, const void *data, size_t length) = crc32cSlicingBy8; // optimized sse4.2 impl #if __GNUC__ >= 8 && (__i386__ || __x86_64__) && __SSE4_2__ /* for __builtin__crc32 */ #include #include "crc32intelc.c" static const char * detect (void) { unsigned int eax, ebx, ecx = 0, edx; __get_cpuid (1, &eax, &ebx, &ecx, &edx); if (ecx & bit_SSE4_2) { crc32c = crc32cIntelC; return "IntelCSSE42"; } return "SlicingBy8"; } #else static const char * detect (void) { return "SlicingBy8"; } #endif MODULE = String::CRC32C PACKAGE = String::CRC32C BOOT: perlmulticore_support (); sv_setpv (get_sv ("String::CRC32C::IMPL", GV_ADD), detect ()); PROTOTYPES: ENABLE U32 crc32c (SV *data, U32 initvalue = 0) CODE: { STRLEN len; const char *ptr = SvPVbyte (data, len); if (len > 65536) perlinterp_release (); RETVAL = ~crc32c (~initvalue, ptr, len); if (len > 65536) perlinterp_acquire (); } OUTPUT: RETVAL