// File: /workspace/github_c_makefile_star2_O1/nh13[P]ksw/src/parasail/src/nw_striped_avx2_256_32.c
// Function: parasail_nw_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;
    int s1Len = 0;
    int32_t end_query = 0;
    int32_t end_ref = 0;
    const parasail_matrix_t *matrix = NULL;
    int32_t segWidth = 0;
    int32_t segLen = 0;
    int32_t offset = 0;
    int32_t position = 0;
    __m256i* restrict vProfile = NULL;
    __m256i* restrict pvHStore = NULL;
    __m256i* restrict pvHLoad = NULL;
    __m256i* restrict pvE = NULL;
    int32_t* restrict boundary = NULL;
    __m256i vGapO;
    __m256i vGapE;
    int32_t NEG_LIMIT = 0;
    int32_t POS_LIMIT = 0;
    int32_t score = 0;
    __m256i vNegLimit;
    __m256i vPosLimit;
    __m256i vSaturationCheckMin;
    __m256i vSaturationCheckMax;
    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;
    s1Len = profile->s1Len;
    end_query = s1Len-1;
    end_ref = s2Len-1;
    matrix = profile->matrix;
    segWidth = 8; /* number of values in vector unit */
    segLen = (s1Len + segWidth - 1) / segWidth;
    offset = (s1Len - 1) % segLen;
    position = (segWidth - 1) - (s1Len - 1) / segLen;
    vProfile = (__m256i*)profile->profile32.score;
    vGapO = _mm256_set1_epi32(open);
    vGapE = _mm256_set1_epi32(gap);
    NEG_LIMIT = (-open < matrix->min ? INT32_MIN + open : INT32_MIN - matrix->min) + 1;
    POS_LIMIT = INT32_MAX - matrix->max - 1;
    score = NEG_LIMIT;
    vNegLimit = _mm256_set1_epi32(NEG_LIMIT);
    vPosLimit = _mm256_set1_epi32(POS_LIMIT);
    vSaturationCheckMin = vPosLimit;
    vSaturationCheckMax = vNegLimit;

    /* 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_NW | 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);
    pvE      = parasail_memalign___m256i(32, segLen);
    boundary = parasail_memalign_int32_t(32, s2Len+1);

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

    /* initialize H and E */
    {
        int32_t index = 0;
        for (i=0; i<segLen; ++i) {
            int32_t segNum = 0;
            __m256i_32_t h;
            __m256i_32_t e;
            for (segNum=0; segNum<segWidth; ++segNum) {
                int64_t tmp = -open-gap*(segNum*segLen+i);
                h.v[segNum] = tmp < INT32_MIN ? INT32_MIN : tmp;
                tmp = tmp - open;
                e.v[segNum] = tmp < INT32_MIN ? INT32_MIN : tmp;
            }
            _mm256_store_si256(&pvHStore[index], h.m);
            _mm256_store_si256(&pvE[index], e.m);
            ++index;
        }
    }

    /* initialize uppder boundary */
    {
        boundary[0] = 0;
        for (i=1; i<=s2Len; ++i) {
            int64_t tmp = -open-gap*(i-1);
            boundary[i] = tmp < INT32_MIN ? INT32_MIN : tmp;
        }
    }

    /* outer loop over database sequence */
    for (j=0; j<s2Len; ++j) {
        __m256i vE;
        /* Initialize F value to -inf.  Any errors to vH values will be
         * corrected in the Lazy_F loop.  */
        __m256i vF = vNegLimit;

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

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

        /* Swap the 2 H buffers. */
        __m256i* pv = pvHLoad;
        pvHLoad = pvHStore;
        pvHStore = pv;

        /* insert upper boundary condition */
        vH = _mm256_insert_epi32_rpl(vH, boundary[j], 0);

        /* 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);
            /* Save vH values. */
            _mm256_store_si256(pvHStore + i, vH);
            vSaturationCheckMax = _mm256_max_epi32(vSaturationCheckMax, vH);
            vSaturationCheckMin = _mm256_min_epi32(vSaturationCheckMin, vH);
            vSaturationCheckMin = _mm256_min_epi32(vSaturationCheckMin, vE);
            vSaturationCheckMin = _mm256_min_epi32(vSaturationCheckMin, vF);
#ifdef PARASAIL_TABLE
            arr_store_si256(result->tables->score_table, vH, i, segLen, j, s2Len);
#endif

            /* 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) {
            int64_t tmp = boundary[j+1]-open;
            int32_t tmp2 = tmp < INT32_MIN ? INT32_MIN : tmp;
            vF = _mm256_slli_si256_rpl(vF, 4);
            vF = _mm256_insert_epi32_rpl(vF, tmp2, 0);
            for (i=0; i<segLen; ++i) {
                vH = _mm256_load_si256(pvHStore + i);
                vH = _mm256_max_epi32(vH,vF);
                _mm256_store_si256(pvHStore + i, vH);
                vSaturationCheckMin = _mm256_min_epi32(vSaturationCheckMin, vH);
                vSaturationCheckMax = _mm256_max_epi32(vSaturationCheckMax, vH);
#ifdef PARASAIL_TABLE
                arr_store_si256(result->tables->score_table, vH, i, segLen, j, s2Len);
#endif
                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
    }

#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

    /* extract last value from the last column */
    {
        __m256i vH = _mm256_load_si256(pvHStore + offset);
        for (k=0; k<position; ++k) {
            vH = _mm256_slli_si256_rpl (vH, 4);
        }
        score = (int32_t) _mm256_extract_epi32_rpl (vH, 7);
    }

    if (_mm256_movemask_epi8(_mm256_or_si256(
            _mm256_cmplt_epi32_rpl(vSaturationCheckMin, vNegLimit),
            _mm256_cmpgt_epi32(vSaturationCheckMax, vPosLimit)))) {
        result->flag |= PARASAIL_FLAG_SATURATED;
        score = 0;
        end_query = 0;
        end_ref = 0;
    }

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

    parasail_free(boundary);
    parasail_free(pvE);
    parasail_free(pvHLoad);
    parasail_free(pvHStore);

    return result;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
andq $-0x20, %rsp
subq $0xe0, %rsp
movq %rsi, 0x40(%rsp)
testq %rdi, %rdi
je 0x539a61
movq 0x48(%rdi), %rax
movq %rax, 0x78(%rsp)
testq %rax, %rax
je 0x539a68
movq 0x10(%rdi), %rax
movq %rax, 0x38(%rsp)
testq %rax, %rax
je 0x539a6f
movl 0x8(%rdi), %edi
testl %edi, %edi
jle 0x539a76
cmpq $0x0, 0x40(%rsp)
je 0x539a7d
movl %edx, %r15d
testl %edx, %edx
jle 0x539a84
movl %ecx, %r14d
testl %ecx, %ecx
js 0x539a8b
movl %r8d, %ebx
testl %r8d, %r8d
js 0x539a92
leal -0x1(%rdi), %eax
addq $0x7, %rdi
movq %rdi, %r12
shrq $0x3, %r12
movl %eax, 0x24(%rsp)
cltd
idivl %r12d
movl %eax, 0x18(%rsp)
movl %edx, 0x58(%rsp)
movl %r14d, %r13d
negl %r13d
movq 0x38(%rsp), %rdx
movl 0x20(%rdx), %eax
movl $0x80000000, %esi       # imm = 0x80000000
movl %r14d, %ecx
orl %esi, %ecx
subl %eax, %esi
cmpl %r13d, %eax
cmovgl %ecx, %esi
movl %esi, 0x50(%rsp)
movl $0x7ffffffe, %eax       # imm = 0x7FFFFFFE
subl 0x1c(%rdx), %eax
movl %eax, 0x14(%rsp)
andl $0x7ffffff8, %edi       # imm = 0x7FFFFFF8
movl %r15d, %esi
callq 0x209630
testq %rax, %rax
je 0x539a97
movl %ebx, 0x30(%rsp)
movq %rax, 0x68(%rsp)
orl $0x8440801, 0xc(%rax)   # imm = 0x8440801
movl $0x20, %edi
movq %r12, %rsi
callq 0x4c5e3c
movq %r15, %rbx
movq %rax, %r15
movl $0x20, %edi
movq %r12, %rsi
callq 0x4c5e3c
movq %rax, 0x60(%rsp)
movl $0x20, %edi
movq %r12, %rsi
callq 0x4c5e3c
movq %r12, 0x48(%rsp)
movq %rax, %r12
movq %rbx, 0x28(%rsp)
leal 0x1(%rbx), %esi
movl $0x20, %edi
movq %rsi, 0x70(%rsp)
callq 0x2094d5
testq %r15, %r15
sete %cl
cmpq $0x0, 0x60(%rsp)
sete %dl
orb %cl, %dl
testq %r12, %r12
sete %cl
testq %rax, %rax
sete %sil
orb %cl, %sil
orb %dl, %sil
jne 0x539a97
movq 0x28(%rsp), %rcx
decl %ecx
movl %ecx, 0x1c(%rsp)
movl $0x7, %ecx
subl 0x18(%rsp), %ecx
movl %ecx, 0x20(%rsp)
vmovd %r14d, %xmm0
vpbroadcastd %xmm0, %ymm2
movl 0x30(%rsp), %edx
vmovd %edx, %xmm0
vpbroadcastd %xmm0, %ymm3
movl 0x50(%rsp), %ecx
incl %ecx
vmovd %ecx, %xmm0
vpbroadcastd %xmm0, %ymm0
vmovd 0x14(%rsp), %xmm1
vpbroadcastd %xmm1, %ymm1
movl %r14d, %ecx
movq 0x48(%rsp), %rdi
movl %edi, %esi
imull %edi, %edx
xorl %edi, %edi
movq $-0x80000000, %r8       # imm = 0x80000000
movl %r13d, %r9d
movl %r9d, %r10d
xorl %r11d, %r11d
movslq %r10d, %r10
movl %r10d, 0xa0(%rsp,%r11,4)
movq %r10, %rbx
subq %rcx, %rbx
cmpq $-0x7fffffff, %rbx      # imm = 0x80000001
cmovlq %r8, %rbx
movl %ebx, 0x80(%rsp,%r11,4)
incq %r11
subl %edx, %r10d
cmpq $0x8, %r11
jne 0x539671
movq %rdi, %r10
shlq $0x5, %r10
vmovaps 0xa0(%rsp), %ymm4
vmovaps %ymm4, (%r15,%r10)
vmovaps 0x80(%rsp), %ymm4
vmovaps %ymm4, (%r12,%r10)
incq %rdi
movl 0x30(%rsp), %r10d
subl %r10d, %r9d
cmpq %rsi, %rdi
jne 0x53966b
movl $0x0, (%rax)
movl $0x1, %ecx
movq 0x70(%rsp), %rdx
movl %r13d, (%rax,%rcx,4)
incq %rcx
subl %r10d, %r13d
cmpq %rcx, %rdx
jne 0x5396e6
movq 0x48(%rsp), %r10
leal -0x1(%r10), %r8d
movl 0x58(%rsp), %edi
movl $0x1, %edx
cmpl %edx, %r10d
adcl $0x0, %r10d
movl 0x20(%rsp), %ecx
cmpl $0x2, %ecx
movl $0x1, %r9d
cmovgel %ecx, %r9d
movl %r9d, 0x14(%rsp)
movq 0x28(%rsp), %rcx
cmpl $0x2, %ecx
cmovgel %ecx, %edx
movq %rdx, 0x58(%rsp)
movq %r10, %rcx
shlq $0x5, %rcx
xorl %edx, %edx
shlq $0x5, %r8
movq %r8, 0x30(%rsp)
vpmovsxbd 0xc0031(%rip), %ymm6 # 0x5f9780
movq %rdi, 0x28(%rsp)
shlq $0x5, %rdi
movq %rdi, 0x50(%rsp)
vmovdqa %ymm0, %ymm4
vmovdqa %ymm1, %ymm5
movq 0x60(%rsp), %rdi
movq %r15, %r13
movq %rdi, %r15
movq 0x30(%rsp), %rdi
vpermd (%r13,%rdi), %ymm6, %ymm7
movq 0x38(%rsp), %rdi
movq 0x10(%rdi), %rdi
movq 0x40(%rsp), %r8
movzbl (%r8,%rdx), %r8d
movslq (%rdi,%r8,4), %rdi
movq %rsi, %r11
imulq %rdi, %r11
shlq $0x5, %r11
addq 0x78(%rsp), %r11
vmovd (%rax,%rdx,4), %xmm8
vpblendd $0x1, %ymm8, %ymm7, %ymm8 # ymm8 = ymm8[0],ymm7[1,2,3,4,5,6,7]
xorl %ebx, %ebx
vmovdqa %ymm0, %ymm7
vpaddd (%r11,%rbx), %ymm8, %ymm8
vmovdqa (%r12,%rbx), %ymm9
vpmaxsd %ymm7, %ymm9, %ymm10
vpmaxsd %ymm10, %ymm8, %ymm8
vmovdqa %ymm8, (%r15,%rbx)
vpmaxsd %ymm8, %ymm4, %ymm4
vpminsd %ymm9, %ymm5, %ymm5
vpminsd %ymm7, %ymm5, %ymm5
vpminsd %ymm8, %ymm5, %ymm5
vpsubd %ymm2, %ymm8, %ymm8
vpsubd %ymm3, %ymm9, %ymm9
vpmaxsd %ymm8, %ymm9, %ymm9
vmovdqa %ymm9, (%r12,%rbx)
vpsubd %ymm3, %ymm7, %ymm7
vpmaxsd %ymm8, %ymm7, %ymm7
vmovdqa (%r13,%rbx), %ymm8
addq $0x20, %rbx
cmpq %rbx, %rcx
jne 0x5397b4
leaq 0x20(%r15), %r9
xorl %r11d, %r11d
movl 0x4(%rax,%rdx,4), %edi
subl %r14d, %edi
vpermd %ymm7, %ymm6, %ymm7
vmovd %edi, %xmm8
vpblendd $0x1, %ymm8, %ymm7, %ymm7 # ymm7 = ymm8[0],ymm7[1,2,3,4,5,6,7]
vpmaxsd (%r15), %ymm7, %ymm8
vmovdqa %ymm8, (%r15)
vpminsd %ymm8, %ymm5, %ymm5
vpmaxsd %ymm8, %ymm4, %ymm4
vpsubd %ymm2, %ymm8, %ymm8
vpsubd %ymm3, %ymm7, %ymm7
vpcmpgtd %ymm8, %ymm7, %ymm8
vtestps %ymm8, %ymm8
je 0x53989d
movl $0x1, %edi
movq %r9, %rbx
movq %rdi, %r8
cmpq %rdi, %r10
je 0x539894
vpmaxsd (%rbx), %ymm7, %ymm8
vmovdqa %ymm8, (%rbx)
vpminsd %ymm8, %ymm5, %ymm5
vpmaxsd %ymm8, %ymm4, %ymm4
vpsubd %ymm2, %ymm8, %ymm8
vpsubd %ymm3, %ymm7, %ymm7
vpcmpgtd %ymm8, %ymm7, %ymm8
leaq 0x1(%r8), %rdi
addq $0x20, %rbx
vtestps %ymm8, %ymm8
jne 0x53985d
cmpq %rsi, %r8
setb %dil
jmp 0x5398a0
movb $0x1, %dil
testb %dil, %dil
jne 0x5398b6
leal 0x1(%r11), %edi
cmpl $0x7, %r11d
movl %edi, %r11d
jb 0x539817
movq 0x50(%rsp), %rdi
vmovdqa (%r15,%rdi), %ymm7
cmpl $0x6, 0x18(%rsp)
jg 0x5398dc
movl 0x14(%rsp), %edi
vperm2i128 $0x28, %ymm7, %ymm7, %ymm8 # ymm8 = zero,zero,ymm7[0,1]
vpalignr $0xc, %ymm8, %ymm7, %ymm7 # ymm7 = ymm8[12,13,14,15],ymm7[0,1,2,3,4,5,6,7,8,9,10,11],ymm8[28,29,30,31],ymm7[16,17,18,19,20,21,22,23,24,25,26,27]
decl %edi
jne 0x5398cc
vextracti128 $0x1, %ymm7, %xmm7
movq 0x68(%rsp), %rdi
movq 0x10(%rdi), %rdi
movq (%rdi), %rdi
vpextrd $0x3, %xmm7, (%rdi,%rdx,4)
incq %rdx
movq %r13, %rdi
cmpq 0x58(%rsp), %rdx
jne 0x53976a
movq 0x48(%rsp), %r14
leal (,%r14,4), %ecx
movq %rcx, 0x40(%rsp)
cmpl $0x1, %r14d
adcl $0x0, %r14d
leaq (%rsi,%rsi,8), %rdx
leaq (%rdx,%rdx,2), %rcx
addq %rsi, %rcx
movq %rcx, 0x38(%rsp)
leaq (,%rsi,8), %rdi
leaq (%rdi,%rdi,2), %r8
leal (,%rsi,4), %r10d
leaq (%r10,%r10,4), %r9
shlq $0x4, %rsi
leaq (%r10,%r10,2), %r10
shll $0x2, %r14d
xorl %r11d, %r11d
movq 0x68(%rsp), %rbx
movq %rbx, %rcx
movq 0x10(%rbx), %rbx
movq 0x8(%rbx), %rbx
vmovdqa (%r15,%r11,8), %xmm2
vmovdqa 0x10(%r15,%r11,8), %xmm3
vmovd %xmm2, (%rbx,%r11)
addq %r11, %rbx
movq 0x40(%rsp), %rdx
vpextrd $0x1, %xmm2, (%rdx,%rbx)
vpextrd $0x2, %xmm2, (%rdi,%rbx)
vpextrd $0x3, %xmm2, (%r10,%rbx)
vmovd %xmm3, (%rsi,%rbx)
vpextrd $0x1, %xmm3, (%r9,%rbx)
vpextrd $0x2, %xmm3, (%r8,%rbx)
movq 0x38(%rsp), %rdx
vpextrd $0x3, %xmm3, (%rdx,%rbx)
movq %rcx, %rbx
addq $0x4, %r11
cmpq %r11, %r14
jne 0x53995c
movq 0x28(%rsp), %rcx
shlq $0x5, %rcx
vmovdqa (%r15,%rcx), %ymm2
cmpl $0x6, 0x18(%rsp)
jg 0x539a01
movl 0x20(%rsp), %edx
cmpl $0x2, %edx
movl $0x1, %ecx
cmovgel %edx, %ecx
movl 0x24(%rsp), %edx
movl 0x1c(%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 %ecx
jne 0x5399ef
jmp 0x539a09
movl 0x24(%rsp), %edx
movl 0x1c(%rsp), %esi
vpcmpgtd %ymm5, %ymm0, %ymm0
vpcmpgtd %ymm1, %ymm4, %ymm1
vpor %ymm0, %ymm1, %ymm0
vtestps %ymm0, %ymm0
je 0x539a28
orb $0x40, 0xc(%rbx)
xorl %ecx, %ecx
xorl %esi, %esi
xorl %edx, %edx
jmp 0x539a34
vextracti128 $0x1, %ymm2, %xmm0
vpextrd $0x3, %xmm0, %ecx
movl %ecx, (%rbx)
movl %edx, 0x4(%rbx)
movl %esi, 0x8(%rbx)
movq %rax, %rdi
vzeroupper
callq 0x2094b5
movq %r12, %rdi
callq 0x2094b5
movq %r13, %rdi
callq 0x2094b5
movq %r15, %rdi
callq 0x2094b5
jmp 0x539a99
callq 0x1f1e57
jmp 0x539a97
callq 0x1f1e31
jmp 0x539a97
callq 0x1f1e0b
jmp 0x539a97
callq 0x1f1de5
jmp 0x539a97
callq 0x1f1dbf
jmp 0x539a97
callq 0x1f1d99
jmp 0x539a97
callq 0x1f1d73
jmp 0x539a97
callq 0x1f1d4d
xorl %ebx, %ebx
movq %rbx, %rax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop