// File: jswaff[P]prophet3/src/search.cpp
// Function: search(position*, move_line*, int, int, int, search_stats*, unsigned long long*, undo*, bool)
int32 search(position *pos,move_line *parent_pv,int32 alpha,int32 beta,int32 depth,
        search_stats *stats,move *move_stack,undo *undo_stack,bool show_thinking) {

    assert(pos);
    assert(parent_pv);
    assert(stats);
    assert(depth > 0);
    assert(beta > alpha);

    stats->nodes++;

    move_line pv; pv.n=0;

    // search each move
    int32 moves_searched=0;
    uint64 hash_val = get_hash_entry(&htbl,pos->hash_key);
    move_order_dto mo_dto = build_move_order_dto(move_stack,
            stats->last_pv.n > 0 ? stats->last_pv.mv[0] : 0,
            get_hash_entry_move(hash_val),
            killer1[0],killer2[0],false);
    move *mp;
    while (next(pos,&mp,&mo_dto)) {
        assert(good_move(pos,*mp));
        apply_move(pos,*mp,undo_stack);
        if (in_check(pos,opposite_player(pos->player))) {
            undo_last_move(pos,undo_stack);
            continue;
        }

        if (moves_searched==0) {
            stats->first_line_searched.mv[0] = *mp;
            stats->first_line_searched.n = 1;
        }

        bool gives_check = in_check(pos,pos->player);
        int32 ext = extend(pos,*mp,gives_check);
        int32 score;
        if (moves_searched==0) {
            score = -search_helper(pos,&pv,-beta,-alpha,depth-1+ext,1,
                    true,gives_check,false,stats,mo_dto.endp,undo_stack);
        } else {
            /*score = -search_helper(pos,&pv,-(alpha+1),-alpha,depth-1+ext,1,
                    false,gives_check,(ext==0),stats,endp,undo_stack);
            if (score > alpha && score < beta) {*/
                score = -search_helper(pos,&pv,-beta,-alpha,depth-1+ext,1,
                    false,gives_check,(ext==0),stats,mo_dto.endp,undo_stack);
            //}
        }
        moves_searched++;

        // restore the position
        undo_last_move(pos,undo_stack);

        // If depth==1, we need to continue with the search to ensure we have something to play.
        if (depth > 1 && abort_search) {
            return 0;
        }

        if (score > alpha) {
            if (score >= beta) {
                return beta;
            }
            alpha = score;
            update_parent_pv(parent_pv,&pv,*mp);
            if (show_thinking) {
                print_thinking_output(parent_pv,depth,alpha,start_time,stats->nodes);
            }
        }
    }

    if (moves_searched==0) {
        return in_check(pos,pos->player) ? -CHECKMATE : DRAWSCORE;
    }

    return alpha;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
subq $0x420, %rsp            # imm = 0x420
movb 0x20(%rbp), %al
movq 0x18(%rbp), %r10
movq 0x10(%rbp), %r10
movq %rdi, -0x20(%rbp)
movq %rsi, -0x28(%rbp)
movl %edx, -0x2c(%rbp)
movl %ecx, -0x30(%rbp)
movl %r8d, -0x34(%rbp)
movq %r9, -0x40(%rbp)
andb $0x1, %al
movb %al, -0x41(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x1038d
jmp 0x103ac
leaq 0x251b5(%rip), %rdi     # 0x35549
leaq 0x27afe(%rip), %rsi     # 0x37e99
movl $0x38, %edx
leaq 0x27b66(%rip), %rcx     # 0x37f0d
callq 0x20c0
cmpq $0x0, -0x28(%rbp)
je 0x103b5
jmp 0x103d4
leaq 0x27bb2(%rip), %rdi     # 0x37f6e
leaq 0x27ad6(%rip), %rsi     # 0x37e99
movl $0x39, %edx
leaq 0x27b3e(%rip), %rcx     # 0x37f0d
callq 0x20c0
cmpq $0x0, -0x40(%rbp)
je 0x103dd
jmp 0x103fc
leaq 0x27b94(%rip), %rdi     # 0x37f78
leaq 0x27aae(%rip), %rsi     # 0x37e99
movl $0x3a, %edx
leaq 0x27b16(%rip), %rcx     # 0x37f0d
callq 0x20c0
cmpl $0x0, -0x34(%rbp)
jle 0x10404
jmp 0x10423
leaq 0x27b73(%rip), %rdi     # 0x37f7e
leaq 0x27a87(%rip), %rsi     # 0x37e99
movl $0x3b, %edx
leaq 0x27aef(%rip), %rcx     # 0x37f0d
callq 0x20c0
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jle 0x1042d
jmp 0x1044c
leaq 0x27b54(%rip), %rdi     # 0x37f88
leaq 0x27a5e(%rip), %rsi     # 0x37e99
movl $0x3c, %edx
leaq 0x27ac6(%rip), %rcx     # 0x37f0d
callq 0x20c0
movq -0x40(%rbp), %rax
movq 0x18(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x18(%rax)
movl $0x0, -0x370(%rbp)
movl $0x0, -0x374(%rbp)
movq -0x20(%rbp), %rax
movq 0x1b8(%rax), %rsi
leaq 0xf2c2e(%rip), %rdi     # 0x1030b0
callq 0x8980
movq %rax, -0x380(%rbp)
movq 0x10(%rbp), %rax
movq %rax, -0x3e0(%rbp)
movq -0x40(%rbp), %rax
cmpl $0x0, 0x28(%rax)
jle 0x104b4
movq -0x40(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x3e8(%rbp)
jmp 0x104bf
xorl %eax, %eax
movq %rax, -0x3e8(%rbp)
jmp 0x104bf
movq -0x3e8(%rbp), %rax
movq %rax, -0x3f0(%rbp)
movq -0x380(%rbp), %rdi
callq 0x87d0
movq -0x3e0(%rbp), %rsi
movq -0x3f0(%rbp), %rdx
movq %rax, %rcx
leaq 0xf2c1f(%rip), %rax     # 0x103110
movq (%rax), %r8
leaq 0xf2f35(%rip), %rax     # 0x103430
movq (%rax), %r9
leaq -0x3c0(%rbp), %rdi
xorl %eax, %eax
movl $0x0, (%rsp)
callq 0x10270
movq -0x20(%rbp), %rdi
leaq -0x3c8(%rbp), %rsi
leaq -0x3c0(%rbp), %rdx
callq 0xc670
testb $0x1, %al
jne 0x10533
jmp 0x107ea
movq -0x20(%rbp), %rdi
movq -0x3c8(%rbp), %rax
movq (%rax), %rsi
callq 0xcef0
testb $0x1, %al
jne 0x1054c
jmp 0x1054e
jmp 0x1056d
leaq 0x27a40(%rip), %rdi     # 0x37f95
leaq 0x2793d(%rip), %rsi     # 0x37e99
movl $0x4b, %edx
leaq 0x279a5(%rip), %rcx     # 0x37f0d
callq 0x20c0
movq -0x20(%rbp), %rdi
movq -0x3c8(%rbp), %rax
movq (%rax), %rsi
movq 0x18(%rbp), %rdx
callq 0x3620
movq -0x20(%rbp), %rax
movq %rax, -0x3f8(%rbp)
movq -0x20(%rbp), %rax
movl 0x138(%rax), %edi
callq 0x14130
movq -0x3f8(%rbp), %rdi
movl %eax, %esi
callq 0xfc10
testb $0x1, %al
jne 0x105b2
jmp 0x105c4
movq -0x20(%rbp), %rdi
movq 0x18(%rbp), %rsi
callq 0x39a0
jmp 0x10513
cmpl $0x0, -0x374(%rbp)
jne 0x105f0
movq -0x3c8(%rbp), %rax
movq (%rax), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x358(%rax)
movq -0x40(%rbp), %rax
movl $0x1, 0x350(%rax)
movq -0x20(%rbp), %rdi
movq -0x20(%rbp), %rax
movl 0x138(%rax), %esi
callq 0xfc10
andb $0x1, %al
movb %al, -0x3c9(%rbp)
movq -0x20(%rbp), %rdi
movq -0x3c8(%rbp), %rax
movq (%rax), %rsi
movb -0x3c9(%rbp), %al
andb $0x1, %al
movzbl %al, %edx
callq 0x8150
movl %eax, -0x3d0(%rbp)
cmpl $0x0, -0x374(%rbp)
jne 0x106bc
movq -0x20(%rbp), %rdi
xorl %edx, %edx
subl -0x30(%rbp), %edx
xorl %ecx, %ecx
subl -0x2c(%rbp), %ecx
movl -0x34(%rbp), %r8d
subl $0x1, %r8d
addl -0x3d0(%rbp), %r8d
movb -0x3c9(%rbp), %bl
movq -0x40(%rbp), %r11
movq -0x390(%rbp), %r10
movq 0x18(%rbp), %rax
leaq -0x370(%rbp), %rsi
movl $0x1, %r9d
xorl %r14d, %r14d
andb $0x1, %bl
movl $0x1, (%rsp)
movzbl %bl, %ebx
movl %ebx, 0x8(%rsp)
movl $0x0, 0x10(%rsp)
movq %r11, 0x18(%rsp)
movq %r10, 0x20(%rsp)
movq %rax, 0x28(%rsp)
callq 0x10830
movl %eax, %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, -0x3d4(%rbp)
jmp 0x10745
movq -0x20(%rbp), %rdi
xorl %edx, %edx
subl -0x30(%rbp), %edx
xorl %ecx, %ecx
subl -0x2c(%rbp), %ecx
movl -0x34(%rbp), %r8d
subl $0x1, %r8d
addl -0x3d0(%rbp), %r8d
movb -0x3c9(%rbp), %sil
cmpl $0x0, -0x3d0(%rbp)
sete %r9b
movq -0x40(%rbp), %r10
movq -0x390(%rbp), %r11
movq 0x18(%rbp), %rbx
xorl %eax, %eax
movq %rsp, %rax
movq %rbx, 0x28(%rax)
movq %r11, 0x20(%rax)
movq %r10, 0x18(%rax)
movzbl %r9b, %r9d
andl $0x1, %r9d
movl %r9d, 0x10(%rax)
movzbl %sil, %esi
andl $0x1, %esi
movl %esi, 0x8(%rax)
movl $0x0, (%rax)
leaq -0x370(%rbp), %rsi
movl $0x1, %r9d
callq 0x10830
movl %eax, %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, -0x3d4(%rbp)
movl -0x374(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x374(%rbp)
movq -0x20(%rbp), %rdi
movq 0x18(%rbp), %rsi
callq 0x39a0
cmpl $0x1, -0x34(%rbp)
jle 0x1077c
testb $0x1, 0x877393(%rip)    # 0x887b01
je 0x1077c
movl $0x0, -0x14(%rbp)
jmp 0x10820
movl -0x3d4(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jle 0x107e5
movl -0x3d4(%rbp), %eax
cmpl -0x30(%rbp), %eax
jl 0x1079d
movl -0x30(%rbp), %eax
movl %eax, -0x14(%rbp)
jmp 0x10820
movl -0x3d4(%rbp), %eax
movl %eax, -0x2c(%rbp)
movq -0x28(%rbp), %rdi
movq -0x3c8(%rbp), %rax
movq (%rax), %rdx
leaq -0x370(%rbp), %rsi
callq 0x113e0
testb $0x1, -0x41(%rbp)
je 0x107e3
movq -0x28(%rbp), %rdi
movl -0x34(%rbp), %esi
movl -0x2c(%rbp), %edx
movl 0x877316(%rip), %ecx    # 0x887aec
movq -0x40(%rbp), %rax
movq 0x18(%rax), %r8
callq 0x152c0
jmp 0x107e5
jmp 0x10513
cmpl $0x0, -0x374(%rbp)
jne 0x1081a
movq -0x20(%rbp), %rdi
movq -0x20(%rbp), %rax
movl 0x138(%rax), %esi
callq 0xfc10
movb %al, %dl
xorl %eax, %eax
movl $0xffff0001, %ecx       # imm = 0xFFFF0001
testb $0x1, %dl
cmovnel %ecx, %eax
movl %eax, -0x14(%rbp)
jmp 0x10820
movl -0x2c(%rbp), %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
addq $0x420, %rsp            # imm = 0x420
popq %rbx
popq %r14
popq %rbp
retq
nop