From Code to Community: Sponsoring The Perl and Raku Conference 2025 Learn more

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
// 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 <cpuid.h>
#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:
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);
RETVAL = ~crc32c (~initvalue, ptr, len);
}
OUTPUT: RETVAL