1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ; Copyright(c) 2011-2015 Intel Corporation All rights reserved.
4 ; Redistribution and use in source and binary forms, with or without
5 ; modification, are permitted provided that the following conditions
7 ; * Redistributions of source code must retain the above copyright
8 ; notice, this list of conditions and the following disclaimer.
9 ; * Redistributions in binary form must reproduce the above copyright
10 ; notice, this list of conditions and the following disclaimer in
11 ; the documentation and/or other materials provided with the
13 ; * Neither the name of Intel Corporation nor the names of its
14 ; contributors may be used to endorse or promote products derived
15 ; from this software without specific prior written permission.
17 ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 ; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 ; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 ; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 ; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 ; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 ; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 ; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 ; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
30 ;;; ISCSI CRC 32 Implementation with crc32 and pclmulqdq Instruction
32 %include "reg_sizes.asm"
35 %define CONCAT(a,b,c) a %+ b %+ c
37 ; Define threshold where buffers are considered "small" and routed to more
38 ; efficient "by-1" code. This "by-1" code only handles up to 255 bytes, so
39 ; SMALL_SIZE can be no larger than 256.
40 %define SMALL_SIZE 200
42 %if (SMALL_SIZE > 256)
43 %error SMALL_ SIZE must be <= 256
44 % error ; needed because '%error' actually generates only a warning
47 ;;; unsigned int crc32_iscsi_01(unsigned char * buffer, int len, unsigned int crc_init);
53 global crc32_iscsi_01:function
56 %ifidn __OUTPUT_FORMAT__, elf64
69 %define crc_init_arg rdx
87 %define crc_init_dw r8d
95 ;; Move crc_init for Linux to a different reg
96 %ifidn __OUTPUT_FORMAT__, elf64
97 mov crc_init, crc_init_arg
100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
101 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
102 ;; 1) ALIGN: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
103 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
105 mov bufptmp, bufp ;; rdi = *buf
107 and bufp, 7 ;; calculate the unalignment amount of
109 je proc_block ;; Skip if aligned
111 ;; If len is less than 8 and we're unaligned, we need to jump
112 ;; to special code to avoid reading beyond the end of the buffer
116 ;;;; Calculate CRC of unaligned bytes of the buffer (if any) ;;;
117 mov tmp, [bufptmp] ;; load a quadword from the buffer
118 add bufptmp, bufp ;; align buffer pointer for quadword
120 sub len, bufp ;; update buffer length
122 crc32 crc_init_dw, bl ;; compute crc32 of 1-byte
123 shr tmp, 8 ;; get next byte
129 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
130 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
131 ;; 2) PROCESS BLOCKS: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
132 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
134 ;; compute num of bytes to be processed
135 mov tmp, len ;; save num bytes in tmp
145 mov rax, 2731 ;; 2731 = ceil(2^16 / 24)
149 ;; eax contains floor(bytes / 24) = num 24-byte chunks to do
151 ;; process rax 24-byte chunks (128 >= rax >= 0)
153 ;; compute end address of each block
154 ;; rdi -> block 0 (base addr + RAX * 8)
155 ;; rsi -> block 1 (base addr + RAX * 16)
156 ;; r11 -> block 2 (base addr + RAX * 24)
157 lea block_0, [bufptmp + rax * 8]
158 lea block_1, [block_0 + rax * 8]
159 lea block_2, [block_1 + rax * 8]
165 lea bufp, [jump_table]
166 movzx len, word [bufp + rax * 2] ;; len is offset from crc_array
167 lea bufp, [bufp + len + crc_array - jump_table]
170 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
171 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
172 ;; 2a) PROCESS FULL BLOCKS: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
173 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
176 lea block_1, [block_0 + 128*8*2]
177 lea block_2, [block_0 + 128*8*3]
183 ; ;; branch into array
184 ; jmp CONCAT(crc_,128,)
185 ; Fall thruogh into top of crc array (crc_128)
187 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
188 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
189 ;; 3) CRC Array: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
190 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
196 crc32 crc_init, qword [block_0 - i*8]
197 crc32 crc1, qword [block_1 - i*8]
198 crc32 crc2, qword [block_2 - i*8]
200 %if i > 128*8 / 32 ; prefetch next 3KB data
201 prefetchnta [block_2 + 128*32 - i*32]
207 crc32 crc_init, qword [block_0 - i*8]
208 crc32 crc1, qword [block_1 - i*8]
209 ; SKIP ;crc32 crc2, [block_2 - i*8] ; Don't do this one yet
213 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
214 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
215 ;; 4) Combine three results: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
216 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
218 lea bufp, [K_table - 16] ; first entry is for idx 1
219 shl rax, 3 ; rax *= 8
220 sub tmp, rax ; tmp -= rax*8
222 sub tmp, rax ; tmp -= rax*16 (total tmp -= rax*24)
225 movdqa xmm0, [bufp] ; 2 consts: K1:K2
227 movq xmm1, crc_init ; CRC for block 1
228 pclmulqdq xmm1, xmm0, 0x00 ; Multiply by K2
230 movq xmm2, crc1 ; CRC for block 2
231 pclmulqdq xmm2, xmm0, 0x10 ; Multiply by K1
235 xor rax, [block_2 - i*8]
239 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
240 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
241 ;; 5) Check for end: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
242 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
252 ;; now fewer than 24 bytes remain
259 shl ebx, 29 ; size now in bits 31:29
263 shl ebx, 1 ; shift out into carry MSB (orig size & 4)
265 crc32 crc_init_dw, bufp_dw
267 shr bufp, 32 ; shift data down by 4 bytes
269 shl ebx, 1 ; shift out into carry MSB (orig size & 2)
271 crc32 crc_init_dw, bufp_w
273 shr bufp, 16 ; shift data down by 2 bytes
275 crc32 crc_init_dw, bufp_b
285 crc32 crc_init, qword [bufptmp]
287 shl ebx, 29 ; size (0...7) in bits 31:29
296 crc32 crc_init, qword [bufptmp]
297 crc32 crc_init, qword [bufptmp+8]
299 shl ebx, 29 ; size (0...7) in bits 31:29
310 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
311 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
312 ;; Handle the case of fewer than 8 bytes, unaligned. In this case
313 ;; we can't read 8 bytes, as this might go beyond the end of the buffer
314 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
319 crc32 crc_init_dw, dword[bufptmp]
324 crc32 crc_init_dw, word[bufptmp]
329 crc32 crc_init_dw, byte[bufptmp]
336 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
337 ;;4) LESS THAN 256-bytes REMAIN AT THIS POINT (8-bits of len are full)
343 shl len_b, 1 ;; shift-out MSB (bit-7)
344 jnc bit7 ;; jump to bit-6 if bit-7 == 0
347 crc32 rax, qword [bufptmp+i] ;; compute crc32 of 8-byte data
350 je do_return2 ;; return if remaining data is zero
351 add bufptmp, 128 ;; buf +=64; (next 64 bytes)
354 shl len_b, 1 ;; shift-out MSB (bit-7)
355 jnc bit6 ;; jump to bit-6 if bit-7 == 0
358 crc32 rax, qword [bufptmp+i] ;; compute crc32 of 8-byte data
361 je do_return2 ;; return if remaining data is zero
362 add bufptmp, 64 ;; buf +=64; (next 64 bytes)
364 shl len_b, 1 ;; shift-out MSB (bit-6)
365 jnc bit5 ;; jump to bit-5 if bit-6 == 0
368 crc32 rax, qword [bufptmp+i] ;; compute crc32 of 8-byte data
371 je do_return2 ;; return if remaining data is zero
372 add bufptmp, 32 ;; buf +=32; (next 32 bytes)
374 shl len_b, 1 ;; shift-out MSB (bit-5)
375 jnc bit4 ;; jump to bit-4 if bit-5 == 0
378 crc32 rax, qword [bufptmp+i] ;; compute crc32 of 8-byte data
381 je do_return2 ;; return if remaining data is zero
382 add bufptmp, 16 ;; buf +=16; (next 16 bytes)
384 shl len_b, 1 ;; shift-out MSB (bit-4)
385 jnc bit3 ;; jump to bit-3 if bit-4 == 0
386 crc32 rax, qword [bufptmp] ;; compute crc32 of 8-byte data
387 je do_return2 ;; return if remaining data is zero
388 add bufptmp, 8 ;; buf +=8; (next 8 bytes)
390 mov rbx, qword [bufptmp] ;; load a 8-bytes from the buffer:
391 shl len_b, 1 ;; shift-out MSB (bit-3)
392 jnc bit2 ;; jump to bit-2 if bit-3 == 0
393 crc32 eax, ebx ;; compute crc32 of 4-byte data
394 je do_return2 ;; return if remaining data is zero
395 shr rbx, 32 ;; get next 3 bytes
397 shl len_b, 1 ;; shift-out MSB (bit-2)
398 jnc bit1 ;; jump to bit-1 if bit-2 == 0
399 crc32 eax, bx ;; compute crc32 of 2-byte data
400 je do_return2 ;; return if remaining data is zero
401 shr rbx, 16 ;; next byte
405 crc32 eax, bl ;; compute crc32 of 1-byte data
406 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
407 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
417 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
418 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
419 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
420 ;; jump table ;; Table is 129 entries x 2 bytes each
421 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
426 dw CONCAT(crc_,i,) - crc_array
432 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
433 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
434 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
436 ;; Table is 128 entries x 2 quad words each
437 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
441 dq 0x14cd00bd6, 0x105ec76f0
442 dq 0x0ba4fc28e, 0x14cd00bd6
443 dq 0x1d82c63da, 0x0f20c0dfe
444 dq 0x09e4addf8, 0x0ba4fc28e
445 dq 0x039d3b296, 0x1384aa63a
446 dq 0x102f9b8a2, 0x1d82c63da
447 dq 0x14237f5e6, 0x01c291d04
448 dq 0x00d3b6092, 0x09e4addf8
449 dq 0x0c96cfdc0, 0x0740eef02
450 dq 0x18266e456, 0x039d3b296
451 dq 0x0daece73e, 0x0083a6eec
452 dq 0x0ab7aff2a, 0x102f9b8a2
453 dq 0x1248ea574, 0x1c1733996
454 dq 0x083348832, 0x14237f5e6
455 dq 0x12c743124, 0x02ad91c30
456 dq 0x0b9e02b86, 0x00d3b6092
457 dq 0x018b33a4e, 0x06992cea2
458 dq 0x1b331e26a, 0x0c96cfdc0
459 dq 0x17d35ba46, 0x07e908048
460 dq 0x1bf2e8b8a, 0x18266e456
461 dq 0x1a3e0968a, 0x11ed1f9d8
462 dq 0x0ce7f39f4, 0x0daece73e
463 dq 0x061d82e56, 0x0f1d0f55e
464 dq 0x0d270f1a2, 0x0ab7aff2a
465 dq 0x1c3f5f66c, 0x0a87ab8a8
466 dq 0x12ed0daac, 0x1248ea574
467 dq 0x065863b64, 0x08462d800
468 dq 0x11eef4f8e, 0x083348832
469 dq 0x1ee54f54c, 0x071d111a8
470 dq 0x0b3e32c28, 0x12c743124
471 dq 0x0064f7f26, 0x0ffd852c6
472 dq 0x0dd7e3b0c, 0x0b9e02b86
473 dq 0x0f285651c, 0x0dcb17aa4
474 dq 0x010746f3c, 0x018b33a4e
475 dq 0x1c24afea4, 0x0f37c5aee
476 dq 0x0271d9844, 0x1b331e26a
477 dq 0x08e766a0c, 0x06051d5a2
478 dq 0x093a5f730, 0x17d35ba46
479 dq 0x06cb08e5c, 0x11d5ca20e
480 dq 0x06b749fb2, 0x1bf2e8b8a
481 dq 0x1167f94f2, 0x021f3d99c
482 dq 0x0cec3662e, 0x1a3e0968a
483 dq 0x19329634a, 0x08f158014
484 dq 0x0e6fc4e6a, 0x0ce7f39f4
485 dq 0x08227bb8a, 0x1a5e82106
486 dq 0x0b0cd4768, 0x061d82e56
487 dq 0x13c2b89c4, 0x188815ab2
488 dq 0x0d7a4825c, 0x0d270f1a2
489 dq 0x10f5ff2ba, 0x105405f3e
490 dq 0x00167d312, 0x1c3f5f66c
491 dq 0x0f6076544, 0x0e9adf796
492 dq 0x026f6a60a, 0x12ed0daac
493 dq 0x1a2adb74e, 0x096638b34
494 dq 0x19d34af3a, 0x065863b64
495 dq 0x049c3cc9c, 0x1e50585a0
496 dq 0x068bce87a, 0x11eef4f8e
497 dq 0x1524fa6c6, 0x19f1c69dc
498 dq 0x16cba8aca, 0x1ee54f54c
499 dq 0x042d98888, 0x12913343e
500 dq 0x1329d9f7e, 0x0b3e32c28
501 dq 0x1b1c69528, 0x088f25a3a
502 dq 0x02178513a, 0x0064f7f26
503 dq 0x0e0ac139e, 0x04e36f0b0
504 dq 0x0170076fa, 0x0dd7e3b0c
505 dq 0x141a1a2e2, 0x0bd6f81f8
506 dq 0x16ad828b4, 0x0f285651c
507 dq 0x041d17b64, 0x19425cbba
508 dq 0x1fae1cc66, 0x010746f3c
509 dq 0x1a75b4b00, 0x18db37e8a
510 dq 0x0f872e54c, 0x1c24afea4
511 dq 0x01e41e9fc, 0x04c144932
512 dq 0x086d8e4d2, 0x0271d9844
513 dq 0x160f7af7a, 0x052148f02
514 dq 0x05bb8f1bc, 0x08e766a0c
515 dq 0x0a90fd27a, 0x0a3c6f37a
516 dq 0x0b3af077a, 0x093a5f730
517 dq 0x04984d782, 0x1d22c238e
518 dq 0x0ca6ef3ac, 0x06cb08e5c
519 dq 0x0234e0b26, 0x063ded06a
520 dq 0x1d88abd4a, 0x06b749fb2
521 dq 0x04597456a, 0x04d56973c
522 dq 0x0e9e28eb4, 0x1167f94f2
523 dq 0x07b3ff57a, 0x19385bf2e
524 dq 0x0c9c8b782, 0x0cec3662e
525 dq 0x13a9cba9e, 0x0e417f38a
526 dq 0x093e106a4, 0x19329634a
527 dq 0x167001a9c, 0x14e727980
528 dq 0x1ddffc5d4, 0x0e6fc4e6a
529 dq 0x00df04680, 0x0d104b8fc
530 dq 0x02342001e, 0x08227bb8a
531 dq 0x00a2a8d7e, 0x05b397730
532 dq 0x168763fa6, 0x0b0cd4768
533 dq 0x1ed5a407a, 0x0e78eb416
534 dq 0x0d2c3ed1a, 0x13c2b89c4
535 dq 0x0995a5724, 0x1641378f0
536 dq 0x19b1afbc4, 0x0d7a4825c
537 dq 0x109ffedc0, 0x08d96551c
538 dq 0x0f2271e60, 0x10f5ff2ba
539 dq 0x00b0bf8ca, 0x00bf80dd2
540 dq 0x123888b7a, 0x00167d312
541 dq 0x1e888f7dc, 0x18dcddd1c
542 dq 0x002ee03b2, 0x0f6076544
543 dq 0x183e8d8fe, 0x06a45d2b2
544 dq 0x133d7a042, 0x026f6a60a
545 dq 0x116b0f50c, 0x1dd3e10e8
546 dq 0x05fabe670, 0x1a2adb74e
547 dq 0x130004488, 0x0de87806c
548 dq 0x000bcf5f6, 0x19d34af3a
549 dq 0x18f0c7078, 0x014338754
550 dq 0x017f27698, 0x049c3cc9c
551 dq 0x058ca5f00, 0x15e3e77ee
552 dq 0x1af900c24, 0x068bce87a
553 dq 0x0b5cfca28, 0x0dd07448e
554 dq 0x0ded288f8, 0x1524fa6c6
555 dq 0x059f229bc, 0x1d8048348
556 dq 0x06d390dec, 0x16cba8aca
557 dq 0x037170390, 0x0a3e3e02c
558 dq 0x06353c1cc, 0x042d98888
559 dq 0x0c4584f5c, 0x0d73c7bea
560 dq 0x1f16a3418, 0x1329d9f7e
561 dq 0x0531377e2, 0x185137662
562 dq 0x1d8d9ca7c, 0x1b1c69528
563 dq 0x0b25b29f2, 0x18a08b5bc
564 dq 0x19fb2a8b0, 0x02178513a
565 dq 0x1a08fe6ac, 0x1da758ae0
566 dq 0x045cddf4e, 0x0e0ac139e
567 dq 0x1a91647f2, 0x169cf9eb0
568 dq 0x1a0f717c4, 0x0170076fa
570 ;;; func core, ver, snum
571 slversion crc32_iscsi_01, 01, 03, 0015