// File: xocoder[P]m_kcptun/vendor/cm256/gf256.cpp
// Function: gf256_muladd_mem
void gf256_muladd_mem(void * GF256_RESTRICT vz, uint8_t y,
                                 const void * GF256_RESTRICT vx, int bytes)
{
    // Use a single if-statement to handle special cases
    if (y <= 1)
    {
        if (y == 1)
            gf256_add_mem(vz, vx, bytes);
        return;
    }

    GF256_M128 * GF256_RESTRICT z16 = reinterpret_cast<GF256_M128 *>(vz);
    const GF256_M128 * GF256_RESTRICT x16 = reinterpret_cast<const GF256_M128 *>(vx);

#if defined(GF256_TARGET_MOBILE)
#if defined(GF256_TRY_NEON)
    if (bytes >= 16 && CpuHasNeon)
    {
        // Partial product tables; see above
        const GF256_M128 table_lo_y = vld1q_u8((uint8_t*)(GF256Ctx.MM128.TABLE_LO_Y + y));
        const GF256_M128 table_hi_y = vld1q_u8((uint8_t*)(GF256Ctx.MM128.TABLE_HI_Y + y));

        // clr_mask = 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f
        const GF256_M128 clr_mask = vdupq_n_u8(0x0f);

        // Handle multiples of 16 bytes
        do
        {
            // See above comments for details
            GF256_M128 x0 = vld1q_u8((uint8_t*)x16);
            GF256_M128 l0 = vandq_u8(x0, clr_mask);

            // x0 = vshrq_n_u8(x0, 4);
            x0 = (GF256_M128)vshrq_n_u64( (uint64x2_t)x0, 4);
            GF256_M128 h0 = vandq_u8(x0, clr_mask);
            l0 = vqtbl1q_u8(table_lo_y, l0);
            h0 = vqtbl1q_u8(table_hi_y, h0);
            const GF256_M128 p0 = veorq_u8(l0, h0);
            const GF256_M128 z0 = vld1q_u8((uint8_t*)z16);
            vst1q_u8((uint8_t*)z16, veorq_u8(p0, z0));
            bytes -= 16, ++x16, ++z16;
        } while (bytes >= 16);
    }
#endif
#else // GF256_TARGET_MOBILE
# if defined(GF256_TRY_AVX2)
    if (bytes >= 32 && CpuHasAVX2)
    {
        // Partial product tables; see above
        const GF256_M256 table_lo_y = _mm256_loadu_si256(GF256Ctx.MM256.TABLE_LO_Y + y);
        const GF256_M256 table_hi_y = _mm256_loadu_si256(GF256Ctx.MM256.TABLE_HI_Y + y);

        // clr_mask = 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f
        const GF256_M256 clr_mask = _mm256_set1_epi8(0x0f);

        GF256_M256 * GF256_RESTRICT z32 = reinterpret_cast<GF256_M256 *>(z16);
        const GF256_M256 * GF256_RESTRICT x32 = reinterpret_cast<const GF256_M256 *>(x16);

        // On my Reed Solomon codec, the encoder unit test runs in 640 usec without and 550 usec with the optimization (86% of the original time)
        const unsigned count = bytes / 64;
        for (unsigned i = 0; i < count; ++i)
        {
            // See above comments for details
            GF256_M256 x0 = _mm256_loadu_si256(x32 + i * 2);
            GF256_M256 l0 = _mm256_and_si256(x0, clr_mask);
            x0 = _mm256_srli_epi64(x0, 4);
            const GF256_M256 z0 = _mm256_loadu_si256(z32 + i * 2);
            GF256_M256 h0 = _mm256_and_si256(x0, clr_mask);
            l0 = _mm256_shuffle_epi8(table_lo_y, l0);
            h0 = _mm256_shuffle_epi8(table_hi_y, h0);
            const GF256_M256 p0 = _mm256_xor_si256(l0, h0);
            _mm256_storeu_si256(z32 + i * 2, _mm256_xor_si256(p0, z0));

            GF256_M256 x1 = _mm256_loadu_si256(x32 + i * 2 + 1);
            GF256_M256 l1 = _mm256_and_si256(x1, clr_mask);
            x1 = _mm256_srli_epi64(x1, 4);
            const GF256_M256 z1 = _mm256_loadu_si256(z32 + i * 2 + 1);
            GF256_M256 h1 = _mm256_and_si256(x1, clr_mask);
            l1 = _mm256_shuffle_epi8(table_lo_y, l1);
            h1 = _mm256_shuffle_epi8(table_hi_y, h1);
            const GF256_M256 p1 = _mm256_xor_si256(l1, h1);
            _mm256_storeu_si256(z32 + i * 2 + 1, _mm256_xor_si256(p1, z1));
        }
        bytes -= count * 64;
        z32 += count * 2;
        x32 += count * 2;

        if (bytes >= 32)
        {
            GF256_M256 x0 = _mm256_loadu_si256(x32);
            GF256_M256 l0 = _mm256_and_si256(x0, clr_mask);
            x0 = _mm256_srli_epi64(x0, 4);
            GF256_M256 h0 = _mm256_and_si256(x0, clr_mask);
            l0 = _mm256_shuffle_epi8(table_lo_y, l0);
            h0 = _mm256_shuffle_epi8(table_hi_y, h0);
            const GF256_M256 p0 = _mm256_xor_si256(l0, h0);
            const GF256_M256 z0 = _mm256_loadu_si256(z32);
            _mm256_storeu_si256(z32, _mm256_xor_si256(p0, z0));

            bytes -= 32;
            z32++;
            x32++;
        }

        z16 = reinterpret_cast<GF256_M128 *>(z32);
        x16 = reinterpret_cast<const GF256_M128 *>(x32);
    }
# endif // GF256_TRY_AVX2
    if (bytes >= 16 && CpuHasSSSE3)
    {
        // Partial product tables; see above
        const GF256_M128 table_lo_y = _mm_loadu_si128(GF256Ctx.MM128.TABLE_LO_Y + y);
        const GF256_M128 table_hi_y = _mm_loadu_si128(GF256Ctx.MM128.TABLE_HI_Y + y);

        // clr_mask = 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f
        const GF256_M128 clr_mask = _mm_set1_epi8(0x0f);

        // This unroll seems to provide about 7% speed boost when AVX2 is disabled
        while (bytes >= 32)
        {
            bytes -= 32;

            GF256_M128 x1 = _mm_loadu_si128(x16 + 1);
            GF256_M128 l1 = _mm_and_si128(x1, clr_mask);
            x1 = _mm_srli_epi64(x1, 4);
            GF256_M128 h1 = _mm_and_si128(x1, clr_mask);
            l1 = _mm_shuffle_epi8(table_lo_y, l1);
            h1 = _mm_shuffle_epi8(table_hi_y, h1);
            const GF256_M128 z1 = _mm_loadu_si128(z16 + 1);

            GF256_M128 x0 = _mm_loadu_si128(x16);
            GF256_M128 l0 = _mm_and_si128(x0, clr_mask);
            x0 = _mm_srli_epi64(x0, 4);
            GF256_M128 h0 = _mm_and_si128(x0, clr_mask);
            l0 = _mm_shuffle_epi8(table_lo_y, l0);
            h0 = _mm_shuffle_epi8(table_hi_y, h0);
            const GF256_M128 z0 = _mm_loadu_si128(z16);

            const GF256_M128 p1 = _mm_xor_si128(l1, h1);
            _mm_storeu_si128(z16 + 1, _mm_xor_si128(p1, z1));

            const GF256_M128 p0 = _mm_xor_si128(l0, h0);
            _mm_storeu_si128(z16, _mm_xor_si128(p0, z0));

            x16 += 2, z16 += 2;
        }

        // Handle multiples of 16 bytes
        while (bytes >= 16)
        {
            // See above comments for details
            GF256_M128 x0 = _mm_loadu_si128(x16);
            GF256_M128 l0 = _mm_and_si128(x0, clr_mask);
            x0 = _mm_srli_epi64(x0, 4);
            GF256_M128 h0 = _mm_and_si128(x0, clr_mask);
            l0 = _mm_shuffle_epi8(table_lo_y, l0);
            h0 = _mm_shuffle_epi8(table_hi_y, h0);
            const GF256_M128 p0 = _mm_xor_si128(l0, h0);
            const GF256_M128 z0 = _mm_loadu_si128(z16);
            _mm_storeu_si128(z16, _mm_xor_si128(p0, z0));

            bytes -= 16, ++x16, ++z16;
        }
    }
#endif // GF256_TARGET_MOBILE

    uint8_t * GF256_RESTRICT z1 = reinterpret_cast<uint8_t*>(z16);
    const uint8_t * GF256_RESTRICT x1 = reinterpret_cast<const uint8_t*>(x16);
    const uint8_t * GF256_RESTRICT table = GF256Ctx.GF256_MUL_TABLE + ((unsigned)y << 8);

    // Handle blocks of 8 bytes
    while (bytes >= 8)
    {
        uint64_t * GF256_RESTRICT z8 = reinterpret_cast<uint64_t *>(z1);
        uint64_t word = table[x1[0]];
        word |= (uint64_t)table[x1[1]] << 8;
        word |= (uint64_t)table[x1[2]] << 16;
        word |= (uint64_t)table[x1[3]] << 24;
        word |= (uint64_t)table[x1[4]] << 32;
        word |= (uint64_t)table[x1[5]] << 40;
        word |= (uint64_t)table[x1[6]] << 48;
        word |= (uint64_t)table[x1[7]] << 56;
        *z8 ^= word;

        bytes -= 8, x1 += 8, z1 += 8;
    }

    // Handle a block of 4 bytes
    const int four = bytes & 4;
    if (four)
    {
        uint32_t * GF256_RESTRICT z4 = reinterpret_cast<uint32_t *>(z1);
        uint32_t word = table[x1[0]];
        word |= (uint32_t)table[x1[1]] << 8;
        word |= (uint32_t)table[x1[2]] << 16;
        word |= (uint32_t)table[x1[3]] << 24;
        *z4 ^= word;
    }

    // Handle single bytes
    const int offset = four;
    switch (bytes & 3)
    {
    case 3: z1[offset + 2] ^= table[x1[offset + 2]];
    case 2: z1[offset + 1] ^= table[x1[offset + 1]];
    case 1: z1[offset] ^= table[x1[offset]];
    default:
        break;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x500, %rsp            # imm = 0x500
movb %sil, %al
movq %rdi, -0x368(%rbp)
movb %al, -0x369(%rbp)
movq %rdx, -0x378(%rbp)
movl %ecx, -0x37c(%rbp)
movzbl -0x369(%rbp), %eax
cmpl $0x1, %eax
jg 0x1203e
movzbl -0x369(%rbp), %eax
cmpl $0x1, %eax
jne 0x12039
movq -0x368(%rbp), %rdi
movq -0x378(%rbp), %rsi
movl -0x37c(%rbp), %edx
callq 0x109a0
jmp 0x12bae
movq -0x368(%rbp), %rax
movq %rax, -0x388(%rbp)
movq -0x378(%rbp), %rax
movq %rax, -0x390(%rbp)
cmpl $0x10, -0x37c(%rbp)
jl 0x12817
testb $0x1, 0x28b33(%rip)     # 0x3aba1
je 0x12817
movzbl -0x369(%rbp), %eax
shll $0x4, %eax
movl %eax, %edx
leaq 0x6309(%rip), %rcx      # 0x18390
movq %rcx, %rax
addq %rdx, %rax
movq %rax, -0x328(%rbp)
movq -0x328(%rbp), %rax
movups (%rax), %xmm0
movaps %xmm0, -0x3a0(%rbp)
movzbl -0x369(%rbp), %eax
shll $0x4, %eax
leaq 0x1000(%rax,%rcx), %rax
movq %rax, -0x330(%rbp)
movq -0x330(%rbp), %rax
movups (%rax), %xmm0
movaps %xmm0, -0x3b0(%rbp)
movb $0xf, -0x201(%rbp)
movb -0x201(%rbp), %al
movb %al, -0x4f1(%rbp)
movb %al, -0x1(%rbp)
movb %al, -0x2(%rbp)
movb %al, -0x3(%rbp)
movb %al, -0x4(%rbp)
movb %al, -0x5(%rbp)
movb %al, -0x6(%rbp)
movb %al, -0x7(%rbp)
movb %al, -0x8(%rbp)
movb %al, -0x9(%rbp)
movb %al, -0xa(%rbp)
movb %al, -0xb(%rbp)
movb %al, -0xc(%rbp)
movb %al, -0xd(%rbp)
movb %al, -0xe(%rbp)
movb %al, -0xf(%rbp)
movb %al, -0x10(%rbp)
movzbl -0x10(%rbp), %eax
movd %eax, %xmm0
movzbl -0xf(%rbp), %eax
pinsrb $0x1, %eax, %xmm0
movzbl -0xe(%rbp), %eax
pinsrb $0x2, %eax, %xmm0
movzbl -0xd(%rbp), %eax
pinsrb $0x3, %eax, %xmm0
movzbl -0xc(%rbp), %eax
pinsrb $0x4, %eax, %xmm0
movzbl -0xb(%rbp), %eax
pinsrb $0x5, %eax, %xmm0
movzbl -0xa(%rbp), %eax
pinsrb $0x6, %eax, %xmm0
movzbl -0x9(%rbp), %eax
pinsrb $0x7, %eax, %xmm0
movzbl -0x8(%rbp), %eax
pinsrb $0x8, %eax, %xmm0
movzbl -0x7(%rbp), %eax
pinsrb $0x9, %eax, %xmm0
movzbl -0x6(%rbp), %eax
pinsrb $0xa, %eax, %xmm0
movzbl -0x5(%rbp), %eax
pinsrb $0xb, %eax, %xmm0
movzbl -0x4(%rbp), %eax
pinsrb $0xc, %eax, %xmm0
movzbl -0x3(%rbp), %eax
pinsrb $0xd, %eax, %xmm0
movzbl -0x2(%rbp), %eax
pinsrb $0xe, %eax, %xmm0
movzbl -0x1(%rbp), %eax
pinsrb $0xf, %eax, %xmm0
movdqa %xmm0, -0x20(%rbp)
movdqa -0x20(%rbp), %xmm0
movdqa %xmm0, -0x3c0(%rbp)
cmpl $0x20, -0x37c(%rbp)
jl 0x125d9
movl -0x37c(%rbp), %eax
subl $0x20, %eax
movl %eax, -0x37c(%rbp)
movq -0x390(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x338(%rbp)
movq -0x338(%rbp), %rax
movdqu (%rax), %xmm0
movdqa %xmm0, -0x3d0(%rbp)
movdqa -0x3d0(%rbp), %xmm1
movdqa -0x3c0(%rbp), %xmm0
movdqa %xmm1, -0x150(%rbp)
movdqa %xmm0, -0x160(%rbp)
movdqa -0x150(%rbp), %xmm0
pand -0x160(%rbp), %xmm0
movdqa %xmm0, -0x3e0(%rbp)
movdqa -0x3d0(%rbp), %xmm0
movdqa %xmm0, -0xf0(%rbp)
movl $0x4, -0xf4(%rbp)
movdqa -0xf0(%rbp), %xmm0
movl -0xf4(%rbp), %eax
movd %eax, %xmm1
psrlq %xmm1, %xmm0
movdqa %xmm0, -0x3d0(%rbp)
movdqa -0x3d0(%rbp), %xmm1
movdqa -0x3c0(%rbp), %xmm0
movdqa %xmm1, -0x170(%rbp)
movdqa %xmm0, -0x180(%rbp)
movdqa -0x170(%rbp), %xmm0
pand -0x180(%rbp), %xmm0
movdqa %xmm0, -0x3f0(%rbp)
movdqa -0x3a0(%rbp), %xmm1
movdqa -0x3e0(%rbp), %xmm0
movdqa %xmm1, -0x30(%rbp)
movdqa %xmm0, -0x40(%rbp)
movdqa -0x30(%rbp), %xmm0
movdqa -0x40(%rbp), %xmm1
pshufb %xmm1, %xmm0
movdqa %xmm0, -0x3e0(%rbp)
movdqa -0x3b0(%rbp), %xmm1
movdqa -0x3f0(%rbp), %xmm0
movdqa %xmm1, -0x50(%rbp)
movdqa %xmm0, -0x60(%rbp)
movdqa -0x50(%rbp), %xmm0
movdqa -0x60(%rbp), %xmm1
pshufb %xmm1, %xmm0
movdqa %xmm0, -0x3f0(%rbp)
movq -0x388(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x340(%rbp)
movq -0x340(%rbp), %rax
movdqu (%rax), %xmm0
movdqa %xmm0, -0x400(%rbp)
movq -0x390(%rbp), %rax
movq %rax, -0x348(%rbp)
movq -0x348(%rbp), %rax
movdqu (%rax), %xmm0
movdqa %xmm0, -0x410(%rbp)
movdqa -0x410(%rbp), %xmm1
movdqa -0x3c0(%rbp), %xmm0
movdqa %xmm1, -0x190(%rbp)
movdqa %xmm0, -0x1a0(%rbp)
movdqa -0x190(%rbp), %xmm0
pand -0x1a0(%rbp), %xmm0
movdqa %xmm0, -0x420(%rbp)
movdqa -0x410(%rbp), %xmm0
movdqa %xmm0, -0x110(%rbp)
movl $0x4, -0x114(%rbp)
movdqa -0x110(%rbp), %xmm0
movl -0x114(%rbp), %eax
movd %eax, %xmm1
psrlq %xmm1, %xmm0
movdqa %xmm0, -0x410(%rbp)
movdqa -0x410(%rbp), %xmm1
movdqa -0x3c0(%rbp), %xmm0
movdqa %xmm1, -0x1b0(%rbp)
movdqa %xmm0, -0x1c0(%rbp)
movdqa -0x1b0(%rbp), %xmm0
pand -0x1c0(%rbp), %xmm0
movdqa %xmm0, -0x430(%rbp)
movdqa -0x3a0(%rbp), %xmm1
movdqa -0x420(%rbp), %xmm0
movdqa %xmm1, -0x70(%rbp)
movdqa %xmm0, -0x80(%rbp)
movdqa -0x70(%rbp), %xmm0
movdqa -0x80(%rbp), %xmm1
pshufb %xmm1, %xmm0
movdqa %xmm0, -0x420(%rbp)
movdqa -0x3b0(%rbp), %xmm1
movdqa -0x430(%rbp), %xmm0
movdqa %xmm1, -0x90(%rbp)
movdqa %xmm0, -0xa0(%rbp)
movdqa -0x90(%rbp), %xmm0
movdqa -0xa0(%rbp), %xmm1
pshufb %xmm1, %xmm0
movdqa %xmm0, -0x430(%rbp)
movq -0x388(%rbp), %rax
movq %rax, -0x350(%rbp)
movq -0x350(%rbp), %rax
movdqu (%rax), %xmm0
movdqa %xmm0, -0x440(%rbp)
movdqa -0x3e0(%rbp), %xmm1
movdqa -0x3f0(%rbp), %xmm0
movdqa %xmm1, -0x270(%rbp)
movdqa %xmm0, -0x280(%rbp)
movdqa -0x270(%rbp), %xmm0
pxor -0x280(%rbp), %xmm0
movdqa %xmm0, -0x450(%rbp)
movq -0x388(%rbp), %rax
addq $0x10, %rax
movdqa -0x450(%rbp), %xmm1
movdqa -0x400(%rbp), %xmm0
movdqa %xmm1, -0x290(%rbp)
movdqa %xmm0, -0x2a0(%rbp)
movdqa -0x290(%rbp), %xmm0
pxor -0x2a0(%rbp), %xmm0
movq %rax, -0x210(%rbp)
movdqa %xmm0, -0x220(%rbp)
movdqa -0x220(%rbp), %xmm0
movq -0x210(%rbp), %rax
movdqu %xmm0, (%rax)
movdqa -0x420(%rbp), %xmm1
movdqa -0x430(%rbp), %xmm0
movdqa %xmm1, -0x2b0(%rbp)
movdqa %xmm0, -0x2c0(%rbp)
movdqa -0x2b0(%rbp), %xmm0
pxor -0x2c0(%rbp), %xmm0
movdqa %xmm0, -0x460(%rbp)
movq -0x388(%rbp), %rax
movdqa -0x460(%rbp), %xmm1
movdqa -0x440(%rbp), %xmm0
movdqa %xmm1, -0x2d0(%rbp)
movdqa %xmm0, -0x2e0(%rbp)
movdqa -0x2d0(%rbp), %xmm0
pxor -0x2e0(%rbp), %xmm0
movq %rax, -0x228(%rbp)
movdqa %xmm0, -0x240(%rbp)
movdqa -0x240(%rbp), %xmm0
movq -0x228(%rbp), %rax
movdqu %xmm0, (%rax)
movq -0x390(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x390(%rbp)
movq -0x388(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x388(%rbp)
jmp 0x121c2
jmp 0x125db
cmpl $0x10, -0x37c(%rbp)
jl 0x12815
movq -0x390(%rbp), %rax
movq %rax, -0x358(%rbp)
movq -0x358(%rbp), %rax
movdqu (%rax), %xmm0
movdqa %xmm0, -0x470(%rbp)
movdqa -0x470(%rbp), %xmm1
movdqa -0x3c0(%rbp), %xmm0
movdqa %xmm1, -0x1d0(%rbp)
movdqa %xmm0, -0x1e0(%rbp)
movdqa -0x1d0(%rbp), %xmm0
pand -0x1e0(%rbp), %xmm0
movdqa %xmm0, -0x480(%rbp)
movdqa -0x470(%rbp), %xmm0
movdqa %xmm0, -0x130(%rbp)
movl $0x4, -0x134(%rbp)
movdqa -0x130(%rbp), %xmm0
movl -0x134(%rbp), %eax
movd %eax, %xmm1
psrlq %xmm1, %xmm0
movdqa %xmm0, -0x470(%rbp)
movdqa -0x470(%rbp), %xmm1
movdqa -0x3c0(%rbp), %xmm0
movdqa %xmm1, -0x1f0(%rbp)
movdqa %xmm0, -0x200(%rbp)
movdqa -0x1f0(%rbp), %xmm0
pand -0x200(%rbp), %xmm0
movdqa %xmm0, -0x490(%rbp)
movdqa -0x3a0(%rbp), %xmm1
movdqa -0x480(%rbp), %xmm0
movdqa %xmm1, -0xb0(%rbp)
movdqa %xmm0, -0xc0(%rbp)
movdqa -0xb0(%rbp), %xmm0
movdqa -0xc0(%rbp), %xmm1
pshufb %xmm1, %xmm0
movdqa %xmm0, -0x480(%rbp)
movdqa -0x3b0(%rbp), %xmm1
movdqa -0x490(%rbp), %xmm0
movdqa %xmm1, -0xd0(%rbp)
movdqa %xmm0, -0xe0(%rbp)
movdqa -0xd0(%rbp), %xmm0
movdqa -0xe0(%rbp), %xmm1
pshufb %xmm1, %xmm0
movdqa %xmm0, -0x490(%rbp)
movdqa -0x480(%rbp), %xmm1
movdqa -0x490(%rbp), %xmm0
movdqa %xmm1, -0x2f0(%rbp)
movdqa %xmm0, -0x300(%rbp)
movdqa -0x2f0(%rbp), %xmm0
pxor -0x300(%rbp), %xmm0
movdqa %xmm0, -0x4a0(%rbp)
movq -0x388(%rbp), %rax
movq %rax, -0x360(%rbp)
movq -0x360(%rbp), %rax
movdqu (%rax), %xmm0
movdqa %xmm0, -0x4b0(%rbp)
movq -0x388(%rbp), %rax
movdqa -0x4a0(%rbp), %xmm1
movdqa -0x4b0(%rbp), %xmm0
movdqa %xmm1, -0x310(%rbp)
movdqa %xmm0, -0x320(%rbp)
movdqa -0x310(%rbp), %xmm0
pxor -0x320(%rbp), %xmm0
movq %rax, -0x248(%rbp)
movdqa %xmm0, -0x260(%rbp)
movdqa -0x260(%rbp), %xmm0
movq -0x248(%rbp), %rax
movdqu %xmm0, (%rax)
movl -0x37c(%rbp), %eax
subl $0x10, %eax
movl %eax, -0x37c(%rbp)
movq -0x390(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x390(%rbp)
movq -0x388(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x388(%rbp)
jmp 0x125db
jmp 0x12817
movq -0x388(%rbp), %rax
movq %rax, -0x4b8(%rbp)
movq -0x390(%rbp), %rax
movq %rax, -0x4c0(%rbp)
movzbl -0x369(%rbp), %eax
shll $0x8, %eax
movl %eax, %eax
movl %eax, %ecx
leaq 0x5b48(%rip), %rax      # 0x18390
addq $0x2000, %rax           # imm = 0x2000
addq %rcx, %rax
movq %rax, -0x4c8(%rbp)
cmpl $0x8, -0x37c(%rbp)
jl 0x129f3
movq -0x4b8(%rbp), %rax
movq %rax, -0x4d0(%rbp)
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movzbl (%rcx), %ecx
movzbl (%rax,%rcx), %eax
movq %rax, -0x4d8(%rbp)
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movzbl 0x1(%rcx), %ecx
movzbl (%rax,%rcx), %eax
shlq $0x8, %rax
orq -0x4d8(%rbp), %rax
movq %rax, -0x4d8(%rbp)
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movzbl 0x2(%rcx), %ecx
movzbl (%rax,%rcx), %eax
shlq $0x10, %rax
orq -0x4d8(%rbp), %rax
movq %rax, -0x4d8(%rbp)
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movzbl 0x3(%rcx), %ecx
movzbl (%rax,%rcx), %eax
shlq $0x18, %rax
orq -0x4d8(%rbp), %rax
movq %rax, -0x4d8(%rbp)
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movzbl 0x4(%rcx), %ecx
movzbl (%rax,%rcx), %eax
shlq $0x20, %rax
orq -0x4d8(%rbp), %rax
movq %rax, -0x4d8(%rbp)
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movzbl 0x5(%rcx), %ecx
movzbl (%rax,%rcx), %eax
shlq $0x28, %rax
orq -0x4d8(%rbp), %rax
movq %rax, -0x4d8(%rbp)
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movzbl 0x6(%rcx), %ecx
movzbl (%rax,%rcx), %eax
shlq $0x30, %rax
orq -0x4d8(%rbp), %rax
movq %rax, -0x4d8(%rbp)
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movzbl 0x7(%rcx), %ecx
movzbl (%rax,%rcx), %eax
shlq $0x38, %rax
orq -0x4d8(%rbp), %rax
movq %rax, -0x4d8(%rbp)
movq -0x4d8(%rbp), %rcx
movq -0x4d0(%rbp), %rax
xorq (%rax), %rcx
movq %rcx, (%rax)
movl -0x37c(%rbp), %eax
subl $0x8, %eax
movl %eax, -0x37c(%rbp)
movq -0x4c0(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x4c0(%rbp)
movq -0x4b8(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x4b8(%rbp)
jmp 0x12858
movl -0x37c(%rbp), %eax
andl $0x4, %eax
movl %eax, -0x4dc(%rbp)
cmpl $0x0, -0x4dc(%rbp)
je 0x12ab8
movq -0x4b8(%rbp), %rax
movq %rax, -0x4e8(%rbp)
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movzbl (%rcx), %ecx
movzbl (%rax,%rcx), %eax
movl %eax, -0x4ec(%rbp)
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movzbl 0x1(%rcx), %ecx
movzbl (%rax,%rcx), %eax
shll $0x8, %eax
orl -0x4ec(%rbp), %eax
movl %eax, -0x4ec(%rbp)
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movzbl 0x2(%rcx), %ecx
movzbl (%rax,%rcx), %eax
shll $0x10, %eax
orl -0x4ec(%rbp), %eax
movl %eax, -0x4ec(%rbp)
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movzbl 0x3(%rcx), %ecx
movzbl (%rax,%rcx), %eax
shll $0x18, %eax
orl -0x4ec(%rbp), %eax
movl %eax, -0x4ec(%rbp)
movl -0x4ec(%rbp), %ecx
movq -0x4e8(%rbp), %rax
xorl (%rax), %ecx
movl %ecx, (%rax)
movl -0x4dc(%rbp), %eax
movl %eax, -0x4f0(%rbp)
movl -0x37c(%rbp), %eax
andl $0x3, %eax
movl %eax, -0x4f8(%rbp)
subl $0x1, %eax
je 0x12b78
jmp 0x12ade
movl -0x4f8(%rbp), %eax
subl $0x2, %eax
je 0x12b3a
jmp 0x12aeb
movl -0x4f8(%rbp), %eax
subl $0x3, %eax
jne 0x12bac
jmp 0x12afc
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movl -0x4f0(%rbp), %edx
addl $0x2, %edx
movslq %edx, %rdx
movzbl (%rcx,%rdx), %ecx
movzbl (%rax,%rcx), %esi
movq -0x4b8(%rbp), %rax
movl -0x4f0(%rbp), %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %edx
xorl %esi, %edx
movb %dl, (%rax,%rcx)
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movl -0x4f0(%rbp), %edx
addl $0x1, %edx
movslq %edx, %rdx
movzbl (%rcx,%rdx), %ecx
movzbl (%rax,%rcx), %esi
movq -0x4b8(%rbp), %rax
movl -0x4f0(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %edx
xorl %esi, %edx
movb %dl, (%rax,%rcx)
movq -0x4c8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movslq -0x4f0(%rbp), %rdx
movzbl (%rcx,%rdx), %ecx
movzbl (%rax,%rcx), %esi
movq -0x4b8(%rbp), %rax
movslq -0x4f0(%rbp), %rcx
movzbl (%rax,%rcx), %edx
xorl %esi, %edx
movb %dl, (%rax,%rcx)
jmp 0x12bae
addq $0x500, %rsp            # imm = 0x500
popq %rbp
retq
nopw (%rax,%rax)