// File: /workspace/github_cpp_makefile_star2_O3/ATOMIC-LICHESS[P]ATOMKRAFT/endgame.cpp
// Function: Endgame<ScaleFactor, (EndgameType)10>::apply(Position const&) const
ScaleFactor Endgame<ScaleFactor, KBPsK>::apply(const Position& pos) const {

  assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
  assert(pos.piece_count(strongerSide, BISHOP) == 1);
  assert(pos.piece_count(strongerSide, PAWN) >= 1);

  // No assertions about the material of weakerSide, because we want draws to
  // be detected even when the weaker side has some pawns.

  Bitboard pawns = pos.pieces(PAWN, strongerSide);
  File pawnFile = square_file(pos.piece_list(strongerSide, PAWN, 0));

  // All pawns are on a single rook file ?
  if (   (pawnFile == FILE_A || pawnFile == FILE_H)
      && (pawns & ~file_bb(pawnFile)) == EmptyBoardBB)
  {
      Square bishopSq = pos.piece_list(strongerSide, BISHOP, 0);
      Square queeningSq = relative_square(strongerSide, make_square(pawnFile, RANK_8));
      Square kingSq = pos.king_square(weakerSide);

      if (   opposite_color_squares(queeningSq, bishopSq)
          && abs(square_file(kingSq) - pawnFile) <= 1)
      {
          // The bishop has the wrong color, and the defending king is on the
          // file of the pawn(s) or the neighboring file. Find the rank of the
          // frontmost pawn.
          Rank rank;
          if (strongerSide == WHITE)
          {
              for (rank = RANK_7; (rank_bb(rank) & pawns) == EmptyBoardBB; rank--) {}
              assert(rank >= RANK_2 && rank <= RANK_7);
          }
          else
          {
              for (rank = RANK_2; (rank_bb(rank) & pawns) == EmptyBoardBB; rank++) {}
              rank = Rank(rank ^ 7);  // HACK to get the relative rank
              assert(rank >= RANK_2 && rank <= RANK_7);
          }
          // If the defending king has distance 1 to the promotion square or
          // is placed somewhere in front of the pawn, it's a draw.
          if (   square_distance(kingSq, queeningSq) <= 1
              || relative_rank(strongerSide, kingSq) >= rank)
              return SCALE_FACTOR_ZERO;
      }
  }
  return SCALE_FACTOR_NONE;
}

// Assembly:
movl 0x8(%rdi), %ecx
movq 0x140(%rsi,%rcx,8), %rdx
andq 0x108(%rsi), %rdx
movq %rcx, %r10
shlq $0x9, %r10
movl 0x1d0(%rsi,%r10), %r9d
andl $0x7, %r9d
movl $0xff, %eax
cmpq $0x7, %r9
je 0xc731
testl %r9d, %r9d
jne 0xc744
leaq 0x10ce98(%rip), %r8     # 0x1195d0
movq (%r8,%r9,8), %r8
notq %r8
testq %r8, %rdx
je 0xc745
retq
addq $0x190, %rsi            # imm = 0x190
leal 0x38(%r9), %r11d
imull $0x38, %ecx, %r8d
xorl %r11d, %r8d
movl 0xc0(%rsi,%r10), %r10d
xorl %r8d, %r10d
movl %r10d, %r11d
shrl $0x3, %r11d
xorl %r10d, %r11d
testb $0x1, %r11b
je 0xc744
movl 0xc(%rdi), %edi
shlq $0x9, %rdi
movl 0x180(%rsi,%rdi), %esi
movl %esi, %r10d
andl $0x7, %r10d
subl %r9d, %r10d
movl %r10d, %edi
negl %edi
cmovsl %r10d, %edi
cmpl $0x1, %edi
ja 0xc744
testq %rcx, %rcx
je 0xc7ba
xorl %r9d, %r9d
leaq 0x10ce69(%rip), %r10    # 0x119610
movq %r9, %r11
incq %r9
testq %rdx, 0x8(%r10,%r11,8)
je 0xc7a7
xorl $0x7, %r9d
jmp 0xc7d6
movl $0x6, %r9d
leaq 0x10ce49(%rip), %r10    # 0x119610
movq %r9, %r11
decq %r9
testq %rdx, (%r10,%r11,8)
je 0xc7c7
incl %r9d
sarl $0x3, %esi
sarl $0x3, %r8d
movl %esi, %edx
subl %r8d, %edx
movl %edx, %r8d
negl %r8d
cmovsl %edx, %r8d
cmpl %r8d, %edi
cmoval %edi, %r8d
cmpl $0x2, %r8d
jb 0xc80d
leal (,%rcx,8), %edx
subl %ecx, %edx
xorl %edx, %esi
cmpl %r9d, %esi
jl 0xc744
xorl %eax, %eax
retq