// File: /workspace/github_cpp_makefile_star2_O1/Ciaxur[P]yagb-emu/include/imgui/imgui_tables.cpp
// Function: ImGui::TableMergeDrawChannels(ImGuiTable*)
void ImGui::TableMergeDrawChannels(ImGuiTable* table)
{
    ImGuiContext& g = *GImGui;
    ImDrawListSplitter* splitter = &table->DrawSplitter;
    const bool has_freeze_v = (table->FreezeRowsCount > 0);
    const bool has_freeze_h = (table->FreezeColumnsCount > 0);
    IM_ASSERT(splitter->_Current == 0);

    // Track which groups we are going to attempt to merge, and which channels goes into each group.
    struct MergeGroup
    {
        ImRect  ClipRect;
        int     ChannelsCount;
        ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> ChannelsMask;
    };
    int merge_group_mask = 0x00;
    MergeGroup merge_groups[4];
    memset(merge_groups, 0, sizeof(merge_groups));

    // 1. Scan channels and take note of those which can be merged
    for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
    {
        if ((table->VisibleMaskByIndex & ((ImU64)1 << column_n)) == 0)
            continue;
        ImGuiTableColumn* column = &table->Columns[column_n];

        const int merge_group_sub_count = has_freeze_v ? 2 : 1;
        for (int merge_group_sub_n = 0; merge_group_sub_n < merge_group_sub_count; merge_group_sub_n++)
        {
            const int channel_no = (merge_group_sub_n == 0) ? column->DrawChannelFrozen : column->DrawChannelUnfrozen;

            // Don't attempt to merge if there are multiple draw calls within the column
            ImDrawChannel* src_channel = &splitter->_Channels[channel_no];
            if (src_channel->_CmdBuffer.Size > 0 && src_channel->_CmdBuffer.back().ElemCount == 0)
                src_channel->_CmdBuffer.pop_back();
            if (src_channel->_CmdBuffer.Size != 1)
                continue;

            // Find out the width of this merge group and check if it will fit in our column
            // (note that we assume that rendering didn't stray on the left direction. we should need a CursorMinPos to detect it)
            if (!(column->Flags & ImGuiTableColumnFlags_NoClip))
            {
                float content_max_x;
                if (!has_freeze_v)
                    content_max_x = ImMax(column->ContentMaxXUnfrozen, column->ContentMaxXHeadersUsed); // No row freeze
                else if (merge_group_sub_n == 0)
                    content_max_x = ImMax(column->ContentMaxXFrozen, column->ContentMaxXHeadersUsed);   // Row freeze: use width before freeze
                else
                    content_max_x = column->ContentMaxXUnfrozen;                                        // Row freeze: use width after freeze
                if (content_max_x > column->ClipRect.Max.x)
                    continue;
            }

            const int merge_group_n = (has_freeze_h && column_n < table->FreezeColumnsCount ? 0 : 1) + (has_freeze_v && merge_group_sub_n == 0 ? 0 : 2);
            IM_ASSERT(channel_no < IMGUI_TABLE_MAX_DRAW_CHANNELS);
            MergeGroup* merge_group = &merge_groups[merge_group_n];
            if (merge_group->ChannelsCount == 0)
                merge_group->ClipRect = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX);
            merge_group->ChannelsMask.SetBit(channel_no);
            merge_group->ChannelsCount++;
            merge_group->ClipRect.Add(src_channel->_CmdBuffer[0].ClipRect);
            merge_group_mask |= (1 << merge_group_n);
        }

        // Invalidate current draw channel
        // (we don't clear DrawChannelFrozen/DrawChannelUnfrozen solely to facilitate debugging/later inspection of data)
        column->DrawChannelCurrent = (ImGuiTableDrawChannelIdx)-1;
    }

    // [DEBUG] Display merge groups
#if 0
    if (g.IO.KeyShift)
        for (int merge_group_n = 0; merge_group_n < IM_ARRAYSIZE(merge_groups); merge_group_n++)
        {
            MergeGroup* merge_group = &merge_groups[merge_group_n];
            if (merge_group->ChannelsCount == 0)
                continue;
            char buf[32];
            ImFormatString(buf, 32, "MG%d:%d", merge_group_n, merge_group->ChannelsCount);
            ImVec2 text_pos = merge_group->ClipRect.Min + ImVec2(4, 4);
            ImVec2 text_size = CalcTextSize(buf, NULL);
            GetForegroundDrawList()->AddRectFilled(text_pos, text_pos + text_size, IM_COL32(0, 0, 0, 255));
            GetForegroundDrawList()->AddText(text_pos, IM_COL32(255, 255, 0, 255), buf, NULL);
            GetForegroundDrawList()->AddRect(merge_group->ClipRect.Min, merge_group->ClipRect.Max, IM_COL32(255, 255, 0, 255));
        }
#endif

    // 2. Rewrite channel list in our preferred order
    if (merge_group_mask != 0)
    {
        // We skip channel 0 (Bg0/Bg1) and 1 (Bg2 frozen) from the shuffling since they won't move - see channels allocation in TableSetupDrawChannels().
        const int LEADING_DRAW_CHANNELS = 2;
        g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - LEADING_DRAW_CHANNELS); // Use shared temporary storage so the allocation gets amortized
        ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data;
        ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> remaining_mask;                       // We need 132-bit of storage
        remaining_mask.ClearAllBits();
        remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count);
        remaining_mask.ClearBit(table->Bg2DrawChannelUnfrozen);
        IM_ASSERT(has_freeze_v == false || table->Bg2DrawChannelUnfrozen != TABLE_DRAW_CHANNEL_BG2_FROZEN);
        int remaining_count = splitter->_Count - (has_freeze_v ? LEADING_DRAW_CHANNELS + 1 : LEADING_DRAW_CHANNELS);
        //ImRect host_rect = (table->InnerWindow == table->OuterWindow) ? table->InnerClipRect : table->HostClipRect;
        ImRect host_rect = table->HostClipRect;
        for (int merge_group_n = 0; merge_group_n < IM_ARRAYSIZE(merge_groups); merge_group_n++)
        {
            if (int merge_channels_count = merge_groups[merge_group_n].ChannelsCount)
            {
                MergeGroup* merge_group = &merge_groups[merge_group_n];
                ImRect merge_clip_rect = merge_group->ClipRect;

                // Extend outer-most clip limits to match those of host, so draw calls can be merged even if
                // outer-most columns have some outer padding offsetting them from their parent ClipRect.
                // The principal cases this is dealing with are:
                // - On a same-window table (not scrolling = single group), all fitting columns ClipRect -> will extend and match host ClipRect -> will merge
                // - Columns can use padding and have left-most ClipRect.Min.x and right-most ClipRect.Max.x != from host ClipRect -> will extend and match host ClipRect -> will merge
                // FIXME-TABLE FIXME-WORKRECT: We are wasting a merge opportunity on tables without scrolling if column doesn't fit
                // within host clip rect, solely because of the half-padding difference between window->WorkRect and window->InnerClipRect.
                if ((merge_group_n & 1) == 0 || !has_freeze_h)
                    merge_clip_rect.Min.x = ImMin(merge_clip_rect.Min.x, host_rect.Min.x);
                if ((merge_group_n & 2) == 0 || !has_freeze_v)
                    merge_clip_rect.Min.y = ImMin(merge_clip_rect.Min.y, host_rect.Min.y);
                if ((merge_group_n & 1) != 0)
                    merge_clip_rect.Max.x = ImMax(merge_clip_rect.Max.x, host_rect.Max.x);
                if ((merge_group_n & 2) != 0 && (table->Flags & ImGuiTableFlags_NoHostExtendY) == 0)
                    merge_clip_rect.Max.y = ImMax(merge_clip_rect.Max.y, host_rect.Max.y);
#if 0
                GetOverlayDrawList()->AddRect(merge_group->ClipRect.Min, merge_group->ClipRect.Max, IM_COL32(255, 0, 0, 200), 0.0f, ~0, 1.0f);
                GetOverlayDrawList()->AddLine(merge_group->ClipRect.Min, merge_clip_rect.Min, IM_COL32(255, 100, 0, 200));
                GetOverlayDrawList()->AddLine(merge_group->ClipRect.Max, merge_clip_rect.Max, IM_COL32(255, 100, 0, 200));
#endif
                remaining_count -= merge_group->ChannelsCount;
                for (int n = 0; n < IM_ARRAYSIZE(remaining_mask.Storage); n++)
                    remaining_mask.Storage[n] &= ~merge_group->ChannelsMask.Storage[n];
                for (int n = 0; n < splitter->_Count && merge_channels_count != 0; n++)
                {
                    // Copy + overwrite new clip rect
                    if (!merge_group->ChannelsMask.TestBit(n))
                        continue;
                    merge_group->ChannelsMask.ClearBit(n);
                    merge_channels_count--;

                    ImDrawChannel* channel = &splitter->_Channels[n];
                    IM_ASSERT(channel->_CmdBuffer.Size == 1 && merge_clip_rect.Contains(ImRect(channel->_CmdBuffer[0].ClipRect)));
                    channel->_CmdBuffer[0].ClipRect = merge_clip_rect.ToVec4();
                    memcpy(dst_tmp++, channel, sizeof(ImDrawChannel));
                }
            }

            // Make sure Bg2DrawChannelUnfrozen appears in the middle of our groups (whereas Bg0/Bg1 and Bg2 frozen are fixed to 0 and 1)
            if (merge_group_n == 1 && has_freeze_v)
                memcpy(dst_tmp++, &splitter->_Channels[table->Bg2DrawChannelUnfrozen], sizeof(ImDrawChannel));
        }

        // Append unmergeable channels that we didn't reorder at the end of the list
        for (int n = 0; n < splitter->_Count && remaining_count != 0; n++)
        {
            if (!remaining_mask.TestBit(n))
                continue;
            ImDrawChannel* channel = &splitter->_Channels[n];
            memcpy(dst_tmp++, channel, sizeof(ImDrawChannel));
            remaining_count--;
        }
        IM_ASSERT(dst_tmp == g.DrawChannelsTempMergeBuffer.Data + g.DrawChannelsTempMergeBuffer.Size);
        memcpy(splitter->_Channels.Data + LEADING_DRAW_CHANNELS, g.DrawChannelsTempMergeBuffer.Data, (splitter->_Count - LEADING_DRAW_CHANNELS) * sizeof(ImDrawChannel));
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x178, %rsp            # imm = 0x178
cmpl $0x0, 0x1e8(%rdi)
jne 0x8cbdd
leaq 0x71893(%rip), %rax     # 0xfdcd0
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movb 0x241(%rdi), %al
movb %al, -0x29(%rbp)
movq %rdi, %rbx
movb 0x243(%rdi), %al
movb %al, -0x2a(%rbp)
xorl %eax, %eax
xorps %xmm0, %xmm0
movups %xmm0, -0x1a0(%rbp,%rax)
addq $0x28, %rax
cmpq $0xa0, %rax
jne 0x8c45e
leaq -0x1a0(%rbp), %rdi
xorl %r14d, %r14d
movl $0xa0, %edx
xorl %esi, %esi
callq 0xc260
cmpl $0x0, 0x6c(%rbx)
movb -0x29(%rbp), %dil
jle 0x8cb38
movq %rbx, %r8
xorl %ecx, %ecx
movq %rbx, -0x40(%rbp)
movq 0x50(%r8), %rax
btq %rcx, %rax
jae 0x8c661
movq %rcx, -0x60(%rbp)
imulq $0x68, %rcx, %r15
addq 0x10(%r8), %r15
cmpq 0x18(%r8), %r15
jae 0x8cbbe
xorl %r13d, %r13d
cmpl $0x1, %r13d
movl $0x59, %eax
sbbq $0x0, %rax
movzbl (%r15,%rax), %esi
cmpl %esi, 0x1f0(%r8)
jle 0x8cb4a
movq 0x1f8(%r8), %rax
movl %esi, %ecx
shll $0x5, %ecx
leaq (%rax,%rcx), %r12
movslq (%rax,%rcx), %rax
testq %rax, %rax
jle 0x8c514
movq 0x8(%r12), %rcx
imulq $0x38, %rax, %rdx
cmpl $0x0, -0x18(%rcx,%rdx)
jne 0x8c514
decl %eax
movl %eax, (%r12)
cmpl $0x1, (%r12)
jne 0x8c644
testb $-0x80, (%r15)
jne 0x8c567
testb %dil, %dil
jle 0x8c537
testl %r13d, %r13d
je 0x8c53f
movss 0x44(%r15), %xmm0
jmp 0x8c55c
movss 0x44(%r15), %xmm1
jmp 0x8c545
movss 0x40(%r15), %xmm1
movss 0x48(%r15), %xmm2
movaps %xmm2, %xmm0
cmpless %xmm1, %xmm0
andps %xmm0, %xmm1
andnps %xmm2, %xmm0
orps %xmm1, %xmm0
ucomiss 0x28(%r15), %xmm0
ja 0x8c644
movq %r14, -0x38(%rbp)
cmpb $0x0, -0x2a(%rbp)
jle 0x8c586
movsbq 0x243(%r8), %rax
xorl %r14d, %r14d
cmpq %rax, -0x60(%rbp)
setge %r14b
jmp 0x8c58c
movl $0x1, %r14d
xorl %eax, %eax
testl %r13d, %r13d
setne %al
addl %eax, %eax
testb %dil, %dil
movl $0x2, %ecx
cmovlel %ecx, %eax
cmpb $-0x7c, %sil
jae 0x8cb80
orl %eax, %r14d
movl %r14d, %eax
leaq (%rax,%rax,4), %rax
leaq -0x1a0(,%rax,8), %rbx
addq %rbp, %rbx
cmpl $0x0, 0x10(%rbx)
jne 0x8c5d0
movaps 0x44893(%rip), %xmm0    # 0xd0e60
movups %xmm0, (%rbx)
leaq 0x14(%rbx), %rdi
callq 0x9179e
incl 0x10(%rbx)
cmpl $0x0, (%r12)
jle 0x8cb9f
movq 0x8(%r12), %rax
movss (%rax), %xmm3
movss 0x4(%rax), %xmm2
movss 0x8(%rax), %xmm1
movss 0xc(%rax), %xmm0
movss (%rbx), %xmm4
ucomiss %xmm3, %xmm4
jbe 0x8c60c
movss %xmm3, (%rbx)
movss 0x4(%rbx), %xmm3
ucomiss %xmm2, %xmm3
movb -0x29(%rbp), %dil
jbe 0x8c61f
movss %xmm2, 0x4(%rbx)
ucomiss 0x8(%rbx), %xmm1
jbe 0x8c62a
movss %xmm1, 0x8(%rbx)
ucomiss 0xc(%rbx), %xmm0
jbe 0x8c635
movss %xmm0, 0xc(%rbx)
movq -0x38(%rbp), %rax
btsl %r14d, %eax
movq %rax, %r14
movq -0x40(%rbp), %r8
subl $0x1, %r13d
setb %al
testb %dil, %dil
jle 0x8c658
testb %al, %al
jne 0x8c4c6
movb $-0x1, 0x57(%r15)
movq -0x60(%rbp), %rcx
incq %rcx
movslq 0x6c(%r8), %rax
cmpq %rax, %rcx
jl 0x8c49f
testl %r14d, %r14d
je 0x8cb38
movl 0x1ec(%r8), %r15d
addl $-0x2, %r15d
movq -0x48(%rbp), %r13
movl 0x20fc(%r13), %eax
cmpl %r15d, %eax
jge 0x8c719
testl %eax, %eax
je 0x8c6af
movl %eax, %r12d
shrl $0x1f, %r12d
addl %eax, %r12d
sarl %r12d
addl %eax, %r12d
jmp 0x8c6b5
movl $0x8, %r12d
cmpl %r15d, %r12d
cmovlel %r15d, %r12d
cmpl %r12d, %eax
movq -0x48(%rbp), %r13
jge 0x8c719
movslq %r12d, %rdi
shlq $0x5, %rdi
callq 0x424fb
movq %rax, %r14
movq 0x2100(%r13), %rsi
testq %rsi, %rsi
je 0x8c707
movslq 0x20f8(%r13), %rdx
shlq $0x5, %rdx
movq %r14, %rdi
callq 0xc080
movq -0x48(%rbp), %rax
movq 0x2100(%rax), %rdi
callq 0x425d4
movq -0x48(%rbp), %r13
movq %r14, 0x2100(%r13)
movl %r12d, 0x20fc(%r13)
movq -0x40(%rbp), %r8
movl %r15d, 0x20f8(%r13)
movq 0x2100(%r13), %r15
xorps %xmm0, %xmm0
leaq -0xd0(%rbp), %r14
movaps %xmm0, (%r14)
movl $0x0, 0x10(%r14)
movl 0x1ec(%r8), %edx
movq %r14, %rdi
movl $0x2, %esi
movq %r8, %rbx
callq 0x917dc
movzbl 0x247(%rbx), %esi
movq %r14, %rdi
callq 0x91832
movb -0x29(%rbp), %dl
testb %dl, %dl
jle 0x8c79b
movl $0xfffffffd, %r14d      # imm = 0xFFFFFFFD
cmpb $0x1, 0x247(%rbx)
movq %rbx, %r11
jne 0x8c7a4
leaq 0x453f9(%rip), %rdi     # 0xd1b7c
leaq 0x44730(%rip), %rsi     # 0xd0eba
leaq 0x453a0(%rip), %rcx     # 0xd1b31
movl $0x909, %edx            # imm = 0x909
callq 0xc140
movl $0xfffffffe, %r14d      # imm = 0xFFFFFFFE
movq %rbx, %r11
addl 0x1ec(%r11), %r14d
movss 0x15c(%r11), %xmm0
movss %xmm0, -0x68(%rbp)
movss 0x160(%r11), %xmm0
movss %xmm0, -0x64(%rbp)
movss 0x164(%r11), %xmm0
movaps %xmm0, -0xf0(%rbp)
movss 0x168(%r11), %xmm0
movaps %xmm0, -0xe0(%rbp)
leaq -0x18c(%rbp), %r9
xorl %r8d, %r8d
leaq (%r8,%r8,4), %rax
movl -0x190(%rbp,%rax,8), %ebx
testl %ebx, %ebx
je 0x8ca1e
leaq -0x1a0(,%rax,8), %rdi
addq %rbp, %rdi
movss (%rdi), %xmm0
movaps %xmm0, %xmm1
minss -0x68(%rbp), %xmm1
movaps %xmm1, -0xa0(%rbp)
cmpb $0x0, -0x2a(%rbp)
jle 0x8c82b
movaps %xmm0, %xmm1
movss 0x4(%rdi), %xmm0
movaps %xmm0, -0x60(%rbp)
minss -0x64(%rbp), %xmm0
testb %dl, %dl
jg 0x8c841
movaps %xmm0, -0x60(%rbp)
testb $0x1, %r8b
je 0x8c84e
movaps %xmm1, -0xa0(%rbp)
movss 0x8(%rdi), %xmm1
je 0x8c873
movaps -0xf0(%rbp), %xmm3
movaps %xmm1, %xmm4
movaps %xmm3, %xmm1
cmpless %xmm4, %xmm1
movaps %xmm1, %xmm2
andps %xmm4, %xmm2
andnps %xmm3, %xmm1
orps %xmm2, %xmm1
cmpq $0x2, %r8
jae 0x8c87d
movaps %xmm0, -0x60(%rbp)
movss 0xc(%rdi), %xmm0
movaps %xmm0, -0x90(%rbp)
movaps %xmm1, -0xb0(%rbp)
jb 0x8c8c6
testb $0x2, 0x6(%r11)
jne 0x8c8c6
movaps -0xe0(%rbp), %xmm1
movaps %xmm1, %xmm0
movaps -0x90(%rbp), %xmm2
cmpless %xmm2, %xmm0
andps %xmm0, %xmm2
andnps %xmm1, %xmm0
movaps -0xb0(%rbp), %xmm1
orps %xmm0, %xmm2
movaps %xmm2, -0x90(%rbp)
xorl %eax, %eax
movl (%r9,%rax,4), %ecx
notl %ecx
andl %ecx, -0xd0(%rbp,%rax,4)
incq %rax
cmpq $0x5, %rax
jne 0x8c8c8
subl %ebx, %r14d
cmpl $0x0, 0x1ec(%r11)
jle 0x8ca1e
movq %r8, -0x70(%rbp)
movq %r9, -0x78(%rbp)
movl %r14d, -0x4c(%rbp)
movq %r15, -0x38(%rbp)
addq $0x14, %rdi
movaps %xmm1, %xmm0
unpcklps -0x90(%rbp), %xmm0      # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
movaps -0xa0(%rbp), %xmm1
unpcklps -0x60(%rbp), %xmm1      # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
movlhps %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
movaps %xmm1, -0x100(%rbp)
xorl %r12d, %r12d
xorl %r15d, %r15d
movl %r15d, %esi
movq %rdi, %r14
callq 0x91870
testb %al, %al
je 0x8c9e9
movq %r14, %r13
movq %r14, %rdi
movl %r15d, %esi
callq 0x91832
movq -0x40(%rbp), %r11
movslq 0x1f0(%r11), %rax
cmpq %rax, %r15
jge 0x8cb4a
movq 0x1f8(%r11), %rax
cmpl $0x1, (%rax,%r12)
movb -0x29(%rbp), %dl
movaps -0xb0(%rbp), %xmm1
jne 0x8cb61
movq 0x8(%rax,%r12), %rcx
movss (%rcx), %xmm0
ucomiss -0xa0(%rbp), %xmm0
jb 0x8cb61
movss 0x4(%rcx), %xmm0
ucomiss -0x60(%rbp), %xmm0
jb 0x8cb61
ucomiss 0x8(%rcx), %xmm1
jb 0x8cb61
movaps -0x90(%rbp), %xmm0
ucomiss 0xc(%rcx), %xmm0
jb 0x8cb61
decl %ebx
addq %r12, %rax
movaps -0x100(%rbp), %xmm0
movups %xmm0, (%rcx)
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movq -0x38(%rbp), %r14
movups %xmm1, 0x10(%r14)
movups %xmm0, (%r14)
leaq 0x20(%r14), %rax
movq %rax, -0x38(%rbp)
movq %r13, %rdi
jmp 0x8c9f3
movb -0x29(%rbp), %dl
movq %r14, %rdi
movq -0x40(%rbp), %r11
incq %r15
movslq 0x1ec(%r11), %rax
cmpq %rax, %r15
jge 0x8ca0e
addq $0x20, %r12
testl %ebx, %ebx
jne 0x8c928
movq -0x38(%rbp), %r15
movl -0x4c(%rbp), %r14d
movq -0x78(%rbp), %r9
movq -0x70(%rbp), %r8
testb %dl, %dl
setg %al
cmpq $0x1, %r8
sete %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x8ca66
movzbl 0x247(%r11), %eax
cmpl %eax, 0x1f0(%r11)
jle 0x8cb4a
movq 0x1f8(%r11), %rcx
shll $0x5, %eax
movups (%rcx,%rax), %xmm0
movups 0x10(%rcx,%rax), %xmm1
movups %xmm1, 0x10(%r15)
movups %xmm0, (%r15)
addq $0x20, %r15
incq %r8
addq $0x28, %r9
cmpq $0x4, %r8
jne 0x8c7f1
movq %r15, %r13
movl 0x1ec(%r11), %eax
testl %eax, %eax
jle 0x8cafb
testl %r14d, %r14d
je 0x8cafb
xorl %r12d, %r12d
leaq -0xd0(%rbp), %rbx
xorl %r15d, %r15d
movq %rbx, %rdi
movl %r15d, %esi
callq 0x91870
testb %al, %al
je 0x8cadf
movq -0x40(%rbp), %r11
movslq 0x1f0(%r11), %rax
cmpq %rax, %r15
jge 0x8cb4a
movq 0x1f8(%r11), %rax
movups (%rax,%r12), %xmm0
movups 0x10(%rax,%r12), %xmm1
movups %xmm1, 0x10(%r13)
movups %xmm0, (%r13)
addq $0x20, %r13
decl %r14d
jmp 0x8cae3
movq -0x40(%rbp), %r11
incq %r15
movslq 0x1ec(%r11), %rax
cmpq %rax, %r15
jge 0x8cafb
addq $0x20, %r12
testl %r14d, %r14d
jne 0x8ca97
movq -0x48(%rbp), %rcx
movq 0x2100(%rcx), %rsi
movslq 0x20f8(%rcx), %rcx
shlq $0x5, %rcx
addq %rsi, %rcx
cmpq %rcx, %r13
jne 0x8cbfc
movq 0x1f8(%r11), %rdi
addq $0x40, %rdi
movslq %eax, %rdx
shlq $0x5, %rdx
addq $-0x40, %rdx
callq 0xc080
addq $0x178, %rsp            # imm = 0x178
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2eb27(%rip), %rdi     # 0xbb678
leaq 0x2eb33(%rip), %rsi     # 0xbb68b
leaq 0x44020(%rip), %rcx     # 0xd0b7f
jmp 0x8cbb4
leaq 0x4506c(%rip), %rdi     # 0xd1bd4
leaq 0x4434b(%rip), %rsi     # 0xd0eba
leaq 0x44fbb(%rip), %rcx     # 0xd1b31
movl $0x934, %edx            # imm = 0x934
callq 0xc140
leaq 0x44fdb(%rip), %rdi     # 0xd1b62
leaq 0x4432c(%rip), %rsi     # 0xd0eba
leaq 0x44f9c(%rip), %rcx     # 0xd1b31
movl $0x8dd, %edx            # imm = 0x8DD
callq 0xc140
leaq 0x2ead2(%rip), %rdi     # 0xbb678
leaq 0x2eade(%rip), %rsi     # 0xbb68b
leaq 0x4400b(%rip), %rcx     # 0xd0bbf
movl $0x65c, %edx            # imm = 0x65C
callq 0xc140
leaq 0x2faf3(%rip), %rdi     # 0xbc6b8
leaq 0x2ea73(%rip), %rsi     # 0xbb63f
leaq 0x2fafe(%rip), %rcx     # 0xbc6d1
movl $0x20e, %edx            # imm = 0x20E
callq 0xc140
leaq 0x44f35(%rip), %rdi     # 0xd1b19
leaq 0x442cf(%rip), %rsi     # 0xd0eba
leaq 0x44f3f(%rip), %rcx     # 0xd1b31
movl $0x8ad, %edx            # imm = 0x8AD
callq 0xc140
leaq 0x45034(%rip), %rdi     # 0xd1c37
leaq 0x442b0(%rip), %rsi     # 0xd0eba
leaq 0x44f20(%rip), %rcx     # 0xd1b31
movl $0x948, %edx            # imm = 0x948
callq 0xc140