18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Implement fast CRC32C with PCLMULQDQ instructions. (x86_64)
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * The white papers on CRC32C calculations with PCLMULQDQ instruction can be
58c2ecf20Sopenharmony_ci * downloaded from:
68c2ecf20Sopenharmony_ci * http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/crc-iscsi-polynomial-crc32-instruction-paper.pdf
78c2ecf20Sopenharmony_ci * http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-paper.pdf
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * Copyright (C) 2012 Intel Corporation.
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * Authors:
128c2ecf20Sopenharmony_ci *	Wajdi Feghali <wajdi.k.feghali@intel.com>
138c2ecf20Sopenharmony_ci *	James Guilford <james.guilford@intel.com>
148c2ecf20Sopenharmony_ci *	David Cote <david.m.cote@intel.com>
158c2ecf20Sopenharmony_ci *	Tim Chen <tim.c.chen@linux.intel.com>
168c2ecf20Sopenharmony_ci *
178c2ecf20Sopenharmony_ci * This software is available to you under a choice of one of two
188c2ecf20Sopenharmony_ci * licenses.  You may choose to be licensed under the terms of the GNU
198c2ecf20Sopenharmony_ci * General Public License (GPL) Version 2, available from the file
208c2ecf20Sopenharmony_ci * COPYING in the main directory of this source tree, or the
218c2ecf20Sopenharmony_ci * OpenIB.org BSD license below:
228c2ecf20Sopenharmony_ci *
238c2ecf20Sopenharmony_ci *     Redistribution and use in source and binary forms, with or
248c2ecf20Sopenharmony_ci *     without modification, are permitted provided that the following
258c2ecf20Sopenharmony_ci *     conditions are met:
268c2ecf20Sopenharmony_ci *
278c2ecf20Sopenharmony_ci *      - Redistributions of source code must retain the above
288c2ecf20Sopenharmony_ci *        copyright notice, this list of conditions and the following
298c2ecf20Sopenharmony_ci *        disclaimer.
308c2ecf20Sopenharmony_ci *
318c2ecf20Sopenharmony_ci *      - Redistributions in binary form must reproduce the above
328c2ecf20Sopenharmony_ci *        copyright notice, this list of conditions and the following
338c2ecf20Sopenharmony_ci *        disclaimer in the documentation and/or other materials
348c2ecf20Sopenharmony_ci *        provided with the distribution.
358c2ecf20Sopenharmony_ci *
368c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
378c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
388c2ecf20Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
398c2ecf20Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
408c2ecf20Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
418c2ecf20Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
428c2ecf20Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
438c2ecf20Sopenharmony_ci * SOFTWARE.
448c2ecf20Sopenharmony_ci */
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#include <linux/linkage.h>
478c2ecf20Sopenharmony_ci#include <asm/nospec-branch.h>
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci## ISCSI CRC 32 Implementation with crc32 and pclmulqdq Instruction
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci.macro LABEL prefix n
528c2ecf20Sopenharmony_ci\prefix\n\():
538c2ecf20Sopenharmony_ci.endm
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci.macro JMPTBL_ENTRY i
568c2ecf20Sopenharmony_ci.word crc_\i - crc_array
578c2ecf20Sopenharmony_ci.endm
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci.macro JNC_LESS_THAN j
608c2ecf20Sopenharmony_ci	jnc less_than_\j
618c2ecf20Sopenharmony_ci.endm
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci# Define threshold where buffers are considered "small" and routed to more
648c2ecf20Sopenharmony_ci# efficient "by-1" code. This "by-1" code only handles up to 255 bytes, so
658c2ecf20Sopenharmony_ci# SMALL_SIZE can be no larger than 255.
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci#define SMALL_SIZE 200
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci.if (SMALL_SIZE > 255)
708c2ecf20Sopenharmony_ci.error "SMALL_ SIZE must be < 256"
718c2ecf20Sopenharmony_ci.endif
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci# unsigned int crc_pcl(u8 *buffer, int len, unsigned int crc_init);
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci.text
768c2ecf20Sopenharmony_ciSYM_FUNC_START(crc_pcl)
778c2ecf20Sopenharmony_ci#define    bufp		rdi
788c2ecf20Sopenharmony_ci#define    bufp_dw	%edi
798c2ecf20Sopenharmony_ci#define    bufp_w	%di
808c2ecf20Sopenharmony_ci#define    bufp_b	%dil
818c2ecf20Sopenharmony_ci#define    bufptmp	%rcx
828c2ecf20Sopenharmony_ci#define    block_0	%rcx
838c2ecf20Sopenharmony_ci#define    block_1	%rdx
848c2ecf20Sopenharmony_ci#define    block_2	%r11
858c2ecf20Sopenharmony_ci#define    len		%rsi
868c2ecf20Sopenharmony_ci#define    len_dw	%esi
878c2ecf20Sopenharmony_ci#define    len_w	%si
888c2ecf20Sopenharmony_ci#define    len_b	%sil
898c2ecf20Sopenharmony_ci#define    crc_init_arg %rdx
908c2ecf20Sopenharmony_ci#define    tmp		%rbx
918c2ecf20Sopenharmony_ci#define    crc_init	%r8
928c2ecf20Sopenharmony_ci#define    crc_init_dw	%r8d
938c2ecf20Sopenharmony_ci#define    crc1		%r9
948c2ecf20Sopenharmony_ci#define    crc2		%r10
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	pushq   %rbx
978c2ecf20Sopenharmony_ci	pushq   %rdi
988c2ecf20Sopenharmony_ci	pushq   %rsi
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	## Move crc_init for Linux to a different
1018c2ecf20Sopenharmony_ci	mov     crc_init_arg, crc_init
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	################################################################
1048c2ecf20Sopenharmony_ci	## 1) ALIGN:
1058c2ecf20Sopenharmony_ci	################################################################
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	mov     %bufp, bufptmp		# rdi = *buf
1088c2ecf20Sopenharmony_ci	neg     %bufp
1098c2ecf20Sopenharmony_ci	and     $7, %bufp		# calculate the unalignment amount of
1108c2ecf20Sopenharmony_ci					# the address
1118c2ecf20Sopenharmony_ci	je      proc_block		# Skip if aligned
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci	## If len is less than 8 and we're unaligned, we need to jump
1148c2ecf20Sopenharmony_ci	## to special code to avoid reading beyond the end of the buffer
1158c2ecf20Sopenharmony_ci	cmp     $8, len
1168c2ecf20Sopenharmony_ci	jae     do_align
1178c2ecf20Sopenharmony_ci	# less_than_8 expects length in upper 3 bits of len_dw
1188c2ecf20Sopenharmony_ci	# less_than_8_post_shl1 expects length = carryflag * 8 + len_dw[31:30]
1198c2ecf20Sopenharmony_ci	shl     $32-3+1, len_dw
1208c2ecf20Sopenharmony_ci	jmp     less_than_8_post_shl1
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_cido_align:
1238c2ecf20Sopenharmony_ci	#### Calculate CRC of unaligned bytes of the buffer (if any)
1248c2ecf20Sopenharmony_ci	movq    (bufptmp), tmp		# load a quadward from the buffer
1258c2ecf20Sopenharmony_ci	add     %bufp, bufptmp		# align buffer pointer for quadword
1268c2ecf20Sopenharmony_ci					# processing
1278c2ecf20Sopenharmony_ci	sub     %bufp, len		# update buffer length
1288c2ecf20Sopenharmony_cialign_loop:
1298c2ecf20Sopenharmony_ci	crc32b  %bl, crc_init_dw 	# compute crc32 of 1-byte
1308c2ecf20Sopenharmony_ci	shr     $8, tmp			# get next byte
1318c2ecf20Sopenharmony_ci	dec     %bufp
1328c2ecf20Sopenharmony_ci	jne     align_loop
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ciproc_block:
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci	################################################################
1378c2ecf20Sopenharmony_ci	## 2) PROCESS  BLOCKS:
1388c2ecf20Sopenharmony_ci	################################################################
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	## compute num of bytes to be processed
1418c2ecf20Sopenharmony_ci	movq    len, tmp		# save num bytes in tmp
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	cmpq    $128*24, len
1448c2ecf20Sopenharmony_ci	jae     full_block
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_cicontinue_block:
1478c2ecf20Sopenharmony_ci	cmpq    $SMALL_SIZE, len
1488c2ecf20Sopenharmony_ci	jb      small
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci	## len < 128*24
1518c2ecf20Sopenharmony_ci	movq    $2731, %rax		# 2731 = ceil(2^16 / 24)
1528c2ecf20Sopenharmony_ci	mul     len_dw
1538c2ecf20Sopenharmony_ci	shrq    $16, %rax
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci	## eax contains floor(bytes / 24) = num 24-byte chunks to do
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci	## process rax 24-byte chunks (128 >= rax >= 0)
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	## compute end address of each block
1608c2ecf20Sopenharmony_ci	## block 0 (base addr + RAX * 8)
1618c2ecf20Sopenharmony_ci	## block 1 (base addr + RAX * 16)
1628c2ecf20Sopenharmony_ci	## block 2 (base addr + RAX * 24)
1638c2ecf20Sopenharmony_ci	lea     (bufptmp, %rax, 8), block_0
1648c2ecf20Sopenharmony_ci	lea     (block_0, %rax, 8), block_1
1658c2ecf20Sopenharmony_ci	lea     (block_1, %rax, 8), block_2
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci	xor     crc1, crc1
1688c2ecf20Sopenharmony_ci	xor     crc2, crc2
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci	## branch into array
1718c2ecf20Sopenharmony_ci	lea	jump_table(%rip), %bufp
1728c2ecf20Sopenharmony_ci	movzwq  (%bufp, %rax, 2), len
1738c2ecf20Sopenharmony_ci	lea	crc_array(%rip), %bufp
1748c2ecf20Sopenharmony_ci	lea     (%bufp, len, 1), %bufp
1758c2ecf20Sopenharmony_ci	JMP_NOSPEC bufp
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci	################################################################
1788c2ecf20Sopenharmony_ci	## 2a) PROCESS FULL BLOCKS:
1798c2ecf20Sopenharmony_ci	################################################################
1808c2ecf20Sopenharmony_cifull_block:
1818c2ecf20Sopenharmony_ci	movl    $128,%eax
1828c2ecf20Sopenharmony_ci	lea     128*8*2(block_0), block_1
1838c2ecf20Sopenharmony_ci	lea     128*8*3(block_0), block_2
1848c2ecf20Sopenharmony_ci	add     $128*8*1, block_0
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	xor     crc1,crc1
1878c2ecf20Sopenharmony_ci	xor     crc2,crc2
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci	# Fall thruogh into top of crc array (crc_128)
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci	################################################################
1928c2ecf20Sopenharmony_ci	## 3) CRC Array:
1938c2ecf20Sopenharmony_ci	################################################################
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_cicrc_array:
1968c2ecf20Sopenharmony_ci	i=128
1978c2ecf20Sopenharmony_ci.rept 128-1
1988c2ecf20Sopenharmony_ci.altmacro
1998c2ecf20Sopenharmony_ciLABEL crc_ %i
2008c2ecf20Sopenharmony_ci.noaltmacro
2018c2ecf20Sopenharmony_ci	crc32q   -i*8(block_0), crc_init
2028c2ecf20Sopenharmony_ci	crc32q   -i*8(block_1), crc1
2038c2ecf20Sopenharmony_ci	crc32q   -i*8(block_2), crc2
2048c2ecf20Sopenharmony_ci	i=(i-1)
2058c2ecf20Sopenharmony_ci.endr
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci.altmacro
2088c2ecf20Sopenharmony_ciLABEL crc_ %i
2098c2ecf20Sopenharmony_ci.noaltmacro
2108c2ecf20Sopenharmony_ci	crc32q   -i*8(block_0), crc_init
2118c2ecf20Sopenharmony_ci	crc32q   -i*8(block_1), crc1
2128c2ecf20Sopenharmony_ci# SKIP  crc32  -i*8(block_2), crc2 ; Don't do this one yet
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	mov     block_2, block_0
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_ci	################################################################
2178c2ecf20Sopenharmony_ci	## 4) Combine three results:
2188c2ecf20Sopenharmony_ci	################################################################
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci	lea	(K_table-8)(%rip), %bufp		# first entry is for idx 1
2218c2ecf20Sopenharmony_ci	shlq    $3, %rax			# rax *= 8
2228c2ecf20Sopenharmony_ci	pmovzxdq (%bufp,%rax), %xmm0		# 2 consts: K1:K2
2238c2ecf20Sopenharmony_ci	leal	(%eax,%eax,2), %eax		# rax *= 3 (total *24)
2248c2ecf20Sopenharmony_ci	subq    %rax, tmp			# tmp -= rax*24
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci	movq    crc_init, %xmm1			# CRC for block 1
2278c2ecf20Sopenharmony_ci	pclmulqdq $0x00, %xmm0, %xmm1		# Multiply by K2
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	movq    crc1, %xmm2			# CRC for block 2
2308c2ecf20Sopenharmony_ci	pclmulqdq $0x10, %xmm0, %xmm2		# Multiply by K1
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci	pxor    %xmm2,%xmm1
2338c2ecf20Sopenharmony_ci	movq    %xmm1, %rax
2348c2ecf20Sopenharmony_ci	xor     -i*8(block_2), %rax
2358c2ecf20Sopenharmony_ci	mov     crc2, crc_init
2368c2ecf20Sopenharmony_ci	crc32   %rax, crc_init
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	################################################################
2398c2ecf20Sopenharmony_ci	## 5) Check for end:
2408c2ecf20Sopenharmony_ci	################################################################
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ciLABEL crc_ 0
2438c2ecf20Sopenharmony_ci	mov     tmp, len
2448c2ecf20Sopenharmony_ci	cmp     $128*24, tmp
2458c2ecf20Sopenharmony_ci	jae     full_block
2468c2ecf20Sopenharmony_ci	cmp     $24, tmp
2478c2ecf20Sopenharmony_ci	jae     continue_block
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ciless_than_24:
2508c2ecf20Sopenharmony_ci	shl     $32-4, len_dw			# less_than_16 expects length
2518c2ecf20Sopenharmony_ci						# in upper 4 bits of len_dw
2528c2ecf20Sopenharmony_ci	jnc     less_than_16
2538c2ecf20Sopenharmony_ci	crc32q  (bufptmp), crc_init
2548c2ecf20Sopenharmony_ci	crc32q  8(bufptmp), crc_init
2558c2ecf20Sopenharmony_ci	jz      do_return
2568c2ecf20Sopenharmony_ci	add     $16, bufptmp
2578c2ecf20Sopenharmony_ci	# len is less than 8 if we got here
2588c2ecf20Sopenharmony_ci	# less_than_8 expects length in upper 3 bits of len_dw
2598c2ecf20Sopenharmony_ci	# less_than_8_post_shl1 expects length = carryflag * 8 + len_dw[31:30]
2608c2ecf20Sopenharmony_ci	shl     $2, len_dw
2618c2ecf20Sopenharmony_ci	jmp     less_than_8_post_shl1
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci	#######################################################################
2648c2ecf20Sopenharmony_ci	## 6) LESS THAN 256-bytes REMAIN AT THIS POINT (8-bits of len are full)
2658c2ecf20Sopenharmony_ci	#######################################################################
2668c2ecf20Sopenharmony_cismall:
2678c2ecf20Sopenharmony_ci	shl $32-8, len_dw		# Prepare len_dw for less_than_256
2688c2ecf20Sopenharmony_ci	j=256
2698c2ecf20Sopenharmony_ci.rept 5					# j = {256, 128, 64, 32, 16}
2708c2ecf20Sopenharmony_ci.altmacro
2718c2ecf20Sopenharmony_ciLABEL less_than_ %j			# less_than_j: Length should be in
2728c2ecf20Sopenharmony_ci					# upper lg(j) bits of len_dw
2738c2ecf20Sopenharmony_ci	j=(j/2)
2748c2ecf20Sopenharmony_ci	shl     $1, len_dw		# Get next MSB
2758c2ecf20Sopenharmony_ci	JNC_LESS_THAN %j
2768c2ecf20Sopenharmony_ci.noaltmacro
2778c2ecf20Sopenharmony_ci	i=0
2788c2ecf20Sopenharmony_ci.rept (j/8)
2798c2ecf20Sopenharmony_ci	crc32q  i(bufptmp), crc_init	# Compute crc32 of 8-byte data
2808c2ecf20Sopenharmony_ci	i=i+8
2818c2ecf20Sopenharmony_ci.endr
2828c2ecf20Sopenharmony_ci	jz      do_return		# Return if remaining length is zero
2838c2ecf20Sopenharmony_ci	add     $j, bufptmp		# Advance buf
2848c2ecf20Sopenharmony_ci.endr
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ciless_than_8:				# Length should be stored in
2878c2ecf20Sopenharmony_ci					# upper 3 bits of len_dw
2888c2ecf20Sopenharmony_ci	shl     $1, len_dw
2898c2ecf20Sopenharmony_ciless_than_8_post_shl1:
2908c2ecf20Sopenharmony_ci	jnc     less_than_4
2918c2ecf20Sopenharmony_ci	crc32l  (bufptmp), crc_init_dw	# CRC of 4 bytes
2928c2ecf20Sopenharmony_ci	jz      do_return		# return if remaining data is zero
2938c2ecf20Sopenharmony_ci	add     $4, bufptmp
2948c2ecf20Sopenharmony_ciless_than_4:				# Length should be stored in
2958c2ecf20Sopenharmony_ci					# upper 2 bits of len_dw
2968c2ecf20Sopenharmony_ci	shl     $1, len_dw
2978c2ecf20Sopenharmony_ci	jnc     less_than_2
2988c2ecf20Sopenharmony_ci	crc32w  (bufptmp), crc_init_dw	# CRC of 2 bytes
2998c2ecf20Sopenharmony_ci	jz      do_return		# return if remaining data is zero
3008c2ecf20Sopenharmony_ci	add     $2, bufptmp
3018c2ecf20Sopenharmony_ciless_than_2:				# Length should be stored in the MSB
3028c2ecf20Sopenharmony_ci					# of len_dw
3038c2ecf20Sopenharmony_ci	shl     $1, len_dw
3048c2ecf20Sopenharmony_ci	jnc     less_than_1
3058c2ecf20Sopenharmony_ci	crc32b  (bufptmp), crc_init_dw	# CRC of 1 byte
3068c2ecf20Sopenharmony_ciless_than_1:				# Length should be zero
3078c2ecf20Sopenharmony_cido_return:
3088c2ecf20Sopenharmony_ci	movq    crc_init, %rax
3098c2ecf20Sopenharmony_ci	popq    %rsi
3108c2ecf20Sopenharmony_ci	popq    %rdi
3118c2ecf20Sopenharmony_ci	popq    %rbx
3128c2ecf20Sopenharmony_ci        RET
3138c2ecf20Sopenharmony_ciSYM_FUNC_END(crc_pcl)
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci.section	.rodata, "a", @progbits
3168c2ecf20Sopenharmony_ci        ################################################################
3178c2ecf20Sopenharmony_ci        ## jump table        Table is 129 entries x 2 bytes each
3188c2ecf20Sopenharmony_ci        ################################################################
3198c2ecf20Sopenharmony_ci.align 4
3208c2ecf20Sopenharmony_cijump_table:
3218c2ecf20Sopenharmony_ci	i=0
3228c2ecf20Sopenharmony_ci.rept 129
3238c2ecf20Sopenharmony_ci.altmacro
3248c2ecf20Sopenharmony_ciJMPTBL_ENTRY %i
3258c2ecf20Sopenharmony_ci.noaltmacro
3268c2ecf20Sopenharmony_ci	i=i+1
3278c2ecf20Sopenharmony_ci.endr
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci	################################################################
3318c2ecf20Sopenharmony_ci	## PCLMULQDQ tables
3328c2ecf20Sopenharmony_ci	## Table is 128 entries x 2 words (8 bytes) each
3338c2ecf20Sopenharmony_ci	################################################################
3348c2ecf20Sopenharmony_ci.align 8
3358c2ecf20Sopenharmony_ciK_table:
3368c2ecf20Sopenharmony_ci	.long 0x493c7d27, 0x00000001
3378c2ecf20Sopenharmony_ci	.long 0xba4fc28e, 0x493c7d27
3388c2ecf20Sopenharmony_ci	.long 0xddc0152b, 0xf20c0dfe
3398c2ecf20Sopenharmony_ci	.long 0x9e4addf8, 0xba4fc28e
3408c2ecf20Sopenharmony_ci	.long 0x39d3b296, 0x3da6d0cb
3418c2ecf20Sopenharmony_ci	.long 0x0715ce53, 0xddc0152b
3428c2ecf20Sopenharmony_ci	.long 0x47db8317, 0x1c291d04
3438c2ecf20Sopenharmony_ci	.long 0x0d3b6092, 0x9e4addf8
3448c2ecf20Sopenharmony_ci	.long 0xc96cfdc0, 0x740eef02
3458c2ecf20Sopenharmony_ci	.long 0x878a92a7, 0x39d3b296
3468c2ecf20Sopenharmony_ci	.long 0xdaece73e, 0x083a6eec
3478c2ecf20Sopenharmony_ci	.long 0xab7aff2a, 0x0715ce53
3488c2ecf20Sopenharmony_ci	.long 0x2162d385, 0xc49f4f67
3498c2ecf20Sopenharmony_ci	.long 0x83348832, 0x47db8317
3508c2ecf20Sopenharmony_ci	.long 0x299847d5, 0x2ad91c30
3518c2ecf20Sopenharmony_ci	.long 0xb9e02b86, 0x0d3b6092
3528c2ecf20Sopenharmony_ci	.long 0x18b33a4e, 0x6992cea2
3538c2ecf20Sopenharmony_ci	.long 0xb6dd949b, 0xc96cfdc0
3548c2ecf20Sopenharmony_ci	.long 0x78d9ccb7, 0x7e908048
3558c2ecf20Sopenharmony_ci	.long 0xbac2fd7b, 0x878a92a7
3568c2ecf20Sopenharmony_ci	.long 0xa60ce07b, 0x1b3d8f29
3578c2ecf20Sopenharmony_ci	.long 0xce7f39f4, 0xdaece73e
3588c2ecf20Sopenharmony_ci	.long 0x61d82e56, 0xf1d0f55e
3598c2ecf20Sopenharmony_ci	.long 0xd270f1a2, 0xab7aff2a
3608c2ecf20Sopenharmony_ci	.long 0xc619809d, 0xa87ab8a8
3618c2ecf20Sopenharmony_ci	.long 0x2b3cac5d, 0x2162d385
3628c2ecf20Sopenharmony_ci	.long 0x65863b64, 0x8462d800
3638c2ecf20Sopenharmony_ci	.long 0x1b03397f, 0x83348832
3648c2ecf20Sopenharmony_ci	.long 0xebb883bd, 0x71d111a8
3658c2ecf20Sopenharmony_ci	.long 0xb3e32c28, 0x299847d5
3668c2ecf20Sopenharmony_ci	.long 0x064f7f26, 0xffd852c6
3678c2ecf20Sopenharmony_ci	.long 0xdd7e3b0c, 0xb9e02b86
3688c2ecf20Sopenharmony_ci	.long 0xf285651c, 0xdcb17aa4
3698c2ecf20Sopenharmony_ci	.long 0x10746f3c, 0x18b33a4e
3708c2ecf20Sopenharmony_ci	.long 0xc7a68855, 0xf37c5aee
3718c2ecf20Sopenharmony_ci	.long 0x271d9844, 0xb6dd949b
3728c2ecf20Sopenharmony_ci	.long 0x8e766a0c, 0x6051d5a2
3738c2ecf20Sopenharmony_ci	.long 0x93a5f730, 0x78d9ccb7
3748c2ecf20Sopenharmony_ci	.long 0x6cb08e5c, 0x18b0d4ff
3758c2ecf20Sopenharmony_ci	.long 0x6b749fb2, 0xbac2fd7b
3768c2ecf20Sopenharmony_ci	.long 0x1393e203, 0x21f3d99c
3778c2ecf20Sopenharmony_ci	.long 0xcec3662e, 0xa60ce07b
3788c2ecf20Sopenharmony_ci	.long 0x96c515bb, 0x8f158014
3798c2ecf20Sopenharmony_ci	.long 0xe6fc4e6a, 0xce7f39f4
3808c2ecf20Sopenharmony_ci	.long 0x8227bb8a, 0xa00457f7
3818c2ecf20Sopenharmony_ci	.long 0xb0cd4768, 0x61d82e56
3828c2ecf20Sopenharmony_ci	.long 0x39c7ff35, 0x8d6d2c43
3838c2ecf20Sopenharmony_ci	.long 0xd7a4825c, 0xd270f1a2
3848c2ecf20Sopenharmony_ci	.long 0x0ab3844b, 0x00ac29cf
3858c2ecf20Sopenharmony_ci	.long 0x0167d312, 0xc619809d
3868c2ecf20Sopenharmony_ci	.long 0xf6076544, 0xe9adf796
3878c2ecf20Sopenharmony_ci	.long 0x26f6a60a, 0x2b3cac5d
3888c2ecf20Sopenharmony_ci	.long 0xa741c1bf, 0x96638b34
3898c2ecf20Sopenharmony_ci	.long 0x98d8d9cb, 0x65863b64
3908c2ecf20Sopenharmony_ci	.long 0x49c3cc9c, 0xe0e9f351
3918c2ecf20Sopenharmony_ci	.long 0x68bce87a, 0x1b03397f
3928c2ecf20Sopenharmony_ci	.long 0x57a3d037, 0x9af01f2d
3938c2ecf20Sopenharmony_ci	.long 0x6956fc3b, 0xebb883bd
3948c2ecf20Sopenharmony_ci	.long 0x42d98888, 0x2cff42cf
3958c2ecf20Sopenharmony_ci	.long 0x3771e98f, 0xb3e32c28
3968c2ecf20Sopenharmony_ci	.long 0xb42ae3d9, 0x88f25a3a
3978c2ecf20Sopenharmony_ci	.long 0x2178513a, 0x064f7f26
3988c2ecf20Sopenharmony_ci	.long 0xe0ac139e, 0x4e36f0b0
3998c2ecf20Sopenharmony_ci	.long 0x170076fa, 0xdd7e3b0c
4008c2ecf20Sopenharmony_ci	.long 0x444dd413, 0xbd6f81f8
4018c2ecf20Sopenharmony_ci	.long 0x6f345e45, 0xf285651c
4028c2ecf20Sopenharmony_ci	.long 0x41d17b64, 0x91c9bd4b
4038c2ecf20Sopenharmony_ci	.long 0xff0dba97, 0x10746f3c
4048c2ecf20Sopenharmony_ci	.long 0xa2b73df1, 0x885f087b
4058c2ecf20Sopenharmony_ci	.long 0xf872e54c, 0xc7a68855
4068c2ecf20Sopenharmony_ci	.long 0x1e41e9fc, 0x4c144932
4078c2ecf20Sopenharmony_ci	.long 0x86d8e4d2, 0x271d9844
4088c2ecf20Sopenharmony_ci	.long 0x651bd98b, 0x52148f02
4098c2ecf20Sopenharmony_ci	.long 0x5bb8f1bc, 0x8e766a0c
4108c2ecf20Sopenharmony_ci	.long 0xa90fd27a, 0xa3c6f37a
4118c2ecf20Sopenharmony_ci	.long 0xb3af077a, 0x93a5f730
4128c2ecf20Sopenharmony_ci	.long 0x4984d782, 0xd7c0557f
4138c2ecf20Sopenharmony_ci	.long 0xca6ef3ac, 0x6cb08e5c
4148c2ecf20Sopenharmony_ci	.long 0x234e0b26, 0x63ded06a
4158c2ecf20Sopenharmony_ci	.long 0xdd66cbbb, 0x6b749fb2
4168c2ecf20Sopenharmony_ci	.long 0x4597456a, 0x4d56973c
4178c2ecf20Sopenharmony_ci	.long 0xe9e28eb4, 0x1393e203
4188c2ecf20Sopenharmony_ci	.long 0x7b3ff57a, 0x9669c9df
4198c2ecf20Sopenharmony_ci	.long 0xc9c8b782, 0xcec3662e
4208c2ecf20Sopenharmony_ci	.long 0x3f70cc6f, 0xe417f38a
4218c2ecf20Sopenharmony_ci	.long 0x93e106a4, 0x96c515bb
4228c2ecf20Sopenharmony_ci	.long 0x62ec6c6d, 0x4b9e0f71
4238c2ecf20Sopenharmony_ci	.long 0xd813b325, 0xe6fc4e6a
4248c2ecf20Sopenharmony_ci	.long 0x0df04680, 0xd104b8fc
4258c2ecf20Sopenharmony_ci	.long 0x2342001e, 0x8227bb8a
4268c2ecf20Sopenharmony_ci	.long 0x0a2a8d7e, 0x5b397730
4278c2ecf20Sopenharmony_ci	.long 0x6d9a4957, 0xb0cd4768
4288c2ecf20Sopenharmony_ci	.long 0xe8b6368b, 0xe78eb416
4298c2ecf20Sopenharmony_ci	.long 0xd2c3ed1a, 0x39c7ff35
4308c2ecf20Sopenharmony_ci	.long 0x995a5724, 0x61ff0e01
4318c2ecf20Sopenharmony_ci	.long 0x9ef68d35, 0xd7a4825c
4328c2ecf20Sopenharmony_ci	.long 0x0c139b31, 0x8d96551c
4338c2ecf20Sopenharmony_ci	.long 0xf2271e60, 0x0ab3844b
4348c2ecf20Sopenharmony_ci	.long 0x0b0bf8ca, 0x0bf80dd2
4358c2ecf20Sopenharmony_ci	.long 0x2664fd8b, 0x0167d312
4368c2ecf20Sopenharmony_ci	.long 0xed64812d, 0x8821abed
4378c2ecf20Sopenharmony_ci	.long 0x02ee03b2, 0xf6076544
4388c2ecf20Sopenharmony_ci	.long 0x8604ae0f, 0x6a45d2b2
4398c2ecf20Sopenharmony_ci	.long 0x363bd6b3, 0x26f6a60a
4408c2ecf20Sopenharmony_ci	.long 0x135c83fd, 0xd8d26619
4418c2ecf20Sopenharmony_ci	.long 0x5fabe670, 0xa741c1bf
4428c2ecf20Sopenharmony_ci	.long 0x35ec3279, 0xde87806c
4438c2ecf20Sopenharmony_ci	.long 0x00bcf5f6, 0x98d8d9cb
4448c2ecf20Sopenharmony_ci	.long 0x8ae00689, 0x14338754
4458c2ecf20Sopenharmony_ci	.long 0x17f27698, 0x49c3cc9c
4468c2ecf20Sopenharmony_ci	.long 0x58ca5f00, 0x5bd2011f
4478c2ecf20Sopenharmony_ci	.long 0xaa7c7ad5, 0x68bce87a
4488c2ecf20Sopenharmony_ci	.long 0xb5cfca28, 0xdd07448e
4498c2ecf20Sopenharmony_ci	.long 0xded288f8, 0x57a3d037
4508c2ecf20Sopenharmony_ci	.long 0x59f229bc, 0xdde8f5b9
4518c2ecf20Sopenharmony_ci	.long 0x6d390dec, 0x6956fc3b
4528c2ecf20Sopenharmony_ci	.long 0x37170390, 0xa3e3e02c
4538c2ecf20Sopenharmony_ci	.long 0x6353c1cc, 0x42d98888
4548c2ecf20Sopenharmony_ci	.long 0xc4584f5c, 0xd73c7bea
4558c2ecf20Sopenharmony_ci	.long 0xf48642e9, 0x3771e98f
4568c2ecf20Sopenharmony_ci	.long 0x531377e2, 0x80ff0093
4578c2ecf20Sopenharmony_ci	.long 0xdd35bc8d, 0xb42ae3d9
4588c2ecf20Sopenharmony_ci	.long 0xb25b29f2, 0x8fe4c34d
4598c2ecf20Sopenharmony_ci	.long 0x9a5ede41, 0x2178513a
4608c2ecf20Sopenharmony_ci	.long 0xa563905d, 0xdf99fc11
4618c2ecf20Sopenharmony_ci	.long 0x45cddf4e, 0xe0ac139e
4628c2ecf20Sopenharmony_ci	.long 0xacfa3103, 0x6c23e841
4638c2ecf20Sopenharmony_ci	.long 0xa51b6135, 0x170076fa
464