// File: SethKasmann[P]clever-girl/src/search.cpp
// Function: scout_search(State&, SearchInfo&, int, int, int, int, bool, bool, bool)
int scout_search(State& s, SearchInfo& si, int depth, int ply, int alpha, int beta, bool isPv, bool isNull, bool isRoot)
{
    assert(depth >= 0);
    Move best_move = nullMove;
    
    if (si.quit || (si.nodes % 3000 == 0 && interrupt(si)))
        return 0;

    si.nodes++;

    // Evaluate leaf nodes.
    if (depth == 0)
        return qsearch(s, si, ply, alpha, beta);

    // Check for draw.
    if (!isRoot && 
        (history.isThreefoldRepetition(s) ||
        s.insufficientMaterial() || 
        s.getFiftyMoveRule() > 99))
        return Draw;

    // Get a pointer to the correction transposition table location.
    const TableEntry* table_entry = ttable.probe(s.getKey());

    // Check if table entry is valid and matches the position key.
    if (table_entry->key == s.getKey() && table_entry->depth >= depth)
    {
        if (table_entry->type == pv)             // PV Node, return the score.
            return table_entry->score;
        else if (table_entry->type == cut)       // Cut Node, adjust alpha.
        {
            if (table_entry->score >= beta)
                return beta;
        }
        else
        {
            if (table_entry->score <= alpha)
                return alpha;
        }

        best_move = table_entry->best;
    }

    // Check if we are at the PV line.
    if (lineManager.getPvKey(ply) == s.getKey())
    {
        best_move = lineManager.getPvMove(ply);
    }

// -------------------------------------------------------------------------- //
//                                                                            //
// Static Evaluation. Evaluate the current position statically if the         //
// current node is not a PV node.                                             //
//                                                                            //
// -------------------------------------------------------------------------- //
    int staticEval = 0;
    if (!isPv)
    {
        Evaluate evaluate(s);
        staticEval = evaluate.getScore();
    }

// -------------------------------------------------------------------------- //
//                                                                            //
// Reverse Futility Pruning. At pre-frontier and pre-pre-frontier, if the     //
// side to move is doing so well that the static evaluation - a futility      //
// penalty still causes a beta cutoff, return beta.                           //
//                                                                            //
// -------------------------------------------------------------------------- //
    if (!isPv && 
        !isNull &&
        !s.inCheck() &&
        depth <= 2 &&
        s.getNonPawnPieceCount(s.getOurColor()))
    {
        if (staticEval - 100 * depth >= beta)
            return beta;
    }

// -------------------------------------------------------------------------- //
//                                                                            //
// Null move pruning. Make a null move and searched to a reduced to check     //
// for fail high under the following conditions:                              //
//   1. The current node is not a PV node.                                    //
//   2. The current state is not in check.                                    //
//   3. The depth is high enough.                                             //
//   4. There are enough non pawn pieces on the board.                        //
//                                                                            //
// -------------------------------------------------------------------------- //
    if (!isPv && !isNull && !s.inCheck() && depth > NullMoveDepth 
        && s.getNonPawnPieceCount(s.getOurColor()) > NullMoveCount)
    {
        State n;
        std::memmove(&n, &s, sizeof s);
        n.makeNull();
        history.push(std::make_pair(nullMove, n.getKey()));
        int nullScore = -scout_search(n, si, depth - 3, ply + 1, -(alpha + 1), -alpha, false, true, false);
        history.pop();
        if (nullScore >= beta)
            return beta;
    }

    // Internal Iterative Deepening. If no best move was found, do a small
    // search to determine which move to search first.
    if (isPv && !isNull && !s.inCheck() && best_move == nullMove && depth > 5)
    {
        // Using depth calculation from Stockfish.
        int d = 3 * depth / 4 - 2;
        scout_search(s, si, d, ply, alpha, beta, isPv, true, false);
        table_entry = ttable.probe(s.getKey());
        if (table_entry->key == s.getKey())
            best_move = table_entry->best;
    }
    // Generate moves and create the movelist.
    MoveList mlist(s, best_move, &history, ply);

    int a = alpha;
    int b = beta;
    int d;
    int score;
    int bestScore = Neg_inf;
    Move m;
    bool first = true;
    int count = 0;

    while (m = mlist.getBestMove())
    {
        d = depth - 1;
// -------------------------------------------------------------------------- //
//                                                                            //
// Early Pruning                                                              //
//                                                                            //
// It may be possible to prune before the child move is made, under the       //
// following conditions:                                                      //
//   1. Current node is not a PV node.                                        //
//   2. Best score searched is greater than the - checkmate bound.            //
//   3. Side to move is not in check.                                         //
//   4. Move itself does not give check.                                      //
//   5. Side to move has at least 1 major or minor piece.                     //
//                                                                            //
// -------------------------------------------------------------------------- //
        if (!isPv &&
            bestScore > -CheckmateBound &&
            !s.inCheck() &&
            !s.givesCheck(m) &&
            s.getNonPawnPieceCount(s.getOurColor()))
        {
// -------------------------------------------------------------------------- //
//                                                                            //
// Futility Pruning                                                           //
//                                                                            //
// Prune quiet moves at depth 1 that will not improve alpha.                  //
//                                                                            //
// -------------------------------------------------------------------------- //
            if (depth == 1 &&
                s.isQuiet(m) &&
                !isPromotion(m) &&
                staticEval + 300 < a)
                continue;

// -------------------------------------------------------------------------- //
//                                                                            //
// Pruning based on SEE.                                                      //
//                                                                            //
// Original idea from Stockfish. If the SEE is low relative to the depth,     //
// prune the move. The calculation I'm currently using is:                    //
//   see(move) < -pawn * 2^(depth - 1)                                        //
//                                                                            //
// -------------------------------------------------------------------------- //
            if (depth < 3 &&
                s.see(m) < -Pawn_wt * (1 << (depth - 1)))
                continue;
        }

        State c(s);
        c.make_t(m);                                 // Make move.
        history.push(std::make_pair(m, c.getKey())); // Add move to gamelist.
        count++;

        if (c.inCheck() && depth == 1)
            d++;

        // Scout alrogithm. Search the first node with a full window.
        if (first)
        {
            // Set the best move to the first move just in case no move
            // improves alpha.
            best_move = m;
            score = -scout_search(c, si, d, ply + 1, -b, -a, isPv, isNull, false);
            first = false;
        }       
        else
        {
// -------------------------------------------------------------------------- //
//                                                                            //
// Late move reduction. Perform a reduced depth search (by 1 ply) under the   //
// following conditions:                                                      //
//   1. A number (LmrCount) of moves have already been tried.                 //
//   2. The current node is not a PV node.                                    //
//   3. The side to move is not in check.                                     //
//   4. The move itself does not give check.                                  //
//   5. The move does not promote a piece.                                    //
//   6. The move does not capture a piece.                                    //
//                                                                            //
// -------------------------------------------------------------------------- //
            if (count > LmrCount && depth > LmrDepth && !isPv && !s.inCheck()
                && !c.inCheck() && !s.isCapture(m) && !isPromotion(m))
                score = -scout_search(c, si, d - 1, ply + 1, -(a + 1), -a, false, isNull, false);
            else
                score = a + 1;

            if (score > a)
                score = -scout_search(c, si, d, ply + 1, -(a + 1), -a, false, isNull, false);

            // If an alpha improvement caused fail high, research using a full window.
            if (a < score && b > score)
            {
                score = -scout_search(c, si, d, ply + 1, -b, -a, true, isNull, false);
            }
        }

        history.pop();                           // Remove move from gamelist.

        if (score > bestScore)
        {
            best_move = m;
            bestScore = score;
        }

        a = std::max(a, bestScore);

        // Alpha-Beta pruning. If the move that caused the Beta cutoff is a
        // quiet move, store it as a killer.
        if (a >= b)
        {
            a = b;
            if (s.isQuiet(m))
                history.update(m, depth, ply, true);
            break;
        }
        else
        {
            if (s.isQuiet(m))
                history.update(m, depth, ply, false);
        }
    }

    if (bestScore == Neg_inf)
        return s.check() ? -Checkmate + ply : Stalemate;

    if (a > alpha && a < b && !si.quit)
    {
        lineManager.pushToPv(best_move, s.getKey(), ply, a);
    }

    ttable.store(s.getKey(), best_move, a <= alpha ? all : a >= b ? cut : pv, depth, a);

    // Fail-Hard alpha beta score.
    return a;

}

