// File: /workspace/github_c_makefile_star2_O1/nh13[P]ksw/src/parasail/src/sw_striped_avx2_256_32.c
// Function: parasail_sw_rowcol_striped_profile_avx2_256_32
parasail_result_t* PNAME(
        const parasail_profile_t * const restrict profile,
        const char * const restrict s2, const int s2Len,
        const int open, const int gap)
{
    /* declare local variables */
    int32_t i = 0;
    int32_t j = 0;
    int32_t k = 0;
    int32_t end_query = 0;
    int32_t end_ref = 0;
    int32_t s1Len = 0;
    const parasail_matrix_t *matrix = NULL;
    int32_t segWidth = 0;
    int32_t segLen = 0;
#ifdef PARASAIL_ROWCOL
    int32_t offset = 0;
    int32_t position = 0;
#endif
    __m256i* restrict vProfile = NULL;
    __m256i* restrict pvHStore = NULL;
    __m256i* restrict pvHLoad = NULL;
    __m256i* restrict pvHMax = NULL;
    __m256i* restrict pvE = NULL;
    __m256i vGapO;
    __m256i vGapE;
    __m256i vZero;
    __m256i vNegInf;
    int32_t score = 0;
    __m256i vMaxH;
    __m256i vMaxHUnit;
    int32_t maxp = 0;
    /*int32_t stop = 0;*/
    parasail_result_t *result = NULL;

    /* validate inputs */
    PARASAIL_CHECK_NULL(profile);
    PARASAIL_CHECK_NULL(profile->profile32.score);
    PARASAIL_CHECK_NULL(profile->matrix);
    PARASAIL_CHECK_GT0(profile->s1Len);
    PARASAIL_CHECK_NULL(s2);
    PARASAIL_CHECK_GT0(s2Len);
    PARASAIL_CHECK_GE0(open);
    PARASAIL_CHECK_GE0(gap);

    /* initialize stack variables */
    i = 0;
    j = 0;
    k = 0;
    end_query = 0;
    end_ref = 0;
    s1Len = profile->s1Len;
    matrix = profile->matrix;
    segWidth = 8; /* number of values in vector unit */
    segLen = (s1Len + segWidth - 1) / segWidth;
#ifdef PARASAIL_ROWCOL
    offset = (s1Len - 1) % segLen;
    position = (segWidth - 1) - (s1Len - 1) / segLen;
#endif
    vProfile = (__m256i*)profile->profile32.score;
    vGapO = _mm256_set1_epi32(open);
    vGapE = _mm256_set1_epi32(gap);
    vZero = _mm256_setzero_si256();
    vNegInf = _mm256_set1_epi32(NEG_INF);
    score = NEG_INF;
    vMaxH = vNegInf;
    vMaxHUnit = vNegInf;
    maxp = INT32_MAX - (int32_t)(matrix->max+1);
    /*stop = profile->stop == INT32_MAX ?  INT32_MAX : (int32_t)profile->stop;*/

    /* initialize result */
#ifdef PARASAIL_TABLE
    result = parasail_result_new_table1(segLen*segWidth, s2Len);
#else
#ifdef PARASAIL_ROWCOL
    result = parasail_result_new_rowcol1(segLen*segWidth, s2Len);
#else
    result = parasail_result_new();
#endif
#endif
    if (!result) return NULL;

    /* set known flags */
    result->flag |= PARASAIL_FLAG_SW | PARASAIL_FLAG_STRIPED
        | PARASAIL_FLAG_BITS_32 | PARASAIL_FLAG_LANES_8;
#ifdef PARASAIL_TABLE
    result->flag |= PARASAIL_FLAG_TABLE;
#endif
#ifdef PARASAIL_ROWCOL
    result->flag |= PARASAIL_FLAG_ROWCOL;
#endif

    /* initialize heap variables */
    pvHStore = parasail_memalign___m256i(32, segLen);
    pvHLoad =  parasail_memalign___m256i(32, segLen);
    pvHMax = parasail_memalign___m256i(32, segLen);
    pvE = parasail_memalign___m256i(32, segLen);

    /* validate heap variables */
    if (!pvHStore) return NULL;
    if (!pvHLoad) return NULL;
    if (!pvHMax) return NULL;
    if (!pvE) return NULL;

    /* initialize H and E */
    parasail_memset___m256i(pvHStore, vZero, segLen);
    parasail_memset___m256i(pvE, _mm256_set1_epi32(-open), segLen);

    /* outer loop over database sequence */
    for (j=0; j<s2Len; ++j) {
        __m256i vE;
        __m256i vF;
        __m256i vH;
        const __m256i* vP = NULL;
        __m256i* pv = NULL;

        /* Initialize F value to 0.  Any errors to vH values will be
         * corrected in the Lazy_F loop. */
        vF = vZero;

        /* load final segment of pvHStore and shift left by 4 bytes */
        vH = _mm256_load_si256(&pvHStore[segLen - 1]);
        vH = _mm256_slli_si256_rpl(vH, 4);

        /* Correct part of the vProfile */
        vP = vProfile + matrix->mapper[(unsigned char)s2[j]] * segLen;

        if (end_ref == j-2) {
            /* Swap in the max buffer. */
            pv = pvHMax;
            pvHMax = pvHLoad;
            pvHLoad = pvHStore;
            pvHStore = pv;
        }
        else {
            /* Swap the 2 H buffers. */
            pv = pvHLoad;
            pvHLoad = pvHStore;
            pvHStore = pv;
        }

        /* inner loop to process the query sequence */
        for (i=0; i<segLen; ++i) {
            vH = _mm256_add_epi32(vH, _mm256_load_si256(vP + i));
            vE = _mm256_load_si256(pvE + i);

            /* Get max from vH, vE and vF. */
            vH = _mm256_max_epi32(vH, vE);
            vH = _mm256_max_epi32(vH, vF);
            vH = _mm256_max_epi32(vH, vZero);
            /* Save vH values. */
            _mm256_store_si256(pvHStore + i, vH);
#ifdef PARASAIL_TABLE
            arr_store_si256(result->tables->score_table, vH, i, segLen, j, s2Len);
#endif
            vMaxH = _mm256_max_epi32(vH, vMaxH);

            /* Update vE value. */
            vH = _mm256_sub_epi32(vH, vGapO);
            vE = _mm256_sub_epi32(vE, vGapE);
            vE = _mm256_max_epi32(vE, vH);
            _mm256_store_si256(pvE + i, vE);

            /* Update vF value. */
            vF = _mm256_sub_epi32(vF, vGapE);
            vF = _mm256_max_epi32(vF, vH);

            /* Load the next vH. */
            vH = _mm256_load_si256(pvHLoad + i);
        }

        /* Lazy_F loop: has been revised to disallow adjecent insertion and
         * then deletion, so don't update E(i, i), learn from SWPS3 */
        for (k=0; k<segWidth; ++k) {
            vF = _mm256_slli_si256_rpl(vF, 4);
            for (i=0; i<segLen; ++i) {
                vH = _mm256_load_si256(pvHStore + i);
                vH = _mm256_max_epi32(vH,vF);
                _mm256_store_si256(pvHStore + i, vH);
#ifdef PARASAIL_TABLE
                arr_store_si256(result->tables->score_table, vH, i, segLen, j, s2Len);
#endif
                vMaxH = _mm256_max_epi32(vH, vMaxH);
                vH = _mm256_sub_epi32(vH, vGapO);
                vF = _mm256_sub_epi32(vF, vGapE);
                if (! _mm256_movemask_epi8(_mm256_cmpgt_epi32(vF, vH))) goto end;
                /*vF = _mm256_max_epi32(vF, vH);*/
            }
        }
end:
        {
        }

#ifdef PARASAIL_ROWCOL
        /* extract last value from the column */
        {
            vH = _mm256_load_si256(pvHStore + offset);
            for (k=0; k<position; ++k) {
                vH = _mm256_slli_si256_rpl(vH, 4);
            }
            result->rowcols->score_row[j] = (int32_t) _mm256_extract_epi32_rpl (vH, 7);
        }
#endif

        {
            __m256i vCompare = _mm256_cmpgt_epi32(vMaxH, vMaxHUnit);
            if (_mm256_movemask_epi8(vCompare)) {
                score = _mm256_hmax_epi32_rpl(vMaxH);
                /* if score has potential to overflow, abort early */
                if (score > maxp) {
                    result->flag |= PARASAIL_FLAG_SATURATED;
                    break;
                }
                vMaxHUnit = _mm256_set1_epi32(score);
                end_ref = j;
            }
        }

        /*if (score == stop) break;*/
    }

#ifdef PARASAIL_ROWCOL
    for (i=0; i<segLen; ++i) {
        __m256i vH = _mm256_load_si256(pvHStore+i);
        arr_store_col(result->rowcols->score_col, vH, i, segLen);
    }
#endif

    if (score == INT32_MAX) {
        result->flag |= PARASAIL_FLAG_SATURATED;
    }

    if (parasail_result_is_saturated(result)) {
        score = INT32_MAX;
        end_query = 0;
        end_ref = 0;
    }
    else {
        if (end_ref == j-1) {
            /* end_ref was the last store column */
            __m256i *pv = pvHMax;
            pvHMax = pvHStore;
            pvHStore = pv;
        }
        else if (end_ref == j-2) {
            /* end_ref was the last load column */
            __m256i *pv = pvHMax;
            pvHMax = pvHLoad;
            pvHLoad = pv;
        }
        /* Trace the alignment ending position on read. */
        {
            int32_t *t = (int32_t*)pvHMax;
            int32_t column_len = segLen * segWidth;
            end_query = s1Len - 1;
            for (i = 0; i<column_len; ++i, ++t) {
                if (*t == score) {
                    int32_t temp = i / segWidth + i % segWidth * segLen;
                    if (temp < end_query) {
                        end_query = temp;
                    }
                }
            }
        }
    }

    result->score = score;
    result->end_query = end_query;
    result->end_ref = end_ref;

    parasail_free(pvE);
    parasail_free(pvHMax);
    parasail_free(pvHLoad);
    parasail_free(pvHStore);

    return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
testq %rdi, %rdi
je 0x53ab89
movq 0x48(%rdi), %rax
movq %rax, 0x58(%rsp)
testq %rax, %rax
je 0x53ab90
movq 0x10(%rdi), %rax
movq %rax, 0x48(%rsp)
testq %rax, %rax
je 0x53ab97
movq %rsi, 0x40(%rsp)
movl 0x8(%rdi), %eax
testl %eax, %eax
jle 0x53ab9e
cmpq $0x0, 0x40(%rsp)
je 0x53aba5
movl %edx, %r14d
testl %edx, %edx
jle 0x53abac
movl %ecx, %ebx
testl %ecx, %ecx
js 0x53abb3
movl %r8d, %r13d
testl %r8d, %r8d
js 0x53abba
movq %rax, %r15
addq $0x7, %r15
movq %r15, %r12
shrq $0x3, %r12
leal -0x1(%rax), %ebp
movl %ebp, %eax
cltd
idivl %r12d
movl %eax, 0x14(%rsp)
movl %edx, 0x28(%rsp)
movl $0x7ffffffe, %ecx       # imm = 0x7FFFFFFE
movq 0x48(%rsp), %rax
subl 0x1c(%rax), %ecx
movl %ecx, 0x34(%rsp)
andl $0x7ffffff8, %r15d      # imm = 0x7FFFFFF8
movl %r15d, %edi
movl %r14d, %esi
callq 0x209630
testq %rax, %rax
je 0x53abbf
movl %r13d, (%rsp)
movq %r15, 0x50(%rsp)
movq %r14, 0x20(%rsp)
movl %ebp, 0x30(%rsp)
movq %rax, 0x8(%rsp)
orl $0x8440804, 0xc(%rax)   # imm = 0x8440804
movl $0x20, %edi
movq %r12, %rsi
callq 0x4c5e3c
movq %rax, %r15
movl $0x20, %edi
movq %r12, %rsi
callq 0x4c5e3c
movq %rax, %r14
movl $0x20, %edi
movq %r12, %rsi
callq 0x4c5e3c
movq %rax, %rbp
movl $0x20, %edi
movq %r12, %rsi
callq 0x4c5e3c
movq %rax, %r13
testq %r15, %r15
sete %al
testq %r14, %r14
sete %cl
orb %al, %cl
movq %rbp, 0x18(%rsp)
testq %rbp, %rbp
sete %al
testq %r13, %r13
sete %dl
orb %al, %dl
orb %cl, %dl
jne 0x53abbf
xorl %ebp, %ebp
movl $0x7, %eax
subl 0x14(%rsp), %eax
movl %eax, 0x4(%rsp)
vmovd %ebx, %xmm0
vpbroadcastd %xmm0, %ymm0
vmovdqu %ymm0, 0x80(%rsp)
vmovss (%rsp), %xmm0
vbroadcastss %xmm0, %ymm0
vmovups %ymm0, 0x60(%rsp)
vxorps %xmm0, %xmm0, %xmm0
movq %r15, %rdi
movq %r12, %rsi
callq 0x4c5e45
negl %ebx
vmovd %ebx, %xmm0
vpbroadcastd %xmm0, %ymm0
movq %r13, %rdi
movq %r12, %rsi
callq 0x4c5e45
vpxor %xmm8, %xmm8, %xmm8
vmovdqu 0x60(%rsp), %ymm7
vmovdqu 0x80(%rsp), %ymm6
leal -0x1(%r12), %ecx
movl 0x28(%rsp), %edx
movl 0x4(%rsp), %esi
cmpl $0x2, %esi
movl $0x1, %eax
cmovgel %esi, %eax
movl %eax, 0x4(%rsp)
movl 0x20(%rsp), %eax
movq %rax, 0x28(%rsp)
movq %r12, 0x38(%rsp)
movl %r12d, %r11d
movq %r11, %r8
shlq $0x5, %r8
movl $0xc0000000, (%rsp)     # imm = 0xC0000000
vpbroadcastd 0xbd0ab(%rip), %ymm0 # 0x5f7920
shlq $0x5, %rcx
shlq $0x5, %rdx
xorl %r9d, %r9d
vmovdqa %ymm0, %ymm1
movq 0x40(%rsp), %rax
movq %r15, %r12
vmovdqa (%r15,%rcx), %ymm2
vperm2i128 $0x28, %ymm2, %ymm2, %ymm3 # ymm3 = zero,zero,ymm2[0,1]
vpalignr $0xc, %ymm3, %ymm2, %ymm3 # ymm3 = ymm3[12,13,14,15],ymm2[0,1,2,3,4,5,6,7,8,9,10,11],ymm3[28,29,30,31],ymm2[16,17,18,19,20,21,22,23,24,25,26,27]
movq 0x48(%rsp), %rsi
movq 0x10(%rsi), %rsi
movzbl (%rax,%r9), %r10d
movslq (%rsi,%r10,4), %rsi
movq %r11, %rdi
movq %r11, %r10
imulq %rsi, %r10
shlq $0x5, %r10
addq 0x58(%rsp), %r10
leal -0x2(%r9), %r11d
cmpl %r11d, %ebp
movq %r14, %r15
cmoveq 0x18(%rsp), %r15
xorl %esi, %esi
vpxor %xmm2, %xmm2, %xmm2
vpaddd (%r10,%rsi), %ymm3, %ymm3
vmovdqa (%r13,%rsi), %ymm4
vpmaxsd %ymm2, %ymm4, %ymm5
vpmaxsd %ymm5, %ymm3, %ymm3
vpmaxsd %ymm8, %ymm3, %ymm3
vmovdqa %ymm3, (%r15,%rsi)
vpmaxsd %ymm1, %ymm3, %ymm1
vpsubd %ymm6, %ymm3, %ymm3
vpsubd %ymm7, %ymm4, %ymm4
vpmaxsd %ymm3, %ymm4, %ymm4
vmovdqa %ymm4, (%r13,%rsi)
vpsubd %ymm7, %ymm2, %ymm2
vpmaxsd %ymm3, %ymm2, %ymm2
vmovdqa (%r12,%rsi), %ymm3
addq $0x20, %rsi
cmpq %rsi, %r8
jne 0x53a8d9
cmpl %r11d, %ebp
movq 0x18(%rsp), %rbx
cmoveq %r14, %rbx
xorl %r10d, %r10d
movq 0x8(%rsp), %r11
vperm2i128 $0x8, %ymm2, %ymm2, %ymm3 # ymm3 = zero,zero,ymm2[0,1]
vpalignr $0xc, %ymm3, %ymm2, %ymm2 # ymm2 = ymm3[12,13,14,15],ymm2[0,1,2,3,4,5,6,7,8,9,10,11],ymm3[28,29,30,31],ymm2[16,17,18,19,20,21,22,23,24,25,26,27]
xorl %esi, %esi
vpmaxsd (%r15,%rsi), %ymm2, %ymm3
vmovdqa %ymm3, (%r15,%rsi)
vpmaxsd %ymm1, %ymm3, %ymm1
vpsubd %ymm6, %ymm3, %ymm3
vpsubd %ymm7, %ymm2, %ymm2
vpcmpgtd %ymm3, %ymm2, %ymm3
vtestps %ymm3, %ymm3
je 0x53a984
addq $0x20, %rsi
cmpq %rsi, %r8
jne 0x53a94e
incl %r10d
cmpl $0x8, %r10d
jne 0x53a940
vmovdqa (%r15,%rdx), %ymm2
cmpl $0x6, 0x14(%rsp)
jg 0x53a9a5
movl 0x4(%rsp), %esi
vperm2i128 $0x28, %ymm2, %ymm2, %ymm3 # ymm3 = zero,zero,ymm2[0,1]
vpalignr $0xc, %ymm3, %ymm2, %ymm2 # ymm2 = ymm3[12,13,14,15],ymm2[0,1,2,3,4,5,6,7,8,9,10,11],ymm3[28,29,30,31],ymm2[16,17,18,19,20,21,22,23,24,25,26,27]
decl %esi
jne 0x53a995
vextracti128 $0x1, %ymm2, %xmm2
movq 0x10(%r11), %rsi
movq (%rsi), %rsi
vpextrd $0x3, %xmm2, (%rsi,%r9,4)
vpcmpgtd %ymm0, %ymm1, %ymm2
movb $0x1, %r10b
vtestps %ymm2, %ymm2
je 0x53aa16
vpermq $0x44, %ymm1, %ymm2     # ymm2 = ymm1[0,1,0,1]
vpmaxsd %ymm2, %ymm1, %ymm2
vpslldq $0x8, %ymm2, %ymm3      # ymm3 = zero,zero,zero,zero,zero,zero,zero,zero,ymm2[0,1,2,3,4,5,6,7],zero,zero,zero,zero,zero,zero,zero,zero,ymm2[16,17,18,19,20,21,22,23]
vpmaxsd %ymm3, %ymm2, %ymm2
vpslldq $0x4, %ymm2, %ymm3      # ymm3 = zero,zero,zero,zero,ymm2[0,1,2,3,4,5,6,7,8,9,10,11],zero,zero,zero,zero,ymm2[16,17,18,19,20,21,22,23,24,25,26,27]
vpmaxsd %ymm3, %ymm2, %ymm2
vextracti128 $0x1, %ymm2, %xmm3
vpextrd $0x3, %xmm3, %esi
movl %esi, (%rsp)
cmpl 0x34(%rsp), %esi
jle 0x53aa05
orb $0x40, 0xc(%r11)
xorl %r10d, %r10d
jmp 0x53aa16
vpbroadcastd 0xbee02(%rip), %ymm0 # 0x5f9810
vpermd %ymm2, %ymm0, %ymm0
movl %r9d, %ebp
movq %rbx, 0x18(%rsp)
testb %r10b, %r10b
movq %rdi, %r11
je 0x53aa36
incq %r9
movq %r12, %r14
cmpq 0x28(%rsp), %r9
jne 0x53a889
jmp 0x53aa3b
movq %r9, 0x20(%rsp)
movq 0x38(%rsp), %rdx
leal (,%rdx,4), %ebx
cmpl $0x1, %edx
adcl $0x0, %edx
leaq (%r11,%r11,8), %rsi
leaq (%rsi,%rsi,2), %rsi
addq %r11, %rsi
leaq (,%r11,8), %rax
leaq (%rax,%rax,2), %r8
leaq (%rbx,%rbx,4), %r9
shlq $0x4, %r11
leaq (%rbx,%rbx,2), %r10
shll $0x2, %edx
movq %r11, %rcx
xorl %r11d, %r11d
movq 0x8(%rsp), %rdi
movq 0x10(%rdi), %r14
movq 0x8(%r14), %r14
vmovdqa (%r15,%r11,8), %xmm0
vmovdqa 0x10(%r15,%r11,8), %xmm1
vmovd %xmm0, (%r14,%r11)
addq %r11, %r14
vpextrd $0x1, %xmm0, (%rbx,%r14)
vpextrd $0x2, %xmm0, (%rax,%r14)
vpextrd $0x3, %xmm0, (%r10,%r14)
vmovd %xmm1, (%rcx,%r14)
vpextrd $0x1, %xmm1, (%r9,%r14)
vpextrd $0x2, %xmm1, (%r8,%r14)
vpextrd $0x3, %xmm1, (%rsi,%r14)
addq $0x4, %r11
cmpq %r11, %rdx
jne 0x53aa7e
cmpl $0x7fffffff, (%rsp)     # imm = 0x7FFFFFFF
jne 0x53aae2
orb $0x40, 0xc(%rdi)
vzeroupper
callq 0x20a805
testl %eax, %eax
movl 0x30(%rsp), %r8d
movq 0x18(%rsp), %r14
je 0x53ab0d
xorl %ebp, %ebp
movl $0x7fffffff, %r11d      # imm = 0x7FFFFFFF
xorl %r8d, %r8d
movq 0x8(%rsp), %r10
jmp 0x53abdd
movq 0x20(%rsp), %rax
leal -0x1(%rax), %ecx
addl $-0x2, %eax
cmpl %eax, %ebp
movq %r12, %rdx
cmoveq %r14, %rdx
movq %r14, %rax
cmoveq %r12, %rax
cmpl %ecx, %ebp
cmovneq %r15, %r14
cmovneq %rdx, %r12
cmoveq %r15, %rax
cmpl $0x0, 0x50(%rsp)
movq 0x8(%rsp), %r10
je 0x53abd3
movq 0x38(%rsp), %r9
movl %r9d, %ecx
andl $0xfffffff, %ecx        # imm = 0xFFFFFFF
shll $0x3, %ecx
xorl %edx, %edx
movl (%rsp), %r11d
cmpl %r11d, (%rax,%rdx,4)
jne 0x53ab7a
movl %edx, %esi
shrl $0x3, %esi
movl %edx, %edi
andl $0x7, %edi
imull %r9d, %edi
addl %esi, %edi
cmpl %r8d, %edi
cmovll %edi, %r8d
incq %rdx
cmpl %edx, %ecx
jne 0x53ab5d
movq %r14, %r15
movq %rax, %r14
jmp 0x53abdd
callq 0x1f22cb
jmp 0x53abbf
callq 0x1f22a5
jmp 0x53abbf
callq 0x1f227f
jmp 0x53abbf
callq 0x1f2259
jmp 0x53abbf
callq 0x1f2233
jmp 0x53abbf
callq 0x1f220d
jmp 0x53abbf
callq 0x1f21e7
jmp 0x53abbf
callq 0x1f21c1
xorl %eax, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r14, %r15
movq %rax, %r14
movl (%rsp), %r11d
movl %r11d, (%r10)
movl %r8d, 0x4(%r10)
movl %ebp, 0x8(%r10)
movq %r13, %rdi
callq 0x2094b5
movq %r14, %rdi
callq 0x2094b5
movq %r12, %rdi
callq 0x2094b5
movq %r15, %rdi
callq 0x2094b5
movq 0x8(%rsp), %rax
jmp 0x53abc1
nop