1 /*
2 * Use SSE4.2 to calculate crc32c.
3 *
4 * Copyright 2015 Kubo Takehiro <kubo@jiubao.org>
5 *
6 * Redistribution and use in source and binary forms, with or without modification, are
7 * permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice, this list of
10 * conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
13 * of conditions and the following disclaimer in the documentation and/or other materials
14 * provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * The views and conclusions contained in the software and documentation are those of the
27 * authors and should not be interpreted as representing official policies, either expressed
28 * or implied, of the authors.
29 */
30 #include <stdlib.h>
31 #include "config.h"
32 #include "crc32.h"
33 #include <nmmintrin.h>
34
35 uint32_t
calculate_crc32c_sse4_2(uint32_t crc32c,const unsigned char * buffer,unsigned int length)36 calculate_crc32c_sse4_2(uint32_t crc32c,
37 const unsigned char *buffer,
38 unsigned int length)
39 {
40 size_t quotient;
41
42 #if defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)
43 quotient = length / 8;
44 while (quotient--) {
45 crc32c = _mm_crc32_u64(crc32c, *(uint64_t*)buffer);
46 buffer += 8;
47 }
48 if (length & 4) {
49 crc32c = _mm_crc32_u32(crc32c, *(uint32_t*)buffer);
50 buffer += 4;
51 }
52 #else
53 quotient = length / 4;
54 while (quotient--) {
55 crc32c = _mm_crc32_u32(crc32c, *(uint32_t*)buffer);
56 buffer += 4;
57 }
58 #endif
59 if (length & 2) {
60 crc32c = _mm_crc32_u16(crc32c, *(uint16_t*)buffer);
61 buffer += 2;
62 }
63 if (length & 1) {
64 crc32c = _mm_crc32_u8(crc32c, *(uint8_t*)buffer);
65 }
66 return crc32c;
67 }
68