1/*****************************************************************************
2
3Copyright (c) 2009, 2010 Facebook, Inc. All Rights Reserved.
4Copyright (c) 2011, 2015, Oracle and/or its affiliates. All Rights Reserved.
5Copyright (c) 2016, MariaDB Corporation.
6
7This program is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free Software
9Foundation; version 2 of the License.
10
11This program is distributed in the hope that it will be useful, but WITHOUT
12ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License along with
16this program; if not, write to the Free Software Foundation, Inc.,
1751 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
18
19*****************************************************************************/
20
21/***************************************************************//**
22@file ut/ut0crc32.cc
23CRC32 implementation from Facebook, based on the zlib implementation.
24
25Created Aug 8, 2011, Vasil Dimov, based on mysys/my_crc32.c and
26mysys/my_perf.c, contributed by Facebook under the following license.
27********************************************************************/
28
29/* Copyright (C) 2009-2010 Facebook, Inc. All Rights Reserved.
30
31 Dual licensed under BSD license and GPLv2.
32
33 Redistribution and use in source and binary forms, with or without
34 modification, are permitted provided that the following conditions are met:
35 1. Redistributions of source code must retain the above copyright notice,
36 this list of conditions and the following disclaimer.
37 2. Redistributions in binary form must reproduce the above copyright notice,
38 this list of conditions and the following disclaimer in the documentation
39 and/or other materials provided with the distribution.
40
41 THIS SOFTWARE IS PROVIDED BY FACEBOOK, INC. ``AS IS'' AND ANY EXPRESS OR
42 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
43 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
44 EVENT SHALL FACEBOOK, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
46 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
47 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
48 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
49 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
50 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51
52 This program is free software; you can redistribute it and/or modify it
53 under the terms of the GNU General Public License as published by the Free
54 Software Foundation; version 2 of the License.
55
56 This program is distributed in the hope that it will be useful, but WITHOUT
57 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
58 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
59 more details.
60
61 You should have received a copy of the GNU General Public License along with
62 this program; if not, write to the Free Software Foundation, Inc.,
63 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
64
65/* The below CRC32 implementation is based on the implementation included with
66 * zlib with modifications to process 8 bytes at a time and using SSE 4.2
67 * extensions when available. The polynomial constant has been changed to
68 * match the one used by SSE 4.2 and does not return the same value as the
69 * version used by zlib. The original zlib copyright notice follows. */
70
71/* crc32.c -- compute the CRC-32 of a buf stream
72 * Copyright (C) 1995-2005 Mark Adler
73 * For conditions of distribution and use, see copyright notice in zlib.h
74 *
75 * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
76 * CRC methods: exclusive-oring 32 bits of buf at a time, and pre-computing
77 * tables for updating the shift register in one step with three exclusive-ors
78 * instead of four steps with four exclusive-ors. This results in about a
79 * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
80 */
81
82// First include (the generated) my_config.h, to get correct platform defines.
83#include "my_config.h"
84#include <string.h>
85
86#include "univ.i"
87#include "ut0crc32.h"
88
89#ifdef _MSC_VER
90#include <intrin.h>
91#endif
92
93/** Swap the byte order of an 8 byte integer.
94@param[in] i 8-byte integer
95@return 8-byte integer */
96inline
97uint64_t
98ut_crc32_swap_byteorder(
99 uint64_t i)
100{
101 return(i << 56
102 | (i & 0x000000000000FF00ULL) << 40
103 | (i & 0x0000000000FF0000ULL) << 24
104 | (i & 0x00000000FF000000ULL) << 8
105 | (i & 0x000000FF00000000ULL) >> 8
106 | (i & 0x0000FF0000000000ULL) >> 24
107 | (i & 0x00FF000000000000ULL) >> 40
108 | i >> 56);
109}
110
111/* CRC32 hardware implementation. */
112
113#ifdef HAVE_CRC32_VPMSUM
114extern "C" {
115unsigned int crc32c_vpmsum(unsigned int crc, const unsigned char *p, unsigned long len);
116};
117UNIV_INLINE
118ib_uint32_t
119ut_crc32_power8(
120/*===========*/
121 const byte* buf, /*!< in: data over which to calculate CRC32 */
122 ulint len) /*!< in: data length */
123{
124 return crc32c_vpmsum(0, buf, len);
125}
126
127ut_crc32_func_t ut_crc32 = ut_crc32_power8;
128const char* ut_crc32_implementation = "Using POWER8 crc32 instructions";
129#else
130uint32_t ut_crc32_sw(const byte* buf, ulint len);
131ut_crc32_func_t ut_crc32 = ut_crc32_sw;
132const char* ut_crc32_implementation = "Using generic crc32 instructions";
133#endif
134
135#if (defined(__GNUC__) && defined(__x86_64__)) || defined(_MSC_VER)
136/********************************************************************//**
137Fetches CPU info */
138static
139void
140ut_cpuid(
141/*=====*/
142 uint32_t vend[3], /*!< out: CPU vendor */
143 uint32_t* model, /*!< out: CPU model */
144 uint32_t* family, /*!< out: CPU family */
145 uint32_t* stepping, /*!< out: CPU stepping */
146 uint32_t* features_ecx, /*!< out: CPU features ecx */
147 uint32_t* features_edx) /*!< out: CPU features edx */
148{
149 uint32_t sig;
150#ifdef _MSC_VER
151 int data[4];
152 __cpuid(data, 0);
153 /* ebx */
154 vend[0] = data[1];
155 /* edx */
156 vend[1] = data[3];
157 /* ecx */
158 vend[2] = data[2];
159
160 __cpuid(data, 1);
161 /* eax */
162 sig = data[0];
163 /* ecx */
164 *features_ecx = data[2];
165 /* edx */
166 *features_edx = data[3];
167#else
168 asm("cpuid" : "=b" (vend[0]), "=c" (vend[2]), "=d" (vend[1]) : "a" (0));
169 asm("cpuid" : "=a" (sig), "=c" (*features_ecx), "=d" (*features_edx)
170 : "a" (1)
171 : "ebx");
172#endif
173
174 *model = ((sig >> 4) & 0xF);
175 *family = ((sig >> 8) & 0xF);
176 *stepping = (sig & 0xF);
177
178 if (memcmp(vend, "GenuineIntel", 12) == 0
179 || (memcmp(vend, "AuthenticAMD", 12) == 0 && *family == 0xF)) {
180
181 *model += (((sig >> 16) & 0xF) << 4);
182 *family += ((sig >> 20) & 0xFF);
183 }
184}
185
186/** Calculate CRC32 over 8-bit data using a hardware/CPU instruction.
187@param[in,out] crc crc32 checksum so far when this function is called,
188when the function ends it will contain the new checksum
189@param[in,out] data data to be checksummed, the pointer will be advanced
190with 1 byte
191@param[in,out] len remaining bytes, it will be decremented with 1 */
192inline
193void
194ut_crc32_8_hw(
195 uint32_t* crc,
196 const byte** data,
197 ulint* len)
198{
199#ifdef _MSC_VER
200 *crc = _mm_crc32_u8(*crc, (*data)[0]);
201#else
202 asm("crc32b %1, %0"
203 /* output operands */
204 : "+r" (*crc)
205 /* input operands */
206 : "rm" ((*data)[0]));
207#endif
208
209 (*data)++;
210 (*len)--;
211}
212
213/** Calculate CRC32 over a 64-bit integer using a hardware/CPU instruction.
214@param[in] crc crc32 checksum so far
215@param[in] data data to be checksummed
216@return resulting checksum of crc + crc(data) */
217inline
218uint32_t
219ut_crc32_64_low_hw(
220 uint32_t crc,
221 uint64_t data)
222{
223 uint64_t crc_64bit = crc;
224#ifdef _MSC_VER
225#ifdef _M_X64
226 crc_64bit = _mm_crc32_u64(crc_64bit, data);
227#elif defined(_M_IX86)
228 crc = _mm_crc32_u32(crc, static_cast<uint32_t>(data));
229 crc_64bit = _mm_crc32_u32(crc, static_cast<uint32_t>(data >> 32));
230#else
231#error Not Supported processors type.
232#endif
233#else
234 asm("crc32q %1, %0"
235 /* output operands */
236 : "+r" (crc_64bit)
237 /* input operands */
238 : "rm" (data));
239#endif
240
241 return(static_cast<uint32_t>(crc_64bit));
242}
243
244/** Calculate CRC32 over 64-bit byte string using a hardware/CPU instruction.
245@param[in,out] crc crc32 checksum so far when this function is called,
246when the function ends it will contain the new checksum
247@param[in,out] data data to be checksummed, the pointer will be advanced
248with 8 bytes
249@param[in,out] len remaining bytes, it will be decremented with 8 */
250inline
251void
252ut_crc32_64_hw(
253 uint32_t* crc,
254 const byte** data,
255 ulint* len)
256{
257 uint64_t data_int = *reinterpret_cast<const uint64_t*>(*data);
258
259#ifdef WORDS_BIGENDIAN
260 /* Currently we only support x86_64 (little endian) CPUs. In case
261 some big endian CPU supports a CRC32 instruction, then maybe we will
262 need a byte order swap here. */
263#error Dont know how to handle big endian CPUs
264 /*
265 data_int = ut_crc32_swap_byteorder(data_int);
266 */
267#endif /* WORDS_BIGENDIAN */
268
269 *crc = ut_crc32_64_low_hw(*crc, data_int);
270
271 *data += 8;
272 *len -= 8;
273}
274
275/** Calculates CRC32 using hardware/CPU instructions.
276@param[in] buf data over which to calculate CRC32
277@param[in] len data length
278@return CRC-32C (polynomial 0x11EDC6F41) */
279uint32_t
280ut_crc32_hw(
281 const byte* buf,
282 ulint len)
283{
284 uint32_t crc = 0xFFFFFFFFU;
285
286 /* Calculate byte-by-byte up to an 8-byte aligned address. After
287 this consume the input 8-bytes at a time. */
288 while (len > 0 && (reinterpret_cast<uintptr_t>(buf) & 7) != 0) {
289 ut_crc32_8_hw(&crc, &buf, &len);
290 }
291
292 /* Perf testing
293 ./unittest/gunit/innodb/merge_innodb_tests-t --gtest_filter=ut0crc32.perf
294 on CPU "Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz"
295 with different N in "while (len >= N) {" shows:
296 N=16
297 2.867254 sec
298 2.866860 sec
299 2.867973 sec
300
301 N=32
302 2.715725 sec
303 2.713008 sec
304 2.712520 sec
305 (5.36% speedup over N=16)
306
307 N=64
308 2.634140 sec
309 2.636558 sec
310 2.636488 sec
311 (2.88% speedup over N=32)
312
313 N=128
314 2.599534 sec
315 2.599919 sec
316 2.598035 sec
317 (1.39% speedup over N=64)
318
319 N=256
320 2.576993 sec
321 2.576748 sec
322 2.575700 sec
323 (0.87% speedup over N=128)
324
325 N=512
326 2.693928 sec
327 2.691663 sec
328 2.692142 sec
329 (4.51% slowdown over N=256)
330 */
331 while (len >= 128) {
332 /* This call is repeated 16 times. 16 * 8 = 128. */
333 ut_crc32_64_hw(&crc, &buf, &len);
334 ut_crc32_64_hw(&crc, &buf, &len);
335 ut_crc32_64_hw(&crc, &buf, &len);
336 ut_crc32_64_hw(&crc, &buf, &len);
337 ut_crc32_64_hw(&crc, &buf, &len);
338 ut_crc32_64_hw(&crc, &buf, &len);
339 ut_crc32_64_hw(&crc, &buf, &len);
340 ut_crc32_64_hw(&crc, &buf, &len);
341 ut_crc32_64_hw(&crc, &buf, &len);
342 ut_crc32_64_hw(&crc, &buf, &len);
343 ut_crc32_64_hw(&crc, &buf, &len);
344 ut_crc32_64_hw(&crc, &buf, &len);
345 ut_crc32_64_hw(&crc, &buf, &len);
346 ut_crc32_64_hw(&crc, &buf, &len);
347 ut_crc32_64_hw(&crc, &buf, &len);
348 ut_crc32_64_hw(&crc, &buf, &len);
349 }
350
351 while (len >= 8) {
352 ut_crc32_64_hw(&crc, &buf, &len);
353 }
354
355 while (len > 0) {
356 ut_crc32_8_hw(&crc, &buf, &len);
357 }
358
359 return(~crc);
360}
361#endif /* defined(__GNUC__) && defined(__x86_64__) || (_WIN64) */
362
363/* CRC32 software implementation. */
364
365/* Precalculated table used to generate the CRC32 if the CPU does not
366have support for it */
367static uint32_t ut_crc32_slice8_table[8][256];
368static bool ut_crc32_slice8_table_initialized = false;
369
370/********************************************************************//**
371Initializes the table that is used to generate the CRC32 if the CPU does
372not have support for it. */
373static
374void
375ut_crc32_slice8_table_init()
376/*========================*/
377{
378 /* bit-reversed poly 0x1EDC6F41 (from SSE42 crc32 instruction) */
379 static const uint32_t poly = 0x82f63b78;
380 uint32_t n;
381 uint32_t k;
382 uint32_t c;
383
384 for (n = 0; n < 256; n++) {
385 c = n;
386 for (k = 0; k < 8; k++) {
387 c = (c & 1) ? (poly ^ (c >> 1)) : (c >> 1);
388 }
389 ut_crc32_slice8_table[0][n] = c;
390 }
391
392 for (n = 0; n < 256; n++) {
393 c = ut_crc32_slice8_table[0][n];
394 for (k = 1; k < 8; k++) {
395 c = ut_crc32_slice8_table[0][c & 0xFF] ^ (c >> 8);
396 ut_crc32_slice8_table[k][n] = c;
397 }
398 }
399
400 ut_crc32_slice8_table_initialized = true;
401}
402
403/** Calculate CRC32 over 8-bit data using a software implementation.
404@param[in,out] crc crc32 checksum so far when this function is called,
405when the function ends it will contain the new checksum
406@param[in,out] data data to be checksummed, the pointer will be advanced
407with 1 byte
408@param[in,out] len remaining bytes, it will be decremented with 1 */
409inline
410void
411ut_crc32_8_sw(
412 uint32_t* crc,
413 const byte** data,
414 ulint* len)
415{
416 const uint8_t i = (*crc ^ (*data)[0]) & 0xFF;
417
418 *crc = (*crc >> 8) ^ ut_crc32_slice8_table[0][i];
419
420 (*data)++;
421 (*len)--;
422}
423
424/** Calculate CRC32 over a 64-bit integer using a software implementation.
425@param[in] crc crc32 checksum so far
426@param[in] data data to be checksummed
427@return resulting checksum of crc + crc(data) */
428inline
429uint32_t
430ut_crc32_64_low_sw(
431 uint32_t crc,
432 uint64_t data)
433{
434 const uint64_t i = crc ^ data;
435
436 return(
437 ut_crc32_slice8_table[7][(i ) & 0xFF] ^
438 ut_crc32_slice8_table[6][(i >> 8) & 0xFF] ^
439 ut_crc32_slice8_table[5][(i >> 16) & 0xFF] ^
440 ut_crc32_slice8_table[4][(i >> 24) & 0xFF] ^
441 ut_crc32_slice8_table[3][(i >> 32) & 0xFF] ^
442 ut_crc32_slice8_table[2][(i >> 40) & 0xFF] ^
443 ut_crc32_slice8_table[1][(i >> 48) & 0xFF] ^
444 ut_crc32_slice8_table[0][(i >> 56)]
445 );
446}
447
448/** Calculate CRC32 over 64-bit byte string using a software implementation.
449@param[in,out] crc crc32 checksum so far when this function is called,
450when the function ends it will contain the new checksum
451@param[in,out] data data to be checksummed, the pointer will be advanced
452with 8 bytes
453@param[in,out] len remaining bytes, it will be decremented with 8 */
454inline
455void
456ut_crc32_64_sw(
457 uint32_t* crc,
458 const byte** data,
459 ulint* len)
460{
461 uint64_t data_int = *reinterpret_cast<const uint64_t*>(*data);
462
463#ifdef WORDS_BIGENDIAN
464 data_int = ut_crc32_swap_byteorder(data_int);
465#endif /* WORDS_BIGENDIAN */
466
467 *crc = ut_crc32_64_low_sw(*crc, data_int);
468
469 *data += 8;
470 *len -= 8;
471}
472
473/** Calculate CRC32 over 64-bit byte string using a software implementation.
474The byte string is converted to a 64-bit integer using big endian byte order.
475@param[in,out] crc crc32 checksum so far when this function is called,
476when the function ends it will contain the new checksum
477@param[in,out] data data to be checksummed, the pointer will be advanced
478with 8 bytes
479@param[in,out] len remaining bytes, it will be decremented with 8 */
480inline
481void
482ut_crc32_64_legacy_big_endian_sw(
483 uint32_t* crc,
484 const byte** data,
485 ulint* len)
486{
487 uint64_t data_int = *reinterpret_cast<const uint64_t*>(*data);
488
489#ifndef WORDS_BIGENDIAN
490 data_int = ut_crc32_swap_byteorder(data_int);
491#endif /* WORDS_BIGENDIAN */
492
493 *crc = ut_crc32_64_low_sw(*crc, data_int);
494
495 *data += 8;
496 *len -= 8;
497}
498
499/** Calculates CRC32 in software, without using CPU instructions.
500@param[in] buf data over which to calculate CRC32
501@param[in] len data length
502@return CRC-32C (polynomial 0x11EDC6F41) */
503uint32_t
504ut_crc32_sw(
505 const byte* buf,
506 ulint len)
507{
508 uint32_t crc = 0xFFFFFFFFU;
509
510 ut_a(ut_crc32_slice8_table_initialized);
511
512 /* Calculate byte-by-byte up to an 8-byte aligned address. After
513 this consume the input 8-bytes at a time. */
514 while (len > 0 && (reinterpret_cast<uintptr_t>(buf) & 7) != 0) {
515 ut_crc32_8_sw(&crc, &buf, &len);
516 }
517
518 while (len >= 128) {
519 /* This call is repeated 16 times. 16 * 8 = 128. */
520 ut_crc32_64_sw(&crc, &buf, &len);
521 ut_crc32_64_sw(&crc, &buf, &len);
522 ut_crc32_64_sw(&crc, &buf, &len);
523 ut_crc32_64_sw(&crc, &buf, &len);
524 ut_crc32_64_sw(&crc, &buf, &len);
525 ut_crc32_64_sw(&crc, &buf, &len);
526 ut_crc32_64_sw(&crc, &buf, &len);
527 ut_crc32_64_sw(&crc, &buf, &len);
528 ut_crc32_64_sw(&crc, &buf, &len);
529 ut_crc32_64_sw(&crc, &buf, &len);
530 ut_crc32_64_sw(&crc, &buf, &len);
531 ut_crc32_64_sw(&crc, &buf, &len);
532 ut_crc32_64_sw(&crc, &buf, &len);
533 ut_crc32_64_sw(&crc, &buf, &len);
534 ut_crc32_64_sw(&crc, &buf, &len);
535 ut_crc32_64_sw(&crc, &buf, &len);
536 }
537
538 while (len >= 8) {
539 ut_crc32_64_sw(&crc, &buf, &len);
540 }
541
542 while (len > 0) {
543 ut_crc32_8_sw(&crc, &buf, &len);
544 }
545
546 return(~crc);
547}
548
549/** Calculates CRC32 in software, without using CPU instructions.
550This function uses big endian byte ordering when converting byte sequence to
551integers.
552@param[in] buf data over which to calculate CRC32
553@param[in] len data length
554@return CRC-32C (polynomial 0x11EDC6F41) */
555uint32_t
556ut_crc32_legacy_big_endian(
557 const byte* buf,
558 ulint len)
559{
560 uint32_t crc = 0xFFFFFFFFU;
561
562 ut_a(ut_crc32_slice8_table_initialized);
563
564 /* Calculate byte-by-byte up to an 8-byte aligned address. After
565 this consume the input 8-bytes at a time. */
566 while (len > 0 && (reinterpret_cast<uintptr_t>(buf) & 7) != 0) {
567 ut_crc32_8_sw(&crc, &buf, &len);
568 }
569
570 while (len >= 128) {
571 /* This call is repeated 16 times. 16 * 8 = 128. */
572 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
573 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
574 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
575 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
576 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
577 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
578 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
579 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
580 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
581 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
582 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
583 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
584 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
585 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
586 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
587 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
588 }
589
590 while (len >= 8) {
591 ut_crc32_64_legacy_big_endian_sw(&crc, &buf, &len);
592 }
593
594 while (len > 0) {
595 ut_crc32_8_sw(&crc, &buf, &len);
596 }
597
598 return(~crc);
599}
600
601/********************************************************************//**
602Initializes the data structures used by ut_crc32*(). Does not do any
603allocations, would not hurt if called twice, but would be pointless. */
604void
605ut_crc32_init()
606/*===========*/
607{
608 ut_crc32_slice8_table_init();
609
610#if (defined(__GNUC__) && defined(__x86_64__)) || defined(_MSC_VER)
611 uint32_t vend[3];
612 uint32_t model;
613 uint32_t family;
614 uint32_t stepping;
615 uint32_t features_ecx;
616 uint32_t features_edx;
617
618 ut_cpuid(vend, &model, &family, &stepping,
619 &features_ecx, &features_edx);
620
621 /* Valgrind does not understand the CRC32 instructions:
622
623 vex amd64->IR: unhandled instruction bytes: 0xF2 0x48 0xF 0x38 0xF0 0xA
624 valgrind: Unrecognised instruction at address 0xad3db5.
625 Your program just tried to execute an instruction that Valgrind
626 did not recognise. There are two possible reasons for this.
627 1. Your program has a bug and erroneously jumped to a non-code
628 location. If you are running Memcheck and you just saw a
629 warning about a bad jump, it's probably your program's fault.
630 2. The instruction is legitimate but Valgrind doesn't handle it,
631 i.e. it's Valgrind's fault. If you think this is the case or
632 you are not sure, please let us know and we'll try to fix it.
633 Either way, Valgrind will now raise a SIGILL signal which will
634 probably kill your program.
635
636 */
637
638 if (features_ecx & 1 << 20) {
639 ut_crc32 = ut_crc32_hw;
640 ut_crc32_implementation = "Using SSE2 crc32 instructions";
641 }
642#endif
643}
644