1*55d1ecceSEric Biggers/* 2*55d1ecceSEric Biggers * Implement fast CRC32C with PCLMULQDQ instructions. (x86_64) 3*55d1ecceSEric Biggers * 4*55d1ecceSEric Biggers * The white papers on CRC32C calculations with PCLMULQDQ instruction can be 5*55d1ecceSEric Biggers * downloaded from: 6*55d1ecceSEric Biggers * http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/crc-iscsi-polynomial-crc32-instruction-paper.pdf 7*55d1ecceSEric Biggers * http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-paper.pdf 8*55d1ecceSEric Biggers * 9*55d1ecceSEric Biggers * Copyright (C) 2012 Intel Corporation. 10*55d1ecceSEric Biggers * Copyright 2024 Google LLC 11*55d1ecceSEric Biggers * 12*55d1ecceSEric Biggers * Authors: 13*55d1ecceSEric Biggers * Wajdi Feghali <wajdi.k.feghali@intel.com> 14*55d1ecceSEric Biggers * James Guilford <james.guilford@intel.com> 15*55d1ecceSEric Biggers * David Cote <david.m.cote@intel.com> 16*55d1ecceSEric Biggers * Tim Chen <tim.c.chen@linux.intel.com> 17*55d1ecceSEric Biggers * 18*55d1ecceSEric Biggers * This software is available to you under a choice of one of two 19*55d1ecceSEric Biggers * licenses. You may choose to be licensed under the terms of the GNU 20*55d1ecceSEric Biggers * General Public License (GPL) Version 2, available from the file 21*55d1ecceSEric Biggers * COPYING in the main directory of this source tree, or the 22*55d1ecceSEric Biggers * OpenIB.org BSD license below: 23*55d1ecceSEric Biggers * 24*55d1ecceSEric Biggers * Redistribution and use in source and binary forms, with or 25*55d1ecceSEric Biggers * without modification, are permitted provided that the following 26*55d1ecceSEric Biggers * conditions are met: 27*55d1ecceSEric Biggers * 28*55d1ecceSEric Biggers * - Redistributions of source code must retain the above 29*55d1ecceSEric Biggers * copyright notice, this list of conditions and the following 30*55d1ecceSEric Biggers * disclaimer. 31*55d1ecceSEric Biggers * 32*55d1ecceSEric Biggers * - Redistributions in binary form must reproduce the above 33*55d1ecceSEric Biggers * copyright notice, this list of conditions and the following 34*55d1ecceSEric Biggers * disclaimer in the documentation and/or other materials 35*55d1ecceSEric Biggers * provided with the distribution. 36*55d1ecceSEric Biggers * 37*55d1ecceSEric Biggers * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 38*55d1ecceSEric Biggers * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 39*55d1ecceSEric Biggers * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 40*55d1ecceSEric Biggers * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 41*55d1ecceSEric Biggers * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 42*55d1ecceSEric Biggers * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 43*55d1ecceSEric Biggers * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 44*55d1ecceSEric Biggers * SOFTWARE. 45*55d1ecceSEric Biggers */ 46*55d1ecceSEric Biggers 47*55d1ecceSEric Biggers#include <linux/linkage.h> 48*55d1ecceSEric Biggers 49*55d1ecceSEric Biggers## ISCSI CRC 32 Implementation with crc32 and pclmulqdq Instruction 50*55d1ecceSEric Biggers 51*55d1ecceSEric Biggers# Define threshold below which buffers are considered "small" and routed to 52*55d1ecceSEric Biggers# regular CRC code that does not interleave the CRC instructions. 53*55d1ecceSEric Biggers#define SMALL_SIZE 200 54*55d1ecceSEric Biggers 55*55d1ecceSEric Biggers# u32 crc32c_x86_3way(u32 crc, const u8 *buffer, size_t len); 56*55d1ecceSEric Biggers 57*55d1ecceSEric Biggers.text 58*55d1ecceSEric BiggersSYM_FUNC_START(crc32c_x86_3way) 59*55d1ecceSEric Biggers#define crc0 %edi 60*55d1ecceSEric Biggers#define crc0_q %rdi 61*55d1ecceSEric Biggers#define bufp %rsi 62*55d1ecceSEric Biggers#define bufp_d %esi 63*55d1ecceSEric Biggers#define len %rdx 64*55d1ecceSEric Biggers#define len_dw %edx 65*55d1ecceSEric Biggers#define n_misaligned %ecx /* overlaps chunk_bytes! */ 66*55d1ecceSEric Biggers#define n_misaligned_q %rcx 67*55d1ecceSEric Biggers#define chunk_bytes %ecx /* overlaps n_misaligned! */ 68*55d1ecceSEric Biggers#define chunk_bytes_q %rcx 69*55d1ecceSEric Biggers#define crc1 %r8 70*55d1ecceSEric Biggers#define crc2 %r9 71*55d1ecceSEric Biggers 72*55d1ecceSEric Biggers cmp $SMALL_SIZE, len 73*55d1ecceSEric Biggers jb .Lsmall 74*55d1ecceSEric Biggers 75*55d1ecceSEric Biggers ################################################################ 76*55d1ecceSEric Biggers ## 1) ALIGN: 77*55d1ecceSEric Biggers ################################################################ 78*55d1ecceSEric Biggers mov bufp_d, n_misaligned 79*55d1ecceSEric Biggers neg n_misaligned 80*55d1ecceSEric Biggers and $7, n_misaligned # calculate the misalignment amount of 81*55d1ecceSEric Biggers # the address 82*55d1ecceSEric Biggers je .Laligned # Skip if aligned 83*55d1ecceSEric Biggers 84*55d1ecceSEric Biggers # Process 1 <= n_misaligned <= 7 bytes individually in order to align 85*55d1ecceSEric Biggers # the remaining data to an 8-byte boundary. 86*55d1ecceSEric Biggers.Ldo_align: 87*55d1ecceSEric Biggers movq (bufp), %rax 88*55d1ecceSEric Biggers add n_misaligned_q, bufp 89*55d1ecceSEric Biggers sub n_misaligned_q, len 90*55d1ecceSEric Biggers.Lalign_loop: 91*55d1ecceSEric Biggers crc32b %al, crc0 # compute crc32 of 1-byte 92*55d1ecceSEric Biggers shr $8, %rax # get next byte 93*55d1ecceSEric Biggers dec n_misaligned 94*55d1ecceSEric Biggers jne .Lalign_loop 95*55d1ecceSEric Biggers.Laligned: 96*55d1ecceSEric Biggers 97*55d1ecceSEric Biggers ################################################################ 98*55d1ecceSEric Biggers ## 2) PROCESS BLOCK: 99*55d1ecceSEric Biggers ################################################################ 100*55d1ecceSEric Biggers 101*55d1ecceSEric Biggers cmp $128*24, len 102*55d1ecceSEric Biggers jae .Lfull_block 103*55d1ecceSEric Biggers 104*55d1ecceSEric Biggers.Lpartial_block: 105*55d1ecceSEric Biggers # Compute floor(len / 24) to get num qwords to process from each lane. 106*55d1ecceSEric Biggers imul $2731, len_dw, %eax # 2731 = ceil(2^16 / 24) 107*55d1ecceSEric Biggers shr $16, %eax 108*55d1ecceSEric Biggers jmp .Lcrc_3lanes 109*55d1ecceSEric Biggers 110*55d1ecceSEric Biggers.Lfull_block: 111*55d1ecceSEric Biggers # Processing 128 qwords from each lane. 112*55d1ecceSEric Biggers mov $128, %eax 113*55d1ecceSEric Biggers 114*55d1ecceSEric Biggers ################################################################ 115*55d1ecceSEric Biggers ## 3) CRC each of three lanes: 116*55d1ecceSEric Biggers ################################################################ 117*55d1ecceSEric Biggers 118*55d1ecceSEric Biggers.Lcrc_3lanes: 119*55d1ecceSEric Biggers xor crc1,crc1 120*55d1ecceSEric Biggers xor crc2,crc2 121*55d1ecceSEric Biggers mov %eax, chunk_bytes 122*55d1ecceSEric Biggers shl $3, chunk_bytes # num bytes to process from each lane 123*55d1ecceSEric Biggers sub $5, %eax # 4 for 4x_loop, 1 for special last iter 124*55d1ecceSEric Biggers jl .Lcrc_3lanes_4x_done 125*55d1ecceSEric Biggers 126*55d1ecceSEric Biggers # Unroll the loop by a factor of 4 to reduce the overhead of the loop 127*55d1ecceSEric Biggers # bookkeeping instructions, which can compete with crc32q for the ALUs. 128*55d1ecceSEric Biggers.Lcrc_3lanes_4x_loop: 129*55d1ecceSEric Biggers crc32q (bufp), crc0_q 130*55d1ecceSEric Biggers crc32q (bufp,chunk_bytes_q), crc1 131*55d1ecceSEric Biggers crc32q (bufp,chunk_bytes_q,2), crc2 132*55d1ecceSEric Biggers crc32q 8(bufp), crc0_q 133*55d1ecceSEric Biggers crc32q 8(bufp,chunk_bytes_q), crc1 134*55d1ecceSEric Biggers crc32q 8(bufp,chunk_bytes_q,2), crc2 135*55d1ecceSEric Biggers crc32q 16(bufp), crc0_q 136*55d1ecceSEric Biggers crc32q 16(bufp,chunk_bytes_q), crc1 137*55d1ecceSEric Biggers crc32q 16(bufp,chunk_bytes_q,2), crc2 138*55d1ecceSEric Biggers crc32q 24(bufp), crc0_q 139*55d1ecceSEric Biggers crc32q 24(bufp,chunk_bytes_q), crc1 140*55d1ecceSEric Biggers crc32q 24(bufp,chunk_bytes_q,2), crc2 141*55d1ecceSEric Biggers add $32, bufp 142*55d1ecceSEric Biggers sub $4, %eax 143*55d1ecceSEric Biggers jge .Lcrc_3lanes_4x_loop 144*55d1ecceSEric Biggers 145*55d1ecceSEric Biggers.Lcrc_3lanes_4x_done: 146*55d1ecceSEric Biggers add $4, %eax 147*55d1ecceSEric Biggers jz .Lcrc_3lanes_last_qword 148*55d1ecceSEric Biggers 149*55d1ecceSEric Biggers.Lcrc_3lanes_1x_loop: 150*55d1ecceSEric Biggers crc32q (bufp), crc0_q 151*55d1ecceSEric Biggers crc32q (bufp,chunk_bytes_q), crc1 152*55d1ecceSEric Biggers crc32q (bufp,chunk_bytes_q,2), crc2 153*55d1ecceSEric Biggers add $8, bufp 154*55d1ecceSEric Biggers dec %eax 155*55d1ecceSEric Biggers jnz .Lcrc_3lanes_1x_loop 156*55d1ecceSEric Biggers 157*55d1ecceSEric Biggers.Lcrc_3lanes_last_qword: 158*55d1ecceSEric Biggers crc32q (bufp), crc0_q 159*55d1ecceSEric Biggers crc32q (bufp,chunk_bytes_q), crc1 160*55d1ecceSEric Biggers# SKIP crc32q (bufp,chunk_bytes_q,2), crc2 ; Don't do this one yet 161*55d1ecceSEric Biggers 162*55d1ecceSEric Biggers ################################################################ 163*55d1ecceSEric Biggers ## 4) Combine three results: 164*55d1ecceSEric Biggers ################################################################ 165*55d1ecceSEric Biggers 166*55d1ecceSEric Biggers lea (K_table-8)(%rip), %rax # first entry is for idx 1 167*55d1ecceSEric Biggers pmovzxdq (%rax,chunk_bytes_q), %xmm0 # 2 consts: K1:K2 168*55d1ecceSEric Biggers lea (chunk_bytes,chunk_bytes,2), %eax # chunk_bytes * 3 169*55d1ecceSEric Biggers sub %rax, len # len -= chunk_bytes * 3 170*55d1ecceSEric Biggers 171*55d1ecceSEric Biggers movq crc0_q, %xmm1 # CRC for block 1 172*55d1ecceSEric Biggers pclmulqdq $0x00, %xmm0, %xmm1 # Multiply by K2 173*55d1ecceSEric Biggers 174*55d1ecceSEric Biggers movq crc1, %xmm2 # CRC for block 2 175*55d1ecceSEric Biggers pclmulqdq $0x10, %xmm0, %xmm2 # Multiply by K1 176*55d1ecceSEric Biggers 177*55d1ecceSEric Biggers pxor %xmm2,%xmm1 178*55d1ecceSEric Biggers movq %xmm1, %rax 179*55d1ecceSEric Biggers xor (bufp,chunk_bytes_q,2), %rax 180*55d1ecceSEric Biggers mov crc2, crc0_q 181*55d1ecceSEric Biggers crc32 %rax, crc0_q 182*55d1ecceSEric Biggers lea 8(bufp,chunk_bytes_q,2), bufp 183*55d1ecceSEric Biggers 184*55d1ecceSEric Biggers ################################################################ 185*55d1ecceSEric Biggers ## 5) If more blocks remain, goto (2): 186*55d1ecceSEric Biggers ################################################################ 187*55d1ecceSEric Biggers 188*55d1ecceSEric Biggers cmp $128*24, len 189*55d1ecceSEric Biggers jae .Lfull_block 190*55d1ecceSEric Biggers cmp $SMALL_SIZE, len 191*55d1ecceSEric Biggers jae .Lpartial_block 192*55d1ecceSEric Biggers 193*55d1ecceSEric Biggers ####################################################################### 194*55d1ecceSEric Biggers ## 6) Process any remainder without interleaving: 195*55d1ecceSEric Biggers ####################################################################### 196*55d1ecceSEric Biggers.Lsmall: 197*55d1ecceSEric Biggers test len_dw, len_dw 198*55d1ecceSEric Biggers jz .Ldone 199*55d1ecceSEric Biggers mov len_dw, %eax 200*55d1ecceSEric Biggers shr $3, %eax 201*55d1ecceSEric Biggers jz .Ldo_dword 202*55d1ecceSEric Biggers.Ldo_qwords: 203*55d1ecceSEric Biggers crc32q (bufp), crc0_q 204*55d1ecceSEric Biggers add $8, bufp 205*55d1ecceSEric Biggers dec %eax 206*55d1ecceSEric Biggers jnz .Ldo_qwords 207*55d1ecceSEric Biggers.Ldo_dword: 208*55d1ecceSEric Biggers test $4, len_dw 209*55d1ecceSEric Biggers jz .Ldo_word 210*55d1ecceSEric Biggers crc32l (bufp), crc0 211*55d1ecceSEric Biggers add $4, bufp 212*55d1ecceSEric Biggers.Ldo_word: 213*55d1ecceSEric Biggers test $2, len_dw 214*55d1ecceSEric Biggers jz .Ldo_byte 215*55d1ecceSEric Biggers crc32w (bufp), crc0 216*55d1ecceSEric Biggers add $2, bufp 217*55d1ecceSEric Biggers.Ldo_byte: 218*55d1ecceSEric Biggers test $1, len_dw 219*55d1ecceSEric Biggers jz .Ldone 220*55d1ecceSEric Biggers crc32b (bufp), crc0 221*55d1ecceSEric Biggers.Ldone: 222*55d1ecceSEric Biggers mov crc0, %eax 223*55d1ecceSEric Biggers RET 224*55d1ecceSEric BiggersSYM_FUNC_END(crc32c_x86_3way) 225*55d1ecceSEric Biggers 226*55d1ecceSEric Biggers.section .rodata, "a", @progbits 227*55d1ecceSEric Biggers ################################################################ 228*55d1ecceSEric Biggers ## PCLMULQDQ tables 229*55d1ecceSEric Biggers ## Table is 128 entries x 2 words (8 bytes) each 230*55d1ecceSEric Biggers ################################################################ 231*55d1ecceSEric Biggers.align 8 232*55d1ecceSEric BiggersK_table: 233*55d1ecceSEric Biggers .long 0x493c7d27, 0x00000001 234*55d1ecceSEric Biggers .long 0xba4fc28e, 0x493c7d27 235*55d1ecceSEric Biggers .long 0xddc0152b, 0xf20c0dfe 236*55d1ecceSEric Biggers .long 0x9e4addf8, 0xba4fc28e 237*55d1ecceSEric Biggers .long 0x39d3b296, 0x3da6d0cb 238*55d1ecceSEric Biggers .long 0x0715ce53, 0xddc0152b 239*55d1ecceSEric Biggers .long 0x47db8317, 0x1c291d04 240*55d1ecceSEric Biggers .long 0x0d3b6092, 0x9e4addf8 241*55d1ecceSEric Biggers .long 0xc96cfdc0, 0x740eef02 242*55d1ecceSEric Biggers .long 0x878a92a7, 0x39d3b296 243*55d1ecceSEric Biggers .long 0xdaece73e, 0x083a6eec 244*55d1ecceSEric Biggers .long 0xab7aff2a, 0x0715ce53 245*55d1ecceSEric Biggers .long 0x2162d385, 0xc49f4f67 246*55d1ecceSEric Biggers .long 0x83348832, 0x47db8317 247*55d1ecceSEric Biggers .long 0x299847d5, 0x2ad91c30 248*55d1ecceSEric Biggers .long 0xb9e02b86, 0x0d3b6092 249*55d1ecceSEric Biggers .long 0x18b33a4e, 0x6992cea2 250*55d1ecceSEric Biggers .long 0xb6dd949b, 0xc96cfdc0 251*55d1ecceSEric Biggers .long 0x78d9ccb7, 0x7e908048 252*55d1ecceSEric Biggers .long 0xbac2fd7b, 0x878a92a7 253*55d1ecceSEric Biggers .long 0xa60ce07b, 0x1b3d8f29 254*55d1ecceSEric Biggers .long 0xce7f39f4, 0xdaece73e 255*55d1ecceSEric Biggers .long 0x61d82e56, 0xf1d0f55e 256*55d1ecceSEric Biggers .long 0xd270f1a2, 0xab7aff2a 257*55d1ecceSEric Biggers .long 0xc619809d, 0xa87ab8a8 258*55d1ecceSEric Biggers .long 0x2b3cac5d, 0x2162d385 259*55d1ecceSEric Biggers .long 0x65863b64, 0x8462d800 260*55d1ecceSEric Biggers .long 0x1b03397f, 0x83348832 261*55d1ecceSEric Biggers .long 0xebb883bd, 0x71d111a8 262*55d1ecceSEric Biggers .long 0xb3e32c28, 0x299847d5 263*55d1ecceSEric Biggers .long 0x064f7f26, 0xffd852c6 264*55d1ecceSEric Biggers .long 0xdd7e3b0c, 0xb9e02b86 265*55d1ecceSEric Biggers .long 0xf285651c, 0xdcb17aa4 266*55d1ecceSEric Biggers .long 0x10746f3c, 0x18b33a4e 267*55d1ecceSEric Biggers .long 0xc7a68855, 0xf37c5aee 268*55d1ecceSEric Biggers .long 0x271d9844, 0xb6dd949b 269*55d1ecceSEric Biggers .long 0x8e766a0c, 0x6051d5a2 270*55d1ecceSEric Biggers .long 0x93a5f730, 0x78d9ccb7 271*55d1ecceSEric Biggers .long 0x6cb08e5c, 0x18b0d4ff 272*55d1ecceSEric Biggers .long 0x6b749fb2, 0xbac2fd7b 273*55d1ecceSEric Biggers .long 0x1393e203, 0x21f3d99c 274*55d1ecceSEric Biggers .long 0xcec3662e, 0xa60ce07b 275*55d1ecceSEric Biggers .long 0x96c515bb, 0x8f158014 276*55d1ecceSEric Biggers .long 0xe6fc4e6a, 0xce7f39f4 277*55d1ecceSEric Biggers .long 0x8227bb8a, 0xa00457f7 278*55d1ecceSEric Biggers .long 0xb0cd4768, 0x61d82e56 279*55d1ecceSEric Biggers .long 0x39c7ff35, 0x8d6d2c43 280*55d1ecceSEric Biggers .long 0xd7a4825c, 0xd270f1a2 281*55d1ecceSEric Biggers .long 0x0ab3844b, 0x00ac29cf 282*55d1ecceSEric Biggers .long 0x0167d312, 0xc619809d 283*55d1ecceSEric Biggers .long 0xf6076544, 0xe9adf796 284*55d1ecceSEric Biggers .long 0x26f6a60a, 0x2b3cac5d 285*55d1ecceSEric Biggers .long 0xa741c1bf, 0x96638b34 286*55d1ecceSEric Biggers .long 0x98d8d9cb, 0x65863b64 287*55d1ecceSEric Biggers .long 0x49c3cc9c, 0xe0e9f351 288*55d1ecceSEric Biggers .long 0x68bce87a, 0x1b03397f 289*55d1ecceSEric Biggers .long 0x57a3d037, 0x9af01f2d 290*55d1ecceSEric Biggers .long 0x6956fc3b, 0xebb883bd 291*55d1ecceSEric Biggers .long 0x42d98888, 0x2cff42cf 292*55d1ecceSEric Biggers .long 0x3771e98f, 0xb3e32c28 293*55d1ecceSEric Biggers .long 0xb42ae3d9, 0x88f25a3a 294*55d1ecceSEric Biggers .long 0x2178513a, 0x064f7f26 295*55d1ecceSEric Biggers .long 0xe0ac139e, 0x4e36f0b0 296*55d1ecceSEric Biggers .long 0x170076fa, 0xdd7e3b0c 297*55d1ecceSEric Biggers .long 0x444dd413, 0xbd6f81f8 298*55d1ecceSEric Biggers .long 0x6f345e45, 0xf285651c 299*55d1ecceSEric Biggers .long 0x41d17b64, 0x91c9bd4b 300*55d1ecceSEric Biggers .long 0xff0dba97, 0x10746f3c 301*55d1ecceSEric Biggers .long 0xa2b73df1, 0x885f087b 302*55d1ecceSEric Biggers .long 0xf872e54c, 0xc7a68855 303*55d1ecceSEric Biggers .long 0x1e41e9fc, 0x4c144932 304*55d1ecceSEric Biggers .long 0x86d8e4d2, 0x271d9844 305*55d1ecceSEric Biggers .long 0x651bd98b, 0x52148f02 306*55d1ecceSEric Biggers .long 0x5bb8f1bc, 0x8e766a0c 307*55d1ecceSEric Biggers .long 0xa90fd27a, 0xa3c6f37a 308*55d1ecceSEric Biggers .long 0xb3af077a, 0x93a5f730 309*55d1ecceSEric Biggers .long 0x4984d782, 0xd7c0557f 310*55d1ecceSEric Biggers .long 0xca6ef3ac, 0x6cb08e5c 311*55d1ecceSEric Biggers .long 0x234e0b26, 0x63ded06a 312*55d1ecceSEric Biggers .long 0xdd66cbbb, 0x6b749fb2 313*55d1ecceSEric Biggers .long 0x4597456a, 0x4d56973c 314*55d1ecceSEric Biggers .long 0xe9e28eb4, 0x1393e203 315*55d1ecceSEric Biggers .long 0x7b3ff57a, 0x9669c9df 316*55d1ecceSEric Biggers .long 0xc9c8b782, 0xcec3662e 317*55d1ecceSEric Biggers .long 0x3f70cc6f, 0xe417f38a 318*55d1ecceSEric Biggers .long 0x93e106a4, 0x96c515bb 319*55d1ecceSEric Biggers .long 0x62ec6c6d, 0x4b9e0f71 320*55d1ecceSEric Biggers .long 0xd813b325, 0xe6fc4e6a 321*55d1ecceSEric Biggers .long 0x0df04680, 0xd104b8fc 322*55d1ecceSEric Biggers .long 0x2342001e, 0x8227bb8a 323*55d1ecceSEric Biggers .long 0x0a2a8d7e, 0x5b397730 324*55d1ecceSEric Biggers .long 0x6d9a4957, 0xb0cd4768 325*55d1ecceSEric Biggers .long 0xe8b6368b, 0xe78eb416 326*55d1ecceSEric Biggers .long 0xd2c3ed1a, 0x39c7ff35 327*55d1ecceSEric Biggers .long 0x995a5724, 0x61ff0e01 328*55d1ecceSEric Biggers .long 0x9ef68d35, 0xd7a4825c 329*55d1ecceSEric Biggers .long 0x0c139b31, 0x8d96551c 330*55d1ecceSEric Biggers .long 0xf2271e60, 0x0ab3844b 331*55d1ecceSEric Biggers .long 0x0b0bf8ca, 0x0bf80dd2 332*55d1ecceSEric Biggers .long 0x2664fd8b, 0x0167d312 333*55d1ecceSEric Biggers .long 0xed64812d, 0x8821abed 334*55d1ecceSEric Biggers .long 0x02ee03b2, 0xf6076544 335*55d1ecceSEric Biggers .long 0x8604ae0f, 0x6a45d2b2 336*55d1ecceSEric Biggers .long 0x363bd6b3, 0x26f6a60a 337*55d1ecceSEric Biggers .long 0x135c83fd, 0xd8d26619 338*55d1ecceSEric Biggers .long 0x5fabe670, 0xa741c1bf 339*55d1ecceSEric Biggers .long 0x35ec3279, 0xde87806c 340*55d1ecceSEric Biggers .long 0x00bcf5f6, 0x98d8d9cb 341*55d1ecceSEric Biggers .long 0x8ae00689, 0x14338754 342*55d1ecceSEric Biggers .long 0x17f27698, 0x49c3cc9c 343*55d1ecceSEric Biggers .long 0x58ca5f00, 0x5bd2011f 344*55d1ecceSEric Biggers .long 0xaa7c7ad5, 0x68bce87a 345*55d1ecceSEric Biggers .long 0xb5cfca28, 0xdd07448e 346*55d1ecceSEric Biggers .long 0xded288f8, 0x57a3d037 347*55d1ecceSEric Biggers .long 0x59f229bc, 0xdde8f5b9 348*55d1ecceSEric Biggers .long 0x6d390dec, 0x6956fc3b 349*55d1ecceSEric Biggers .long 0x37170390, 0xa3e3e02c 350*55d1ecceSEric Biggers .long 0x6353c1cc, 0x42d98888 351*55d1ecceSEric Biggers .long 0xc4584f5c, 0xd73c7bea 352*55d1ecceSEric Biggers .long 0xf48642e9, 0x3771e98f 353*55d1ecceSEric Biggers .long 0x531377e2, 0x80ff0093 354*55d1ecceSEric Biggers .long 0xdd35bc8d, 0xb42ae3d9 355*55d1ecceSEric Biggers .long 0xb25b29f2, 0x8fe4c34d 356*55d1ecceSEric Biggers .long 0x9a5ede41, 0x2178513a 357*55d1ecceSEric Biggers .long 0xa563905d, 0xdf99fc11 358*55d1ecceSEric Biggers .long 0x45cddf4e, 0xe0ac139e 359*55d1ecceSEric Biggers .long 0xacfa3103, 0x6c23e841 360*55d1ecceSEric Biggers .long 0xa51b6135, 0x170076fa 361