// File: /workspace/github_c_makefile_star2_O2/mjosaarinen[P]brutus/crypto_aead/lunarkeyakv2/Haswell/KeccakP-1600-times4-SIMD256.c
// Function: KeccakP1600times4_ExtractAndAddLanesAll
void KeccakP1600times4_ExtractAndAddLanesAll(const void *states, const unsigned char *input, unsigned char *output, unsigned int laneCount, unsigned int laneOffset)
{
    const UINT64 *curInput0 = (UINT64 *)input;
    const UINT64 *curInput1 = (UINT64 *)(input+laneOffset*1*SnP_laneLengthInBytes);
    const UINT64 *curInput2 = (UINT64 *)(input+laneOffset*2*SnP_laneLengthInBytes);
    const UINT64 *curInput3 = (UINT64 *)(input+laneOffset*3*SnP_laneLengthInBytes);
    UINT64 *curOutput0 = (UINT64 *)output;
    UINT64 *curOutput1 = (UINT64 *)(output+laneOffset*1*SnP_laneLengthInBytes);
    UINT64 *curOutput2 = (UINT64 *)(output+laneOffset*2*SnP_laneLengthInBytes);
    UINT64 *curOutput3 = (UINT64 *)(output+laneOffset*3*SnP_laneLengthInBytes);

    const V256 *stateAsLanes = (const V256 *)states;
    const UINT64 *stateAsLanes64 = (const UINT64*)states;
    V256    lanes0, lanes1, lanes2, lanes3, lanesL01, lanesL23, lanesH01, lanesH23;
    unsigned int i;

    #define ExtrXor( argIndex ) \
                                curOutput0[argIndex] = curInput0[argIndex] ^ stateAsLanes64[4*(argIndex)],\
                                curOutput1[argIndex] = curInput1[argIndex] ^ stateAsLanes64[4*(argIndex)+1],\
                                curOutput2[argIndex] = curInput2[argIndex] ^ stateAsLanes64[4*(argIndex)+2],\
                                curOutput3[argIndex] = curInput3[argIndex] ^ stateAsLanes64[4*(argIndex)+3]

    #define ExtrXor4( argIndex ) \
                                    lanes0 = LOAD256( stateAsLanes[argIndex+0] ),\
                                    lanes1 = LOAD256( stateAsLanes[argIndex+1] ),\
                                    lanes2 = LOAD256( stateAsLanes[argIndex+2] ),\
                                    lanes3 = LOAD256( stateAsLanes[argIndex+3] ),\
                                    UNINTLEAVE(),\
                                    lanesL01 = LOAD256u( curInput0[argIndex]),\
                                    lanesH01 = LOAD256u( curInput1[argIndex]),\
                                    lanesL23 = LOAD256u( curInput2[argIndex]),\
                                    lanesH23 = LOAD256u( curInput3[argIndex]),\
                                    XOReq256( lanes0, lanesL01 ),\
                                    XOReq256( lanes1, lanesH01 ),\
                                    XOReq256( lanes2, lanesL23 ),\
                                    XOReq256( lanes3, lanesH23 ),\
                                    STORE256u( curOutput0[argIndex], lanes0 ),\
                                    STORE256u( curOutput1[argIndex], lanes1 ),\
                                    STORE256u( curOutput2[argIndex], lanes2 ),\
                                    STORE256u( curOutput3[argIndex], lanes3 )

    if ( laneCount >= 16 )  {
        ExtrXor4( 0 );
        ExtrXor4( 4 );
        ExtrXor4( 8 );
        ExtrXor4( 12 );
        if ( laneCount >= 20 )  {
            ExtrXor4( 16 );
            for(i=20; i<laneCount; i++)
                ExtrXor( i );
        }
        else {
            for(i=16; i<laneCount; i++)
                ExtrXor( i );
        }
    }
    else {
        for(i=0; i<laneCount; i++)
            ExtrXor( i );
    }
    #undef  ExtrXor
    #undef  ExtrXor4
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
leal (,%r8,8), %r9d
leaq (%rsi,%r9), %r10
imull $0x18, %r8d, %eax
shll $0x4, %r8d
leaq (%rsi,%r8), %r11
leaq (%rsi,%rax), %r12
leaq (%rdx,%r9), %rbx
leaq (%rdx,%r8), %r14
leaq (%rdx,%rax), %r15
cmpl $0xf, %ecx
jbe 0x9855
vmovdqa (%rdi), %ymm0
vmovdqa 0x20(%rdi), %ymm1
vmovdqa 0x40(%rdi), %ymm2
vmovdqa 0x60(%rdi), %ymm3
vpunpcklqdq %ymm1, %ymm0, %ymm4 # ymm4 = ymm0[0],ymm1[0],ymm0[2],ymm1[2]
vpunpckhqdq %ymm1, %ymm0, %ymm0 # ymm0 = ymm0[1],ymm1[1],ymm0[3],ymm1[3]
vpunpcklqdq %ymm3, %ymm2, %ymm1 # ymm1 = ymm2[0],ymm3[0],ymm2[2],ymm3[2]
vpunpckhqdq %ymm3, %ymm2, %ymm2 # ymm2 = ymm2[1],ymm3[1],ymm2[3],ymm3[3]
vinserti128 $0x1, %xmm1, %ymm4, %ymm3
vperm2i128 $0x31, %ymm1, %ymm4, %ymm1 # ymm1 = ymm4[2,3],ymm1[2,3]
vinserti128 $0x1, %xmm2, %ymm0, %ymm4
vperm2i128 $0x31, %ymm2, %ymm0, %ymm0 # ymm0 = ymm0[2,3],ymm2[2,3]
vpxor (%rsi), %ymm3, %ymm2
vpxor (%r10), %ymm4, %ymm3
vpxor (%r11), %ymm1, %ymm1
vpxor (%r12), %ymm0, %ymm0
vmovdqu %ymm2, (%rdx)
vmovdqu %ymm3, (%rbx)
vmovdqu %ymm1, (%r14)
vmovdqu %ymm0, (%r15)
vmovdqa 0x80(%rdi), %ymm0
vmovdqa 0xa0(%rdi), %ymm1
vmovdqa 0xc0(%rdi), %ymm2
vmovdqa 0xe0(%rdi), %ymm3
vpunpcklqdq %ymm1, %ymm0, %ymm4 # ymm4 = ymm0[0],ymm1[0],ymm0[2],ymm1[2]
vpunpckhqdq %ymm1, %ymm0, %ymm0 # ymm0 = ymm0[1],ymm1[1],ymm0[3],ymm1[3]
vpunpcklqdq %ymm3, %ymm2, %ymm1 # ymm1 = ymm2[0],ymm3[0],ymm2[2],ymm3[2]
vpunpckhqdq %ymm3, %ymm2, %ymm2 # ymm2 = ymm2[1],ymm3[1],ymm2[3],ymm3[3]
vinserti128 $0x1, %xmm1, %ymm4, %ymm3
vperm2i128 $0x31, %ymm1, %ymm4, %ymm1 # ymm1 = ymm4[2,3],ymm1[2,3]
vinserti128 $0x1, %xmm2, %ymm0, %ymm4
vperm2i128 $0x31, %ymm2, %ymm0, %ymm0 # ymm0 = ymm0[2,3],ymm2[2,3]
vpxor 0x20(%rsi), %ymm3, %ymm2
vpxor 0x20(%r10), %ymm4, %ymm3
vpxor 0x20(%r11), %ymm1, %ymm1
vpxor 0x20(%r12), %ymm0, %ymm0
vmovdqu %ymm2, 0x20(%rdx)
vmovdqu %ymm3, 0x20(%rbx)
vmovdqu %ymm1, 0x20(%r14)
vmovdqu %ymm0, 0x20(%r15)
vmovdqa 0x100(%rdi), %ymm0
vmovdqa 0x120(%rdi), %ymm1
vmovdqa 0x140(%rdi), %ymm2
vmovdqa 0x160(%rdi), %ymm3
vpunpcklqdq %ymm1, %ymm0, %ymm4 # ymm4 = ymm0[0],ymm1[0],ymm0[2],ymm1[2]
vpunpckhqdq %ymm1, %ymm0, %ymm0 # ymm0 = ymm0[1],ymm1[1],ymm0[3],ymm1[3]
vpunpcklqdq %ymm3, %ymm2, %ymm1 # ymm1 = ymm2[0],ymm3[0],ymm2[2],ymm3[2]
vpunpckhqdq %ymm3, %ymm2, %ymm2 # ymm2 = ymm2[1],ymm3[1],ymm2[3],ymm3[3]
vinserti128 $0x1, %xmm1, %ymm4, %ymm3
vperm2i128 $0x31, %ymm1, %ymm4, %ymm1 # ymm1 = ymm4[2,3],ymm1[2,3]
vinserti128 $0x1, %xmm2, %ymm0, %ymm4
vperm2i128 $0x31, %ymm2, %ymm0, %ymm0 # ymm0 = ymm0[2,3],ymm2[2,3]
vpxor 0x40(%rsi), %ymm3, %ymm2
vpxor 0x40(%r10), %ymm4, %ymm3
vpxor 0x40(%r11), %ymm1, %ymm1
vpxor 0x40(%r12), %ymm0, %ymm0
vmovdqu %ymm2, 0x40(%rdx)
vmovdqu %ymm3, 0x40(%rbx)
vmovdqu %ymm1, 0x40(%r14)
vmovdqu %ymm0, 0x40(%r15)
vmovdqa 0x180(%rdi), %ymm0
vmovdqa 0x1a0(%rdi), %ymm1
vmovdqa 0x1c0(%rdi), %ymm2
vmovdqa 0x1e0(%rdi), %ymm3
vpunpcklqdq %ymm1, %ymm0, %ymm4 # ymm4 = ymm0[0],ymm1[0],ymm0[2],ymm1[2]
vpunpckhqdq %ymm1, %ymm0, %ymm0 # ymm0 = ymm0[1],ymm1[1],ymm0[3],ymm1[3]
vpunpcklqdq %ymm3, %ymm2, %ymm1 # ymm1 = ymm2[0],ymm3[0],ymm2[2],ymm3[2]
vpunpckhqdq %ymm3, %ymm2, %ymm2 # ymm2 = ymm2[1],ymm3[1],ymm2[3],ymm3[3]
vinserti128 $0x1, %xmm1, %ymm4, %ymm3
vperm2i128 $0x31, %ymm1, %ymm4, %ymm1 # ymm1 = ymm4[2,3],ymm1[2,3]
vinserti128 $0x1, %xmm2, %ymm0, %ymm4
vperm2i128 $0x31, %ymm2, %ymm0, %ymm0 # ymm0 = ymm0[2,3],ymm2[2,3]
vpxor 0x60(%rsi), %ymm3, %ymm2
vpxor 0x60(%r10), %ymm4, %ymm3
vpxor 0x60(%r11), %ymm1, %ymm1
vpxor 0x60(%r12), %ymm0, %ymm0
vmovdqu %ymm2, 0x60(%rdx)
vmovdqu %ymm3, 0x60(%rbx)
vmovdqu %ymm1, 0x60(%r14)
vmovdqu %ymm0, 0x60(%r15)
cmpl $0x13, %ecx
jbe 0x989f
vmovdqa 0x200(%rdi), %ymm0
vmovdqa 0x220(%rdi), %ymm1
vmovdqa 0x240(%rdi), %ymm2
vmovdqa 0x260(%rdi), %ymm3
vpunpcklqdq %ymm1, %ymm0, %ymm4 # ymm4 = ymm0[0],ymm1[0],ymm0[2],ymm1[2]
vpunpckhqdq %ymm1, %ymm0, %ymm0 # ymm0 = ymm0[1],ymm1[1],ymm0[3],ymm1[3]
vpunpcklqdq %ymm3, %ymm2, %ymm1 # ymm1 = ymm2[0],ymm3[0],ymm2[2],ymm3[2]
vpunpckhqdq %ymm3, %ymm2, %ymm2 # ymm2 = ymm2[1],ymm3[1],ymm2[3],ymm3[3]
vinserti128 $0x1, %xmm1, %ymm4, %ymm3
vperm2i128 $0x31, %ymm1, %ymm4, %ymm1 # ymm1 = ymm4[2,3],ymm1[2,3]
vinserti128 $0x1, %xmm2, %ymm0, %ymm4
vpxor 0x80(%rsi), %ymm3, %ymm3
leaq 0xa0(%rsi,%r9), %r10
vpxor -0x20(%r10), %ymm4, %ymm4
leaq 0xa0(%rsi,%r8), %r11
vpxor -0x20(%r11), %ymm1, %ymm1
vperm2i128 $0x31, %ymm2, %ymm0, %ymm0 # ymm0 = ymm0[2,3],ymm2[2,3]
leaq 0xa0(%rsi,%rax), %rbx
vpxor -0x20(%rbx), %ymm0, %ymm0
vmovdqu %ymm3, 0x80(%rdx)
leaq 0xa0(%rdx,%r9), %r9
vmovdqu %ymm4, -0x20(%r9)
leaq 0xa0(%rdx,%r8), %r8
vmovdqu %ymm1, -0x20(%r8)
leaq 0xa0(%rdx,%rax), %rax
vmovdqu %ymm0, -0x20(%rax)
movl %ecx, %ecx
leaq -0x50(,%rcx,4), %rcx
xorl %r14d, %r14d
cmpq %r14, %rcx
je 0x9938
leal 0x50(%r14), %r15d
movq (%rdi,%r15,8), %r15
xorq 0xa0(%rsi,%r14,2), %r15
movq %r15, 0xa0(%rdx,%r14,2)
leal 0x51(%r14), %r15d
movq (%rdi,%r15,8), %r15
xorq (%r10,%r14,2), %r15
movq %r15, (%r9,%r14,2)
leal 0x52(%r14), %r15d
movq (%rdi,%r15,8), %r15
xorq (%r11,%r14,2), %r15
movq %r15, (%r8,%r14,2)
leal 0x53(%r14), %r15d
movq (%rdi,%r15,8), %r15
xorq (%rbx,%r14,2), %r15
movq %r15, (%rax,%r14,2)
addq $0x4, %r14
jmp 0x97fe
movl %ecx, %eax
shlq $0x3, %rax
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0x9938
movq (%rdi,%rcx,4), %r8
xorq (%rsi,%rcx), %r8
movq %r8, (%rdx,%rcx)
movq 0x8(%rdi,%rcx,4), %r8
xorq (%r10,%rcx), %r8
movq %r8, (%rbx,%rcx)
movq 0x10(%rdi,%rcx,4), %r8
xorq (%r11,%rcx), %r8
movq %r8, (%r14,%rcx)
movq 0x18(%rdi,%rcx,4), %r8
xorq (%r12,%rcx), %r8
movq %r8, (%r15,%rcx)
addq $0x8, %rcx
jmp 0x985d
movl %ecx, %ecx
leaq -0x80(,%rcx,8), %rcx
leaq (%rsi,%r9), %r10
addq $0x80, %r10
leaq 0x80(%rdx,%r9), %r9
leaq 0x80(%rsi,%r8), %r11
addq %rdx, %r8
addq $0x80, %r8
leaq (%rsi,%rax), %rbx
addq $0x80, %rbx
addq %rdx, %rax
addq $0x80, %rax
xorl %r14d, %r14d
cmpq %r14, %rcx
je 0x9938
movq 0x200(%rdi,%r14,4), %r15
xorq 0x80(%rsi,%r14), %r15
movq %r15, 0x80(%rdx,%r14)
movq 0x208(%rdi,%r14,4), %r15
xorq (%r10,%r14), %r15
movq %r15, (%r9,%r14)
movq 0x210(%rdi,%r14,4), %r15
xorq (%r11,%r14), %r15
movq %r15, (%r8,%r14)
movq 0x218(%rdi,%r14,4), %r15
xorq (%rbx,%r14), %r15
movq %r15, (%rax,%r14)
addq $0x8, %r14
jmp 0x98e5
popq %rbx
popq %r12
popq %r14
popq %r15
vzeroupper
retq