// File: /workspace/github_cpp_makefile_star2_O3/ATOMIC-LICHESS[P]ATOMKRAFT/position.cpp
// Function: unsigned long Position::hidden_checkers<true>(Color) const
Bitboard Position::hidden_checkers(Color c) const {
  
  STARTNEW
  // no kings, no checks
  if (piece_count(c, KING) == 0 || piece_count(opposite_color(c), KING) == 0) {
	  return EmptyBoardBB;
  }
  
  // if kings touch there are neither pinned pieces nor discovered check candidates
  Square ksq1 = king_square(c);
  Square ksq2 = king_square(opposite_color(c));
  if (squares_touch[ksq1][ksq2]) {
	  return EmptyBoardBB;
  }
  ENDNEW
	
  Bitboard result = EmptyBoardBB;
  Bitboard pinners = pieces_of_color(FindPinned ? opposite_color(c) : c);

  // Pinned pieces protect our king, dicovery checks attack
  // the enemy king.
  NEW assert(piece_count(FindPinned ? c : opposite_color(c), KING));
  Square ksq = king_square(FindPinned ? c : opposite_color(c));

  // Pinners are sliders, not checkers, that give check when candidate pinned is removed
  pinners &= (  (pieces(ROOK, QUEEN) & RookPseudoAttacks[ksq]) 
		      | (pieces(BISHOP, QUEEN) & BishopPseudoAttacks[ksq])  );

  if (FindPinned && pinners)
      pinners &= ~st->checkersBB;
  

  while (pinners)
  {
      Square s = pop_1st_bit(&pinners);
      Bitboard b = squares_between(s, ksq) & occupied_squares();
      
      STARTNEW //DEBUG
#ifndef NDEBUG
      if (!b) {
    	  cout << "FindPinned: " << FindPinned << endl;
    	  Bitboard aux_pinners = pieces_of_color(FindPinned ? opposite_color(c) : c);
    	  aux_pinners &= (pieces(ROOK, QUEEN) & RookPseudoAttacks[ksq]) | (pieces(BISHOP, QUEEN) & BishopPseudoAttacks[ksq]);
    	  if (FindPinned && aux_pinners)
    	        aux_pinners &= ~st->checkersBB;
    	  
    	  print_bb(aux_pinners);
    	  print_debuginfo(*this);
      }
#endif
      ENDNEW
      
      assert(b);
      
      NEW // TODO: this is an often seen and difficult error, 
      NEW // to avoid problems in the release version return 0
      NEW if (!b) return EmptyBoardBB;

      if (  !(b & (b - 1)) // Only one bit set?
          && (b & pieces_of_color(c))) // Is an our piece?
          result |= b;
  }
  return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %esi, %r12d
movq %r12, %rax
shlq $0x5, %rax
cmpl $0x0, 0x168(%rdi,%rax)
je 0x2144f
movq %rdi, %rbx
leaq 0x150(%rdi), %rax
xorl $0x1, %esi
movq %rsi, %rcx
shlq $0x5, %rcx
cmpl $0x0, 0x18(%rax,%rcx)
je 0x2144f
movq %r12, %rax
shlq $0x9, %rax
movslq 0x310(%rbx,%rax), %r13
movq %rsi, %rax
shlq $0x9, %rax
movslq 0x310(%rbx,%rax), %rax
movq %r13, %rcx
shlq $0x6, %rcx
addq 0x1bbde(%rip), %rcx     # 0x3cf78
cmpb $0x0, (%rax,%rcx)
jne 0x2144f
movq 0x128(%rbx), %rax
movq 0x120(%rbx), %rcx
orq %rax, %rcx
leaq 0x103194(%rip), %rdx    # 0x124550
andq (%rdx,%r13,8), %rcx
orq 0x118(%rbx), %rax
leaq 0x102f82(%rip), %rdx    # 0x124350
andq (%rdx,%r13,8), %rax
orq %rcx, %rax
andq 0x140(%rbx,%rsi,8), %rax
movq %rax, (%rsp)
je 0x213f8
movq 0x1938(%rbx), %rcx
movq 0x40(%rcx), %rcx
notq %rcx
andq %rcx, %rax
movq %rax, (%rsp)
movq %rsp, %r15
leaq 0xfa34e(%rip), %rbp     # 0x11b750
xorl %r14d, %r14d
cmpq $0x0, (%rsp)
je 0x21452
movq %r15, %rdi
callq 0x827b
movslq %eax, %rcx
shlq $0x9, %rcx
addq %rbp, %rcx
movq 0x100(%rbx), %rax
andq (%rcx,%r13,8), %rax
leaq -0x1(%rax), %rcx
movq %rax, %rdx
xorq %rcx, %rdx
cmpq %rcx, %rdx
jbe 0x2144a
movq 0x140(%rbx,%r12,8), %rcx
andq %rax, %rcx
cmovneq %rax, %rcx
orq %rcx, %r14
testq %rax, %rax
jne 0x21405
xorl %r14d, %r14d
movq %r14, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq