// File: SethKasmann[P]clever-girl/src/state.cpp
// Function: State::isLegal(unsigned short) const
bool State::isLegal(Move pMove) const
{
    Square src = getSrc(pMove);
    Square dst = getDst(pMove);

// -------------------------------------------------------------------------- //
//                                                                            //
// Check if the piece is pinned. If so, confirm it is moving along it's       //
// pin ray.                                                                   //
//                                                                            //
// -------------------------------------------------------------------------- //
    if (square_bb[src] & mPinned[mUs]
        && !(coplanar[src][dst] & getPieceBB<king>(mUs)))
        return false;

// -------------------------------------------------------------------------- //
//                                                                            //
// Check for en-passant. Remove both the attacking pawn and the captured      //
// pawn from the occupancy and see if the king is left in check. This avoids  //
// the rare scenario where both pawns are pinned to the king by a slider.     //
//                                                                            //
// -------------------------------------------------------------------------- //
    if (onSquare(src) == pawn && square_bb[dst] & mEnPassant)
    {
        U64 change = mUs == white ? square_bb[src] | square_bb[dst - 8]
                                  : square_bb[src] | square_bb[dst + 8];
        if (check(change))
            return false;
    }

// -------------------------------------------------------------------------- //
//                                                                            //
// Check for king non-castling king moves. See if the king is left in check   //
// after the move is made. Since castling moves are a more difficult case     //
// only legal castling moves are generated.                                   //
//                                                                            //
// -------------------------------------------------------------------------- //
    if (onSquare(src) == king && !isCastle(pMove))
    {
        U64 change = square_bb[src];
        if (isAttacked(dst, mUs, change))
            return false;
    }

    assert(dst != getKingSquare(mThem));
    assert((square_bb[dst] & mOccupancy[mUs]) == 0);

    return true;
}

// Assembly:
subq $0x68, %rsp
movw %si, %ax
movq %rdi, 0x58(%rsp)
movw %ax, 0x56(%rsp)
movq 0x58(%rsp), %rax
movq %rax, 0x28(%rsp)
movzwl 0x56(%rsp), %edi
callq 0x26810
movl %eax, 0x50(%rsp)
movzwl 0x56(%rsp), %edi
callq 0x26830
movl %eax, %ecx
movq 0x28(%rsp), %rax
movl %ecx, 0x4c(%rsp)
movl 0x50(%rsp), %ecx
movl %ecx, %edx
leaq 0x11da75(%rip), %rcx    # 0x154b10
movq (%rcx,%rdx,8), %rcx
movq %rcx, 0x30(%rsp)
movq %rax, %rdi
addq $0x68, %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0x25890
movq %rax, %rcx
movq 0x30(%rsp), %rax
andq (%rcx), %rax
cmpq $0x0, %rax
je 0x3710d
movq 0x28(%rsp), %rdi
movl 0x50(%rsp), %eax
movl %eax, %ecx
leaq 0x136c39(%rip), %rax    # 0x16dd10
shlq $0x9, %rcx
addq %rcx, %rax
movl 0x4c(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movq %rax, 0x20(%rsp)
movl (%rdi), %esi
callq 0x25510
movq %rax, %rcx
movq 0x20(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
jne 0x3710d
movb $0x0, 0x67(%rsp)
jmp 0x3725a
movq 0x28(%rsp), %rdi
movl 0x50(%rsp), %esi
callq 0x29bd0
cmpl $0x0, %eax
jne 0x371fa
movq 0x28(%rsp), %rcx
movl 0x4c(%rsp), %eax
movl %eax, %edx
leaq 0x11d9da(%rip), %rax    # 0x154b10
movq (%rax,%rdx,8), %rax
andq 0x30(%rcx), %rax
cmpq $0x0, %rax
je 0x371fa
movq 0x28(%rsp), %rax
cmpl $0x0, (%rax)
jne 0x37193
movl 0x50(%rsp), %eax
movl %eax, %ecx
leaq 0x11d9b1(%rip), %rax    # 0x154b10
movq (%rax,%rcx,8), %rax
movq %rax, 0x10(%rsp)
movl 0x4c(%rsp), %edi
movl $0x8, %esi
callq 0x24e80
movl %eax, %ecx
movq 0x10(%rsp), %rax
movl %ecx, %ecx
movl %ecx, %edx
leaq 0x11d988(%rip), %rcx    # 0x154b10
orq (%rcx,%rdx,8), %rax
movq %rax, 0x18(%rsp)
jmp 0x371d2
movl 0x50(%rsp), %eax
movl %eax, %ecx
leaq 0x11d970(%rip), %rax    # 0x154b10
movq (%rax,%rcx,8), %rax
movq %rax, 0x8(%rsp)
movl 0x4c(%rsp), %edi
movl $0x8, %esi
callq 0x24e60
movl %eax, %ecx
movq 0x8(%rsp), %rax
movl %ecx, %ecx
movl %ecx, %edx
leaq 0x11d947(%rip), %rcx    # 0x154b10
orq (%rcx,%rdx,8), %rax
movq %rax, 0x18(%rsp)
movq 0x28(%rsp), %rdi
movq 0x18(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rsi
callq 0x3a020
testb $0x1, %al
jne 0x371f1
jmp 0x371f8
movb $0x0, 0x67(%rsp)
jmp 0x3725a
jmp 0x371fa
movq 0x28(%rsp), %rdi
movl 0x50(%rsp), %esi
callq 0x29bd0
cmpl $0x5, %eax
jne 0x37255
movzwl 0x56(%rsp), %edi
callq 0x3a1d0
testb $0x1, %al
jne 0x37255
movq 0x28(%rsp), %rdi
movl 0x50(%rsp), %eax
movl %eax, %ecx
leaq 0x11d8e3(%rip), %rax    # 0x154b10
movq (%rax,%rcx,8), %rax
movq %rax, 0x38(%rsp)
movl 0x4c(%rsp), %esi
movl (%rdi), %edx
movq 0x38(%rsp), %rcx
callq 0x3a1f0
testb $0x1, %al
jne 0x3724c
jmp 0x37253
movb $0x0, 0x67(%rsp)
jmp 0x3725a
jmp 0x37255
movb $0x1, 0x67(%rsp)
movb 0x67(%rsp), %al
andb $0x1, %al
addq $0x68, %rsp
retq
nopw %cs:(%rax,%rax)