1e1f5284fSGreg Tucker;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2e1f5284fSGreg Tucker; Copyright(c) 2011-2017 Intel Corporation All rights reserved. 3e1f5284fSGreg Tucker; 4e1f5284fSGreg Tucker; Redistribution and use in source and binary forms, with or without 5e1f5284fSGreg Tucker; modification, are permitted provided that the following conditions 6e1f5284fSGreg Tucker; are met: 7e1f5284fSGreg Tucker; * Redistributions of source code must retain the above copyright 8e1f5284fSGreg Tucker; notice, this list of conditions and the following disclaimer. 9e1f5284fSGreg Tucker; * Redistributions in binary form must reproduce the above copyright 10e1f5284fSGreg Tucker; notice, this list of conditions and the following disclaimer in 11e1f5284fSGreg Tucker; the documentation and/or other materials provided with the 12e1f5284fSGreg Tucker; distribution. 13e1f5284fSGreg Tucker; * Neither the name of Intel Corporation nor the names of its 14e1f5284fSGreg Tucker; contributors may be used to endorse or promote products derived 15e1f5284fSGreg Tucker; from this software without specific prior written permission. 16e1f5284fSGreg Tucker; 17e1f5284fSGreg Tucker; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18e1f5284fSGreg Tucker; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19e1f5284fSGreg Tucker; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20e1f5284fSGreg Tucker; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21e1f5284fSGreg Tucker; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22e1f5284fSGreg Tucker; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23e1f5284fSGreg Tucker; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24e1f5284fSGreg Tucker; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25e1f5284fSGreg Tucker; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26e1f5284fSGreg Tucker; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27e1f5284fSGreg Tucker; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28e1f5284fSGreg Tucker;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 29e1f5284fSGreg Tucker 30e1f5284fSGreg Tucker; uint32_t adler32_avx2(uint32_t init, const unsigned char *buf, uint64_t len) 31e1f5284fSGreg Tucker 32e1f5284fSGreg Tucker%define LIMIT 5552 33e1f5284fSGreg Tucker%define BASE 0xFFF1 ; 65521 34e1f5284fSGreg Tucker 35e1f5284fSGreg Tucker%include "reg_sizes.asm" 36e1f5284fSGreg Tucker 37e1f5284fSGreg Tuckerdefault rel 38e1f5284fSGreg Tucker[bits 64] 39e1f5284fSGreg Tucker 40e1f5284fSGreg Tucker; need to keep free: eax, ecx, edx 41e1f5284fSGreg Tucker 42e1f5284fSGreg Tucker%ifidn __OUTPUT_FORMAT__, elf64 43e1f5284fSGreg Tucker %define arg1 rdi 44e1f5284fSGreg Tucker %define arg2 rsi 45e1f5284fSGreg Tucker %define arg3 rdx 46e1f5284fSGreg Tucker 47e1f5284fSGreg Tucker %define init_d edi 48e1f5284fSGreg Tucker %define data r9 49e1f5284fSGreg Tucker %define size r10 50e1f5284fSGreg Tucker %define s r11 51e1f5284fSGreg Tucker %define a_d r12d 52e1f5284fSGreg Tucker %define b_d r8d 53e1f5284fSGreg Tucker %define end r13 54e1f5284fSGreg Tucker 55cd888f01SH.J. Lu %define func(x) x: endbranch 56e1f5284fSGreg Tucker %macro FUNC_SAVE 0 57e1f5284fSGreg Tucker push r12 58e1f5284fSGreg Tucker push r13 59e1f5284fSGreg Tucker %endmacro 60e1f5284fSGreg Tucker%macro FUNC_RESTORE 0 61e1f5284fSGreg Tucker pop r13 62e1f5284fSGreg Tucker pop r12 63e1f5284fSGreg Tucker %endmacro 64e1f5284fSGreg Tucker%endif 65e1f5284fSGreg Tucker 66e1f5284fSGreg Tucker 67e1f5284fSGreg Tucker%ifidn __OUTPUT_FORMAT__, win64 68e1f5284fSGreg Tucker %define arg1 rcx 69e1f5284fSGreg Tucker %define arg2 rdx 70e1f5284fSGreg Tucker %define arg3 r8 71e1f5284fSGreg Tucker 72e1f5284fSGreg Tucker %define init_d r12d 73e1f5284fSGreg Tucker %define data r9 74e1f5284fSGreg Tucker %define size r10 75e1f5284fSGreg Tucker %define s r11 76e1f5284fSGreg Tucker %define a_d esi 77e1f5284fSGreg Tucker %define b_d edi 78e1f5284fSGreg Tucker %define end r13 79e1f5284fSGreg Tucker 80e1f5284fSGreg Tucker %define stack_size 5*8 ; must be an odd multiple of 8 81e1f5284fSGreg Tucker %define func(x) proc_frame x 82e1f5284fSGreg Tucker %macro FUNC_SAVE 0 83e1f5284fSGreg Tucker alloc_stack stack_size 84e1f5284fSGreg Tucker save_reg rdi, 0*8 85e1f5284fSGreg Tucker save_reg rsi, 1*8 86e1f5284fSGreg Tucker save_reg r12, 2*8 87e1f5284fSGreg Tucker save_reg r13, 3*8 88e1f5284fSGreg Tucker end_prolog 89*1500db75SColin Ian King mov init_d, ecx ; initialize init_d from arg1 to keep ecx free 90e1f5284fSGreg Tucker %endmacro 91e1f5284fSGreg Tucker 92e1f5284fSGreg Tucker %macro FUNC_RESTORE 0 93e1f5284fSGreg Tucker mov rdi, [rsp + 0*8] 94e1f5284fSGreg Tucker mov rsi, [rsp + 1*8] 95e1f5284fSGreg Tucker mov r12, [rsp + 2*8] 96e1f5284fSGreg Tucker mov r13, [rsp + 3*8] 97e1f5284fSGreg Tucker add rsp, stack_size 98e1f5284fSGreg Tucker %endmacro 99e1f5284fSGreg Tucker%endif 100e1f5284fSGreg Tucker 101e1f5284fSGreg Tucker%define xa xmm0 102e1f5284fSGreg Tucker%define xb xmm1 103e1f5284fSGreg Tucker%define xdata0 xmm2 104e1f5284fSGreg Tucker%define xdata1 xmm3 105e1f5284fSGreg Tucker%define xsa xmm4 106e1f5284fSGreg Tucker 107ede04f0aSGreg Tucker[bits 64] 108ede04f0aSGreg Tuckerdefault rel 109ede04f0aSGreg Tuckersection .text 110ede04f0aSGreg Tucker 111ede04f0aSGreg Tuckermk_global adler32_sse, function 112e1f5284fSGreg Tuckerfunc(adler32_sse) 113e1f5284fSGreg Tucker FUNC_SAVE 114e1f5284fSGreg Tucker 115e1f5284fSGreg Tucker mov data, arg2 116e1f5284fSGreg Tucker mov size, arg3 117e1f5284fSGreg Tucker 118e1f5284fSGreg Tucker mov b_d, init_d 119e1f5284fSGreg Tucker shr b_d, 16 120e1f5284fSGreg Tucker and init_d, 0xFFFF 121e1f5284fSGreg Tucker cmp size, 32 122e1f5284fSGreg Tucker jb .lt64 123e1f5284fSGreg Tucker movd xa, init_d 124e1f5284fSGreg Tucker pxor xb, xb 125e1f5284fSGreg Tucker.sloop1: 126e1f5284fSGreg Tucker mov s, LIMIT 127e1f5284fSGreg Tucker cmp s, size 128e1f5284fSGreg Tucker cmova s, size ; s = min(size, LIMIT) 129e1f5284fSGreg Tucker lea end, [data + s - 7] 130e1f5284fSGreg Tucker cmp data, end 131e1f5284fSGreg Tucker jae .skip_loop_1a 132e1f5284fSGreg Tuckeralign 32 133e1f5284fSGreg Tucker.sloop1a: 134e1f5284fSGreg Tucker ; do 8 adds 135e1f5284fSGreg Tucker pmovzxbd xdata0, [data] 136e1f5284fSGreg Tucker pmovzxbd xdata1, [data + 4] 137e1f5284fSGreg Tucker add data, 8 138e1f5284fSGreg Tucker paddd xa, xdata0 139e1f5284fSGreg Tucker paddd xb, xa 140e1f5284fSGreg Tucker paddd xa, xdata1 141e1f5284fSGreg Tucker paddd xb, xa 142e1f5284fSGreg Tucker cmp data, end 143e1f5284fSGreg Tucker jb .sloop1a 144e1f5284fSGreg Tucker 145e1f5284fSGreg Tucker.skip_loop_1a: 146e1f5284fSGreg Tucker add end, 7 147e1f5284fSGreg Tucker 148e1f5284fSGreg Tucker test s, 7 149e1f5284fSGreg Tucker jnz .do_final 150e1f5284fSGreg Tucker 151e1f5284fSGreg Tucker ; either we're done, or we just did LIMIT 152e1f5284fSGreg Tucker sub size, s 153e1f5284fSGreg Tucker 154e1f5284fSGreg Tucker ; reduce 155e1f5284fSGreg Tucker pslld xb, 2 ; b is scaled by 4 156e1f5284fSGreg Tucker movdqa xsa, xa ; scaled a 157e1f5284fSGreg Tucker pmulld xsa, [A_SCALE] 158e1f5284fSGreg Tucker 159e1f5284fSGreg Tucker phaddd xa, xa 160e1f5284fSGreg Tucker phaddd xb, xb 161e1f5284fSGreg Tucker phaddd xsa, xsa 162e1f5284fSGreg Tucker phaddd xa, xa 163e1f5284fSGreg Tucker phaddd xb, xb 164e1f5284fSGreg Tucker phaddd xsa, xsa 165e1f5284fSGreg Tucker 166e1f5284fSGreg Tucker movd eax, xa 167e1f5284fSGreg Tucker xor edx, edx 168e1f5284fSGreg Tucker mov ecx, BASE 169e1f5284fSGreg Tucker div ecx ; divide edx:eax by ecx, quot->eax, rem->edx 170e1f5284fSGreg Tucker mov a_d, edx 171e1f5284fSGreg Tucker 172e1f5284fSGreg Tucker psubd xb, xsa 173e1f5284fSGreg Tucker movd eax, xb 174e1f5284fSGreg Tucker add eax, b_d 175e1f5284fSGreg Tucker xor edx, edx 176e1f5284fSGreg Tucker mov ecx, BASE 177e1f5284fSGreg Tucker div ecx ; divide edx:eax by ecx, quot->eax, rem->edx 178e1f5284fSGreg Tucker mov b_d, edx 179e1f5284fSGreg Tucker 180e1f5284fSGreg Tucker test size, size 181e1f5284fSGreg Tucker jz .finish 182e1f5284fSGreg Tucker 183e1f5284fSGreg Tucker ; continue loop 184e1f5284fSGreg Tucker movd xa, a_d 185e1f5284fSGreg Tucker pxor xb, xb 186e1f5284fSGreg Tucker jmp .sloop1 187e1f5284fSGreg Tucker 188e1f5284fSGreg Tucker.finish: 189e1f5284fSGreg Tucker mov eax, b_d 190e1f5284fSGreg Tucker shl eax, 16 191e1f5284fSGreg Tucker or eax, a_d 192e1f5284fSGreg Tucker jmp .end 193e1f5284fSGreg Tucker 194e1f5284fSGreg Tucker.lt64: 195e1f5284fSGreg Tucker mov a_d, init_d 196e1f5284fSGreg Tucker lea end, [data + size] 197e1f5284fSGreg Tucker test size, size 198e1f5284fSGreg Tucker jnz .final_loop 199e1f5284fSGreg Tucker jmp .zero_size 200e1f5284fSGreg Tucker 201e1f5284fSGreg Tucker ; handle remaining 1...15 bytes 202e1f5284fSGreg Tucker.do_final: 203e1f5284fSGreg Tucker ; reduce 204e1f5284fSGreg Tucker pslld xb, 2 ; b is scaled by 4 205e1f5284fSGreg Tucker movdqa xsa, xa ; scaled a 206e1f5284fSGreg Tucker pmulld xsa, [A_SCALE] 207e1f5284fSGreg Tucker 208e1f5284fSGreg Tucker phaddd xa, xa 209e1f5284fSGreg Tucker phaddd xb, xb 210e1f5284fSGreg Tucker phaddd xsa, xsa 211e1f5284fSGreg Tucker phaddd xa, xa 212e1f5284fSGreg Tucker phaddd xb, xb 213e1f5284fSGreg Tucker phaddd xsa, xsa 214e1f5284fSGreg Tucker psubd xb, xsa 215e1f5284fSGreg Tucker 216e1f5284fSGreg Tucker movd a_d, xa 217e1f5284fSGreg Tucker movd eax, xb 218e1f5284fSGreg Tucker add b_d, eax 219e1f5284fSGreg Tucker 220e1f5284fSGreg Tuckeralign 32 221e1f5284fSGreg Tucker.final_loop: 222e1f5284fSGreg Tucker movzx eax, byte[data] 223e1f5284fSGreg Tucker add a_d, eax 224e1f5284fSGreg Tucker inc data 225e1f5284fSGreg Tucker add b_d, a_d 226e1f5284fSGreg Tucker cmp data, end 227e1f5284fSGreg Tucker jb .final_loop 228e1f5284fSGreg Tucker 229e1f5284fSGreg Tucker.zero_size: 230e1f5284fSGreg Tucker mov eax, a_d 231e1f5284fSGreg Tucker xor edx, edx 232e1f5284fSGreg Tucker mov ecx, BASE 233e1f5284fSGreg Tucker div ecx ; divide edx:eax by ecx, quot->eax, rem->edx 234e1f5284fSGreg Tucker mov a_d, edx 235e1f5284fSGreg Tucker 236e1f5284fSGreg Tucker mov eax, b_d 237e1f5284fSGreg Tucker xor edx, edx 238e1f5284fSGreg Tucker mov ecx, BASE 239e1f5284fSGreg Tucker div ecx ; divide edx:eax by ecx, quot->eax, rem->edx 240e1f5284fSGreg Tucker shl edx, 16 241e1f5284fSGreg Tucker or edx, a_d 242e1f5284fSGreg Tucker mov eax, edx 243e1f5284fSGreg Tucker 244e1f5284fSGreg Tucker.end: 245e1f5284fSGreg Tucker FUNC_RESTORE 246e1f5284fSGreg Tucker ret 247e1f5284fSGreg Tucker 248e1f5284fSGreg Tuckerendproc_frame 249e1f5284fSGreg Tucker 250e1f5284fSGreg Tuckersection .data 251e1f5284fSGreg Tuckeralign 32 252e1f5284fSGreg TuckerA_SCALE: 253e1f5284fSGreg Tucker dq 0x0000000100000000, 0x0000000300000002 254