// File: 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:
subq $0x68, %rsp
movq %rdi, 0x58(%rsp)
movl %esi, 0x54(%rsp)
movq 0x58(%rsp), %rdi
movq %rdi, 0x20(%rsp)
movl 0x54(%rsp), %esi
movl $0x6, %edx
callq 0x164c0
cmpl $0x0, %eax
je 0x3e219
movl 0x54(%rsp), %edi
callq 0x122b0
movq 0x20(%rsp), %rdi
movl %eax, %esi
movl $0x6, %edx
callq 0x164c0
cmpl $0x0, %eax
jne 0x3e227
movq $0x0, 0x60(%rsp)
jmp 0x3e3f4
movq 0x20(%rsp), %rdi
movl 0x54(%rsp), %esi
callq 0x1b250
movl %eax, 0x50(%rsp)
movl 0x54(%rsp), %edi
callq 0x122b0
movq 0x20(%rsp), %rdi
movl %eax, %esi
callq 0x1b250
movl %eax, 0x4c(%rsp)
movslq 0x50(%rsp), %rcx
leaq 0x2f642(%rip), %rax     # 0x6d8a0
shlq $0x6, %rcx
addq %rcx, %rax
movslq 0x4c(%rsp), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x3e27e
movq $0x0, 0x60(%rsp)
jmp 0x3e3f4
movq $0x0, 0x40(%rsp)
movl 0x54(%rsp), %edi
callq 0x122b0
movq 0x20(%rsp), %rdi
movl %eax, %esi
callq 0x298c0
movq 0x20(%rsp), %rdi
movq %rax, 0x38(%rsp)
movl 0x54(%rsp), %esi
callq 0x1b250
movq 0x20(%rsp), %rdi
movl %eax, 0x34(%rsp)
movl $0x4, %esi
movl $0x5, %edx
callq 0x33a90
movq 0x20(%rsp), %rdi
movslq 0x34(%rsp), %rdx
leaq 0x115388(%rip), %rcx    # 0x153660
andq (%rcx,%rdx,8), %rax
movq %rax, 0x18(%rsp)
movl $0x3, %esi
movl $0x5, %edx
callq 0x33a90
movq %rax, %rcx
movq 0x18(%rsp), %rax
movslq 0x34(%rsp), %rsi
leaq 0x11515c(%rip), %rdx    # 0x153460
andq (%rdx,%rsi,8), %rcx
orq %rcx, %rax
andq 0x38(%rsp), %rax
movq %rax, 0x38(%rsp)
cmpq $0x0, 0x38(%rsp)
je 0x3e33b
movq 0x20(%rsp), %rax
movq 0x1938(%rax), %rax
movq 0x40(%rax), %rax
xorq $-0x1, %rax
andq 0x38(%rsp), %rax
movq %rax, 0x38(%rsp)
jmp 0x3e33d
cmpq $0x0, 0x38(%rsp)
je 0x3e3ea
leaq 0x38(%rsp), %rdi
callq 0xd940
movl %eax, 0x30(%rsp)
movl 0x30(%rsp), %edi
movl 0x34(%rsp), %esi
callq 0x339d0
movq 0x20(%rsp), %rdi
movq %rax, 0x10(%rsp)
callq 0xf510
movq %rax, %rcx
movq 0x10(%rsp), %rax
andq %rcx, %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, 0x28(%rsp)
jne 0x3e396
movq $0x0, 0x60(%rsp)
jmp 0x3e3f4
movq 0x28(%rsp), %rax
movq 0x28(%rsp), %rcx
subq $0x1, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
jne 0x3e3e5
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rax
movq %rax, 0x8(%rsp)
movl 0x54(%rsp), %esi
callq 0x298c0
movq %rax, %rcx
movq 0x8(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x3e3e5
movq 0x28(%rsp), %rax
orq 0x40(%rsp), %rax
movq %rax, 0x40(%rsp)
jmp 0x3e33d
movq 0x40(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
addq $0x68, %rsp
retq
nop