// File: /workspace/github_cpp_makefile_star2_O3/bjohnsonfl[P]Overhead-Chess-Engine-/position.cpp
// Function: position::legal(move) const
bool position::legal (move m) const
{
    /*
     Much inspiration from stockfish in this function
     A move is legal if the king is not exposed or left in check.
     In movegeneration, only castling tests for legality, all other moves must be checked.
     If our king is in check, evasions are created, but we need to check that the king doesnt move into check.
     All king moves, except castling, needs to make sure it doesnt move into check.
     All other moves cannot be pinned except moving torwards or away from the king.
     En Passent needs to be checked for exposing the 5th (4th for black) rank in check.
     */
    
    player us  = get_sideToPlay();
    player them = player(!us);
    square from = source_sq(m);
    square to = destination_sq(m);
    square kingSq = get_king_sq(us);
    bitboard kingSqBB = get_king(us);
    bitboard piece = squareBitMask[from];
    
    //King moves
    if(kingSqBB & piece)
    {
      return (move_flag(m) == castling) || !(squareAttackedBy(to) & get_pieces(them));
    }
    
    if(move_flag(m) == enPass)
    {
        bitboard newOccupied = 0;
        square theirPawn = empty;
        theirPawn = square_to_rank(to) == rank_6 ? square( get_enPassent() + south ) :
                                                   square( get_enPassent() + nort );
        newOccupied = get_pieces() ^ squareBitMask[from] ^ squareBitMask[to] ^ squareBitMask[theirPawn];
        //printBitboard(newOccupied);
        bitboard rookQueen = sliderAttacks(kingSq, newOccupied, p_rook) & get_pieces(p_rook, p_queen) & get_pieces(them);
        bitboard bishopQueen = sliderAttacks(kingSq, newOccupied, p_bishop) & get_pieces(p_bishop, p_queen) & get_pieces(them);
        return !rookQueen && !bishopQueen;
    }
    
    return !(get_pinned(us) & squareBitMask[from]) || (lineSqBitMask[from][to] & kingSqBB);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movl %esi, %eax
movq %rdi, %rbx
movl 0x17c(%rdi), %ecx
movl %esi, %edx
andl $0x3f, %edx
shrl $0x6, %esi
andl $0x3f, %esi
addq $0x128, %rdi            # imm = 0x128
bsfq 0x128(%rbx), %r8
bsfq 0x158(%rbx), %r14
leaq 0x158(%rbx), %r9
testq %rcx, %rcx
cmovel %r8d, %r14d
cmoveq %rdi, %r9
movq (%r9), %r9
leaq 0x643c(%rip), %r8       # 0xbde0
movq (%r8,%rdx,8), %rdi
movl %eax, %r10d
andl $0xc000, %r10d          # imm = 0xC000
testq %r9, %rdi
je 0x59e5
movb $0x1, %al
cmpl $0x8000, %r10d          # imm = 0x8000
je 0x5aa5
xorl %r14d, %r14d
testq %rcx, %rcx
sete %r14b
movq %rbx, %rdi
callq 0x57e6
testq %rax, 0x160(%rbx,%r14,8)
jmp 0x5aa2
cmpl $0x4000, %r10d          # imm = 0x4000
jne 0x5aaf
xorl %r12d, %r12d
testq %rcx, %rcx
sete %r12b
andl $0xe00, %eax            # imm = 0xE00
xorl %ecx, %ecx
cmpl $0xa00, %eax            # imm = 0xA00
setne %cl
movq 0x170(%rbx), %r15
movq 0x188(%rbx), %rax
movl 0x4(%rax), %eax
shll $0x4, %ecx
movl %esi, %edx
xorq (%r8,%rdx,8), %r15
addl %ecx, %eax
addl $-0x8, %eax
xorq (%r8,%rax,8), %r15
xorq %rdi, %r15
movl %r14d, %edi
movq %r15, %rsi
movl $0x3, %edx
callq 0x357e
movq 0x148(%rbx), %r13
orq 0x118(%rbx), %r13
orq 0x120(%rbx), %r13
orq 0x150(%rbx), %r13
andq %rax, %r13
andq 0x160(%rbx,%r12,8), %r13
movl %r14d, %edi
movq %r15, %rsi
movl $0x2, %edx
callq 0x357e
movq 0x140(%rbx), %rcx
orq 0x110(%rbx), %rcx
orq 0x120(%rbx), %rcx
orq 0x150(%rbx), %rcx
andq %rax, %rcx
andq 0x160(%rbx,%r12,8), %rcx
orq %r13, %rcx
sete %al
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
movq 0x188(%rbx), %rax
testq %rdi, 0x20(%rax,%rcx,8)
je 0x5ad2
shll $0x9, %edx
addq 0x5509(%rip), %rdx      # 0xafd0
movl %esi, %eax
testq %r9, (%rdx,%rax,8)
setne %al
jmp 0x5aa5
movb $0x1, %al
jmp 0x5aa5