1 /*-------------------------------------------------------------------------
3 * pg_crc32c_sse42_choose.c
4 * Choose between Intel SSE 4.2 and software CRC-32C implementation.
6 * On first call, checks if the CPU we're running on supports Intel SSE
7 * 4.2. If it does, use the special SSE instructions for CRC-32C
8 * computation. Otherwise, fall back to the pure software implementation
11 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
12 * Portions Copyright (c) 1994, Regents of the University of California
16 * src/port/pg_crc32c_sse42_choose.c
18 *-------------------------------------------------------------------------
23 #ifdef HAVE__GET_CPUID
31 #include "port/pg_crc32c.h"
34 pg_crc32c_sse42_available(void)
36 unsigned int exx
[4] = {0, 0, 0, 0};
38 #if defined(HAVE__GET_CPUID)
39 __get_cpuid(1, &exx
[0], &exx
[1], &exx
[2], &exx
[3]);
40 #elif defined(HAVE__CPUID)
43 #error cpuid instruction not available
46 return (exx
[2] & (1 << 20)) != 0; /* SSE 4.2 */
50 * This gets called on the first call. It replaces the function pointer
51 * so that subsequent calls are routed directly to the chosen implementation.
54 pg_comp_crc32c_choose(pg_crc32c crc
, const void *data
, size_t len
)
56 if (pg_crc32c_sse42_available())
57 pg_comp_crc32c
= pg_comp_crc32c_sse42
;
59 pg_comp_crc32c
= pg_comp_crc32c_sb8
;
61 return pg_comp_crc32c(crc
, data
, len
);
64 pg_crc32c (*pg_comp_crc32c
) (pg_crc32c crc
, const void *data
, size_t len
) = pg_comp_crc32c_choose
;