// File: /workspace/github_cpp_makefile_star2_O1/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 $0xf8, %rsp
movl %r8d, -0x34(%rbp)
testq %r9, %r9
je 0x9229
movq %r9, %rbx
movl %ecx, %r13d
movl %edx, %r12d
movq %rsi, %r14
movq %rdi, %r15
movq 0x10(%rbp), %rax
movq %rax, -0x68(%rbp)
movq %rsi, %rdi
callq 0x7681
movl $0x0, -0x2c(%rbp)
testb %al, %al
jne 0x8b74
movzbl (%rbx), %esi
movq %r14, %rdi
callq 0x762f
testb %al, %al
je 0x8b89
movl -0x2c(%rbp), %eax
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x28(%r14), %r10
movq 0x30(%r14), %rcx
movq %rcx, %rax
andq %r10, %rax
je 0x9248
bsfq %rax, %rsi
movq 0x38(%r14), %rax
orq %rax, %rcx
leal (,%rsi,8), %edx
leaq 0x860a(%rip), %r9       # 0x111c0
movq (%r14), %r8
movq 0x8(%r14), %rdi
andq (%r9,%rdx), %r8
leaq 0x89f8(%rip), %r9       # 0x115c0
andq (%r9,%rdx), %rdi
leaq 0x38cd(%rip), %r9       # 0xc4a0
movq (%r9,%rdx), %r9
andq %rcx, %r9
leaq 0x36bf(%rip), %r11      # 0xc2a0
imulq (%r11,%rdx), %r9
orq %r8, %rdi
shrq $0x37, %r9
movl %esi, %r8d
shll $0xc, %r8d
addq 0x83b5(%rip), %r8       # 0x10fb0
movq (%r8,%r9,8), %r8
movq 0x10(%r14), %r9
andq %r8, %r9
leaq 0x3393(%rip), %r11      # 0xbfa0
andq (%r11,%rdx), %rcx
orq %rdi, %r9
leaq 0x3185(%rip), %rdi      # 0xbda0
imulq (%rdi,%rdx), %rcx
shrq $0x34, %rcx
shll $0xf, %esi
addq 0x836a(%rip), %rsi      # 0x10f98
movq (%rsi,%rcx,8), %rcx
movq 0x18(%r14), %rsi
andq %rcx, %rsi
orq %r9, %rsi
orq %r8, %rcx
leaq 0x8b7a(%rip), %rdi      # 0x117c0
andq (%rdi,%rdx), %r10
orq %rsi, %r10
andq 0x20(%r14), %rcx
orq %rcx, %r10
xorl %ecx, %ecx
andq %rax, %r10
setne %cl
addl %r12d, %ecx
jle 0x8c7f
cmpb $0x40, (%rbx)
jb 0x8ca4
movq %r14, %rdi
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3bbb
movq %r15, %rdi
movq %r14, %rsi
movl %r13d, %edx
movl -0x34(%rbp), %ecx
movq %rbx, %r8
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x7bee
movq %rcx, -0x50(%rbp)
movq %r10, -0xa8(%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 0x8ce4
cmpq 0x80(%r15), %rcx
jge 0x8b74
movq 0x810(%rbx), %rax
movq (%rax), %rax
testl $0xfffff, %eax          # imm = 0xFFFFF
jne 0x8d18
subq 0x78(%r15), %rcx
jle 0x8d18
imulq $0x3e8, %rax, %rax      # imm = 0x3E8
xorl %edx, %edx
divq %rcx
leaq 0x449d(%rip), %rdi      # 0xd1ab
movq %rax, %rsi
xorl %eax, %eax
callq 0x3040
movq 0x810(%rbx), %rax
incq (%rax)
movl $0x0, -0x40(%rbp)
leaq 0x98(%r15), %rdi
movq 0x48(%r14), %rsi
movq %rdi, -0x98(%rbp)
callq 0x976d
movq %rax, %r12
cmpq 0x48(%r14), %rdx
jne 0x8df9
movl %r12d, %eax
andl $0x7f, %eax
cmpl $0x40, %eax
jae 0x9267
movq %r12, %rcx
shrq $0x29, %rcx
andl $0x3ffff, %ecx          # imm = 0x3FFFF
movl %ecx, -0x40(%rbp)
movb $0x1, %cl
cmpl -0x50(%rbp), %eax
jge 0x8d75
jmp 0x8deb
movq %r12, %rdi
callq 0x933e
movzbl (%rbx), %esi
movl %eax, %edi
callq 0x92fc
movl %eax, -0x30(%rbp)
movq %r12, %rdi
callq 0x9398
cmpl $0x2, %eax
je 0x8db9
cmpl $0x1, %eax
je 0x8dd6
testl %eax, %eax
jne 0x8ddc
movl -0x30(%rbp), %ecx
cmpl -0x34(%rbp), %ecx
jge 0x8db9
cmpl $0x1, %eax
setne %al
cmpl %r13d, -0x30(%rbp)
setg %cl
orb %al, %cl
jne 0x8ddc
movq -0x68(%rbp), %rdi
movq 0x8(%rdi), %rsi
cmpq 0x10(%rdi), %rsi
je 0x8de0
movl -0x40(%rbp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x8(%rdi)
jmp 0x8de9
cmpl %r13d, -0x30(%rbp)
jle 0x8db9
movb $0x1, %cl
jmp 0x8deb
leaq -0x40(%rbp), %rdx
callq 0x93d8
xorl %ecx, %ecx
movl -0x30(%rbp), %eax
movl %eax, -0x2c(%rbp)
testb %cl, %cl
je 0x8b74
leaq 0x4(%rbx), %rsi
movq %r14, %rdi
callq 0x608e
leaq -0x70(%rbp), %r12
movl %eax, (%r12)
movl -0x40(%rbp), %ecx
movq %r14, %rdi
movq %rbx, %rsi
movl %eax, %edx
callq 0x7a40
xorps %xmm0, %xmm0
movaps %xmm0, -0x90(%rbp)
movq $0x0, -0x80(%rbp)
movq %rbx, %rdi
movq %r12, %rsi
callq 0x7b5f
movl %eax, -0x38(%rbp)
testl %eax, %eax
je 0x9192
leaq 0x50(%r14), %rax
movq %rax, -0xb0(%rbp)
movq -0x50(%rbp), %rax
decl %eax
movl %eax, -0x58(%rbp)
movl -0x34(%rbp), %eax
negl %eax
movl %eax, -0x54(%rbp)
leaq 0x818(%rbx), %rax
movq %rax, -0xa0(%rbp)
movl $0xffff8ad0, -0x3c(%rbp) # imm = 0xFFFF8AD0
movl $0x0, -0x44(%rbp)
movl %r13d, -0x2c(%rbp)
movl $0x0, -0x48(%rbp)
movl %r13d, -0x6c(%rbp)
movq %rbx, -0x60(%rbp)
movq -0x90(%rbp), %rax
cmpq %rax, -0x88(%rbp)
je 0x8ea7
movq %rax, -0x88(%rbp)
movq %r15, %rbx
movl $0xa, %ecx
leaq -0x118(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0xc8(%rbp), %rdi
movq -0xb0(%rbp), %rsi
callq 0x5692
movl -0x38(%rbp), %esi
movq %r15, %rdi
callq 0x4ac0
movq -0xf0(%rbp), %rax
movq -0xe0(%rbp), %rcx
andq %rax, %rcx
je 0x9248
bsfq %rcx, %rsi
movq -0xe8(%rbp), %rcx
movq -0xe0(%rbp), %rdi
orq %rcx, %rdi
leal (,%rsi,8), %edx
movq -0x118(%rbp), %r8
leaq 0x82a2(%rip), %r9       # 0x111c0
andq 0x200(%r9,%rdx), %r8
movq -0x110(%rbp), %r9
leaq 0x868c(%rip), %r10      # 0x115c0
andq (%r10,%rdx), %r9
orq %r8, %r9
leaq 0x355e(%rip), %r8       # 0xc4a0
movq (%r8,%rdx), %r8
andq %rdi, %r8
leaq 0x3350(%rip), %r10      # 0xc2a0
imulq (%r10,%rdx), %r8
shrq $0x37, %r8
movl %esi, %r10d
shll $0xc, %r10d
addq 0x8049(%rip), %r10      # 0x10fb0
movq (%r10,%r8,8), %r8
movq -0x108(%rbp), %r10
andq %r8, %r10
orq %r9, %r10
leaq 0x3021(%rip), %r9       # 0xbfa0
andq (%r9,%rdx), %rdi
leaq 0x2e16(%rip), %r9       # 0xbda0
imulq (%r9,%rdx), %rdi
shrq $0x34, %rdi
shll $0xf, %esi
addq 0x7ffb(%rip), %rsi      # 0x10f98
movq (%rsi,%rdi,8), %rsi
movq -0x100(%rbp), %rdi
andq %rsi, %rdi
orq %r10, %rdi
orq %r8, %rsi
leaq 0x8808(%rip), %r8       # 0x117c0
andq (%r8,%rdx), %rax
andq -0xf8(%rbp), %rsi
orq %rdi, %rax
orq %rsi, %rax
movl $0x2, %r13d
testq %rcx, %rax
jne 0x9123
movl -0x2c(%rbp), %r8d
negl %r8d
cmpl $0x0, -0x48(%rbp)
je 0x900e
leaq -0x90(%rbp), %rax
movq %rax, (%rsp)
movq %rbx, %rdi
leaq -0x118(%rbp), %rsi
movl -0x58(%rbp), %edx
movl -0x54(%rbp), %ecx
movq -0xa0(%rbp), %r9
callq 0x8b1a
jmp 0x9035
leaq -0x90(%rbp), %rax
movq %rax, (%rsp)
movq %rbx, %rdi
leaq -0x118(%rbp), %rsi
movl -0x58(%rbp), %edx
movl -0x54(%rbp), %ecx
movq -0xa0(%rbp), %r9
callq 0x8349
movl %eax, %r15d
movl %eax, %r12d
negl %r12d
cmpl %r12d, -0x3c(%rbp)
movq -0x68(%rbp), %rdi
jge 0x90a9
movq (%rdi), %rax
cmpq %rax, 0x8(%rdi)
je 0x9055
movq %rax, 0x8(%rdi)
movl -0x38(%rbp), %eax
movq 0x8(%rdi), %rsi
cmpq 0x10(%rdi), %rsi
movl %eax, -0x44(%rbp)
je 0x9071
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x8(%rdi)
jmp 0x907a
leaq -0x38(%rbp), %rdx
callq 0x93d8
movq -0x68(%rbp), %rdi
movq (%rdi), %rsi
addq $0x4, %rsi
movq -0x90(%rbp), %rdx
movq -0x88(%rbp), %rcx
callq 0x9510
movl -0x2c(%rbp), %eax
cmpl %r12d, %eax
cmovlel %r12d, %eax
movl %eax, -0x2c(%rbp)
movl %r12d, -0x3c(%rbp)
incl -0x48(%rbp)
xorl %r13d, %r13d
cmpl -0x34(%rbp), %r12d
jl 0x9123
movl -0x38(%rbp), %edx
testl $0x38000, %edx          # imm = 0x38000
jne 0x90d7
movl %edx, %eax
orl $0x1000, %eax           # imm = 0x1000
andl $0x7000, %eax           # imm = 0x7000
cmpl $0x3000, %eax           # imm = 0x3000
jne 0x9162
movq 0x48(%r14), %rsi
movq -0x60(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x74f0, %r15d          # imm = 0x74F0
movl $0x0, %r9d
cmovgel %eax, %r9d
negl %r9d
cmpl $0xffff8b11, %r15d      # imm = 0xFFFF8B11
cmovll %eax, %r9d
subl %r15d, %r9d
movl $0x1, %r13d
movq -0x98(%rbp), %rdi
movq -0x50(%rbp), %rcx
xorl %r8d, %r8d
callq 0x98c1
movl -0x34(%rbp), %eax
movl %eax, -0x30(%rbp)
movq -0xc8(%rbp), %rdi
testq %rdi, %rdi
je 0x9134
callq 0x31a0
testb $0x1, %r13b
jne 0x9200
movq %rbx, %r15
movq -0x60(%rbp), %rbx
movq %rbx, %rdi
leaq -0x70(%rbp), %rsi
callq 0x7b5f
movl %eax, -0x38(%rbp)
testl %eax, %eax
movl -0x6c(%rbp), %r13d
jne 0x8e90
jmp 0x9189
movq -0x60(%rbp), %rax
movl 0x804(%rax), %eax
cmpl %edx, %eax
je 0x90d7
movq -0x60(%rbp), %rcx
movl %eax, 0x808(%rcx)
movl %edx, 0x804(%rcx)
jmp 0x90d7
cmpl $0x0, -0x48(%rbp)
sete %al
jmp 0x91a6
movl $0x0, -0x44(%rbp)
movl $0xffff8ad0, -0x3c(%rbp) # imm = 0xFFFF8AD0
movb $0x1, %al
movl %r13d, -0x2c(%rbp)
movq -0x50(%rbp), %rcx
testb %al, %al
movq -0xa8(%rbp), %rax
je 0x91c4
testq %rax, %rax
je 0x9208
movzbl (%rbx), %eax
addl $0xffff8ad0, %eax       # imm = 0xFFFF8AD0
jmp 0x9203
xorl %r15d, %r15d
cmpl %r13d, -0x2c(%rbp)
setne %r15b
incl %r15d
movq 0x48(%r14), %r14
movzbl (%rbx), %esi
movl -0x3c(%rbp), %edi
movq %rcx, %rbx
callq 0x92bc
movq -0x98(%rbp), %rdi
movq %r14, %rsi
movl -0x44(%rbp), %edx
movl %ebx, %ecx
movl %r15d, %r8d
movl %eax, %r9d
callq 0x98c1
jmp 0x920f
movl -0x30(%rbp), %eax
movl %eax, -0x2c(%rbp)
jmp 0x920f
movl $0x0, -0x2c(%rbp)
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x8b74
callq 0x31a0
jmp 0x8b74
leaq 0x3d50(%rip), %rdi      # 0xcf80
leaq 0x3d4c(%rip), %rsi      # 0xcf83
leaq 0x3f7b(%rip), %rcx      # 0xd1b9
movl $0x9d, %edx
callq 0x3100
leaq 0x2a01(%rip), %rdi      # 0xbc50
leaq 0x29fd(%rip), %rsi      # 0xbc53
leaq 0x2a05(%rip), %rcx      # 0xbc62
movl $0x3e, %edx
callq 0x3100
leaq 0x395e(%rip), %rdi      # 0xcbcc
leaq 0x392c(%rip), %rsi      # 0xcba1
leaq 0x392e(%rip), %rcx      # 0xcbaa
movl $0x64, %edx
callq 0x3100
jmp 0x928a
jmp 0x928f
movq %rax, %rbx
jmp 0x92a3
movq %rax, %rbx
movq -0xc8(%rbp), %rdi
testq %rdi, %rdi
je 0x92a3
callq 0x31a0
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x92b4
callq 0x31a0
movq %rbx, %rdi
callq 0x32d0