1 /*-------------------------------------------------------------------------
4 * Choose which CRC-32C implementation to use, at runtime.
6 * Try to the special CRC instructions introduced in Intel SSE 4.2,
7 * if available on the platform we're running on, but fall back to the
8 * slicing-by-8 implementation otherwise.
10 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
11 * Portions Copyright (c) 1994, Regents of the University of California
15 * src/port/pg_crc32c_choose.c
17 *-------------------------------------------------------------------------
22 #ifdef HAVE__GET_CPUID
30 #include "port/pg_crc32c.h"
33 pg_crc32c_sse42_available(void)
35 unsigned int exx[4] = {0, 0, 0, 0};
37 #if defined(HAVE__GET_CPUID)
38 __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
39 #elif defined(HAVE__CPUID)
42 #error cpuid instruction not available
45 return (exx[2] & (1 << 20)) != 0; /* SSE 4.2 */
49 * This gets called on the first call. It replaces the function pointer
50 * so that subsequent calls are routed directly to the chosen implementation.
53 pg_comp_crc32c_choose(pg_crc32c crc, const void *data, size_t len)
55 if (pg_crc32c_sse42_available())
56 pg_comp_crc32c = pg_comp_crc32c_sse42;
58 pg_comp_crc32c = pg_comp_crc32c_sb8;
60 return pg_comp_crc32c(crc, data, len);
63 pg_crc32c (*pg_comp_crc32c) (pg_crc32c crc, const void *data, size_t len) = pg_comp_crc32c_choose;