1/******************************************************
2Copyright (c) 2017 Percona LLC and/or its affiliates.
3
4Zlib compatible CRC-32 implementation.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; version 2 of the License.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18
19*******************************************************/
20#include "my_config.h"
21#include "crc_glue.h"
22#include "crc-intel-pclmul.h"
23#include <stdint.h>
24#include <string.h>
25#include <zlib.h>
26
27#if defined(__GNUC__) && defined(__x86_64__)
28static int pclmul_enabled = 0;
29#endif
30
31#if defined(__GNUC__) && defined(__x86_64__)
32static
33uint32_t
34cpuid(uint32_t* ecx, uint32_t* edx)
35{
36 uint32_t level;
37
38 asm("cpuid" : "=a" (level) : "a" (0) : "ebx", "ecx", "edx");
39
40 if (level < 1) {
41 return level;
42 }
43
44 asm("cpuid" : "=c" (*ecx), "=d" (*edx)
45 : "a" (1)
46 : "ebx");
47
48 return level;
49}
50#endif
51
52void crc_init() {
53#if defined(__GNUC__) && defined(__x86_64__)
54 uint32_t ecx, edx;
55
56 if (cpuid(&ecx, &edx) > 0) {
57 pclmul_enabled = ((ecx >> 19) & 1) && ((ecx >> 1) & 1);
58 }
59#endif
60}
61
62unsigned long crc32_iso3309(unsigned long crc, const unsigned char *buf, unsigned int len)
63{
64#if __GNUC__ >= 4 && defined(__x86_64__) && defined(HAVE_CLMUL_INSTRUCTION)
65 if (pclmul_enabled) {
66 uint32_t crc_accum = crc ^ 0xffffffffL;
67 crc32_intel_pclmul(&crc_accum, buf, len);
68 return crc_accum ^ 0xffffffffL;
69 }
70#endif
71 return crc32(crc, buf, len);
72}
73