// File: /workspace/github_c_makefile_star2_O1/nh13[P]ksw/src/parasail/src/sw_striped_sse2_128_32.c
// Function: parasail_sw_rowcol_striped_profile_sse2_128_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
    __m128i* restrict vProfile = NULL;
    __m128i* restrict pvHStore = NULL;
    __m128i* restrict pvHLoad = NULL;
    __m128i* restrict pvHMax = NULL;
    __m128i* restrict pvE = NULL;
    __m128i vGapO;
    __m128i vGapE;
    __m128i vZero;
    __m128i vNegInf;
    int32_t score = 0;
    __m128i vMaxH;
    __m128i 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 = 4; /* 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 = (__m128i*)profile->profile32.score;
    vGapO = _mm_set1_epi32(open);
    vGapE = _mm_set1_epi32(gap);
    vZero = _mm_setzero_si128();
    vNegInf = _mm_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_4;
#ifdef PARASAIL_TABLE
    result->flag |= PARASAIL_FLAG_TABLE;
#endif
#ifdef PARASAIL_ROWCOL
    result->flag |= PARASAIL_FLAG_ROWCOL;
#endif

    /* initialize heap variables */
    pvHStore = parasail_memalign___m128i(16, segLen);
    pvHLoad =  parasail_memalign___m128i(16, segLen);
    pvHMax = parasail_memalign___m128i(16, segLen);
    pvE = parasail_memalign___m128i(16, 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___m128i(pvHStore, vZero, segLen);
    parasail_memset___m128i(pvE, _mm_set1_epi32(-open), segLen);

    /* outer loop over database sequence */
    for (j=0; j<s2Len; ++j) {
        __m128i vE;
        __m128i vF;
        __m128i vH;
        const __m128i* vP = NULL;
        __m128i* 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 = _mm_load_si128(&pvHStore[segLen - 1]);
        vH = _mm_slli_si128(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 = _mm_add_epi32(vH, _mm_load_si128(vP + i));
            vE = _mm_load_si128(pvE + i);

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

            /* Update vE value. */
            vH = _mm_sub_epi32(vH, vGapO);
            vE = _mm_sub_epi32(vE, vGapE);
            vE = _mm_max_epi32_rpl(vE, vH);
            _mm_store_si128(pvE + i, vE);

            /* Update vF value. */
            vF = _mm_sub_epi32(vF, vGapE);
            vF = _mm_max_epi32_rpl(vF, vH);

            /* Load the next vH. */
            vH = _mm_load_si128(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 = _mm_slli_si128(vF, 4);
            for (i=0; i<segLen; ++i) {
                vH = _mm_load_si128(pvHStore + i);
                vH = _mm_max_epi32_rpl(vH,vF);
                _mm_store_si128(pvHStore + i, vH);
#ifdef PARASAIL_TABLE
                arr_store_si128(result->tables->score_table, vH, i, segLen, j, s2Len);
#endif
                vMaxH = _mm_max_epi32_rpl(vH, vMaxH);
                vH = _mm_sub_epi32(vH, vGapO);
                vF = _mm_sub_epi32(vF, vGapE);
                if (! _mm_movemask_epi8(_mm_cmpgt_epi32(vF, vH))) goto end;
                /*vF = _mm_max_epi32_rpl(vF, vH);*/
            }
        }
end:
        {
        }

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

        {
            __m128i vCompare = _mm_cmpgt_epi32(vMaxH, vMaxHUnit);
            if (_mm_movemask_epi8(vCompare)) {
                score = _mm_hmax_epi32_rpl(vMaxH);
                /* if score has potential to overflow, abort early */
                if (score > maxp) {
                    result->flag |= PARASAIL_FLAG_SATURATED;
                    break;
                }
                vMaxHUnit = _mm_set1_epi32(score);
                end_ref = j;
            }
        }

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

#ifdef PARASAIL_ROWCOL
    for (i=0; i<segLen; ++i) {
        __m128i vH = _mm_load_si128(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 */
            __m128i *pv = pvHMax;
            pvHMax = pvHStore;
            pvHStore = pv;
        }
        else if (end_ref == j-2) {
            /* end_ref was the last load column */
            __m128i *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 $0x88, %rsp
movq %rsi, 0x40(%rsp)
testq %rdi, %rdi
je 0x34ee3a
movq 0x48(%rdi), %rax
movq %rax, 0x58(%rsp)
testq %rax, %rax
je 0x34ee41
movq 0x10(%rdi), %rax
movq %rax, 0x38(%rsp)
testq %rax, %rax
je 0x34ee48
movl 0x8(%rdi), %eax
testl %eax, %eax
jle 0x34ee4f
cmpq $0x0, 0x40(%rsp)
je 0x34ee56
movl %edx, %r14d
testl %edx, %edx
jle 0x34ee5d
movl %ecx, %ebp
testl %ecx, %ecx
js 0x34ee64
movl %r8d, %r13d
testl %r8d, %r8d
js 0x34ee6b
movq %rax, %r15
addq $0x3, %r15
movq %r15, %r12
shrq $0x2, %r12
decl %eax
movl %eax, 0x18(%rsp)
cltd
idivl %r12d
movl %eax, 0x1c(%rsp)
movl %edx, 0x8(%rsp)
movl $0x7ffffffe, %ecx       # imm = 0x7FFFFFFE
movq 0x38(%rsp), %rax
subl 0x1c(%rax), %ecx
movl %ecx, 0x2c(%rsp)
andl $0x7ffffffc, %r15d      # imm = 0x7FFFFFFC
movl %r15d, %edi
movl %r14d, %esi
callq 0x209630
testq %rax, %rax
je 0x34ee70
movq %rax, %rbx
movl %r13d, 0x20(%rsp)
movl %ebp, 0xc(%rsp)
movq %r15, 0x50(%rsp)
movq %r14, 0x30(%rsp)
orl $0x4440804, 0xc(%rax)   # imm = 0x4440804
movl $0x10, %edi
movq %r12, %rsi
callq 0x2ea474
movq %rax, %r15
movl $0x10, %edi
movq %r12, %rsi
callq 0x2ea474
movq %rax, %r14
movl $0x10, %edi
movq %r12, %rsi
callq 0x2ea474
movq %rax, %rbp
movl $0x10, %edi
movq %r12, %rsi
callq 0x2ea474
movq %rax, %r13
testq %r15, %r15
sete %al
testq %r14, %r14
sete %cl
orb %al, %cl
testq %rbp, %rbp
sete %al
testq %r13, %r13
sete %dl
orb %al, %dl
orb %cl, %dl
jne 0x34ee70
movq $0x0, 0x10(%rsp)
movl $0x3, %eax
subl 0x1c(%rsp), %eax
movl %eax, 0x28(%rsp)
movq %rbp, 0x48(%rsp)
movl 0xc(%rsp), %ebp
movd %ebp, %xmm0
pshufd $0x0, %xmm0, %xmm0      # xmm0 = xmm0[0,0,0,0]
movdqa %xmm0, 0x70(%rsp)
movd 0x20(%rsp), %xmm0
pshufd $0x0, %xmm0, %xmm0      # xmm0 = xmm0[0,0,0,0]
movdqa %xmm0, 0x60(%rsp)
pxor %xmm0, %xmm0
movq %r15, %rdi
movq %r12, %rsi
callq 0x2ea47d
negl %ebp
movd %ebp, %xmm0
movq 0x48(%rsp), %rbp
pshufd $0x0, %xmm0, %xmm0      # xmm0 = xmm0[0,0,0,0]
movq %r13, %rdi
movq %r12, %rsi
callq 0x2ea47d
pxor %xmm9, %xmm9
movdqa 0x60(%rsp), %xmm8
movdqa 0x70(%rsp), %xmm7
leal -0x1(%r12), %ecx
movl 0x8(%rsp), %edx
movl 0x28(%rsp), %esi
cmpl $0x2, %esi
movl $0x1, %eax
cmovgel %esi, %eax
movl %eax, 0xc(%rsp)
movl 0x30(%rsp), %edi
movq %r12, 0x20(%rsp)
movl %r12d, %eax
movq %rax, %r8
shlq $0x4, %r8
movl $0xc0000000, 0x8(%rsp)  # imm = 0xC0000000
movdqa 0x2a72d0(%rip), %xmm0   # 0x5f5db0
shlq $0x4, %rcx
shlq $0x4, %rdx
xorl %r9d, %r9d
movdqa %xmm0, %xmm1
movq %r15, %r12
movdqa (%r15,%rcx), %xmm3
pslldq $0x4, %xmm3             # xmm3 = zero,zero,zero,zero,xmm3[0,1,2,3,4,5,6,7,8,9,10,11]
movq 0x38(%rsp), %rsi
movq 0x10(%rsi), %rsi
movq 0x40(%rsp), %r10
movzbl (%r10,%r9), %r10d
movslq (%rsi,%r10,4), %rsi
movq %rax, %r10
imulq %rsi, %r10
shlq $0x4, %r10
addq 0x58(%rsp), %r10
leal -0x2(%r9), %r11d
cmpl %r11d, 0x10(%rsp)
movq %r14, %r15
cmoveq %rbp, %r15
xorl %esi, %esi
pxor %xmm2, %xmm2
paddd (%r10,%rsi), %xmm3
movdqa (%r13,%rsi), %xmm4
movdqa %xmm3, %xmm5
pcmpgtd %xmm4, %xmm5
pand %xmm5, %xmm3
pandn %xmm4, %xmm5
por %xmm3, %xmm5
movdqa %xmm5, %xmm6
pcmpgtd %xmm2, %xmm6
pand %xmm6, %xmm5
pandn %xmm2, %xmm6
por %xmm5, %xmm6
movdqa %xmm6, %xmm3
pcmpgtd %xmm9, %xmm3
pand %xmm6, %xmm3
movdqa %xmm3, (%r15,%rsi)
movdqa %xmm3, %xmm5
pcmpgtd %xmm1, %xmm5
movdqa %xmm3, %xmm6
pand %xmm5, %xmm6
pandn %xmm1, %xmm5
movdqa %xmm5, %xmm1
por %xmm6, %xmm1
psubd %xmm7, %xmm3
psubd %xmm8, %xmm4
movdqa %xmm4, %xmm5
pcmpgtd %xmm3, %xmm5
pand %xmm5, %xmm4
pandn %xmm3, %xmm5
por %xmm4, %xmm5
movdqa %xmm5, (%r13,%rsi)
psubd %xmm8, %xmm2
movdqa %xmm2, %xmm4
pcmpgtd %xmm3, %xmm2
pand %xmm2, %xmm4
pandn %xmm3, %xmm2
por %xmm4, %xmm2
movdqa (%r12,%rsi), %xmm3
addq $0x10, %rsi
cmpq %rsi, %r8
jne 0x34eb3a
cmpl %r11d, 0x10(%rsp)
cmoveq %r14, %rbp
xorl %esi, %esi
pslldq $0x4, %xmm2             # xmm2 = zero,zero,zero,zero,xmm2[0,1,2,3,4,5,6,7,8,9,10,11]
xorl %r10d, %r10d
movdqa (%r15,%r10), %xmm3
movdqa %xmm3, %xmm4
pcmpgtd %xmm2, %xmm4
pand %xmm4, %xmm3
pandn %xmm2, %xmm4
por %xmm3, %xmm4
movdqa %xmm4, (%r15,%r10)
movdqa %xmm4, %xmm3
pcmpgtd %xmm1, %xmm3
movdqa %xmm4, %xmm5
pand %xmm3, %xmm5
pandn %xmm1, %xmm3
movdqa %xmm3, %xmm1
por %xmm5, %xmm1
psubd %xmm7, %xmm4
psubd %xmm8, %xmm2
movdqa %xmm2, %xmm3
pcmpgtd %xmm4, %xmm3
movmskps %xmm3, %r11d
testl %r11d, %r11d
je 0x34ec67
addq $0x10, %r10
cmpq %r10, %r8
jne 0x34ec01
incl %esi
cmpl $0x4, %esi
jne 0x34ebf9
movdqa (%r15,%rdx), %xmm2
cmpl $0x2, 0x1c(%rsp)
jg 0x34ec81
movl 0xc(%rsp), %esi
pslldq $0x4, %xmm2             # xmm2 = zero,zero,zero,zero,xmm2[0,1,2,3,4,5,6,7,8,9,10,11]
decl %esi
jne 0x34ec78
pshufd $0xff, %xmm2, %xmm2     # xmm2 = xmm2[3,3,3,3]
movq 0x10(%rbx), %rsi
movq (%rsi), %rsi
movd %xmm2, (%rsi,%r9,4)
movdqa %xmm1, %xmm2
pcmpgtd %xmm0, %xmm2
movmskps %xmm2, %r10d
movb $0x1, %sil
testl %r10d, %r10d
je 0x34ed0b
movdqa %xmm1, %xmm2
psrldq $0x8, %xmm2             # xmm2 = xmm2[8,9,10,11,12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero
movdqa %xmm1, %xmm3
pcmpgtd %xmm2, %xmm3
movdqa %xmm1, %xmm4
pand %xmm3, %xmm4
pandn %xmm2, %xmm3
por %xmm4, %xmm3
movdqa %xmm3, %xmm4
psrldq $0x4, %xmm4             # xmm4 = xmm4[4,5,6,7,8,9,10,11,12,13,14,15],zero,zero,zero,zero
movdqa %xmm3, %xmm2
pcmpgtd %xmm4, %xmm2
pand %xmm2, %xmm3
pandn %xmm4, %xmm2
por %xmm3, %xmm2
movd %xmm2, %r10d
movl %r10d, 0x8(%rsp)
cmpl 0x2c(%rsp), %r10d
jle 0x34ecfe
orb $0x40, 0xc(%rbx)
xorl %esi, %esi
jmp 0x34ed0b
pshufd $0x0, %xmm2, %xmm0      # xmm0 = xmm2[0,0,0,0]
movl %r9d, %r10d
movq %r10, 0x10(%rsp)
testb %sil, %sil
je 0x34ed26
incq %r9
movq %r12, %r14
cmpq %rdi, %r9
jne 0x34eaef
movq 0x30(%rsp), %r14
jmp 0x34ed29
movl %r9d, %r14d
movq 0x20(%rsp), %rcx
cmpl $0x1, %ecx
adcl $0x0, %ecx
leaq (,%rax,4), %rdx
leaq (%rdx,%rdx,2), %rsi
shlq $0x3, %rax
shlq $0x2, %rcx
xorl %edi, %edi
movdqa (%r15,%rdi,4), %xmm0
movq 0x10(%rbx), %r8
movq 0x8(%r8), %r8
movd %xmm0, (%r8,%rdi)
addq %rdi, %r8
pshufd $0x55, %xmm0, %xmm1     # xmm1 = xmm0[1,1,1,1]
movd %xmm1, (%rdx,%r8)
pshufd $0xee, %xmm0, %xmm1     # xmm1 = xmm0[2,3,2,3]
movd %xmm1, (%rax,%r8)
pshufd $0xff, %xmm0, %xmm0     # xmm0 = xmm0[3,3,3,3]
movd %xmm0, (%rsi,%r8)
addq $0x4, %rdi
cmpq %rdi, %rcx
jne 0x34ed4a
cmpl $0x7fffffff, 0x8(%rsp)  # imm = 0x7FFFFFFF
jne 0x34ed99
orb $0x40, 0xc(%rbx)
movq %rbx, %rdi
callq 0x20a805
testl %eax, %eax
je 0x34edb5
xorl %esi, %esi
movl $0x7fffffff, %r10d      # imm = 0x7FFFFFFF
xorl %r8d, %r8d
jmp 0x34ee97
leal -0x1(%r14), %ecx
addl $-0x2, %r14d
movq 0x10(%rsp), %rsi
cmpl %r14d, %esi
movq %r12, %rdx
cmoveq %rbp, %rdx
movq %rbp, %rax
cmoveq %r12, %rax
cmpl %ecx, %esi
cmovneq %r15, %rbp
cmovneq %rdx, %r12
cmoveq %r15, %rax
cmpl $0x0, 0x50(%rsp)
je 0x34ee87
movq 0x20(%rsp), %r9
movl %r9d, %ecx
andl $0x1fffffff, %ecx       # imm = 0x1FFFFFFF
shll $0x2, %ecx
xorl %edx, %edx
movl 0x18(%rsp), %r8d
movl 0x8(%rsp), %r10d
cmpl %r10d, (%rax,%rdx,4)
jne 0x34ee26
movl %edx, %esi
shrl $0x2, %esi
movl %edx, %edi
andl $0x3, %edi
imull %r9d, %edi
addl %esi, %edi
cmpl %r8d, %edi
cmovll %edi, %r8d
incq %rdx
cmpl %edx, %ecx
jne 0x34ee09
movq %rbp, %r15
movq %rax, %rbp
movq 0x10(%rsp), %rsi
jmp 0x34ee97
callq 0x1b6b93
jmp 0x34ee70
callq 0x1b6b6d
jmp 0x34ee70
callq 0x1b6b47
jmp 0x34ee70
callq 0x1b6b21
jmp 0x34ee70
callq 0x1b6afb
jmp 0x34ee70
callq 0x1b6ad5
jmp 0x34ee70
callq 0x1b6aaf
jmp 0x34ee70
callq 0x1b6a89
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbp, %r15
movq %rax, %rbp
movl 0x18(%rsp), %r8d
movl 0x8(%rsp), %r10d
movl %r10d, (%rbx)
movl %r8d, 0x4(%rbx)
movl %esi, 0x8(%rbx)
movq %r13, %rdi
callq 0x2094b5
movq %rbp, %rdi
callq 0x2094b5
movq %r12, %rdi
callq 0x2094b5
movq %r15, %rdi
callq 0x2094b5
jmp 0x34ee72
nop