// File: /workspace/github_cpp_makefile_star2_O2/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 0x69e0(%rip), %r8       # 0xbde0
movq (%r8,%rdx,8), %rdi
movl %eax, %r10d
andl $0xc000, %r10d          # imm = 0xC000
testq %r9, %rdi
je 0x5441
movb $0x1, %al
cmpl $0x8000, %r10d          # imm = 0x8000
je 0x54fd
xorl %r14d, %r14d
testq %rcx, %rcx
sete %r14b
movq %rbx, %rdi
callq 0x525a
testq %rax, 0x160(%rbx,%r14,8)
jmp 0x54fa
cmpl $0x4000, %r10d          # imm = 0x4000
jne 0x5507
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
pushq $0x3
popq %rdx
movl %r14d, %edi
movq %r15, %rsi
callq 0x33a4
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
pushq $0x2
popq %rdx
movl %r14d, %edi
movq %r15, %rsi
callq 0x33a4
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 0x552a
shll $0x9, %edx
addq 0x5ab1(%rip), %rdx      # 0xafd0
movl %esi, %eax
testq %r9, (%rdx,%rax,8)
setne %al
jmp 0x54fd
movb $0x1, %al
jmp 0x54fd