// File: /workspace/github_c_makefile_star2_O3/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 %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rdi, %r14
vmovdqa (%rdi), %xmm9
vmovdqa 0x10(%rdi), %xmm8
vmovdqa 0x20(%rdi), %xmm10
movl %r9d, %ebp
movl %r8d, %r12d
movq %rcx, %r15
movl %edx, %ebx
vmovdqa 0x50(%rdi), %xmm3
vmovdqa 0x60(%rdi), %xmm5
testb $0xf, %sil
je 0x15f5
testl %ebx, %ebx
je 0x15fd
movl %ebx, %edx
leaq 0x50(%rsp), %r13
movq %r13, %rdi
vmovdqa %xmm8, 0x40(%rsp)
vmovdqa %xmm9, 0x30(%rsp)
vmovdqa %xmm10, 0x20(%rsp)
vmovdqa %xmm5, 0x10(%rsp)
vmovdqa %xmm3, (%rsp)
callq 0x10c0
vmovdqa (%rsp), %xmm3
vmovdqa 0x10(%rsp), %xmm5
vmovdqa 0x20(%rsp), %xmm10
vmovdqa 0x30(%rsp), %xmm9
vmovdqa 0x40(%rsp), %xmm8
vmovdqa64 (%r13), %xmm16
jmp 0x15fd
vmovdqu64 (%rsi), %xmm16
jmp 0x15fd
vpxor %xmm3, %xmm5, %xmm4
movl $0x10, %ecx
subl %ebx, %ecx
leaq 0x2af1(%rip), %rax      # 0x4100
vmovdqu64 (%rcx,%rax), %xmm17
vmovdqu64 0x10(%rcx,%rax), %xmm19
testl %r12d, %r12d
je 0x188b
testq %r15, %r15
je 0x18b0
vmovdqa64 %xmm3, %xmm26
vmovdqa64 %xmm5, %xmm25
vmovdqa64 %xmm10, %xmm23
vmovdqa64 %xmm9, %xmm21
vpxor %xmm4, %xmm8, %xmm5
vpxor %xmm0, %xmm0, %xmm0
cmpl $0x80, %r12d
jb 0x17d8
vpshufb 0x2a1a(%rip), %xmm8, %xmm6 # 0x4080
vmovdqa 0x30(%r14), %xmm7
vmovdqa64 0x40(%r14), %xmm20
vpxor %xmm9, %xmm9, %xmm9
vpmovzxbd 0x2a5e(%rip), %xmm22 # 0x40e0
vmovdqa64 0x29f4(%rip), %xmm24 # 0x4080
vpxor %xmm12, %xmm12, %xmm12
vmovdqa64 %xmm21, %xmm10
vmovdqa64 %xmm23, %xmm11
vpxor %xmm5, %xmm11, %xmm3
vpxor %xmm5, %xmm7, %xmm15
vpxor %xmm3, %xmm7, %xmm13
vpshufd $0x93, %xmm6, %xmm0     # xmm0 = xmm6[3,0,1,2]
vpsrad $0x1f, %xmm0, %xmm0
vpaddd %xmm6, %xmm6, %xmm6
vpternlogd $0x78, %xmm22, %xmm0, %xmm6
vpshufb %xmm24, %xmm6, %xmm18
vpxor (%r15), %xmm3, %xmm0
vaesenc %xmm10, %xmm0, %xmm0
vaesenc %xmm11, %xmm0, %xmm0
vaesenc %xmm8, %xmm0, %xmm0
vaesenc %xmm9, %xmm0, %xmm14
vpxor 0x10(%r15), %xmm15, %xmm0
vaesenc %xmm10, %xmm0, %xmm0
vaesenc %xmm11, %xmm0, %xmm0
vaesenc %xmm8, %xmm0, %xmm0
vaesenc %xmm9, %xmm0, %xmm0
vpxor 0x20(%r15), %xmm13, %xmm1
vaesenc %xmm10, %xmm1, %xmm1
vaesenc %xmm11, %xmm1, %xmm1
vaesenc %xmm8, %xmm1, %xmm1
vaesenc %xmm9, %xmm1, %xmm1
vmovdqu 0x30(%r15), %xmm2
vpternlogq $0x96, %xmm20, %xmm5, %xmm2
vaesenc %xmm10, %xmm2, %xmm2
vaesenc %xmm11, %xmm2, %xmm2
vaesenc %xmm8, %xmm2, %xmm2
vaesenc %xmm9, %xmm2, %xmm2
vpternlogq $0x96, 0x40(%r15), %xmm20, %xmm3
vaesenc %xmm10, %xmm3, %xmm3
vaesenc %xmm11, %xmm3, %xmm3
vaesenc %xmm8, %xmm3, %xmm3
vaesenc %xmm9, %xmm3, %xmm3
vpternlogq $0x96, 0x50(%r15), %xmm20, %xmm15
vaesenc %xmm10, %xmm15, %xmm15
vaesenc %xmm11, %xmm15, %xmm15
vaesenc %xmm8, %xmm15, %xmm15
vaesenc %xmm9, %xmm15, %xmm15
vpternlogq $0x96, 0x60(%r15), %xmm20, %xmm13
vaesenc %xmm10, %xmm13, %xmm13
vaesenc %xmm11, %xmm13, %xmm13
vaesenc %xmm8, %xmm13, %xmm13
vaesenc %xmm9, %xmm13, %xmm13
vpxor 0x70(%r15), %xmm5, %xmm5
vaesenc %xmm10, %xmm5, %xmm5
vaesenc %xmm11, %xmm5, %xmm5
vaesenc %xmm8, %xmm5, %xmm5
vaesenc %xmm9, %xmm5, %xmm5
vpternlogq $0x96, %xmm12, %xmm14, %xmm0
vpternlogq $0x96, %xmm1, %xmm2, %xmm0
vpternlogq $0x96, %xmm3, %xmm15, %xmm0
vpternlogq $0x96, %xmm13, %xmm5, %xmm0
addl $-0x80, %r12d
subq $-0x80, %r15
vpxorq %xmm18, %xmm4, %xmm5
vmovdqa %xmm0, %xmm12
cmpl $0x7f, %r12d
ja 0x169d
cmpl $0x40, %r12d
jb 0x18bb
vmovdqa 0x30(%r14), %xmm1
vpxor 0x40(%r14), %xmm5, %xmm2
vmovdqa64 %xmm23, %xmm10
vpxorq %xmm23, %xmm5, %xmm3
vpxor (%r15), %xmm3, %xmm6
vmovdqa64 %xmm21, %xmm9
vaesenc %xmm9, %xmm6, %xmm6
vaesenc %xmm10, %xmm6, %xmm6
vaesenc %xmm8, %xmm6, %xmm6
vpxor %xmm7, %xmm7, %xmm7
vaesenc %xmm7, %xmm6, %xmm6
vpternlogq $0x96, 0x10(%r15), %xmm1, %xmm5
vaesenc %xmm9, %xmm5, %xmm5
vaesenc %xmm10, %xmm5, %xmm5
vaesenc %xmm8, %xmm5, %xmm5
vaesenc %xmm7, %xmm5, %xmm5
vpternlogq $0x96, 0x20(%r15), %xmm3, %xmm1
vaesenc %xmm9, %xmm1, %xmm1
vaesenc %xmm10, %xmm1, %xmm1
vaesenc %xmm8, %xmm1, %xmm1
vaesenc %xmm7, %xmm1, %xmm1
vpxor 0x30(%r15), %xmm2, %xmm3
vaesenc %xmm9, %xmm3, %xmm3
vaesenc %xmm10, %xmm3, %xmm3
vaesenc %xmm8, %xmm3, %xmm3
vaesenc %xmm7, %xmm3, %xmm3
vpternlogq $0x96, %xmm5, %xmm6, %xmm1
vpternlogq $0x96, %xmm3, %xmm1, %xmm0
addl $-0x40, %r12d
addq $0x40, %r15
vmovdqa %xmm2, %xmm5
jmp 0x18c7
vpxor 0x281d(%rip), %xmm4, %xmm0 # 0x40b0
vaesenc %xmm9, %xmm0, %xmm0
vaesenc %xmm10, %xmm0, %xmm0
vaesenc %xmm8, %xmm0, %xmm0
vpxor %xmm1, %xmm1, %xmm1
vaesenc %xmm1, %xmm0, %xmm0
jmp 0x198d
vmovdqa 0x70(%r14), %xmm0
jmp 0x1993
vmovdqa64 %xmm21, %xmm9
vmovdqa64 %xmm23, %xmm10
cmpl $0x20, %r12d
jb 0x191f
vpxor 0x30(%r14), %xmm5, %xmm1
vpternlogq $0x96, (%r15), %xmm10, %xmm5
vaesenc %xmm9, %xmm5, %xmm2
vaesenc %xmm10, %xmm2, %xmm2
vaesenc %xmm8, %xmm2, %xmm2
vpxor %xmm3, %xmm3, %xmm3
vaesenc %xmm3, %xmm2, %xmm2
vpxor 0x10(%r15), %xmm1, %xmm5
vaesenc %xmm9, %xmm5, %xmm5
vaesenc %xmm10, %xmm5, %xmm5
vaesenc %xmm8, %xmm5, %xmm5
vaesenc %xmm3, %xmm5, %xmm3
vpternlogq $0x96, %xmm3, %xmm2, %xmm0
addl $-0x20, %r12d
addq $0x20, %r15
vmovdqa %xmm1, %xmm5
vmovdqa64 %xmm26, %xmm3
cmpl $0x10, %r12d
jb 0x1956
vpternlogq $0x96, (%r15), %xmm10, %xmm5
vaesenc %xmm9, %xmm5, %xmm1
vaesenc %xmm10, %xmm1, %xmm1
vaesenc %xmm8, %xmm1, %xmm1
vpxor %xmm2, %xmm2, %xmm2
vaesenc %xmm2, %xmm1, %xmm1
vpxor %xmm0, %xmm1, %xmm0
addl $-0x10, %r12d
addq $0x10, %r15
vmovdqa64 %xmm25, %xmm5
testl %r12d, %r12d
je 0x198d
movl %r12d, %ecx
subq %rcx, %rax
vmovdqu 0x10(%rax), %xmm1
vpand (%r15), %xmm1, %xmm1
vpternlogq $0x1e, 0x20(%rax), %xmm1, %xmm4
vaesenc %xmm9, %xmm4, %xmm1
vaesenc %xmm10, %xmm1, %xmm1
vaesenc %xmm8, %xmm1, %xmm1
vaesenc %xmm0, %xmm1, %xmm0
vmovdqa %xmm0, 0x70(%r14)
shlb $0x3, %bpl
vpxor %xmm1, %xmm1, %xmm1
vpinsrb $0xf, %ebp, %xmm1, %xmm2
vpxor %xmm2, %xmm8, %xmm2
vpternlogq $0x96, %xmm10, %xmm2, %xmm3
vaesenc %xmm9, %xmm3, %xmm2
vaesenc %xmm10, %xmm2, %xmm2
vaesenc %xmm8, %xmm2, %xmm2
vaesenc %xmm1, %xmm2, %xmm3
vpternlogq $0xf8, %xmm16, %xmm17, %xmm19
cmpl $0x10, %ebx
je 0x19d2
vpxor %xmm4, %xmm4, %xmm4
jmp 0x19d7
vpxor %xmm8, %xmm10, %xmm4
vpternlogq $0x96, %xmm4, %xmm19, %xmm5
vaesenc %xmm9, %xmm5, %xmm2
vaesenc %xmm10, %xmm2, %xmm2
vaesenc %xmm8, %xmm2, %xmm2
vaesenc %xmm1, %xmm2, %xmm1
vpternlogq $0x96, %xmm3, %xmm1, %xmm0
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq