// File: /workspace/github_c_makefile_star2_O2/mjosaarinen[P]brutus/crypto_aead/aezv3/aesni/aez_ni.c
// Function: aez_hash
__m128i aez_hash(aez_ctx_t *ctx, char *n, unsigned nbytes, char *ad,
                     unsigned adbytes, unsigned abytes) {
    __m128i o0, o1, o2, o3, o4, o5, o6, o7, sum, offset, tmp1, tmp2;
    __m128i I=ctx->I, L=ctx->L, J=ctx->J[0], J8=ctx->J[3], J16=ctx->J[4];
    __m128i J24 = vxor(J16,J8);

    /* Process abytes and nonce */
    tmp1 = vxor4(_mm_insert_epi8(zero,(int)(8*abytes),15), J, L, J8);
    tmp2 = vxor(one_zero_pad(load_partial(n,nbytes),16-nbytes), J16);
    if (nbytes==16) tmp2 = vxor3(tmp2, J, L);
    sum = aes4(tmp1,I,J,L,zero);
    sum = vxor(sum, aes4(tmp2,I,J,L,zero));

    if (adbytes==0) ctx->delta3_cache = aes4(vxor(loadu(pad+32),J24),I,J,L,zero);
    else if (ad) {
        __m128i delta3 = zero, Lfordoubling = bswap16(L);
        offset = vxor(L, J24);
        while (adbytes >= 8*16) {
            o0 = offset;
            o1 = vxor(o0,ctx->J[0]);
            o2 = vxor(o0,ctx->J[1]);
            o3 = vxor(o1,ctx->J[1]);
            o4 = vxor(o0,ctx->J[2]);
            o5 = vxor(o1,ctx->J[2]);
            o6 = vxor(o2,ctx->J[2]);
            o7 = vxor(o3,ctx->J[2]);
            offset = vxor(bswap16(Lfordoubling = double_block(Lfordoubling)),J24);
            delta3 = vxor(delta3, aes4(vxor(load(ad+  0),o1), I, J, L, zero));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 16),o2), I, J, L, zero));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 32),o3), I, J, L, zero));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 48),o4), I, J, L, zero));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 64),o5), I, J, L, zero));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 80),o6), I, J, L, zero));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 96),o7), I, J, L, zero));
            delta3 = vxor(delta3, aes4(vxor(load(ad+112),o0), I, J, L, zero));
            adbytes-=8*16; ad+=8*16;
        }
        if (adbytes >= 4*16) {
            o1 = vxor(offset,ctx->J[0]);
            o2 = vxor(offset,ctx->J[1]);
            o3 = vxor(o1,ctx->J[1]);
            o4 = offset = vxor(offset,ctx->J[2]);
            delta3 = vxor(delta3, aes4(vxor(load(ad+  0),o1), I, J, L, zero));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 16),o2), I, J, L, zero));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 32),o3), I, J, L, zero));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 48),o4), I, J, L, zero));
            adbytes-=4*16; ad+=4*16;
        }
        if (adbytes >= 2*16) {
            o1 = vxor(offset,ctx->J[0]);
            o2 = offset = vxor(offset,ctx->J[1]);
            delta3 = vxor(delta3, aes4(vxor(load(ad+  0),o1), I, J, L, zero));
            delta3 = vxor(delta3, aes4(vxor(load(ad+ 16),o2), I, J, L, zero));
            adbytes-=2*16; ad+=2*16;
        }
        if (adbytes >= 1*16) {
            o1 = offset = vxor(offset,ctx->J[0]);
            delta3 = vxor(delta3, aes4(vxor(load(ad+  0),o1), I, J, L, zero));
            adbytes-=1*16; ad+=1*16;
        }
        if (adbytes) {
            __m128i tmp = one_zero_pad(load(ad),16-adbytes);
            delta3 = aes4(vxor(tmp,J24), I, J, L, delta3);
        }
        ctx->delta3_cache = delta3;
    }
    return vxor(sum,ctx->delta3_cache);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x60, %rsp