// Assembly:
subq $0x1498, %rsp           # imm = 0x1498
movl %ecx, 0xcc(%rsp)
movl %edx, 0xd0(%rsp)
movq %rsi, %r10
movl 0xcc(%rsp), %esi
movq %rdi, %r11
movl 0xd0(%rsp), %edi
movb 0x14b0(%rsp), %al
movb 0x14a8(%rsp), %cl
movb 0x14a0(%rsp), %dl
movq %r11, 0x1488(%rsp)
movq %r10, 0x1480(%rsp)
movl %edi, 0x147c(%rsp)
movl %esi, 0x1478(%rsp)
movl %r8d, 0x1474(%rsp)
movl %r9d, 0x1470(%rsp)
andb $0x1, %dl
movb %dl, 0x146f(%rsp)
andb $0x1, %cl
movb %cl, 0x146e(%rsp)
andb $0x1, %al
movb %al, 0x146d(%rsp)
movw $0x0, 0x146a(%rsp)
movq 0x1480(%rsp), %rax
testb $0x1, 0x3a(%rax)
jne 0x340bc
movq 0x1480(%rsp), %rax
movl 0x1c(%rax), %eax
movl $0xbb8, %ecx            # imm = 0xBB8
cltd
idivl %ecx
cmpl $0x0, %edx
jne 0x340cc
movq 0x1480(%rsp), %rdi
callq 0x33a50
testb $0x1, %al
jne 0x340bc
jmp 0x340cc
movl $0x0, 0x1494(%rsp)
jmp 0x34f31
movq 0x1480(%rsp), %rax
movl 0x1c(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x1c(%rax)
cmpl $0x0, 0x147c(%rsp)
jne 0x3411e
movq 0x1488(%rsp), %rdi
movq 0x1480(%rsp), %rsi
movl 0x1478(%rsp), %edx
movl 0x1474(%rsp), %ecx
movl 0x1470(%rsp), %r8d
callq 0x33b60
movl %eax, 0x1494(%rsp)
jmp 0x34f31
testb $0x1, 0x146d(%rsp)
jne 0x34173
movq 0x1488(%rsp), %rsi
leaq 0x1e2609(%rip), %rdi    # 0x216740
callq 0x35570
testb $0x1, %al
jne 0x34163
movq 0x1488(%rsp), %rdi
callq 0x38990
testb $0x1, %al
jne 0x34163
movq 0x1488(%rsp), %rdi
callq 0x30090
cmpl $0x63, %eax
jle 0x34173
movl $0x0, 0x1494(%rsp)
jmp 0x34f31
movq 0x1488(%rsp), %rdi
callq 0x308b0
movq %rax, %rsi
leaq 0x21c506(%rip), %rdi    # 0x250690
callq 0x35760
movq %rax, 0x1460(%rsp)
movq 0x1460(%rsp), %rax
movq (%rax), %rax
movq %rax, 0xc0(%rsp)
movq 0x1488(%rsp), %rdi
callq 0x308b0
movq %rax, %rcx
movq 0xc0(%rsp), %rax
cmpq %rcx, %rax
jne 0x3427e
movq 0x1460(%rsp), %rax
movl 0x10(%rax), %eax
cmpl 0x147c(%rsp), %eax
jl 0x3427e
movq 0x1460(%rsp), %rax
cmpl $0x0, 0xc(%rax)
jne 0x34208
movq 0x1460(%rsp), %rax
movl 0x14(%rax), %eax
movl %eax, 0x1494(%rsp)
jmp 0x34f31
movq 0x1460(%rsp), %rax
cmpl $0x1, 0xc(%rax)
jne 0x3423f
movq 0x1460(%rsp), %rax
movl 0x14(%rax), %eax
cmpl 0x1470(%rsp), %eax
jl 0x3423d
movl 0x1470(%rsp), %eax
movl %eax, 0x1494(%rsp)
jmp 0x34f31
jmp 0x34268
movq 0x1460(%rsp), %rax
movl 0x14(%rax), %eax
cmpl 0x1474(%rsp), %eax
jg 0x34266
movl 0x1474(%rsp), %eax
movl %eax, 0x1494(%rsp)
jmp 0x34f31
jmp 0x34268
jmp 0x3426a
movq 0x1460(%rsp), %rax
movw 0x8(%rax), %ax
movw %ax, 0x146a(%rsp)
movl 0x1478(%rsp), %esi
leaq 0x1dd4f4(%rip), %rdi    # 0x211780
callq 0x25da0
movq %rax, 0xb8(%rsp)
movq 0x1488(%rsp), %rdi
callq 0x308b0
movq %rax, %rcx
movq 0xb8(%rsp), %rax
cmpq %rcx, %rax
jne 0x342d1
movl 0x1478(%rsp), %esi
leaq 0x1dd4bc(%rip), %rdi    # 0x211780
callq 0x25dd0
movw %ax, 0x146a(%rsp)
movl $0x0, 0x145c(%rsp)
testb $0x1, 0x146f(%rsp)
jne 0x3430f
movq 0x1488(%rsp), %rsi
leaq 0x13a8(%rsp), %rdi
callq 0x21910
leaq 0x13a8(%rsp), %rdi
callq 0x237f0
movl %eax, 0x145c(%rsp)
testb $0x1, 0x146f(%rsp)
jne 0x343a2
testb $0x1, 0x146e(%rsp)
jne 0x343a2
movq 0x1488(%rsp), %rdi
callq 0x28680
testb $0x1, %al
jne 0x343a2
cmpl $0x2, 0x147c(%rsp)
jg 0x343a2
movq 0x1488(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq 0x1488(%rsp), %rdi
callq 0x24ca0
movq 0xb0(%rsp), %rdi
movl %eax, %esi
callq 0x357c0
cmpl $0x0, %eax
je 0x343a2
movl 0x145c(%rsp), %eax
imull $0x64, 0x147c(%rsp), %ecx
subl %ecx, %eax
cmpl 0x1470(%rsp), %eax
jl 0x343a0
movl 0x1470(%rsp), %eax
movl %eax, 0x1494(%rsp)
jmp 0x34f31
jmp 0x343a2
testb $0x1, 0x146f(%rsp)
jne 0x34532
testb $0x1, 0x146e(%rsp)
jne 0x34532
movq 0x1488(%rsp), %rdi
callq 0x28680
testb $0x1, %al
jne 0x34532
cmpl $0x3, 0x147c(%rsp)
jle 0x34532
movq 0x1488(%rsp), %rax
movq %rax, 0xa8(%rsp)
movq 0x1488(%rsp), %rdi
callq 0x24ca0
movq 0xa8(%rsp), %rdi
movl %eax, %esi
callq 0x357c0
cmpl $0x3, %eax
jle 0x34532
leaq 0xea0(%rsp), %rdi
callq 0x263c0
movq 0x1488(%rsp), %rsi
leaq 0xea0(%rsp), %rdi
movl $0x508, %edx            # imm = 0x508
callq 0x5430
leaq 0xea0(%rsp), %rdi
callq 0x387f0
leaq 0xea0(%rsp), %rdi
callq 0x308b0
movq %rax, 0xe88(%rsp)
leaq 0xefa6(%rip), %rdi      # 0x4340c
leaq 0xe88(%rsp), %rsi
callq 0x30870
movw %ax, 0xe90(%rsp)
movq %rdx, 0xe98(%rsp)
leaq 0x1e22b6(%rip), %rdi    # 0x216740
leaq 0xe90(%rsp), %rsi
callq 0x30840
movq 0x1480(%rsp), %rsi
movl 0x147c(%rsp), %edx
subl $0x3, %edx
movl 0x1478(%rsp), %ecx
addl $0x1, %ecx
movl 0x1474(%rsp), %eax
addl $0x1, %eax
xorl %r8d, %r8d
subl %eax, %r8d
xorl %r9d, %r9d
subl 0x1474(%rsp), %r9d
leaq 0xea0(%rsp), %rdi
xorl %eax, %eax
movl $0x0, (%rsp)
movl $0x1, 0x8(%rsp)
movl $0x0, 0x10(%rsp)
callq 0x33ff0
movl %eax, %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, 0xe84(%rsp)
leaq 0x1e2238(%rip), %rdi    # 0x216740
callq 0x35700
movl 0xe84(%rsp), %eax
cmpl 0x1470(%rsp), %eax
jl 0x34530
movl 0x1470(%rsp), %eax
movl %eax, 0x1494(%rsp)
jmp 0x34f31
jmp 0x34532
testb $0x1, 0x146f(%rsp)
je 0x3465b
testb $0x1, 0x146e(%rsp)
jne 0x3465b
movq 0x1488(%rsp), %rdi
callq 0x28680
testb $0x1, %al
jne 0x3465b
movzwl 0x146a(%rsp), %eax
cmpl $0x0, %eax
jne 0x3465b
cmpl $0x5, 0x147c(%rsp)
jle 0x3465b
imull $0x3, 0x147c(%rsp), %eax
movl $0x4, %ecx
cltd
idivl %ecx
subl $0x2, %eax
movl %eax, 0xe80(%rsp)
movq 0x1488(%rsp), %rdi
movq 0x1480(%rsp), %rsi
movl 0xe80(%rsp), %edx
movl 0x1478(%rsp), %ecx
movl 0x1474(%rsp), %r8d
movl 0x1470(%rsp), %r9d
movb 0x146f(%rsp), %al
xorl %r10d, %r10d
andb $0x1, %al
movzbl %al, %eax
movl %eax, (%rsp)
movl $0x1, 0x8(%rsp)
movl $0x0, 0x10(%rsp)
callq 0x33ff0
movq 0x1488(%rsp), %rdi
callq 0x308b0
movq %rax, %rsi
leaq 0x21c088(%rip), %rdi    # 0x250690
callq 0x35760
movq %rax, 0x1460(%rsp)
movq 0x1460(%rsp), %rax
movq (%rax), %rax
movq %rax, 0xa0(%rsp)
movq 0x1488(%rsp), %rdi
callq 0x308b0
movq %rax, %rcx
movq 0xa0(%rsp), %rax
cmpq %rcx, %rax
jne 0x34659
movq 0x1460(%rsp), %rax
movw 0x8(%rax), %ax
movw %ax, 0x146a(%rsp)
jmp 0x3465b
movq 0x1488(%rsp), %rsi
movw 0x146a(%rsp), %ax
movl 0x1478(%rsp), %r8d
leaq 0x628(%rsp), %rdi
leaq 0x1e20be(%rip), %rcx    # 0x216740
xorl %r9d, %r9d
movzwl %ax, %edx
callq 0x26ba0
movl 0x1474(%rsp), %eax
movl %eax, 0x624(%rsp)
movl 0x1470(%rsp), %eax
movl %eax, 0x620(%rsp)
movl $0xffff3cb0, 0x614(%rsp) # imm = 0xFFFF3CB0
movb $0x1, 0x611(%rsp)
movl $0x0, 0x60c(%rsp)
leaq 0x628(%rsp), %rdi
callq 0x27210
movw %ax, 0x9e(%rsp)
jmp 0x346de
movw 0x9e(%rsp), %ax
movw %ax, 0x612(%rsp)
cmpw $0x0, %ax
je 0x34da8
movl 0x147c(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x61c(%rsp)
testb $0x1, 0x146f(%rsp)
jne 0x348b8
cmpl $0xffff8033, 0x614(%rsp) # imm = 0xFFFF8033
jle 0x348b8
movq 0x1488(%rsp), %rdi
callq 0x28680
movb %al, 0x9d(%rsp)
jmp 0x3473e
movb 0x9d(%rsp), %al
testb $0x1, %al
jne 0x348b8
jmp 0x3474f
movq 0x1488(%rsp), %rdi
movzwl 0x612(%rsp), %esi
callq 0x379e0
movb %al, 0x9c(%rsp)
jmp 0x3476d
movb 0x9c(%rsp), %al
testb $0x1, %al
jne 0x348b8
jmp 0x3477e
movq 0x1488(%rsp), %rdi
movq %rdi, 0x90(%rsp)
callq 0x24ca0
movl %eax, 0x98(%rsp)
jmp 0x3479c
movl 0x98(%rsp), %esi
movq 0x90(%rsp), %rdi
callq 0x357c0
movl %eax, 0x8c(%rsp)
jmp 0x347b9
movl 0x8c(%rsp), %eax
cmpl $0x0, %eax
je 0x348b8
cmpl $0x1, 0x147c(%rsp)
jne 0x34865
movq 0x1488(%rsp), %rdi
movzwl 0x612(%rsp), %esi
callq 0x29d30
movb %al, 0x8b(%rsp)
jmp 0x347f5
movb 0x8b(%rsp), %al
testb $0x1, %al
jne 0x34802
jmp 0x34865
movzwl 0x612(%rsp), %edi
callq 0x2a0c0
movb %al, 0x8a(%rsp)
jmp 0x34818
movb 0x8a(%rsp), %al
testb $0x1, %al
jne 0x34865
jmp 0x34825
movl 0x145c(%rsp), %eax
addl $0x12c, %eax            # imm = 0x12C
cmpl 0x624(%rsp), %eax
jge 0x34865
jmp 0x346c7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x600(%rsp)
movl %eax, 0x5fc(%rsp)
leaq 0x628(%rsp), %rdi
callq 0x263d0
jmp 0x34f40
cmpl $0x3, 0x147c(%rsp)
jge 0x348b6
movq 0x1488(%rsp), %rdi
movzwl 0x612(%rsp), %esi
callq 0x37ce0
movl %eax, 0x84(%rsp)
jmp 0x3488d
movl 0x84(%rsp), %eax
movl 0x147c(%rsp), %ecx
subl $0x1, %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
imull $0xffffff9c, %ecx, %ecx # imm = 0xFFFFFF9C
cmpl %ecx, %eax
jge 0x348b6
jmp 0x346c7
jmp 0x348b8
movq 0x1488(%rsp), %rsi
leaq 0xf0(%rsp), %rdi
callq 0x36210
jmp 0x348cf
movzwl 0x612(%rsp), %esi
leaq 0xf0(%rsp), %rdi
callq 0x38340
jmp 0x348e6
leaq 0xf0(%rsp), %rdi
callq 0x308b0
movq %rax, 0x78(%rsp)
jmp 0x348fa
movq 0x78(%rsp), %rax
movq %rax, 0xd8(%rsp)
leaq 0x612(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0x356c0
movq %rdx, 0x68(%rsp)
movw %ax, 0x76(%rsp)
jmp 0x34928
movq 0x68(%rsp), %rax
movw 0x76(%rsp), %cx
movw %cx, 0xe0(%rsp)
movq %rax, 0xe8(%rsp)
leaq 0x1e1df7(%rip), %rdi    # 0x216740
leaq 0xe0(%rsp), %rsi
callq 0x30840
jmp 0x34958
movl 0x60c(%rsp), %eax
incl %eax
movl %eax, 0x60c(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0x28680
movb %al, 0x67(%rsp)
jmp 0x3497b
movb 0x67(%rsp), %al
testb $0x1, %al
jne 0x34985
jmp 0x349a0
cmpl $0x1, 0x147c(%rsp)
jne 0x349a0
movl 0x61c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x61c(%rsp)
testb $0x1, 0x611(%rsp)
je 0x34a43
movw 0x612(%rsp), %ax
movw %ax, 0x146a(%rsp)
movq 0x1480(%rsp), %rsi
movl 0x61c(%rsp), %edx
movl 0x1478(%rsp), %ecx
incl %ecx
movl 0x620(%rsp), %r8d
negl %r8d
movl 0x624(%rsp), %r9d
negl %r9d
movzbl 0x146f(%rsp), %edi
movzbl 0x146e(%rsp), %r10d
andl $0x1, %r10d
movq %rsp, %rax
movl %r10d, 0x8(%rax)
andl $0x1, %edi
movl %edi, (%rax)
movl $0x0, 0x10(%rax)
leaq 0xf0(%rsp), %rdi
callq 0x33ff0
movl %eax, 0x60(%rsp)
jmp 0x34a27
movl 0x60(%rsp), %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, 0x618(%rsp)
movb $0x0, 0x611(%rsp)
jmp 0x34c7c
cmpl $0x3, 0x60c(%rsp)
jle 0x34b62
cmpl $0x2, 0x147c(%rsp)
jle 0x34b62
testb $0x1, 0x146f(%rsp)
jne 0x34b62
movq 0x1488(%rsp), %rdi
callq 0x28680
movb %al, 0x5f(%rsp)
jmp 0x34a80
movb 0x5f(%rsp), %al
testb $0x1, %al
jne 0x34b62
jmp 0x34a8e
leaq 0xf0(%rsp), %rdi
callq 0x28680
movb %al, 0x5e(%rsp)
jmp 0x34aa1
movb 0x5e(%rsp), %al
testb $0x1, %al
jne 0x34b62
jmp 0x34aaf
movq 0x1488(%rsp), %rdi
movzwl 0x612(%rsp), %esi
callq 0x2a0e0
movb %al, 0x5d(%rsp)
jmp 0x34aca
movb 0x5d(%rsp), %al
testb $0x1, %al
jne 0x34b62
jmp 0x34ad8
movzwl 0x612(%rsp), %edi
callq 0x2a0c0
movb %al, 0x5c(%rsp)
jmp 0x34aeb
movb 0x5c(%rsp), %al
testb $0x1, %al
jne 0x34b62
jmp 0x34af5
movq 0x1480(%rsp), %rsi
movl 0x61c(%rsp), %edx
decl %edx
movl 0x1478(%rsp), %ecx
incl %ecx
movl 0x624(%rsp), %r9d
movl %r9d, %r8d
notl %r8d
negl %r9d
movzbl 0x146e(%rsp), %edi
andl $0x1, %edi
movq %rsp, %rax
movl %edi, 0x8(%rax)
movl $0x0, 0x10(%rax)
movl $0x0, (%rax)
leaq 0xf0(%rsp), %rdi
callq 0x33ff0
movl %eax, 0x58(%rsp)
jmp 0x34b51
movl 0x58(%rsp), %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, 0x618(%rsp)
jmp 0x34b73
movl 0x624(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x618(%rsp)
movl 0x618(%rsp), %eax
cmpl 0x624(%rsp), %eax
jle 0x34bec
movq 0x1480(%rsp), %rsi
movl 0x61c(%rsp), %edx
movl 0x1478(%rsp), %ecx
incl %ecx
movl 0x624(%rsp), %r9d
movl %r9d, %r8d
notl %r8d
negl %r9d
movzbl 0x146e(%rsp), %edi
andl $0x1, %edi
movq %rsp, %rax
movl %edi, 0x8(%rax)
movl $0x0, 0x10(%rax)
movl $0x0, (%rax)
leaq 0xf0(%rsp), %rdi
callq 0x33ff0
movl %eax, 0x54(%rsp)
jmp 0x34bdd
movl 0x54(%rsp), %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, 0x618(%rsp)
movl 0x624(%rsp), %eax
cmpl 0x618(%rsp), %eax
jge 0x34c7a
movl 0x620(%rsp), %eax
cmpl 0x618(%rsp), %eax
jle 0x34c7a
movq 0x1480(%rsp), %rsi
movl 0x61c(%rsp), %edx
movl 0x1478(%rsp), %ecx
incl %ecx
movl 0x620(%rsp), %r8d
negl %r8d
movl 0x624(%rsp), %r9d
negl %r9d
movzbl 0x146e(%rsp), %edi
andl $0x1, %edi
movq %rsp, %rax
movl %edi, 0x8(%rax)
movl $0x0, 0x10(%rax)
movl $0x1, (%rax)
leaq 0xf0(%rsp), %rdi
callq 0x33ff0
movl %eax, 0x50(%rsp)
jmp 0x34c6b
movl 0x50(%rsp), %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, 0x618(%rsp)
jmp 0x34c7c
leaq 0x1e1abd(%rip), %rdi    # 0x216740
callq 0x35700
jmp 0x34c8a
movl 0x618(%rsp), %eax
cmpl 0x614(%rsp), %eax
jle 0x34cb8
movw 0x612(%rsp), %ax
movw %ax, 0x146a(%rsp)
movl 0x618(%rsp), %eax
movl %eax, 0x614(%rsp)
leaq 0x624(%rsp), %rdi
leaq 0x614(%rsp), %rsi
callq 0x35600
movq %rax, 0x48(%rsp)
jmp 0x34cd4
movq 0x48(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x624(%rsp)
movl 0x624(%rsp), %eax
cmpl 0x620(%rsp), %eax
jl 0x34d53
movl 0x620(%rsp), %eax
movl %eax, 0x624(%rsp)
movq 0x1488(%rsp), %rdi
movzwl 0x612(%rsp), %esi
callq 0x29d30
movb %al, 0x47(%rsp)
jmp 0x34d1b
movb 0x47(%rsp), %al
testb $0x1, %al
jne 0x34d25
jmp 0x34d51
movzwl 0x612(%rsp), %esi
movl 0x147c(%rsp), %edx
movl 0x1478(%rsp), %ecx
leaq 0x1e19fe(%rip), %rdi    # 0x216740
movl $0x1, %r8d
callq 0x35890
jmp 0x34d4f
jmp 0x34d51
jmp 0x34da8
movq 0x1488(%rsp), %rdi
movzwl 0x612(%rsp), %esi
callq 0x29d30
movb %al, 0x46(%rsp)
jmp 0x34d6e
movb 0x46(%rsp), %al
testb $0x1, %al
jne 0x34d78
jmp 0x34da1
movzwl 0x612(%rsp), %esi
movl 0x147c(%rsp), %edx
movl 0x1478(%rsp), %ecx
leaq 0x1e19ab(%rip), %rdi    # 0x216740
xorl %r8d, %r8d
callq 0x35890
jmp 0x34d9f
jmp 0x34da1
jmp 0x34da3
jmp 0x346c7
cmpl $0xffff3cb0, 0x614(%rsp) # imm = 0xFFFF3CB0
jne 0x34e07
movq 0x1488(%rsp), %rdi
callq 0x35730
movb %al, 0x45(%rsp)
jmp 0x34dc8
movb 0x45(%rsp), %al
testb $0x1, %al
jne 0x34dd2
jmp 0x34de4
movl 0x1478(%rsp), %eax
addl $0xffff8001, %eax       # imm = 0xFFFF8001
movl %eax, 0x40(%rsp)
jmp 0x34dec
xorl %eax, %eax
movl %eax, 0x40(%rsp)
jmp 0x34dec
movl 0x40(%rsp), %eax
movl %eax, 0x1494(%rsp)
movl $0x1, 0xd4(%rsp)
jmp 0x34f24
movl 0x624(%rsp), %eax
cmpl 0x1474(%rsp), %eax
jle 0x34e82
movl 0x624(%rsp), %eax
cmpl 0x620(%rsp), %eax
jge 0x34e82
movq 0x1480(%rsp), %rax
testb $0x1, 0x3a(%rax)
jne 0x34e82
movw 0x146a(%rsp), %ax
movw %ax, 0x36(%rsp)
movq 0x1488(%rsp), %rdi
callq 0x308b0
movq %rax, 0x38(%rsp)
jmp 0x34e56
movq 0x38(%rsp), %rdx
movw 0x36(%rsp), %ax
movl 0x1478(%rsp), %ecx
movl 0x624(%rsp), %r8d
movzwl %ax, %esi
leaq 0x1dc907(%rip), %rdi    # 0x211780
callq 0x25c70
jmp 0x34e80
jmp 0x34e82
movq 0x1488(%rsp), %rdi
callq 0x308b0
movq %rax, 0x28(%rsp)
jmp 0x34e96
movw 0x146a(%rsp), %ax
movw %ax, 0x26(%rsp)
movl 0x624(%rsp), %eax
cmpl 0x1474(%rsp), %eax
jg 0x34ebe
movl $0x2, %eax
movl %eax, 0x20(%rsp)
jmp 0x34edc
movl 0x624(%rsp), %edx
movl 0x620(%rsp), %esi
xorl %eax, %eax
movl $0x1, %ecx
cmpl %esi, %edx
cmovgel %ecx, %eax
movl %eax, 0x20(%rsp)
movq 0x28(%rsp), %rsi
movw 0x26(%rsp), %ax
movl 0x20(%rsp), %ecx
movl 0x147c(%rsp), %r8d
movl 0x624(%rsp), %r9d
movzwl %ax, %edx
leaq 0x21b78c(%rip), %rdi    # 0x250690
callq 0x35a00
jmp 0x34f0b
movl 0x624(%rsp), %eax
movl %eax, 0x1494(%rsp)
movl $0x1, 0xd4(%rsp)
leaq 0x628(%rsp), %rdi
callq 0x263d0
movl 0x1494(%rsp), %eax
addq $0x1498, %rsp           # imm = 0x1498
retq
movq 0x600(%rsp), %rdi
callq 0x54b0
nopl (%rax)