xref: /linux/arch/x86/lib/crc32c-3way.S (revision 37b33c68b00089a574ebd0a856a5d554eb3001b7)
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