// File: /workspace/github_c_makefile_star2_O2/mjosaarinen[P]brutus/crypto_aead/aezv3/aesni/aez_ni.c
// Function: cipher_aez_tiny
int cipher_aez_tiny(aez_ctx_t *ctx, __m128i t, int d, char *src, unsigned bytes, unsigned abytes, char *dst) {
    __m128i l, r, tmp, one, rcon, buf[2], mask_10, mask_ff;
    __m128i I=ctx->I, L=ctx->L, J=ctx->J[0], t_orig = t;
    unsigned rnds, i;

    /* load src into buf, zero pad, update bytes for abytes */
    if (bytes >= 16) {
        buf[0] = load(src);
        buf[1] = zero_pad(load_partial(src+16,bytes-16),32-bytes);
    } else {
        buf[0] = zero_pad(load_partial(src,bytes),16-bytes);
        buf[1] = zero;
    }
    if (!d) bytes += abytes;

    /* load l/r, create 10* padding masks, shift r 4 bits if odd length */
    l = buf[0];
    r = loadu((char*)buf+bytes/2);
    mask_ff = loadu(pad+16-bytes/2);
    mask_10 = loadu(pad+32-bytes/2);
    if (bytes&1) {  /* Odd length. Deal with nibbles. */
        mask_10 = _mm_srli_epi32(mask_10,4);
        ((char*)&mask_ff)[bytes/2] = 0xf0;
        r = bswap16(r);
        r = vor(_mm_slli_epi64(r, 4), _mm_srli_epi64(_mm_slli_si128(r, 8), 60));
        r = bswap16(r);
    }
    r = vor(vand(r, mask_ff), mask_10);

    /* Add tweak offset into t, and determine the number of rounds */
    if (bytes >= 16) {
        t = vxor3(t, ctx->J[1], ctx->J[2]);             /* (0,6) offset */
        rnds = 8;
    } else {
        t = vxor4(t, ctx->J[0], ctx->J[1], ctx->J[2]);  /* (0,7) offset */
        if (bytes>=3) rnds = 10; else if (bytes==2) rnds = 16; else rnds = 24;
    }

    if (!d) {
        one = _mm_insert_epi8(zero,1,15);
        rcon = zero;
    } else {
        one = _mm_insert_epi8(zero,-1,15);
        rcon = _mm_insert_epi8(zero,rnds-1,15);
    }

    if ((d) && (bytes < 16)) {
        tmp = vor(l, loadu(pad+32));
        tmp = aes4(vxor4(tmp,t_orig,ctx->J[0],ctx->J[1]), I, J, L, zero);
        tmp = vand(tmp, loadu(pad+32));
        l = vxor(l, tmp);
    }

    /* Feistel */
    for (i=0; i<rnds; i+=2) {
        l = vor(vand(aes4(vxor3(t,r,rcon), I, J, L, l), mask_ff), mask_10);
        rcon = _mm_add_epi8(rcon,one);
        r = vor(vand(aes4(vxor3(t,l,rcon), I, J, L, r), mask_ff), mask_10);
        rcon = _mm_add_epi8(rcon,one);
    }
    buf[0] = r;
    if (bytes&1) {
        l = bswap16(l);
        l = vor(_mm_srli_epi64(l, 4), _mm_slli_epi64(_mm_srli_si128(l, 8), 60));
        l = bswap16(l);
        r = vand(loadu((char*)buf+bytes/2), _mm_insert_epi8(zero,0xf0,0));
        l = vor(l, r);
    }
    storeu((char*)buf+bytes/2, l);
    if (d) {
        bytes -= abytes;
        if (abytes==16) tmp = loadu((char*)buf+bytes);
        else {
            tmp = zero;
            for (i=0; i<abytes; i++) ((char*)&tmp)[i] = ((char*)buf+bytes)[i];
        }
        if (!_mm_testz_si128(tmp,tmp)) return -1;
    } else if (bytes < 16) {
        tmp = vor(zero_pad(buf[0], 16-bytes), loadu(pad+32));
        tmp = aes4(vxor4(tmp,t_orig,ctx->J[0],ctx->J[1]), I, J, L, zero);
        buf[0] = vxor(buf[0], vand(tmp, loadu(pad+32)));
    }
    for (i=0; i<bytes; i++) dst[i] = ((char*)buf)[i];
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x90, %rsp
movq %rdi, %r12
vmovaps (%rdi), %xmm1
vmovaps %xmm1, 0x50(%rsp)
movq %r9, %rbx
movl %r8d, %r15d
movl %ecx, %r14d
movq %rdx, %rdi
movl %esi, %ebp
vmovaps %xmm0, 0x30(%rsp)
vmovaps 0x10(%r12), %xmm0
vmovaps %xmm0, 0x40(%rsp)
vmovdqa 0x20(%r12), %xmm0
vmovdqa %xmm0, 0x20(%rsp)
cmpl $0x10, %ecx
jb 0x2bf0
vmovdqu (%rdi), %xmm0
vmovdqa %xmm0, 0x70(%rsp)
addq $0x10, %rdi
leal -0x10(%r14), %esi
callq 0x1515
vmovdqa 0x70(%rsp), %xmm14
pushq $0x20
popq %rax
subl %r14d, %eax
leaq 0x1517(%rip), %rcx      # 0x4100
vpand (%rax,%rcx), %xmm0, %xmm0
jmp 0x2c0e
movl %r14d, %esi
callq 0x1515
movl %r14d, %eax
leaq 0x14fe(%rip), %rcx      # 0x4100
subq %rax, %rcx
vpand 0x10(%rcx), %xmm0, %xmm14
vpxor %xmm0, %xmm0, %xmm0
vmovdqa %xmm14, (%rsp)
vmovdqa %xmm0, 0x10(%rsp)
leal (%r15,%r14), %eax
testl %ebp, %ebp
movl %r14d, %esi
cmovel %eax, %esi
movl %esi, %edx
shrl %edx
vmovdqu (%rsp,%rdx), %xmm1
leaq 0x14cb(%rip), %rcx      # 0x4100
movq %rcx, %rdi
subq %rdx, %rdi
vmovdqu 0x10(%rdi), %xmm3
vmovdqu 0x20(%rdi), %xmm2
vmovdqa %xmm3, 0x60(%rsp)
testb $0x1, %sil
je 0x2c86
vpsrld $0x4, %xmm2, %xmm2
movb $-0x10, 0x60(%rsp,%rdx)
vmovdqa 0x141d(%rip), %xmm0     # 0x4080
vpshufb %xmm0, %xmm1, %xmm1
vpslldq $0x8, %xmm1, %xmm3      # xmm3 = zero,zero,zero,zero,zero,zero,zero,zero,xmm1[0,1,2,3,4,5,6,7]
vpsllq $0x4, %xmm1, %xmm1
vpsrlq $0x3c, %xmm3, %xmm3
vpor %xmm3, %xmm1, %xmm1
vpshufb %xmm0, %xmm1, %xmm1
vmovdqa 0x60(%rsp), %xmm3
vmovdqa 0x50(%rsp), %xmm10
vmovdqa 0x40(%rsp), %xmm11
vmovdqa 0x30(%rsp), %xmm12
vmovdqa 0x20(%rsp), %xmm13
vmovdqa 0x30(%r12), %xmm0
vmovdqa 0x40(%r12), %xmm4
vpternlogq $0x96, %xmm12, %xmm0, %xmm4
cmpl $0xf, %esi
jbe 0x2cbc
pushq $0x8
jmp 0x2cc7
vpxor %xmm4, %xmm13, %xmm4
cmpl $0x2, %esi
jbe 0x2cca
pushq $0xa
popq %rdi
jmp 0x2cd9
setne %dil
movzbl %dil, %edi
leal 0x10(,%rdi,8), %edi
testl %ebp, %ebp
je 0x2d39
leal -0x1(%rdi), %r8d
vpxor %xmm7, %xmm7, %xmm7
vpinsrb $0xf, %r8d, %xmm7, %xmm6
vmovdqa 0x13cd(%rip), %xmm5     # 0x40c0
cmpl $0xf, %r14d
ja 0x2d4e
vpmovzxbq 0x13ee(%rip), %xmm8 # 0x40f0
vmovdqa %xmm12, %xmm9
vpternlogq $0x1e, %xmm8, %xmm14, %xmm9
vpternlogq $0x96, %xmm0, %xmm13, %xmm9
vaesenc %xmm10, %xmm9, %xmm9
vaesenc %xmm13, %xmm9, %xmm9
vaesenc %xmm11, %xmm9, %xmm9
vaesenc %xmm7, %xmm9, %xmm7
vpternlogq $0x6c, %xmm8, %xmm14, %xmm7
movb $0x1, %r8b
vmovdqa %xmm7, %xmm14
jmp 0x2d51
cmpl $0x10, %eax
setb %r8b
vmovdqa 0x12b8(%rip), %xmm5     # 0x4000
vpxor %xmm6, %xmm6, %xmm6
jmp 0x2d51
xorl %r8d, %r8d
xorl %r9d, %r9d
vpternlogq $0xec, %xmm3, %xmm2, %xmm1
cmpl %edi, %r9d
jae 0x2db3
vmovdqa %xmm1, %xmm7
vpternlogq $0x96, %xmm4, %xmm6, %xmm7
vaesenc %xmm10, %xmm7, %xmm7
vaesenc %xmm13, %xmm7, %xmm7
vaesenc %xmm11, %xmm7, %xmm7
vaesenc %xmm14, %xmm7, %xmm14
vpternlogq $0xec, %xmm3, %xmm2, %xmm14
vpaddb %xmm6, %xmm5, %xmm6
vmovdqa %xmm14, %xmm7
vpternlogq $0x96, %xmm6, %xmm4, %xmm7
vaesenc %xmm10, %xmm7, %xmm7
vaesenc %xmm13, %xmm7, %xmm7
vaesenc %xmm11, %xmm7, %xmm7
vaesenc %xmm1, %xmm7, %xmm1
vpaddb %xmm5, %xmm6, %xmm6
addl $0x2, %r9d
jmp 0x2d54
vmovdqa %xmm1, (%rsp)
testb $0x1, %sil
je 0x2df3
vmovdqa 0x12ba(%rip), %xmm1     # 0x4080
vpshufb %xmm1, %xmm14, %xmm2
vpsrldq $0x8, %xmm2, %xmm3      # xmm3 = xmm2[8,9,10,11,12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero
vpsrlq $0x4, %xmm2, %xmm2
vpsllq $0x3c, %xmm3, %xmm3
vpor %xmm2, %xmm3, %xmm2
vpshufb %xmm1, %xmm2, %xmm1
vmovdqu (%rsp,%rdx), %xmm14
vpternlogq $0xec, 0x12dd(%rip), %xmm1, %xmm14 # 0x40d0
vmovdqu %xmm14, (%rsp,%rdx)
testl %ebp, %ebp
je 0x2e2d
subl %r15d, %r14d
cmpl $0x10, %r15d
jne 0x2e98
movl %r14d, %eax
addq %rsp, %rax
vmovdqu (%rax), %xmm0
vptest %xmm0, %xmm0
je 0x2e7f
pushq $-0x1
popq %rax
addq $0x90, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
testb %r8b, %r8b
je 0x2e7c
vmovdqa (%rsp), %xmm1
movl %eax, %edx
subq %rdx, %rcx
vpand 0x10(%rcx), %xmm1, %xmm2
vpmovzxbq 0x12a6(%rip), %xmm3 # 0x40f0
vpternlogq $0x1e, %xmm3, %xmm2, %xmm12
vpternlogq $0x96, %xmm0, %xmm13, %xmm12
vaesenc %xmm10, %xmm12, %xmm0
vaesenc %xmm13, %xmm0, %xmm0
vaesenc %xmm11, %xmm0, %xmm0
vpxor %xmm2, %xmm2, %xmm2
vaesenc %xmm2, %xmm0, %xmm0
vpternlogq $0x6c, %xmm3, %xmm1, %xmm0
vmovdqa %xmm0, (%rsp)
movl %eax, %r14d
movl %r14d, %ecx
xorl %eax, %eax
xorl %edx, %edx
cmpq %rdx, %rcx
je 0x2e1d
movb (%rsp,%rdx), %sil
movb %sil, (%rbx,%rdx)
incq %rdx
jmp 0x2e86
vpxor %xmm0, %xmm0, %xmm0
leaq 0x80(%rsp), %rax
vmovdqa %xmm0, (%rax)
movl %r14d, %ecx
addq %rsp, %rcx
movl %r15d, %edx
xorl %esi, %esi
cmpq %rsi, %rdx
je 0x2e0f
movb (%rcx,%rsi), %dil
movb %dil, 0x80(%rsp,%rsi)
incq %rsi
jmp 0x2eb3