movq %rdi, %r14
vmovaps (%rdi), %xmm0
vmovaps %xmm0, 0x30(%rsp)
vmovaps 0x10(%rdi), %xmm0
vmovaps %xmm0, 0x20(%rsp)
vmovaps 0x20(%rdi), %xmm0
vmovaps %xmm0, 0x10(%rsp)
movl %r9d, %ebp
movl %r8d, %r12d
movq %rcx, %r15
movl %edx, %ebx
movq %rsi, %rdi
vmovdqa 0x50(%r14), %xmm1
vmovdqa 0x60(%r14), %xmm0
vmovdqa %xmm0, 0x50(%rsp)
vmovdqa %xmm1, 0x40(%rsp)
vpxor %xmm1, %xmm0, %xmm0
vmovdqa %xmm0, (%rsp)
movl %edx, %esi
callq 0x1515
pushq $0x10
popq %rcx
subl %ebx, %ecx
leaq 0x2b53(%rip), %rax      # 0x4100
vmovdqu64 (%rcx,%rax), %xmm17
vmovdqu64 0x10(%rcx,%rax), %xmm19
testl %r12d, %r12d
je 0x182f
vmovdqa64 (%rsp), %xmm23
vmovdqa 0x10(%rsp), %xmm8
vmovdqa64 0x30(%rsp), %xmm20
vmovdqa64 0x20(%rsp), %xmm18
testq %r15, %r15
je 0x186b
vmovdqa64 %xmm18, %xmm9
vpshufb 0x2a85(%rip), %xmm18, %xmm5 # 0x4080
addq $0x40, %r15
vpxor %xmm6, %xmm6, %xmm6
vpmovzxbd 0x2ad3(%rip), %xmm21 # 0x40e0
vmovdqa64 0x2a69(%rip), %xmm22 # 0x4080
vpxor %xmm1, %xmm1, %xmm1
vmovdqa %xmm8, %xmm14
vpxorq %xmm23, %xmm9, %xmm4
vpxor %xmm4, %xmm14, %xmm10
cmpl $0x80, %r12d
jb 0x177f
vmovdqa 0x30(%r14), %xmm9
vmovdqa64 0x40(%r14), %xmm16
vpxor %xmm4, %xmm9, %xmm13
vpxor %xmm10, %xmm9, %xmm11
vpshufd $0x93, %xmm5, %xmm9     # xmm9 = xmm5[3,0,1,2]
vpsrad $0x1f, %xmm9, %xmm9
vpaddd %xmm5, %xmm5, %xmm5
vpternlogd $0x78, %xmm21, %xmm9, %xmm5
vpxor -0x40(%r15), %xmm10, %xmm12
vpshufb %xmm22, %xmm5, %xmm9
vmovdqa64 %xmm20, %xmm7
vaesenc %xmm7, %xmm12, %xmm12
vaesenc %xmm14, %xmm12, %xmm12
vmovdqa64 %xmm18, %xmm2
vaesenc %xmm2, %xmm12, %xmm12
vpxor -0x30(%r15), %xmm13, %xmm14
vaesenc %xmm6, %xmm12, %xmm12
vaesenc %xmm7, %xmm14, %xmm14
vaesenc %xmm8, %xmm14, %xmm14
vaesenc %xmm2, %xmm14, %xmm14
vpxor -0x20(%r15), %xmm11, %xmm15
vaesenc %xmm6, %xmm14, %xmm14
vaesenc %xmm7, %xmm15, %xmm15
vaesenc %xmm8, %xmm15, %xmm15
vaesenc %xmm2, %xmm15, %xmm15
vmovdqu -0x10(%r15), %xmm3
vaesenc %xmm6, %xmm15, %xmm15
vpternlogq $0x96, %xmm16, %xmm4, %xmm3
vaesenc %xmm7, %xmm3, %xmm3
vaesenc %xmm8, %xmm3, %xmm3
vaesenc %xmm2, %xmm3, %xmm3
vaesenc %xmm6, %xmm3, %xmm3
vpternlogq $0x96, (%r15), %xmm16, %xmm10
vaesenc %xmm7, %xmm10, %xmm10
vaesenc %xmm8, %xmm10, %xmm10
vaesenc %xmm2, %xmm10, %xmm10
vaesenc %xmm6, %xmm10, %xmm10
vpternlogq $0x96, 0x10(%r15), %xmm16, %xmm13
vaesenc %xmm7, %xmm13, %xmm13
vaesenc %xmm8, %xmm13, %xmm13
vaesenc %xmm2, %xmm13, %xmm13
vaesenc %xmm6, %xmm13, %xmm13
vpternlogq $0x96, 0x20(%r15), %xmm16, %xmm11
vaesenc %xmm7, %xmm11, %xmm11
vaesenc %xmm8, %xmm11, %xmm11
vaesenc %xmm2, %xmm11, %xmm11
vaesenc %xmm6, %xmm11, %xmm11
vpxor 0x30(%r15), %xmm4, %xmm4
vaesenc %xmm7, %xmm4, %xmm4
vaesenc %xmm8, %xmm4, %xmm4
vaesenc %xmm2, %xmm4, %xmm4
vaesenc %xmm6, %xmm4, %xmm4
vpternlogq $0x96, %xmm14, %xmm12, %xmm15
vmovdqa %xmm8, %xmm14
vpternlogq $0x96, %xmm3, %xmm10, %xmm15
vpternlogq $0x96, %xmm13, %xmm11, %xmm15
vpternlogq $0x96, %xmm4, %xmm15, %xmm1
addl $-0x80, %r12d
subq $-0x80, %r15
jmp 0x1620
vmovdqa64 %xmm23, %xmm11
cmpl $0x40, %r12d
jb 0x1887
vmovdqa 0x30(%r14), %xmm3
vpxor 0x40(%r14), %xmm4, %xmm5
vpxor -0x40(%r15), %xmm10, %xmm6
vmovdqa64 %xmm20, %xmm2
vaesenc %xmm2, %xmm6, %xmm6
vaesenc %xmm14, %xmm6, %xmm6
vmovdqa64 %xmm18, %xmm9
vaesenc %xmm9, %xmm6, %xmm6
vpxor %xmm7, %xmm7, %xmm7
vaesenc %xmm7, %xmm6, %xmm6
vpternlogq $0x96, -0x30(%r15), %xmm3, %xmm4
vaesenc %xmm2, %xmm4, %xmm4
vaesenc %xmm14, %xmm4, %xmm4
vaesenc %xmm9, %xmm4, %xmm4
vaesenc %xmm7, %xmm4, %xmm4
vpternlogq $0x96, -0x20(%r15), %xmm10, %xmm3
vaesenc %xmm2, %xmm3, %xmm3
vaesenc %xmm14, %xmm3, %xmm3
vaesenc %xmm9, %xmm3, %xmm3
vaesenc %xmm7, %xmm3, %xmm3
vpxor -0x10(%r15), %xmm5, %xmm8
vaesenc %xmm2, %xmm8, %xmm8
vaesenc %xmm14, %xmm8, %xmm8
vaesenc %xmm9, %xmm8, %xmm8
vaesenc %xmm7, %xmm8, %xmm7
vpternlogq $0x96, %xmm4, %xmm6, %xmm3
vpternlogq $0x96, %xmm7, %xmm3, %xmm1
addl $-0x40, %r12d
vmovdqa %xmm5, %xmm4
jmp 0x1897
vmovdqa (%rsp), %xmm1
vpxor 0x2874(%rip), %xmm1, %xmm1 # 0x40b0
vmovdqa 0x30(%rsp), %xmm2
vaesenc %xmm2, %xmm1, %xmm1
vmovdqa 0x10(%rsp), %xmm14
vaesenc %xmm14, %xmm1, %xmm1
vmovdqa 0x20(%rsp), %xmm9
vaesenc %xmm9, %xmm1, %xmm1
vpxor %xmm4, %xmm4, %xmm4
vaesenc %xmm4, %xmm1, %xmm1
jmp 0x1951
vmovdqa 0x70(%r14), %xmm1
vmovdqa64 %xmm18, %xmm9
vmovdqa64 %xmm20, %xmm2
vmovdqa %xmm8, %xmm14
jmp 0x1957
addq $-0x40, %r15
vmovdqa64 %xmm18, %xmm9
vmovdqa64 %xmm20, %xmm2
cmpl $0x20, %r12d
jb 0x18ef
vpxor 0x30(%r14), %xmm4, %xmm3
vpternlogq $0x96, (%r15), %xmm14, %xmm4
vaesenc %xmm2, %xmm4, %xmm4
vaesenc %xmm14, %xmm4, %xmm4
vaesenc %xmm9, %xmm4, %xmm4
vpxor %xmm5, %xmm5, %xmm5
vaesenc %xmm5, %xmm4, %xmm4
vpxor 0x10(%r15), %xmm3, %xmm6
vaesenc %xmm2, %xmm6, %xmm6
vaesenc %xmm14, %xmm6, %xmm6
vaesenc %xmm9, %xmm6, %xmm6
vaesenc %xmm5, %xmm6, %xmm5
vpternlogq $0x96, %xmm5, %xmm4, %xmm1
addl $-0x20, %r12d
addq $0x20, %r15
vmovdqa %xmm3, %xmm4
cmpl $0x10, %r12d
jb 0x1920
vpternlogq $0x96, (%r15), %xmm14, %xmm4
vaesenc %xmm2, %xmm4, %xmm3
vaesenc %xmm14, %xmm3, %xmm3
vaesenc %xmm9, %xmm3, %xmm3
vpxor %xmm4, %xmm4, %xmm4
vaesenc %xmm4, %xmm3, %xmm3
vpxor %xmm1, %xmm3, %xmm1
addl $-0x10, %r12d
addq $0x10, %r15
testl %r12d, %r12d
je 0x1951
movl %r12d, %ecx
subq %rcx, %rax
vmovdqu 0x10(%rax), %xmm3
vpand (%r15), %xmm3, %xmm3
vpternlogq $0x1e, 0x20(%rax), %xmm3, %xmm11
vaesenc %xmm2, %xmm11, %xmm3
vaesenc %xmm14, %xmm3, %xmm3
vaesenc %xmm9, %xmm3, %xmm3
vaesenc %xmm1, %xmm3, %xmm1
vmovdqa %xmm1, 0x70(%r14)
shlb $0x3, %bpl
vpxor %xmm4, %xmm4, %xmm4
vpinsrb $0xf, %ebp, %xmm4, %xmm3
vpxor %xmm3, %xmm9, %xmm3
vmovdqa 0x40(%rsp), %xmm5
vpternlogq $0x96, %xmm14, %xmm3, %xmm5
vaesenc %xmm2, %xmm5, %xmm3
vaesenc %xmm14, %xmm3, %xmm3
vaesenc %xmm9, %xmm3, %xmm3
vaesenc %xmm4, %xmm3, %xmm5
vpternlogq $0xf8, %xmm0, %xmm17, %xmm19
cmpl $0x10, %ebx
je 0x199c
vpxor %xmm0, %xmm0, %xmm0
jmp 0x19a1
vpxor %xmm9, %xmm14, %xmm0
vmovdqa 0x50(%rsp), %xmm3
vpternlogq $0x96, %xmm0, %xmm19, %xmm3
vaesenc %xmm2, %xmm3, %xmm0
vaesenc %xmm14, %xmm0, %xmm0
vaesenc %xmm9, %xmm0, %xmm0
vaesenc %xmm4, %xmm0, %xmm0
vpternlogq $0x96, %xmm5, %xmm0, %xmm1
vmovdqa %xmm1, %xmm0
addq $0x60, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq