// File: /workspace/github_cpp_makefile_star2_O3/cpirc[P]Monochrome/src/search.cpp
// Function: int search<false>(SearchController&, Position&, int, int, int, SearchStack*, std::vector<unsigned int, std::allocator<unsigned int>>&)
int search(SearchController& sc, Position& pos, int depth, int alpha, int beta,
           SearchStack* ss, PV& pv) {
    assert(ss);

    if (is_fifty_moves(pos) || is_threefold(pos, ss->ply)) {
        return 0;
    }

    const bool in_check = is_checked(pos, US);

    // Check extensions
    if (in_check) depth++;

    if (depth <= 0) {
        return quiesce(sc, pos, alpha, beta, ss);
    }

    if (ss->ply >= MAX_PLY) {
        return evaluate(pos);
    }

    // Check time left
    clock_t current_time = clock() * 1000 / CLOCKS_PER_SEC;
    if (ss->ply && current_time >= sc.search_end_time) {
        return 0;
    }

    // Update info
    if (ss->stats->node_count % 1048576 == 0) {
        if (current_time > sc.search_start_time) {
            printf("info nps %" PRIu64 "\n",
                   1000 * (ss->stats->node_count) /
                       (current_time - sc.search_start_time));
        }
    }

    ++ss->stats->node_count;

    // Check transposition table
    Move hash_move = 0;
    TTEntry entry = tt_poll(&sc.tt, pos.hash_key);

    if (entry.hash_key == pos.hash_key) {
        int entry_depth = tt_depth(entry.data);
        hash_move = tt_move(entry.data);

        if (!pv_node && entry_depth >= depth) {
            int entry_eval = eval_from_tt(tt_eval(entry.data), ss->ply);
            int entry_flag = tt_flag(entry.data);

            if (entry_flag == TT_EXACT ||
                (entry_flag == TT_LOWER && entry_eval >= beta) ||
                (entry_flag == TT_UPPER && entry_eval <= alpha)) {
                pv.push_back(hash_move);
                return entry_eval;
            }
        }
    }

    int movecount, value;
    movecount = generate(pos, ss->ml);

    score_moves(pos, ss, movecount, hash_move);

    int legal_moves = 0;
    int best_value = -INF;
    int old_alpha = alpha;

    Move move;
    Move best_move = 0;
    PV child_pv;
    while ((move = next_move(ss, movecount))) {
        child_pv.clear();
        Position npos = pos;

        make_move(npos, move);
        if (is_checked(npos, THEM)) {
            continue;
        }

        ++legal_moves;

        if (legal_moves == 1)
            value =
                -search(sc, npos, depth - 1, -beta, -alpha, ss + 1, child_pv);
        else
            value = -search<false>(sc, npos, depth - 1, -beta, -alpha, ss + 1,
                                   child_pv);

        if (value > best_value) {
            best_value = value;
            best_move = move;

            // Update PV
            pv.clear();
            pv.push_back(move);
            pv.insert(pv.begin() + 1, child_pv.begin(), child_pv.end());

            if (value > alpha) {
                alpha = value;
            }
        }
        if (value >= beta) {
#ifdef TESTING
            ++ss->stats->fail_highs;
            if (legal_moves == 1) ++ss->stats->first_move_fail_highs;
#endif
            if (!promotion_type(move) && move_type(move) != CAPTURE &&
                move_type(move) != ENPASSANT && ss->killers[0] != move) {
                ss->killers[1] = ss->killers[0];
                ss->killers[0] = move;
            }
            tt_add(&sc.tt, pos.hash_key, move, depth, TT_LOWER,
                   eval_to_tt(value, ss->ply));
            return beta;
        }
    }

    if (!legal_moves) {
        if (in_check)
            return -INF + ss->ply;
        else
            return 0;
    }

    // Add entry to transposition table
    int flag = alpha == old_alpha ? TT_UPPER : TT_EXACT;
    tt_add(&sc.tt, pos.hash_key, best_move, depth, flag,
           eval_to_tt(best_value, ss->ply));

#ifdef TESTING
    if (!ss->ply) {
        printf(
            "info string ordering = %lf\n",
            double(ss->stats->first_move_fail_highs) / ss->stats->fail_highs);
    }
#endif

    return alpha;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x108, %rsp            # imm = 0x108
movl %r8d, -0x30(%rbp)
testq %r9, %r9
je 0x8fae
movq %r9, %rbx
movl %ecx, %r12d
movl %edx, %r15d
movq %rsi, %r14
movq %rdi, %r13
movq 0x10(%rbp), %rax
movq %rax, -0x68(%rbp)
movq %rsi, %rdi
callq 0x73e8
movl $0x0, -0x2c(%rbp)
testb %al, %al
jne 0x891c
movzbl (%rbx), %esi
movq %r14, %rdi
callq 0x7398
testb %al, %al
je 0x8931
movl -0x2c(%rbp), %eax
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x28(%r14), %r9
movq 0x30(%r14), %rax
movq %rax, %rcx
andq %r9, %rcx
je 0x8fcd
bsfq %rcx, %rdx
movq 0x38(%r14), %r10
orq %r10, %rax
leal (,%rdx,8), %ecx
leaq 0x8862(%rip), %r8       # 0x111c0
movq (%r14), %rdi
movq 0x8(%r14), %rsi
andq (%r8,%rcx), %rdi
leaq 0x8c50(%rip), %r8       # 0x115c0
andq (%r8,%rcx), %rsi
leaq 0x3b25(%rip), %r8       # 0xc4a0
movq (%r8,%rcx), %r8
andq %rax, %r8
leaq 0x3917(%rip), %r11      # 0xc2a0
imulq (%r11,%rcx), %r8
orq %rdi, %rsi
shrq $0x37, %r8
movl %edx, %edi
shll $0xc, %edi
addq 0x860f(%rip), %rdi      # 0x10fb0
movq (%rdi,%r8,8), %rdi
movq 0x10(%r14), %r8
andq %rdi, %r8
leaq 0x35ed(%rip), %r11      # 0xbfa0
andq (%r11,%rcx), %rax
orq %rsi, %r8
leaq 0x33df(%rip), %rsi      # 0xbda0
imulq (%rsi,%rcx), %rax
shrq $0x34, %rax
shll $0xf, %edx
addq 0x85c4(%rip), %rdx      # 0x10f98
movq (%rdx,%rax,8), %rax
movq 0x18(%r14), %rdx
andq %rax, %rdx
orq %r8, %rdx
orq %rdi, %rax
leaq 0x8dd4(%rip), %rsi      # 0x117c0
andq (%rsi,%rcx), %r9
orq %rdx, %r9
andq 0x20(%r14), %rax
orq %rax, %r9
xorl %eax, %eax
testq %r10, %r9
setne %al
addl %r15d, %eax
jle 0x8a25
cmpb $0x40, (%rbx)
jb 0x8a4a
movq %r14, %rdi
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x395b
movq %r13, %rdi
movq %r14, %rsi
movl %r12d, %edx
movl -0x30(%rbp), %ecx
movq %rbx, %r8
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x796d
movq %rax, -0x60(%rbp)
movq %r10, -0xa8(%rbp)
movq %r9, -0xb0(%rbp)
callq 0x3110
movabsq $0x20c49ba5e353f7cf, %rcx # imm = 0x20C49BA5E353F7CF
imulq %rcx
movq %rdx, %rcx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x7, %rcx
addq %rax, %rcx
cmpb $0x0, (%rbx)
je 0x8a91
cmpq 0x80(%r13), %rcx
jge 0x891c
movq 0x810(%rbx), %rax
movq (%rax), %rdx
testl $0xfffff, %edx          # imm = 0xFFFFF
jne 0x8ad0
subq 0x78(%r13), %rcx
jle 0x8ad0
imulq $0x3e8, %rdx, %rax      # imm = 0x3E8
xorl %edx, %edx
divq %rcx
leaq 0x462f(%rip), %rdi      # 0xd0eb
movq %rax, %rsi
xorl %eax, %eax
callq 0x3040
movq 0x810(%rbx), %rax
movq (%rax), %rdx
incq %rdx
movq %rdx, (%rax)
leaq 0x98(%r13), %rdi
movq 0x48(%r14), %rsi
movq %rdi, -0x98(%rbp)
callq 0x94d9
cmpq 0x48(%r14), %rdx
jne 0x8b25
movq %rax, %r15
andl $0x7f, %eax
cmpl $0x40, %eax
jae 0x8fec
movq %r15, %rcx
shrq $0x29, %rcx
andl $0x3ffff, %ecx          # imm = 0x3FFFF
movq %rcx, -0x40(%rbp)
movl %ecx, -0x70(%rbp)
cmpl -0x60(%rbp), %eax
jae 0x8f11
movq -0x40(%rbp), %r15
jmp 0x8b28
xorl %r15d, %r15d
leaq 0x4(%rbx), %rsi
movq %r14, %rdi
callq 0x5d4e
leaq -0x58(%rbp), %rcx
movl %eax, (%rcx)
movq %r14, %rdi
movq %rbx, %rsi
movl %eax, %edx
movl %r15d, %ecx
callq 0x77a8
xorps %xmm0, %xmm0
movaps %xmm0, -0x90(%rbp)
movq $0x0, -0x80(%rbp)
movq %rbx, %rdi
leaq -0x58(%rbp), %rsi
callq 0x78de
movl %eax, -0x34(%rbp)
testl %eax, %eax
je 0x8ef7
leaq 0x50(%r14), %rax
movq %rax, -0xb8(%rbp)
movq -0x60(%rbp), %rax
decl %eax
movl %eax, -0x54(%rbp)
movl -0x30(%rbp), %eax
negl %eax
movl %eax, -0x50(%rbp)
movq %rbx, -0x40(%rbp)
leaq 0x818(%rbx), %rax
movq %rax, -0xa0(%rbp)
movl $0xffff8ad0, -0x44(%rbp) # imm = 0xFFFF8AD0
movl $0x0, -0x4c(%rbp)
movl %r12d, -0x2c(%rbp)
movl $0x0, -0x48(%rbp)
movl %r12d, -0x6c(%rbp)
movq -0x90(%rbp), %rax
cmpq %rax, -0x88(%rbp)
je 0x8bd5
movq %rax, -0x88(%rbp)
movq %r13, %rbx
movl $0xa, %ecx
leaq -0x120(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0xd0(%rbp), %rdi
movq -0xb8(%rbp), %rsi
callq 0x5300
movl -0x34(%rbp), %esi
movq %r15, %rdi
callq 0x47a0
movq -0xf8(%rbp), %rax
movq -0xe8(%rbp), %rdx
movq %rdx, %rcx
andq %rax, %rcx
je 0x8fcd
bsfq %rcx, %rdi
movq -0xf0(%rbp), %rcx
orq %rcx, %rdx
leal (,%rdi,8), %esi
movq -0x120(%rbp), %r8
leaq 0x8578(%rip), %r9       # 0x111c0
andq 0x200(%r9,%rsi), %r8
movq -0x118(%rbp), %r9
leaq 0x8962(%rip), %r10      # 0x115c0
andq (%r10,%rsi), %r9
orq %r8, %r9
leaq 0x3834(%rip), %r8       # 0xc4a0
movq (%r8,%rsi), %r8
andq %rdx, %r8
leaq 0x3626(%rip), %r10      # 0xc2a0
imulq (%r10,%rsi), %r8
shrq $0x37, %r8
movl %edi, %r10d
shll $0xc, %r10d
addq 0x831f(%rip), %r10      # 0x10fb0
movq (%r10,%r8,8), %r8
movq -0x110(%rbp), %r10
andq %r8, %r10
orq %r9, %r10
leaq 0x32f7(%rip), %r9       # 0xbfa0
andq (%r9,%rsi), %rdx
leaq 0x30ec(%rip), %r9       # 0xbda0
imulq (%r9,%rsi), %rdx
shrq $0x34, %rdx
shll $0xf, %edi
addq 0x82d1(%rip), %rdi      # 0x10f98
movq (%rdi,%rdx,8), %rdx
movq -0x108(%rbp), %rdi
andq %rdx, %rdi
orq %r10, %rdi
orq %r8, %rdx
leaq 0x8ade(%rip), %r8       # 0x117c0
andq (%r8,%rsi), %rax
andq -0x100(%rbp), %rdx
orq %rdi, %rax
orq %rdx, %rax
movl $0x2, %r12d
testq %rcx, %rax
jne 0x8e4f
movl -0x2c(%rbp), %r8d
negl %r8d
cmpl $0x0, -0x48(%rbp)
je 0x8d38
leaq -0x90(%rbp), %rax
movq %rax, (%rsp)
movq %rbx, %rdi
leaq -0x120(%rbp), %rsi
movl -0x54(%rbp), %edx
movl -0x50(%rbp), %ecx
movq -0xa0(%rbp), %r9
callq 0x88c2
jmp 0x8d5f
leaq -0x90(%rbp), %rax
movq %rax, (%rsp)
movq %rbx, %rdi
leaq -0x120(%rbp), %rsi
movl -0x54(%rbp), %edx
movl -0x50(%rbp), %ecx
movq -0xa0(%rbp), %r9
callq 0x80dd
movl %eax, %r13d
movl %eax, %r15d
negl %r15d
cmpl %r15d, -0x44(%rbp)
movq -0x68(%rbp), %rdi
jge 0x8dd5
movq (%rdi), %rax
movq 0x8(%rdi), %rsi
cmpq %rax, %rsi
je 0x8d85
movq %rax, 0x8(%rdi)
movq %rax, %rsi
movl -0x34(%rbp), %eax
cmpq 0x10(%rdi), %rsi
movl %eax, -0x4c(%rbp)
je 0x8d9d
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x8(%rdi)
jmp 0x8da6
leaq -0x34(%rbp), %rdx
callq 0x915e
movq -0x68(%rbp), %rdi
movq (%rdi), %rsi
addq $0x4, %rsi
movq -0x90(%rbp), %rdx
movq -0x88(%rbp), %rcx
callq 0x9296
movl -0x2c(%rbp), %eax
cmpl %r15d, %eax
cmovlel %r15d, %eax
movl %eax, -0x2c(%rbp)
movl %r15d, -0x44(%rbp)
incl -0x48(%rbp)
xorl %r12d, %r12d
cmpl -0x30(%rbp), %r15d
jl 0x8e4f
movl -0x34(%rbp), %edx
testl $0x38000, %edx          # imm = 0x38000
jne 0x8e03
movl %edx, %eax
orl $0x1000, %eax           # imm = 0x1000
andl $0x7000, %eax           # imm = 0x7000
cmpl $0x3000, %eax           # imm = 0x3000
jne 0x8e8b
movq 0x48(%r14), %rsi
movq -0x40(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x74f0, %r13d          # imm = 0x74F0
movl $0x0, %r9d
cmovgel %eax, %r9d
negl %r9d
cmpl $0xffff8b11, %r13d      # imm = 0xFFFF8B11
cmovll %eax, %r9d
subl %r13d, %r9d
movl $0x1, %r12d
movq -0x98(%rbp), %rdi
movq -0x60(%rbp), %rcx
xorl %r8d, %r8d
callq 0x962d
movl -0x30(%rbp), %eax
movl %eax, -0x38(%rbp)
movq -0xd0(%rbp), %rdi
testq %rdi, %rdi
je 0x8e60
callq 0x31a0
testb $0x1, %r12b
jne 0x8f66
movq %rbx, %r13
movq -0x40(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x78de
movl %eax, -0x34(%rbp)
testl %eax, %eax
movl -0x6c(%rbp), %r12d
jne 0x8bbe
jmp 0x8eb2
movq -0x40(%rbp), %rax
movl 0x804(%rax), %eax
cmpl %edx, %eax
je 0x8e03
movq -0x40(%rbp), %rcx
movl %eax, 0x808(%rcx)
movl %edx, 0x804(%rcx)
jmp 0x8e03
cmpl $0x0, -0x48(%rbp)
movq -0x40(%rbp), %rbx
je 0x8ef7
xorl %r15d, %r15d
cmpl %r12d, -0x2c(%rbp)
setne %r15b
incl %r15d
movq 0x48(%r14), %r14
movzbl (%rbx), %esi
movl -0x44(%rbp), %edi
callq 0x9041
movq -0x98(%rbp), %rdi
movq %r14, %rsi
movl -0x4c(%rbp), %edx
movq -0x60(%rbp), %rcx
movl %r15d, %r8d
movl %eax, %r9d
callq 0x962d
jmp 0x8f75
movq -0xa8(%rbp), %rax
testq %rax, -0xb0(%rbp)
je 0x8f6e
movzbl (%rbx), %eax
addl $0xffff8ad0, %eax       # imm = 0xFFFF8AD0
jmp 0x8f69
movq %r15, %rdi
callq 0x90c3
movzbl (%rbx), %esi
movl %eax, %edi
callq 0x9081
movl %eax, -0x2c(%rbp)
movq %r15, %rdi
callq 0x911d
cmpl $0x2, %eax
movq -0x40(%rbp), %r15
je 0x8f48
cmpl $0x1, %eax
je 0x8f8f
testl %eax, %eax
jne 0x8f95
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jl 0x8f95
movq -0x68(%rbp), %rdi
movq 0x8(%rdi), %rsi
cmpq 0x10(%rdi), %rsi
je 0x8fa0
movl %r15d, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x8(%rdi)
jmp 0x891c
movl -0x38(%rbp), %eax
movl %eax, -0x2c(%rbp)
jmp 0x8f75
movl $0x0, -0x2c(%rbp)
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x891c
callq 0x31a0
jmp 0x891c
cmpl %r12d, -0x2c(%rbp)
jle 0x8f48
movl -0x2c(%rbp), %eax
movl %eax, -0x38(%rbp)
jmp 0x8b28
leaq -0x70(%rbp), %rdx
callq 0x915e
jmp 0x891c
leaq 0x3f0b(%rip), %rdi      # 0xcec0
leaq 0x3f07(%rip), %rsi      # 0xcec3
leaq 0x4136(%rip), %rcx      # 0xd0f9
movl $0x9d, %edx
callq 0x3100
leaq 0x2c7c(%rip), %rdi      # 0xbc50
leaq 0x2c78(%rip), %rsi      # 0xbc53
leaq 0x2c80(%rip), %rcx      # 0xbc62
movl $0x3e, %edx
callq 0x3100
leaq 0x3b19(%rip), %rdi      # 0xcb0c
leaq 0x3ae7(%rip), %rsi      # 0xcae1
leaq 0x3ae9(%rip), %rcx      # 0xcaea
movl $0x64, %edx
callq 0x3100
jmp 0x900f
jmp 0x9014
movq %rax, %rbx
jmp 0x9028
movq %rax, %rbx
movq -0xd0(%rbp), %rdi
testq %rdi, %rdi
je 0x9028
callq 0x31a0
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x9039
callq 0x31a0
movq %rbx, %rdi
callq 0x32d0