// File: xocoder[P]m_kcptun/vendor/cm256/gf256.cpp
// Function: gf256_mul_mem_init()
static void gf256_mul_mem_init()
{
    // Reuse aligned self test buffers to load table data
    uint8_t* lo = m_SelfTestBuffers.A;
    uint8_t* hi = m_SelfTestBuffers.B;

    for (int y = 0; y < 256; ++y)
    {
        // TABLE_LO_Y maps 0..15 to 8-bit partial product based on y.
        for (unsigned char x = 0; x < 16; ++x)
        {
            lo[x] = gf256_mul(x, static_cast<uint8_t>( y ));
            hi[x] = gf256_mul(x << 4, static_cast<uint8_t>( y ));
        }

#if defined(GF256_TRY_NEON)
        if (CpuHasNeon)
        {
            GF256Ctx.MM128.TABLE_LO_Y[y] = vld1q_u8(lo);
            GF256Ctx.MM128.TABLE_HI_Y[y] = vld1q_u8(hi);
        }
#elif !defined(GF256_TARGET_MOBILE)
        const GF256_M128 table_lo = _mm_loadu_si128((GF256_M128*)lo);
        const GF256_M128 table_hi = _mm_loadu_si128((GF256_M128*)hi);
        _mm_storeu_si128(GF256Ctx.MM128.TABLE_LO_Y + y, table_lo);
        _mm_storeu_si128(GF256Ctx.MM128.TABLE_HI_Y + y, table_hi);
# ifdef GF256_TRY_AVX2
        if (CpuHasAVX2)
        {
            const GF256_M256 table_lo2 = _mm256_broadcastsi128_si256(table_lo);
            const GF256_M256 table_hi2 = _mm256_broadcastsi128_si256(table_hi);
            _mm256_storeu_si256(GF256Ctx.MM256.TABLE_LO_Y + y, table_lo2);
            _mm256_storeu_si256(GF256Ctx.MM256.TABLE_HI_Y + y, table_hi2);
        }
# endif // GF256_TRY_AVX2
#endif // GF256_TARGET_MOBILE
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x10, %rsp
leaq 0x2a8e1(%rip), %rax     # 0x3abb0
movq %rax, -0x58(%rbp)
leaq 0x2a8d6(%rip), %rax     # 0x3abb0
addq $0x40, %rax
movq %rax, -0x60(%rbp)
movl $0x0, -0x64(%rbp)
cmpl $0x100, -0x64(%rbp)     # imm = 0x100
jge 0x10420
movb $0x0, -0x65(%rbp)
movzbl -0x65(%rbp), %eax
cmpl $0x10, %eax
jge 0x10382
movb -0x65(%rbp), %cl
movl -0x64(%rbp), %eax
movb %cl, -0x1(%rbp)
movb %al, -0x2(%rbp)
movzbl -0x2(%rbp), %eax
shll $0x8, %eax
movzbl -0x1(%rbp), %ecx
addl %ecx, %eax
movl %eax, %eax
movl %eax, %ecx
leaq 0x8069(%rip), %rax      # 0x18390
movb 0x2000(%rax,%rcx), %dl
movq -0x58(%rbp), %rax
movzbl -0x65(%rbp), %ecx
movb %dl, (%rax,%rcx)
movzbl -0x65(%rbp), %eax
shll $0x4, %eax
movb %al, %cl
movl -0x64(%rbp), %eax
movb %cl, -0x3(%rbp)
movb %al, -0x4(%rbp)
movzbl -0x4(%rbp), %eax
shll $0x8, %eax
movzbl -0x3(%rbp), %ecx
addl %ecx, %eax
movl %eax, %eax
movl %eax, %ecx
leaq 0x802d(%rip), %rax      # 0x18390
movb 0x2000(%rax,%rcx), %dl
movq -0x60(%rbp), %rax
movzbl -0x65(%rbp), %ecx
movb %dl, (%rax,%rcx)
movb -0x65(%rbp), %al
addb $0x1, %al
movb %al, -0x65(%rbp)
jmp 0x102fa
movq -0x58(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movdqu (%rax), %xmm0
movdqa %xmm0, -0x80(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movdqu (%rax), %xmm0
movdqa %xmm0, -0x90(%rbp)
movslq -0x64(%rbp), %rcx
leaq 0x7fd6(%rip), %rax      # 0x18390
shlq $0x4, %rcx
addq %rcx, %rax
movdqa -0x80(%rbp), %xmm0
movq %rax, -0x10(%rbp)
movdqa %xmm0, -0x20(%rbp)
movdqa -0x20(%rbp), %xmm0
movq -0x10(%rbp), %rax
movdqu %xmm0, (%rax)
movslq -0x64(%rbp), %rcx
leaq 0x7fa9(%rip), %rax      # 0x18390
addq $0x1000, %rax           # imm = 0x1000
shlq $0x4, %rcx
addq %rcx, %rax
movdqa -0x90(%rbp), %xmm0
movq %rax, -0x28(%rbp)
movdqa %xmm0, -0x40(%rbp)
movdqa -0x40(%rbp), %xmm0
movq -0x28(%rbp), %rax
movdqu %xmm0, (%rax)
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x102e9
addq $0x10, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)