// File: /workspace/github_cpp_makefile_star2_O2/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rax
movq %rdi, %r14
movl 0x8(%rdi), %edx
movq 0x140(%rsi,%rdx,8), %rcx
andq 0x108(%rsi), %rcx
movq %rdx, %r8
shlq $0x9, %r8
movl 0x1d0(%rsi,%r8), %edi
andl $0x7, %edi
movl $0xff, %ebx
cmpq $0x7, %rdi
je 0xb626
testl %edi, %edi
jne 0xb6e4
leaq 0x105fa3(%rip), %rsi    # 0x1115d0
movq (%rsi,%rdi,8), %rsi
notq %rsi
testq %rsi, %rcx
jne 0xb6e4
addq $0x190, %rax            # imm = 0x190
leal 0x38(%rdi), %r9d
imull $0x38, %edx, %esi
xorl %r9d, %esi
movl 0xc0(%rax,%r8), %r8d
xorl %esi, %r8d
movl %r8d, %r9d
shrl $0x3, %r9d
xorl %r8d, %r9d
testb $0x1, %r9b
je 0xb6e4
movl 0xc(%r14), %r8d
shlq $0x9, %r8
movl 0x180(%rax,%r8), %ebp
movl %ebp, %eax
andl $0x7, %eax
subl %edi, %eax
movl %eax, %edi
negl %edi
cmovsl %eax, %edi
cmpl $0x1, %edi
ja 0xb6e4
testq %rdx, %rdx
je 0xb6ad
xorl %r15d, %r15d
leaq 0x105f76(%rip), %rax    # 0x111610
movq %r15, %rdx
incq %r15
testq %rcx, 0x8(%rax,%rdx,8)
je 0xb69a
xorl $0x7, %r15d
jmp 0xb6c7
pushq $0x6
popq %r15
leaq 0x105f58(%rip), %rax    # 0x111610
movq %r15, %rdx
decq %r15
testq %rcx, (%rax,%rdx,8)
je 0xb6b8
incl %r15d
movl %ebp, %edi
callq 0x75ec
cmpl $0x2, %eax
jl 0xb6e2
sarl $0x3, %ebp
imull $0x7, 0x8(%r14), %eax
xorl %ebp, %eax
cmpl %r15d, %eax
jl 0xb6e4
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
nop