// File: /workspace/github_c_makefile_star2_O3/samtools[P]htslib/simd.c
// Function: nibble2base_ssse3
__attribute__((target("ssse3")))
static void nibble2base_ssse3(uint8_t *nib, char *seq, int len) {
    const char *seq_end_ptr = seq + len;
    char *seq_cursor = seq;
    uint8_t *nibble_cursor = nib;
    const char *seq_vec_end_ptr = seq_end_ptr - (2 * sizeof(__m128i) - 1);
    __m128i nuc_lookup_vec = _mm_lddqu_si128((__m128i *)seq_nt16_str);
    /* Nucleotides are encoded 4-bits per nucleotide and stored in 8-bit bytes
       as follows: |AB|CD|EF|GH|. The 4-bit codes (going from 0-15) can be used
       together with the pshufb instruction as a lookup table. The most efficient
       way is to use bitwise AND and shift to create two vectors. One with all
       the upper codes (|A|C|E|G|) and one with the lower codes (|B|D|F|H|).
       The lookup can then be performed and the resulting vectors can be
       interleaved again using the unpack instructions. */
    while (seq_cursor < seq_vec_end_ptr) {
        __m128i encoded = _mm_lddqu_si128((__m128i *)nibble_cursor);
        __m128i encoded_upper = _mm_srli_epi64(encoded, 4);
        encoded_upper = _mm_and_si128(encoded_upper, _mm_set1_epi8(15));
        __m128i encoded_lower = _mm_and_si128(encoded, _mm_set1_epi8(15));
        __m128i nucs_upper = _mm_shuffle_epi8(nuc_lookup_vec, encoded_upper);
        __m128i nucs_lower = _mm_shuffle_epi8(nuc_lookup_vec, encoded_lower);
        __m128i first_nucleotides = _mm_unpacklo_epi8(nucs_upper, nucs_lower);
        __m128i second_nucleotides = _mm_unpackhi_epi8(nucs_upper, nucs_lower);
        _mm_storeu_si128((__m128i *)seq_cursor, first_nucleotides);
        _mm_storeu_si128((__m128i *)(seq_cursor + sizeof(__m128i)),
                         second_nucleotides);
        nibble_cursor += sizeof(__m128i);
        seq_cursor += 2 * sizeof(__m128i);
    }
    nibble2base_default(nibble_cursor, seq_cursor, seq_end_ptr - seq_cursor);
}

// Assembly:
movslq %edx, %rax
leaq (%rsi,%rax), %rcx
leaq (%rsi,%rax), %rdx
addq $-0x1f, %rdx
leaq 0x60f99(%rip), %rax     # 0x95a60
lddqu (%rax), %xmm0
cmpq %rsi, %rdx
jbe 0x34b21
movdqa 0x64098(%rip), %xmm1    # 0x98b70
lddqu (%rdi), %xmm2
movapd %xmm2, %xmm3
psrlq $0x4, %xmm3
pand %xmm1, %xmm3
movapd %xmm0, %xmm4
pshufb %xmm3, %xmm4
andpd %xmm1, %xmm2
movapd %xmm0, %xmm3
pshufb %xmm2, %xmm3
movdqa %xmm4, %xmm2
punpcklbw %xmm3, %xmm2    # xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1],xmm2[2],xmm3[2],xmm2[3],xmm3[3],xmm2[4],xmm3[4],xmm2[5],xmm3[5],xmm2[6],xmm3[6],xmm2[7],xmm3[7]
punpckhbw %xmm3, %xmm4    # xmm4 = xmm4[8],xmm3[8],xmm4[9],xmm3[9],xmm4[10],xmm3[10],xmm4[11],xmm3[11],xmm4[12],xmm3[12],xmm4[13],xmm3[13],xmm4[14],xmm3[14],xmm4[15],xmm3[15]
movdqu %xmm2, (%rsi)
movdqu %xmm4, 0x10(%rsi)
addq $0x10, %rdi
addq $0x20, %rsi
cmpq %rdx, %rsi
jb 0x34ad8
subl %esi, %ecx
movb $0x0, (%rsi)
xorl %edx, %edx
cmpl $0x2, %ecx
jl 0x34b5a
movl %ecx, %edx
shrl $0x1f, %edx
addl %ecx, %edx
sarl %edx
movl %edx, %r8d
xorl %r9d, %r9d
leaq 0x6406d(%rip), %r10     # 0x98bb0
movzbl (%rdi,%r9), %r11d
movzwl (%r10,%r11,2), %r11d
movw %r11w, (%rsi,%r9,2)
incq %r9
cmpq %r9, %r8
jne 0x34b43
movl %edx, %r8d
leaq (%r8,%r8), %rdx
cmpl %ecx, %edx
jge 0x34b73
movzbl (%rdi,%r8), %ecx
shrl $0x4, %ecx
movb (%rax,%rcx), %al
movb %al, (%rsi,%rdx)
retq