// File: /workspace/github_cpp_makefile_star2_O3/ATOMIC-LICHESS[P]ATOMKRAFT/pawns.cpp
// Function: Score PawnInfoTable::evaluate_pawns<(Color)1>(Position const&, unsigned long, unsigned long, PawnInfo*)
Score PawnInfoTable::evaluate_pawns(const Position& pos, Bitboard ourPawns,
                                    Bitboard theirPawns, PawnInfo* pi) {

  const BitCountType Max15 = CpuIs64Bit ? CNT64_MAX15 : CNT32_MAX15;
  const Color Them = (Us == WHITE ? BLACK : WHITE);

  Bitboard b;
  Square s;
  File f;
  Rank r;
  bool passed, isolated, doubled, opposed, chain, backward, candidate;
  Score value = SCORE_ZERO;
  const Square* ptr = pos.piece_list_begin(Us, PAWN);
  
  NEW const Square opp_ksq = pos.king_square(Them);

  // Loop through all pawns of the current color and score each pawn
  while ((s = *ptr++) != SQ_NONE)
  {
      assert(pos.piece_on(s) == make_piece(Us, PAWN));

      f = square_file(s);
      r = square_rank(s);
      
      STARTNEW
      // pawn tropism
      //if (useImprovements) {
	    value += PawnTropism[square_dist(s, opp_ksq)];
      //}
      ENDNEW

      // This file cannot be half open
      pi->halfOpenFiles[Us] &= ~(1 << f);

      // Our rank plus previous one. Used for chain detection
      b = rank_bb(r) | rank_bb(Us == WHITE ? r - Rank(1) : r + Rank(1));

      // Flag the pawn as passed, isolated, doubled or member of a pawn
      // chain (but not the backward one).
      passed   = !(theirPawns & passed_pawn_mask(Us, s));
      doubled  =   ourPawns   & squares_in_front_of(Us, s);
      opposed  =   theirPawns & squares_in_front_of(Us, s);
      isolated = !(ourPawns   & neighboring_files_bb(f));
      chain    =   ourPawns   & neighboring_files_bb(f) & b;

      // Test for backward pawn
      backward = false;

      // If the pawn is passed, isolated, or member of a pawn chain it cannot
      // be backward. If there are friendly pawns behind on neighboring files
      // or if can capture an enemy pawn it cannot be backward either.
      if (   !(passed | isolated | chain)
          && !(ourPawns & attack_span_mask(Them, s))
          && !(pos.attacks_from<PAWN>(s, Us) & theirPawns))
      {
          // We now know that there are no friendly pawns beside or behind this
          // pawn on neighboring files. We now check whether the pawn is
          // backward by looking in the forward direction on the neighboring
          // files, and seeing whether we meet a friendly or an enemy pawn first.
          b = pos.attacks_from<PAWN>(s, Us);

          // Note that we are sure to find something because pawn is not passed
          // nor isolated, so loop is potentially infinite, but it isn't.
          while (!(b & (ourPawns | theirPawns)))
              Us == WHITE ? b <<= 8 : b >>= 8;

          // The friendly pawn needs to be at least two ranks closer than the
          // enemy pawn in order to help the potentially backward pawn advance.
          backward = (b | (Us == WHITE ? b << 8 : b >> 8)) & theirPawns;
      }

      assert(opposed | passed | (attack_span_mask(Us, s) & theirPawns));

      // A not passed pawn is a candidate to become passed if it is free to
      // advance and if the number of friendly pawns beside or behind this
      // pawn on neighboring files is higher or equal than the number of
      // enemy pawns in the forward direction on the neighboring files.
      candidate =   !(opposed | passed | backward | isolated)
                 && (b = attack_span_mask(Them, s + pawn_push(Us)) & ourPawns) != EmptyBoardBB
                 &&  count_1s<Max15>(b) >= count_1s<Max15>(attack_span_mask(Us, s) & theirPawns);

      // Passed pawns will be properly scored in evaluation because we need
      // full attack info to evaluate passed pawns. Only the frontmost passed
      // pawn on each file is considered a true passed pawn.
      if (passed && !doubled)
          set_bit(&(pi->passedPawns[Us]), s);

      // Score this pawn
      OLD if (isolated)
          value -= IsolatedPawnPenalty[opposed][f];

      OLD if (doubled)
          value -= DoubledPawnPenalty[opposed][f];

      if (backward)
          value -= BackwardPawnPenalty[opposed][f];

      OLD if (chain)
          value += ChainBonus[f];

      if (candidate) {
          OLD value += CandidateBonus[relative_rank(Us, s)];
          NEW value += 3 * CandidateBonus[relative_rank(Us, s)] / 2;
      }
  }
  return value;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rcx, -0x10(%rsp)
movl 0x3d0(%rdi), %ebx
xorl %eax, %eax
cmpl $0x40, %ebx
je 0x1c530
movq %rsi, %r12
movslq 0x310(%rdi), %rax
movq %rax, -0x8(%rsp)
addq $0x3d4, %rdi            # imm = 0x3D4
movq %rdx, %rcx
orq %rsi, %rcx
movq -0x10(%rsp), %rax
movl 0x38(%rax), %r10d
xorl %eax, %eax
movdqa 0x1677b(%rip), %xmm0    # 0x32a10
movdqa 0x16783(%rip), %xmm1    # 0x32a20
movdqa 0x1678b(%rip), %xmm2    # 0x32a30
movl %ebx, %r15d
andl $0x7, %r15d
movslq %ebx, %rbp
sarl $0x3, %ebx
movq %rbp, %r11
shlq $0x6, %r11
addq 0x20cd8(%rip), %r11     # 0x3cf98
movq -0x8(%rsp), %r8
movsbq (%r8,%r11), %r11
leaq 0x397cef(%rip), %r8     # 0x3b3fc0
addl (%r8,%r11,4), %eax
movl %eax, -0x14(%rsp)
btrl %r15d, %r10d
movq -0x10(%rsp), %r8
movl %r10d, 0x38(%r8)
leaq 0xfd363(%rip), %rax     # 0x119650
movq (%rax,%r15,8), %r11
xorl %eax, %eax
leaq 0x107856(%rip), %rsi    # 0x123b50
movq 0x200(%rsi,%rbp,8), %r14
andq %rdx, %r14
je 0x1c371
movq %r11, %r13
andq %r12, %r13
je 0x1c371
movslq %ebx, %r8
leaq 0xfd2f7(%rip), %r9      # 0x119610
movq %r12, %rsi
movq %r9, %r12
movq 0x8(%r9,%r8,8), %r9
orq (%r12,%r8,8), %r9
movq %rsi, %r12
andq %r13, %r9
jne 0x1c371
leaq 0x107c19(%rip), %rax    # 0x123f50
testq %r12, (%rax,%rbp,8)
je 0x1c341
xorl %eax, %eax
jmp 0x1c371
leaq 0xfd408(%rip), %rax     # 0x119750
movq 0x1200(%rax,%rbp,8), %r12
testq %rdx, %r12
je 0x1c359
xorl %eax, %eax
jmp 0x1c36e
movq %r12, %r13
shrq $0x8, %r12
testq %rcx, %r13
je 0x1c359
orq %r13, %r12
testq %rdx, %r12
setne %al
movq %rsi, %r12
leaq 0x1073d8(%rip), %rsi    # 0x123750
movq 0x200(%rsi,%rbp,8), %r13
testq %r12, %r11
je 0x1c470
testq %r14, %r14
je 0x1c470
movq %r13, %r8
andq %rdx, %r8
jne 0x1c470
testb %al, %al
jne 0x1c470
leaq 0x107ba3(%rip), %rsi    # 0x123f50
movq -0x40(%rsi,%rbp,8), %r11
andq %r12, %r11
je 0x1c48f
movq 0x200(%rsi,%rbp,8), %r8
andq %rdx, %r8
movq %r8, %xmm3
movq %r11, %xmm4
punpcklqdq %xmm3, %xmm4    # xmm4 = xmm4[0],xmm3[0]
movdqa %xmm4, %xmm3
psrlq $0x20, %xmm3
pshufd $0xe8, %xmm3, %xmm3     # xmm3 = xmm3[0,2,2,3]
pshufd $0xe8, %xmm4, %xmm5     # xmm5 = xmm4[0,2,2,3]
movdqa %xmm5, %xmm6
psrld $0x1, %xmm6
pand %xmm0, %xmm6
psubd %xmm6, %xmm5
psrlq $0x21, %xmm4
pshufd $0xe8, %xmm4, %xmm4     # xmm4 = xmm4[0,2,2,3]
pand %xmm0, %xmm4
psubd %xmm4, %xmm3
movdqa %xmm5, %xmm4
psrld $0x2, %xmm4
pand %xmm1, %xmm4
pand %xmm1, %xmm5
movdqa %xmm3, %xmm6
psrld $0x2, %xmm6
pand %xmm1, %xmm6
pand %xmm1, %xmm3
paddd %xmm5, %xmm3
paddd %xmm4, %xmm3
paddd %xmm6, %xmm3
pshufd $0xf5, %xmm3, %xmm4     # xmm4 = xmm3[1,1,3,3]
pmuludq %xmm2, %xmm3
pshufd $0xe8, %xmm3, %xmm3     # xmm3 = xmm3[0,2,2,3]
pmuludq %xmm2, %xmm4
pshufd $0xe8, %xmm4, %xmm4     # xmm4 = xmm4[0,2,2,3]
punpckldq %xmm4, %xmm3    # xmm3 = xmm3[0],xmm4[0],xmm3[1],xmm4[1]
psrld $0x1c, %xmm3
movd %xmm3, %r8d
pshufd $0x55, %xmm3, %xmm3     # xmm3 = xmm3[1,1,1,1]
movd %xmm3, %r9d
cmpl %r9d, %r8d
setae %r11b
jmp 0x1c492
movq %r13, %r8
andq %r12, %r8
orq %r14, %r8
jne 0x1c48f
leaq 0xfcd1e(%rip), %rsi     # 0x1191a0
movq (%rsi,%rbp,8), %r8
movq -0x10(%rsp), %r9
orq %r8, 0x10(%r9)
xorl %r11d, %r11d
testb %al, %al
je 0x1c4b8
xorl %r8d, %r8d
testq %rdx, %r13
setne %r8b
shll $0x5, %r8d
leaq 0x397a85(%rip), %rax    # 0x3b3f30
addq %rax, %r8
movl -0x14(%rsp), %eax
subl (%r8,%r15,4), %eax
jmp 0x1c4bc
movl -0x14(%rsp), %eax
testb %r11b, %r11b
je 0x1c521
xorl $0x7, %ebx
movslq %ebx, %r8
leaq 0x397ac2(%rip), %rsi    # 0x3b3f90
movl (%rsi,%r8,4), %r8d
leal (%r8,%r8,2), %r8d
movl $0x8000, %esi           # imm = 0x8000
leal (%r8,%rsi), %r9d
movl %r9d, %r11d
shrl $0x10, %r11d
shrl $0x1f, %r9d
addl %r11d, %r9d
movswl %r9w, %r9d
movl %r8d, %r11d
andl $0x7fff, %r11d          # imm = 0x7FFF
andl %esi, %r8d
subl %r8d, %r11d
movzwl %r11w, %r8d
shrl $0xf, %r8d
addl %r11d, %r8d
movswl %r8w, %r8d
sarl %r8d
andl $-0x2, %r9d
shll $0xf, %r9d
addl %r8d, %r9d
addl %r9d, %eax
movl (%rdi), %ebx
addq $0x4, %rdi
cmpl $0x40, %ebx
jne 0x1c2a5
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop