// File: /workspace/github_cpp_makefile_star2_O1/Ciaxur[P]yagb-emu/include/imgui/imgui.cpp
// Function: ImGui::FindBestWindowPosForPopupEx(ImVec2 const&, ImVec2 const&, int*, ImRect const&, ImRect const&, ImGuiPopupPositionPolicy)
ImVec2 ImGui::FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy)
{
    ImVec2 base_pos_clamped = ImClamp(ref_pos, r_outer.Min, r_outer.Max - size);
    //GetForegroundDrawList()->AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255));
    //GetForegroundDrawList()->AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255));

    // Combo Box policy (we want a connecting edge)
    if (policy == ImGuiPopupPositionPolicy_ComboBox)
    {
        const ImGuiDir dir_prefered_order[ImGuiDir_COUNT] = { ImGuiDir_Down, ImGuiDir_Right, ImGuiDir_Left, ImGuiDir_Up };
        for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_COUNT; n++)
        {
            const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n];
            if (n != -1 && dir == *last_dir) // Already tried this direction?
                continue;
            ImVec2 pos;
            if (dir == ImGuiDir_Down)  pos = ImVec2(r_avoid.Min.x, r_avoid.Max.y);          // Below, Toward Right (default)
            if (dir == ImGuiDir_Right) pos = ImVec2(r_avoid.Min.x, r_avoid.Min.y - size.y); // Above, Toward Right
            if (dir == ImGuiDir_Left)  pos = ImVec2(r_avoid.Max.x - size.x, r_avoid.Max.y); // Below, Toward Left
            if (dir == ImGuiDir_Up)    pos = ImVec2(r_avoid.Max.x - size.x, r_avoid.Min.y - size.y); // Above, Toward Left
            if (!r_outer.Contains(ImRect(pos, pos + size)))
                continue;
            *last_dir = dir;
            return pos;
        }
    }

    // Tooltip and Default popup policy
    // (Always first try the direction we used on the last frame, if any)
    if (policy == ImGuiPopupPositionPolicy_Tooltip || policy == ImGuiPopupPositionPolicy_Default)
    {
        const ImGuiDir dir_prefered_order[ImGuiDir_COUNT] = { ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left };
        for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_COUNT; n++)
        {
            const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n];
            if (n != -1 && dir == *last_dir) // Already tried this direction?
                continue;

            const float avail_w = (dir == ImGuiDir_Left ? r_avoid.Min.x : r_outer.Max.x) - (dir == ImGuiDir_Right ? r_avoid.Max.x : r_outer.Min.x);
            const float avail_h = (dir == ImGuiDir_Up ? r_avoid.Min.y : r_outer.Max.y) - (dir == ImGuiDir_Down ? r_avoid.Max.y : r_outer.Min.y);

            // If there not enough room on one axis, there's no point in positioning on a side on this axis (e.g. when not enough width, use a top/bottom position to maximize available width)
            if (avail_w < size.x && (dir == ImGuiDir_Left || dir == ImGuiDir_Right))
                continue;
            if (avail_h < size.y && (dir == ImGuiDir_Up || dir == ImGuiDir_Down))
                continue;

            ImVec2 pos;
            pos.x = (dir == ImGuiDir_Left) ? r_avoid.Min.x - size.x : (dir == ImGuiDir_Right) ? r_avoid.Max.x : base_pos_clamped.x;
            pos.y = (dir == ImGuiDir_Up) ? r_avoid.Min.y - size.y : (dir == ImGuiDir_Down) ? r_avoid.Max.y : base_pos_clamped.y;

            // Clamp top-left corner of popup
            pos.x = ImMax(pos.x, r_outer.Min.x);
            pos.y = ImMax(pos.y, r_outer.Min.y);

            *last_dir = dir;
            return pos;
        }
    }

    // Fallback when not enough room:
    *last_dir = ImGuiDir_None;

    // For tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible.
    if (policy == ImGuiPopupPositionPolicy_Tooltip)
        return ref_pos + ImVec2(2, 2);

    // Otherwise try to keep within display
    ImVec2 pos = ref_pos;
    pos.x = ImMax(ImMin(pos.x + size.x, r_outer.Max.x) - size.x, r_outer.Min.x);
    pos.y = ImMax(ImMin(pos.y + size.y, r_outer.Max.y) - size.y, r_outer.Min.y);
    return pos;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
movss 0x8(%rcx), %xmm5
movss (%rsi), %xmm4
movss 0x4(%rsi), %xmm3
movss 0xc(%rcx), %xmm9
movss (%rdi), %xmm0
movaps %xmm0, -0x40(%rbp)
movss 0x4(%rdi), %xmm0
movaps %xmm0, -0x30(%rbp)
movss (%rcx), %xmm2
movss 0x4(%rcx), %xmm1
cmpl $0x1, %r9d
jne 0x58a98
movl (%rdx), %eax
xorl %r11d, %r11d
xorl %esi, %esi
cmpl $-0x1, %eax
setne %r11b
sete %sil
movss 0x8(%r8), %xmm8
subss %xmm4, %xmm8
movss 0x4(%r8), %xmm0
subss %xmm3, %xmm0
movaps %xmm8, %xmm10
unpcklps %xmm0, %xmm10           # xmm10 = xmm10[0],xmm0[0],xmm10[1],xmm0[1]
movss 0xc(%r8), %xmm6
unpcklps %xmm6, %xmm8            # xmm8 = xmm8[0],xmm6[0],xmm8[1],xmm6[1]
movss (%r8), %xmm11
movaps %xmm11, %xmm12
unpcklps %xmm0, %xmm12           # xmm12 = xmm12[0],xmm0[0],xmm12[1],xmm0[1]
unpcklps %xmm6, %xmm11           # xmm11 = xmm11[0],xmm6[0],xmm11[1],xmm6[1]
movss 0xc(%rcx), %xmm7
shll $0x2, %r11d
leaq 0x5ee1b(%rip), %r10     # 0xb7830
subq %r11, %r10
leaq 0x5ef39(%rip), %r11     # 0xb7958
movq %rdx, %rbx
testq %rsi, %rsi
cmovneq %r10, %rbx
movl (%rbx), %ebx
je 0x58a31
cmpl %eax, %ebx
je 0x58a8b
cmpl $0x3, %ebx
ja 0x58a5b
movl %ebx, %r14d
movslq (%r11,%r14,4), %r14
addq %r11, %r14
jmpq *%r14
movaps %xmm8, %xmm0
jmp 0x58a5e
movaps %xmm10, %xmm0
jmp 0x58a5e
movaps %xmm11, %xmm0
jmp 0x58a5e
movaps %xmm12, %xmm0
jmp 0x58a5e
xorps %xmm0, %xmm0
ucomiss %xmm2, %xmm0
jb 0x58a8b
movaps %xmm0, %xmm6
shufps $0x55, %xmm0, %xmm6     # xmm6 = xmm6[1,1],xmm0[1,1]
ucomiss %xmm1, %xmm6
jb 0x58a8b
movaps %xmm4, %xmm13
addss %xmm0, %xmm13
ucomiss %xmm13, %xmm5
jb 0x58a8b
addss %xmm3, %xmm6
ucomiss %xmm6, %xmm7
jae 0x58c44
incq %rsi
addq $0x4, %r10
cmpq $0x5, %rsi
jne 0x58a1f
testl $0xfffffffd, %r9d       # imm = 0xFFFFFFFD
jne 0x58bca
movaps %xmm5, %xmm0
subss %xmm4, %xmm0
subss %xmm3, %xmm9
movaps -0x30(%rbp), %xmm8
minss %xmm8, %xmm9
cmpltss %xmm1, %xmm8
movaps %xmm8, %xmm6
andnps %xmm9, %xmm6
andps %xmm1, %xmm8
orps %xmm6, %xmm8
movaps -0x40(%rbp), %xmm9
minss %xmm9, %xmm0
cmpltss %xmm2, %xmm9
movaps %xmm9, %xmm6
andnps %xmm0, %xmm6
andps %xmm2, %xmm9
orps %xmm6, %xmm9
movl (%rdx), %esi
xorl %eax, %eax
xorl %r10d, %r10d
cmpl $-0x1, %esi
setne %al
sete %r10b
movss (%r8), %xmm6
movss 0x4(%r8), %xmm10
movss 0x8(%rcx), %xmm11
movss 0x8(%r8), %xmm14
movss (%rcx), %xmm13
movss 0x4(%rcx), %xmm0
movss %xmm0, -0x14(%rbp)
movss 0xc(%rcx), %xmm15
movss 0xc(%r8), %xmm7
shll $0x2, %eax
leaq 0x64383(%rip), %r11     # 0xbcec0
subq %rax, %r11
movq %rdx, %rax
testq %r10, %r10
cmovneq %r11, %rax
movl (%rax), %eax
je 0x58b52
cmpl %esi, %eax
je 0x58bb9
movaps %xmm6, %xmm0
testl %eax, %eax
je 0x58b5d
movaps %xmm11, %xmm0
movaps %xmm14, %xmm12
cmpl $0x1, %eax
je 0x58b6a
movaps %xmm13, %xmm12
subss %xmm12, %xmm0
ucomiss %xmm0, %xmm4
seta %bl
cmpl $0x2, %eax
setb %r14b
testb %r14b, %bl
jne 0x58bb9
movaps %xmm10, %xmm0
cmpl $0x2, %eax
je 0x58b8e
movaps %xmm15, %xmm0
movaps %xmm7, %xmm12
cmpl $0x3, %eax
je 0x58b9d
movss -0x14(%rbp), %xmm12
subss %xmm12, %xmm0
ucomiss %xmm0, %xmm3
jbe 0x58c48
movl %eax, %ebx
andl $-0x2, %ebx
cmpl $0x2, %ebx
jne 0x58c48
incq %r10
addq $0x4, %r11
cmpq $0x5, %r10
jne 0x58b40
movl $0xffffffff, (%rdx)     # imm = 0xFFFFFFFF
cmpl $0x2, %r9d
jne 0x58bf9
movss 0x5ec8a(%rip), %xmm0    # 0xb7868
movaps -0x40(%rbp), %xmm1
addss %xmm0, %xmm1
movaps -0x30(%rbp), %xmm2
addss %xmm0, %xmm2
unpcklps %xmm2, %xmm1            # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movaps %xmm1, %xmm0
jmp 0x58cad
movsd (%rdi), %xmm6
movaps %xmm4, %xmm7
addss %xmm6, %xmm7
minss %xmm5, %xmm7
subss %xmm4, %xmm7
movaps %xmm2, %xmm0
cmpless %xmm7, %xmm0
andps %xmm0, %xmm7
andnps %xmm2, %xmm0
shufps $0x55, %xmm6, %xmm6     # xmm6 = xmm6[1,1,1,1]
addss %xmm3, %xmm6
minss 0xc(%rcx), %xmm6
orps %xmm7, %xmm0
subss %xmm3, %xmm6
movaps %xmm1, %xmm2
cmpless %xmm6, %xmm2
andps %xmm2, %xmm6
andnps %xmm1, %xmm2
orps %xmm6, %xmm2
unpcklps %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
jmp 0x58cad
movl %ebx, (%rdx)
jmp 0x58cad
testl %eax, %eax
je 0x58c59
cmpl $0x1, %eax
jne 0x58c63
movss 0x8(%r8), %xmm9
jmp 0x58c63
movss (%r8), %xmm9
subss %xmm4, %xmm9
cmpl $0x2, %eax
jne 0x58c75
movss 0x4(%r8), %xmm8
subss %xmm3, %xmm8
jmp 0x58c80
cmpl $0x3, %eax
jne 0x58c80
movss 0xc(%r8), %xmm8
movaps %xmm2, %xmm0
cmpless %xmm9, %xmm0
andps %xmm0, %xmm9
andnps %xmm2, %xmm0
orps %xmm9, %xmm0
movaps %xmm1, %xmm2
cmpless %xmm8, %xmm2
andps %xmm2, %xmm8
andnps %xmm1, %xmm2
orps %xmm8, %xmm2
unpcklps %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
movl %eax, (%rdx)
popq %rbx
popq %r14
popq %rbp
retq