github.com/grailbio/base@v0.0.11/compress/libdeflate/crc32_pclmul_template.h (about) 1 // NOLINT(build/header_guard) 2 /* 3 * x86/crc32_pclmul_template.h 4 * 5 * Copyright 2016 Eric Biggers 6 * 7 * Permission is hereby granted, free of charge, to any person 8 * obtaining a copy of this software and associated documentation 9 * files (the "Software"), to deal in the Software without 10 * restriction, including without limitation the rights to use, 11 * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following 14 * conditions: 15 * 16 * The above copyright notice and this permission notice shall be 17 * included in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 * OTHER DEALINGS IN THE SOFTWARE. 27 */ 28 29 #include <wmmintrin.h> 30 31 /* 32 * CRC-32 folding with PCLMULQDQ. 33 * 34 * The basic idea is to repeatedly "fold" each 512 bits into the next 512 bits, 35 * producing an abbreviated message which is congruent the original message 36 * modulo the generator polynomial G(x). 37 * 38 * Folding each 512 bits is implemented as eight 64-bit folds, each of which 39 * uses one carryless multiplication instruction. It's expected that CPUs may 40 * be able to execute some of these multiplications in parallel. 41 * 42 * Explanation of "folding": let A(x) be 64 bits from the message, and let B(x) 43 * be 95 bits from a constant distance D later in the message. The relevant 44 * portion of the message can be written as: 45 * 46 * M(x) = A(x)*x^D + B(x) 47 * 48 * ... where + and * represent addition and multiplication, respectively, of 49 * polynomials over GF(2). Note that when implemented on a computer, these 50 * operations are equivalent to XOR and carryless multiplication, respectively. 51 * 52 * For the purpose of CRC calculation, only the remainder modulo the generator 53 * polynomial G(x) matters: 54 * 55 * M(x) mod G(x) = (A(x)*x^D + B(x)) mod G(x) 56 * 57 * Since the modulo operation can be applied anywhere in a sequence of additions 58 * and multiplications without affecting the result, this is equivalent to: 59 * 60 * M(x) mod G(x) = (A(x)*(x^D mod G(x)) + B(x)) mod G(x) 61 * 62 * For any D, 'x^D mod G(x)' will be a polynomial with maximum degree 31, i.e. 63 * a 32-bit quantity. So 'A(x) * (x^D mod G(x))' is equivalent to a carryless 64 * multiplication of a 64-bit quantity by a 32-bit quantity, producing a 95-bit 65 * product. Then, adding (XOR-ing) the product to B(x) produces a polynomial 66 * with the same length as B(x) but with the same remainder as 'A(x)*x^D + 67 * B(x)'. This is the basic fold operation with 64 bits. 68 * 69 * Note that the carryless multiplication instruction PCLMULQDQ actually takes 70 * two 64-bit inputs and produces a 127-bit product in the low-order bits of a 71 * 128-bit XMM register. This works fine, but care must be taken to account for 72 * "bit endianness". With the CRC version implemented here, bits are always 73 * ordered such that the lowest-order bit represents the coefficient of highest 74 * power of x and the highest-order bit represents the coefficient of the lowest 75 * power of x. This is backwards from the more intuitive order. Still, 76 * carryless multiplication works essentially the same either way. It just must 77 * be accounted for that when we XOR the 95-bit product in the low-order 95 bits 78 * of a 128-bit XMM register into 128-bits of later data held in another XMM 79 * register, we'll really be XOR-ing the product into the mathematically higher 80 * degree end of those later bits, not the lower degree end as may be expected. 81 * 82 * So given that caveat and the fact that we process 512 bits per iteration, the 83 * 'D' values we need for the two 64-bit halves of each 128 bits of data are: 84 * 85 * D = (512 + 95) - 64 for the higher-degree half of each 128 bits, 86 * i.e. the lower order bits in the XMM register 87 * 88 * D = (512 + 95) - 128 for the lower-degree half of each 128 bits, 89 * i.e. the higher order bits in the XMM register 90 * 91 * The required 'x^D mod G(x)' values were precomputed. 92 * 93 * When <= 512 bits remain in the message, we finish up by folding across 94 * smaller distances. This works similarly; the distance D is just different, 95 * so different constant multipliers must be used. Finally, once the remaining 96 * message is just 64 bits, it is is reduced to the CRC-32 using Barrett 97 * reduction (explained later). 98 * 99 * For more information see the original paper from Intel: 100 * "Fast CRC Computation for Generic Polynomials Using PCLMULQDQ Instruction" 101 * December 2009 102 * http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf 103 */ 104 static u32 ATTRIBUTES 105 FUNCNAME_ALIGNED(u32 remainder, const __m128i *p, size_t nr_segs) 106 { 107 /* Constants precomputed by gen_crc32_multipliers.c. Do not edit! */ 108 const __v2di multipliers_4 = (__v2di){ 0x8F352D95, 0x1D9513D7 }; 109 const __v2di multipliers_2 = (__v2di){ 0xF1DA05AA, 0x81256527 }; 110 const __v2di multipliers_1 = (__v2di){ 0xAE689191, 0xCCAA009E }; 111 const __v2di final_multiplier = (__v2di){ 0xB8BC6765 }; 112 const __m128i mask32 = (__m128i)(__v4si){ 0xFFFFFFFF }; 113 const __v2di barrett_reduction_constants = 114 (__v2di){ 0x00000001F7011641, 0x00000001DB710641 }; 115 116 const __m128i * const end = p + nr_segs; 117 const __m128i * const end512 = p + (nr_segs & ~3); 118 __m128i x0, x1, x2, x3; 119 120 /* 121 * Account for the current 'remainder', i.e. the CRC of the part of the 122 * message already processed. Explanation: rewrite the message 123 * polynomial M(x) in terms of the first part A(x), the second part 124 * B(x), and the length of the second part in bits |B(x)| >= 32: 125 * 126 * M(x) = A(x)*x^|B(x)| + B(x) 127 * 128 * Then the CRC of M(x) is: 129 * 130 * CRC(M(x)) = CRC(A(x)*x^|B(x)| + B(x)) 131 * = CRC(A(x)*x^32*x^(|B(x)| - 32) + B(x)) 132 * = CRC(CRC(A(x))*x^(|B(x)| - 32) + B(x)) 133 * 134 * Note: all arithmetic is modulo G(x), the generator polynomial; that's 135 * why A(x)*x^32 can be replaced with CRC(A(x)) = A(x)*x^32 mod G(x). 136 * 137 * So the CRC of the full message is the CRC of the second part of the 138 * message where the first 32 bits of the second part of the message 139 * have been XOR'ed with the CRC of the first part of the message. 140 */ 141 x0 = *p++; 142 x0 ^= (__m128i)(__v4si){ remainder }; 143 144 if (p > end512) /* only 128, 256, or 384 bits of input? */ 145 goto _128_bits_at_a_time; 146 x1 = *p++; 147 x2 = *p++; 148 x3 = *p++; 149 150 /* Fold 512 bits at a time */ 151 for (; p != end512; p += 4) { 152 __m128i y0, y1, y2, y3; 153 154 y0 = p[0]; 155 y1 = p[1]; 156 y2 = p[2]; 157 y3 = p[3]; 158 159 /* 160 * Note: the immediate constant for PCLMULQDQ specifies which 161 * 64-bit halves of the 128-bit vectors to multiply: 162 * 163 * 0x00 means low halves (higher degree polynomial terms for us) 164 * 0x11 means high halves (lower degree polynomial terms for us) 165 */ 166 y0 ^= _mm_clmulepi64_si128(x0, multipliers_4, 0x00); 167 y1 ^= _mm_clmulepi64_si128(x1, multipliers_4, 0x00); 168 y2 ^= _mm_clmulepi64_si128(x2, multipliers_4, 0x00); 169 y3 ^= _mm_clmulepi64_si128(x3, multipliers_4, 0x00); 170 y0 ^= _mm_clmulepi64_si128(x0, multipliers_4, 0x11); 171 y1 ^= _mm_clmulepi64_si128(x1, multipliers_4, 0x11); 172 y2 ^= _mm_clmulepi64_si128(x2, multipliers_4, 0x11); 173 y3 ^= _mm_clmulepi64_si128(x3, multipliers_4, 0x11); 174 175 x0 = y0; 176 x1 = y1; 177 x2 = y2; 178 x3 = y3; 179 } 180 181 /* Fold 512 bits => 128 bits */ 182 x2 ^= _mm_clmulepi64_si128(x0, multipliers_2, 0x00); 183 x3 ^= _mm_clmulepi64_si128(x1, multipliers_2, 0x00); 184 x2 ^= _mm_clmulepi64_si128(x0, multipliers_2, 0x11); 185 x3 ^= _mm_clmulepi64_si128(x1, multipliers_2, 0x11); 186 x3 ^= _mm_clmulepi64_si128(x2, multipliers_1, 0x00); 187 x3 ^= _mm_clmulepi64_si128(x2, multipliers_1, 0x11); 188 x0 = x3; 189 190 _128_bits_at_a_time: 191 while (p != end) { 192 /* Fold 128 bits into next 128 bits */ 193 x1 = *p++; 194 x1 ^= _mm_clmulepi64_si128(x0, multipliers_1, 0x00); 195 x1 ^= _mm_clmulepi64_si128(x0, multipliers_1, 0x11); 196 x0 = x1; 197 } 198 199 /* Now there are just 128 bits left, stored in 'x0'. */ 200 201 /* 202 * Fold 128 => 96 bits. This also implicitly appends 32 zero bits, 203 * which is equivalent to multiplying by x^32. This is needed because 204 * the CRC is defined as M(x)*x^32 mod G(x), not just M(x) mod G(x). 205 */ 206 x0 = _mm_srli_si128(x0, 8) ^ 207 _mm_clmulepi64_si128(x0, multipliers_1, 0x10); 208 209 /* Fold 96 => 64 bits */ 210 x0 = _mm_srli_si128(x0, 4) ^ 211 _mm_clmulepi64_si128(x0 & mask32, final_multiplier, 0x00); 212 213 /* 214 * Finally, reduce 64 => 32 bits using Barrett reduction. 215 * 216 * Let M(x) = A(x)*x^32 + B(x) be the remaining message. The goal is to 217 * compute R(x) = M(x) mod G(x). Since degree(B(x)) < degree(G(x)): 218 * 219 * R(x) = (A(x)*x^32 + B(x)) mod G(x) 220 * = (A(x)*x^32) mod G(x) + B(x) 221 * 222 * Then, by the Division Algorithm there exists a unique q(x) such that: 223 * 224 * A(x)*x^32 mod G(x) = A(x)*x^32 - q(x)*G(x) 225 * 226 * Since the left-hand side is of maximum degree 31, the right-hand side 227 * must be too. This implies that we can apply 'mod x^32' to the 228 * right-hand side without changing its value: 229 * 230 * (A(x)*x^32 - q(x)*G(x)) mod x^32 = q(x)*G(x) mod x^32 231 * 232 * Note that '+' is equivalent to '-' in polynomials over GF(2). 233 * 234 * We also know that: 235 * 236 * / A(x)*x^32 \ 237 * q(x) = floor ( --------- ) 238 * \ G(x) / 239 * 240 * To compute this efficiently, we can multiply the top and bottom by 241 * x^32 and move the division by G(x) to the top: 242 * 243 * / A(x) * floor(x^64 / G(x)) \ 244 * q(x) = floor ( ------------------------- ) 245 * \ x^32 / 246 * 247 * Note that floor(x^64 / G(x)) is a constant. 248 * 249 * So finally we have: 250 * 251 * / A(x) * floor(x^64 / G(x)) \ 252 * R(x) = B(x) + G(x)*floor ( ------------------------- ) 253 * \ x^32 / 254 */ 255 x1 = x0; 256 x0 = _mm_clmulepi64_si128(x0 & mask32, barrett_reduction_constants, 0x00); 257 x0 = _mm_clmulepi64_si128(x0 & mask32, barrett_reduction_constants, 0x10); 258 return _mm_cvtsi128_si32(_mm_srli_si128(x0 ^ x1, 4)); 259 } 260 261 #define IMPL_ALIGNMENT 16 262 #define IMPL_SEGMENT_SIZE 16 263 #include "crc32_vec_template.h"