^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Implement fast CRC32C with PCLMULQDQ instructions. (x86_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * The white papers on CRC32C calculations with PCLMULQDQ instruction can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * downloaded from:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/crc-iscsi-polynomial-crc32-instruction-paper.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-paper.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2012 Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Wajdi Feghali <wajdi.k.feghali@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * James Guilford <james.guilford@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * David Cote <david.m.cote@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Tim Chen <tim.c.chen@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * This software is available to you under a choice of one of two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * licenses. You may choose to be licensed under the terms of the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * General Public License (GPL) Version 2, available from the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * COPYING in the main directory of this source tree, or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * OpenIB.org BSD license below:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Redistribution and use in source and binary forms, with or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * without modification, are permitted provided that the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * conditions are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * - Redistributions of source code must retain the above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * copyright notice, this list of conditions and the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * - Redistributions in binary form must reproduce the above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * copyright notice, this list of conditions and the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * disclaimer in the documentation and/or other materials
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <asm/nospec-branch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) ## ISCSI CRC 32 Implementation with crc32 and pclmulqdq Instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .macro LABEL prefix n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) \prefix\n\():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .macro JMPTBL_ENTRY i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .word crc_\i - crc_array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .macro JNC_LESS_THAN j
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) jnc less_than_\j
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) # Define threshold where buffers are considered "small" and routed to more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) # efficient "by-1" code. This "by-1" code only handles up to 255 bytes, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) # SMALL_SIZE can be no larger than 255.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define SMALL_SIZE 200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .if (SMALL_SIZE > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .error "SMALL_ SIZE must be < 256"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) # unsigned int crc_pcl(u8 *buffer, int len, unsigned int crc_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) SYM_FUNC_START(crc_pcl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define bufp rdi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define bufp_dw %edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define bufp_w %di
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define bufp_b %dil
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define bufptmp %rcx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define block_0 %rcx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define block_1 %rdx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define block_2 %r11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define len %rsi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define len_dw %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define len_w %si
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define len_b %sil
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define crc_init_arg %rdx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define tmp %rbx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define crc_init %r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define crc_init_dw %r8d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define crc1 %r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define crc2 %r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) pushq %rbx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) pushq %rdi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) pushq %rsi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ## Move crc_init for Linux to a different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) mov crc_init_arg, crc_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ## 1) ALIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) mov %bufp, bufptmp # rdi = *buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) neg %bufp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) and $7, %bufp # calculate the unalignment amount of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) # the address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) je proc_block # Skip if aligned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ## If len is less than 8 and we're unaligned, we need to jump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ## to special code to avoid reading beyond the end of the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) cmp $8, len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) jae do_align
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) # less_than_8 expects length in upper 3 bits of len_dw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) # less_than_8_post_shl1 expects length = carryflag * 8 + len_dw[31:30]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) shl $32-3+1, len_dw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) jmp less_than_8_post_shl1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) do_align:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #### Calculate CRC of unaligned bytes of the buffer (if any)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) movq (bufptmp), tmp # load a quadward from the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) add %bufp, bufptmp # align buffer pointer for quadword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) # processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) sub %bufp, len # update buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) align_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) crc32b %bl, crc_init_dw # compute crc32 of 1-byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) shr $8, tmp # get next byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) dec %bufp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) jne align_loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) proc_block:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ## 2) PROCESS BLOCKS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ## compute num of bytes to be processed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) movq len, tmp # save num bytes in tmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) cmpq $128*24, len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) jae full_block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) continue_block:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) cmpq $SMALL_SIZE, len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) jb small
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ## len < 128*24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) movq $2731, %rax # 2731 = ceil(2^16 / 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) mul len_dw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) shrq $16, %rax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ## eax contains floor(bytes / 24) = num 24-byte chunks to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ## process rax 24-byte chunks (128 >= rax >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ## compute end address of each block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ## block 0 (base addr + RAX * 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ## block 1 (base addr + RAX * 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ## block 2 (base addr + RAX * 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) lea (bufptmp, %rax, 8), block_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) lea (block_0, %rax, 8), block_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) lea (block_1, %rax, 8), block_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) xor crc1, crc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) xor crc2, crc2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ## branch into array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) lea jump_table(%rip), %bufp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) movzwq (%bufp, %rax, 2), len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) lea crc_array(%rip), %bufp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) lea (%bufp, len, 1), %bufp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) JMP_NOSPEC bufp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ## 2a) PROCESS FULL BLOCKS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) full_block:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) movl $128,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) lea 128*8*2(block_0), block_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) lea 128*8*3(block_0), block_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) add $128*8*1, block_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) xor crc1,crc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) xor crc2,crc2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) # Fall thruogh into top of crc array (crc_128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ## 3) CRC Array:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) crc_array:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) i=128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .rept 128-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .altmacro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) LABEL crc_ %i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) .noaltmacro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) crc32q -i*8(block_0), crc_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) crc32q -i*8(block_1), crc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) crc32q -i*8(block_2), crc2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) i=(i-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .endr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .altmacro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) LABEL crc_ %i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .noaltmacro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) crc32q -i*8(block_0), crc_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) crc32q -i*8(block_1), crc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) # SKIP crc32 -i*8(block_2), crc2 ; Don't do this one yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) mov block_2, block_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ## 4) Combine three results:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) lea (K_table-8)(%rip), %bufp # first entry is for idx 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) shlq $3, %rax # rax *= 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) pmovzxdq (%bufp,%rax), %xmm0 # 2 consts: K1:K2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) leal (%eax,%eax,2), %eax # rax *= 3 (total *24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) subq %rax, tmp # tmp -= rax*24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) movq crc_init, %xmm1 # CRC for block 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) pclmulqdq $0x00, %xmm0, %xmm1 # Multiply by K2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) movq crc1, %xmm2 # CRC for block 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) pclmulqdq $0x10, %xmm0, %xmm2 # Multiply by K1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) pxor %xmm2,%xmm1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) movq %xmm1, %rax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) xor -i*8(block_2), %rax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) mov crc2, crc_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) crc32 %rax, crc_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ## 5) Check for end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) LABEL crc_ 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) mov tmp, len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) cmp $128*24, tmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) jae full_block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) cmp $24, tmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) jae continue_block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) less_than_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) shl $32-4, len_dw # less_than_16 expects length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) # in upper 4 bits of len_dw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) jnc less_than_16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) crc32q (bufptmp), crc_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) crc32q 8(bufptmp), crc_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) jz do_return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) add $16, bufptmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) # len is less than 8 if we got here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) # less_than_8 expects length in upper 3 bits of len_dw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) # less_than_8_post_shl1 expects length = carryflag * 8 + len_dw[31:30]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) shl $2, len_dw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) jmp less_than_8_post_shl1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #######################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ## 6) LESS THAN 256-bytes REMAIN AT THIS POINT (8-bits of len are full)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) #######################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) small:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) shl $32-8, len_dw # Prepare len_dw for less_than_256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) j=256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) .rept 5 # j = {256, 128, 64, 32, 16}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .altmacro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) LABEL less_than_ %j # less_than_j: Length should be in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) # upper lg(j) bits of len_dw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) j=(j/2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) shl $1, len_dw # Get next MSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) JNC_LESS_THAN %j
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .noaltmacro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) i=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) .rept (j/8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) crc32q i(bufptmp), crc_init # Compute crc32 of 8-byte data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) i=i+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) .endr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) jz do_return # Return if remaining length is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) add $j, bufptmp # Advance buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) .endr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) less_than_8: # Length should be stored in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) # upper 3 bits of len_dw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) shl $1, len_dw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) less_than_8_post_shl1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) jnc less_than_4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) crc32l (bufptmp), crc_init_dw # CRC of 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) jz do_return # return if remaining data is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) add $4, bufptmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) less_than_4: # Length should be stored in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) # upper 2 bits of len_dw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) shl $1, len_dw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) jnc less_than_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) crc32w (bufptmp), crc_init_dw # CRC of 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) jz do_return # return if remaining data is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) add $2, bufptmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) less_than_2: # Length should be stored in the MSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) # of len_dw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) shl $1, len_dw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) jnc less_than_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) crc32b (bufptmp), crc_init_dw # CRC of 1 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) less_than_1: # Length should be zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) do_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) movq crc_init, %rax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) popq %rsi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) popq %rdi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) popq %rbx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) SYM_FUNC_END(crc_pcl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) .section .rodata, "a", @progbits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) ## jump table Table is 129 entries x 2 bytes each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) jump_table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) i=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) .rept 129
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) .altmacro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) JMPTBL_ENTRY %i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .noaltmacro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) i=i+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .endr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ## PCLMULQDQ tables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) ## Table is 128 entries x 2 words (8 bytes) each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) .align 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) K_table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) .long 0x493c7d27, 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .long 0xba4fc28e, 0x493c7d27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) .long 0xddc0152b, 0xf20c0dfe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) .long 0x9e4addf8, 0xba4fc28e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) .long 0x39d3b296, 0x3da6d0cb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) .long 0x0715ce53, 0xddc0152b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) .long 0x47db8317, 0x1c291d04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) .long 0x0d3b6092, 0x9e4addf8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) .long 0xc96cfdc0, 0x740eef02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) .long 0x878a92a7, 0x39d3b296
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) .long 0xdaece73e, 0x083a6eec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) .long 0xab7aff2a, 0x0715ce53
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) .long 0x2162d385, 0xc49f4f67
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) .long 0x83348832, 0x47db8317
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) .long 0x299847d5, 0x2ad91c30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) .long 0xb9e02b86, 0x0d3b6092
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) .long 0x18b33a4e, 0x6992cea2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) .long 0xb6dd949b, 0xc96cfdc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) .long 0x78d9ccb7, 0x7e908048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) .long 0xbac2fd7b, 0x878a92a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .long 0xa60ce07b, 0x1b3d8f29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) .long 0xce7f39f4, 0xdaece73e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) .long 0x61d82e56, 0xf1d0f55e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) .long 0xd270f1a2, 0xab7aff2a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) .long 0xc619809d, 0xa87ab8a8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) .long 0x2b3cac5d, 0x2162d385
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) .long 0x65863b64, 0x8462d800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) .long 0x1b03397f, 0x83348832
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) .long 0xebb883bd, 0x71d111a8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) .long 0xb3e32c28, 0x299847d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) .long 0x064f7f26, 0xffd852c6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) .long 0xdd7e3b0c, 0xb9e02b86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) .long 0xf285651c, 0xdcb17aa4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) .long 0x10746f3c, 0x18b33a4e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .long 0xc7a68855, 0xf37c5aee
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .long 0x271d9844, 0xb6dd949b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .long 0x8e766a0c, 0x6051d5a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .long 0x93a5f730, 0x78d9ccb7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) .long 0x6cb08e5c, 0x18b0d4ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) .long 0x6b749fb2, 0xbac2fd7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) .long 0x1393e203, 0x21f3d99c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) .long 0xcec3662e, 0xa60ce07b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) .long 0x96c515bb, 0x8f158014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) .long 0xe6fc4e6a, 0xce7f39f4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) .long 0x8227bb8a, 0xa00457f7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .long 0xb0cd4768, 0x61d82e56
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .long 0x39c7ff35, 0x8d6d2c43
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) .long 0xd7a4825c, 0xd270f1a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) .long 0x0ab3844b, 0x00ac29cf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .long 0x0167d312, 0xc619809d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) .long 0xf6076544, 0xe9adf796
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .long 0x26f6a60a, 0x2b3cac5d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) .long 0xa741c1bf, 0x96638b34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) .long 0x98d8d9cb, 0x65863b64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) .long 0x49c3cc9c, 0xe0e9f351
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .long 0x68bce87a, 0x1b03397f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .long 0x57a3d037, 0x9af01f2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .long 0x6956fc3b, 0xebb883bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .long 0x42d98888, 0x2cff42cf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .long 0x3771e98f, 0xb3e32c28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) .long 0xb42ae3d9, 0x88f25a3a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) .long 0x2178513a, 0x064f7f26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) .long 0xe0ac139e, 0x4e36f0b0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) .long 0x170076fa, 0xdd7e3b0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) .long 0x444dd413, 0xbd6f81f8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) .long 0x6f345e45, 0xf285651c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) .long 0x41d17b64, 0x91c9bd4b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) .long 0xff0dba97, 0x10746f3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) .long 0xa2b73df1, 0x885f087b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) .long 0xf872e54c, 0xc7a68855
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) .long 0x1e41e9fc, 0x4c144932
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) .long 0x86d8e4d2, 0x271d9844
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .long 0x651bd98b, 0x52148f02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .long 0x5bb8f1bc, 0x8e766a0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) .long 0xa90fd27a, 0xa3c6f37a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .long 0xb3af077a, 0x93a5f730
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .long 0x4984d782, 0xd7c0557f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .long 0xca6ef3ac, 0x6cb08e5c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) .long 0x234e0b26, 0x63ded06a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .long 0xdd66cbbb, 0x6b749fb2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .long 0x4597456a, 0x4d56973c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .long 0xe9e28eb4, 0x1393e203
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .long 0x7b3ff57a, 0x9669c9df
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) .long 0xc9c8b782, 0xcec3662e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) .long 0x3f70cc6f, 0xe417f38a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) .long 0x93e106a4, 0x96c515bb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .long 0x62ec6c6d, 0x4b9e0f71
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .long 0xd813b325, 0xe6fc4e6a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) .long 0x0df04680, 0xd104b8fc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .long 0x2342001e, 0x8227bb8a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .long 0x0a2a8d7e, 0x5b397730
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .long 0x6d9a4957, 0xb0cd4768
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .long 0xe8b6368b, 0xe78eb416
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) .long 0xd2c3ed1a, 0x39c7ff35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) .long 0x995a5724, 0x61ff0e01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) .long 0x9ef68d35, 0xd7a4825c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .long 0x0c139b31, 0x8d96551c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) .long 0xf2271e60, 0x0ab3844b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .long 0x0b0bf8ca, 0x0bf80dd2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .long 0x2664fd8b, 0x0167d312
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) .long 0xed64812d, 0x8821abed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .long 0x02ee03b2, 0xf6076544
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .long 0x8604ae0f, 0x6a45d2b2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .long 0x363bd6b3, 0x26f6a60a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .long 0x135c83fd, 0xd8d26619
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) .long 0x5fabe670, 0xa741c1bf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) .long 0x35ec3279, 0xde87806c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .long 0x00bcf5f6, 0x98d8d9cb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .long 0x8ae00689, 0x14338754
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .long 0x17f27698, 0x49c3cc9c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) .long 0x58ca5f00, 0x5bd2011f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) .long 0xaa7c7ad5, 0x68bce87a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) .long 0xb5cfca28, 0xdd07448e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) .long 0xded288f8, 0x57a3d037
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) .long 0x59f229bc, 0xdde8f5b9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) .long 0x6d390dec, 0x6956fc3b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) .long 0x37170390, 0xa3e3e02c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) .long 0x6353c1cc, 0x42d98888
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) .long 0xc4584f5c, 0xd73c7bea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) .long 0xf48642e9, 0x3771e98f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) .long 0x531377e2, 0x80ff0093
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .long 0xdd35bc8d, 0xb42ae3d9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .long 0xb25b29f2, 0x8fe4c34d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) .long 0x9a5ede41, 0x2178513a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .long 0xa563905d, 0xdf99fc11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .long 0x45cddf4e, 0xe0ac139e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) .long 0xacfa3103, 0x6c23e841
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .long 0xa51b6135, 0x170076fa