// File: /workspace/github_cpp_makefile_star2_O2/ATOMIC-LICHESS[P]ATOMKRAFT/position.cpp
// Function: Position::do_move(Move, StateInfo&, CheckInfo const&, bool)
void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveIsCheck) {

  assert(is_ok());
  assert(move_is_ok(m));
  assert(&newSt != st);

  nodes++;
  Key key = st->key;

  // Copy some fields of old state to our new StateInfo object except the
  // ones which are recalculated from scratch anyway, then switch our state
  // pointer to point to the new, ready to be updated, state.
  struct ReducedStateInfo {
    Key pawnKey, materialKey;
    int castleRights, rule50, gamePly, pliesFromNull;
    Square epSquare;
    Score value;
    Value npMaterial[2];
  };

  memcpy(&newSt, st, sizeof(ReducedStateInfo));

  newSt.previous = st;
  st = &newSt;

  // Save the current key to the history[] array, in order to be able to
  // detect repetition draws.
  history[st->gamePly++] = key;

  // Update side to move
  key ^= zobSideToMove;

  // Increment the 50 moves rule draw counter. Resetting it to zero in the
  // case of non-reversible moves is taken care of later.
  st->rule50++;
  st->pliesFromNull++;

  if (move_is_castle(m))
  {
      st->key = key;
      do_castle_move(m);
      return;
  }

  Color us = side_to_move();
  Color them = opposite_color(us);
  Square from = move_from(m);
  Square to = move_to(m);
  bool ep = move_is_ep(m);
  bool pm = move_is_promotion(m);

  Piece piece = piece_on(from);
  PieceType pt = type_of_piece(piece);
  PieceType capture = ep ? PAWN : type_of_piece_on(to);

  assert(color_of_piece_on(from) == us);
  assert(color_of_piece_on(to) == them || square_is_empty(to));
  assert(!(ep || pm) || piece == make_piece(us, PAWN));
  assert(!pm || relative_rank(us, to) == RANK_8);
  
  if (capture)
      do_capture_move(key, capture, them, to, from, ep);

  // Update hash key
  key ^= zobrist[us][pt][from] ^ zobrist[us][pt][to];

  // Reset en passant square
  if (st->epSquare != SQ_NONE)
  {
      key ^= zobEp[st->epSquare];
      st->epSquare = SQ_NONE;
  }

  // Update castle rights, try to shortcut a common case
  int cm = castleRightsMask[from] & castleRightsMask[to];
  NEW if (capture) cm &= expl_castleRightsMask[to];	// 
  if (cm != ALL_CASTLES && ((cm & st->castleRights) != st->castleRights))
  {
      key ^= zobCastle[st->castleRights];
      OLD st->castleRights &= castleRightsMask[from];
      OLD st->castleRights &= castleRightsMask[to];
      NEW st->castleRights &= cm;
      key ^= zobCastle[st->castleRights];
  }
  
  // TODO: PREFETCH
  // Prefetch TT access as soon as we know key is updated
  prefetch((char*)TT.first_entry(key));

  // Move the piece
  Bitboard move_bb = make_move_bb(from, to);
  do_move_bb(&(byColorBB[us]), move_bb);
  do_move_bb(&(byTypeBB[pt]), move_bb);
  do_move_bb(&(byTypeBB[0]), move_bb); // HACK: byTypeBB[0] == occupied squares

  board[to] = board[from];
  board[from] = PIECE_NONE;

  // Update piece lists, note that index[from] is not updated and
  // becomes stale. This works as long as index[] is accessed just
  // by known occupied squares.
  index[to] = index[from];
  pieceList[us][pt][index[to]] = to;

  // If the moving piece was a pawn do some special extra work
  if (pt == PAWN)
  {
      // Reset rule 50 draw counter
      st->rule50 = 0;

      // Update pawn hash key and prefetch in L1/L2 cache
      OLD st->pawnKey ^= zobrist[us][PAWN][from] ^ zobrist[us][PAWN][to];
      STARTNEW
      if (capture) {
    	  st->pawnKey ^= zobrist[us][PAWN][from];
      } else {
    	  st->pawnKey ^= zobrist[us][PAWN][from] ^ zobrist[us][PAWN][to];
      }
      ENDNEW

      // Set en passant square, only if moved pawn can be captured
      if ((to ^ from) == 16)
      {
          if (attacks_from<PAWN>(from + (us == WHITE ? DELTA_N : DELTA_S), us) & pieces(PAWN, them))
          {
              st->epSquare = Square((int(from) + int(to)) / 2);
              key ^= zobEp[st->epSquare];
          }
      }

      if (pm) // promotion ?
      //NEW if (pm && !capture)	// if capture the following code is unnecessary
      {
    	  NEW assert(!capture); // if capture the following code is unnecessary
    	  
          PieceType promotion = move_promotion_piece(m);

          assert(promotion >= KNIGHT && promotion <= QUEEN);

          // Insert promoted piece instead of pawn
          clear_bit(&(byTypeBB[PAWN]), to);
          set_bit(&(byTypeBB[promotion]), to);
          board[to] = make_piece(us, promotion);

          // Update piece counts
          pieceCount[us][promotion]++;
          pieceCount[us][PAWN]--;

          // Update material key
          st->materialKey ^= zobrist[us][PAWN][pieceCount[us][PAWN]];
          st->materialKey ^= zobrist[us][promotion][pieceCount[us][promotion]-1];

          // Update piece lists, move the last pawn at index[to] position
          // and shrink the list. Add a new promotion piece to the list.
          Square lastPawnSquare = pieceList[us][PAWN][pieceCount[us][PAWN]];
          index[lastPawnSquare] = index[to];
          pieceList[us][PAWN][index[lastPawnSquare]] = lastPawnSquare;
          pieceList[us][PAWN][pieceCount[us][PAWN]] = SQ_NONE;
          index[to] = pieceCount[us][promotion] - 1;
          pieceList[us][promotion][index[to]] = to;

          // Partially revert hash keys update
          key ^= zobrist[us][PAWN][to] ^ zobrist[us][promotion][to];
          st->pawnKey ^= zobrist[us][PAWN][to];

          // Partially revert and update incremental scores
          st->value -= pst(us, PAWN, to);
          st->value += pst(us, promotion, to);

          // Update material
          st->npMaterial[us] += PieceValueMidgame[promotion];
      }
  }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movl %esi, %r14d
movq %rdi, %rbx
incq 0x1930(%rdi)
movq 0x1938(%rdi), %rax
movq 0x38(%rax), %rdi
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups 0x20(%rax), %xmm2
movups %xmm2, 0x20(%rdx)
movups %xmm1, 0x10(%rdx)
movups %xmm0, (%rdx)
movq 0x1938(%rbx), %rax
movq %rax, 0x98(%rdx)
movq %rdx, 0x1938(%rbx)
movq 0x39a053(%rip), %rax    # 0x3b3210
xorq %rdi, %rax
movq %rax, 0x20(%rsp)
movq 0x14(%rdx), %xmm0
pshufd $0x55, %xmm0, %xmm1     # xmm1 = xmm0[1,1,1,1]
movd %xmm1, %esi
movslq %esi, %rsi
movq %rdi, 0x1098(%rbx,%rsi,8)
pcmpeqd %xmm1, %xmm1
psubd %xmm1, %xmm0
movq %xmm0, 0x14(%rdx)
incl 0x1c(%rdx)
movl $0xc000, %esi           # imm = 0xC000
movl %r14d, %r12d
andl %esi, %r12d
cmpl %esi, %r12d
jne 0x1921e
movq %rax, 0x38(%rdx)
movq %rbx, %rdi
movl %r14d, %esi
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x19942
movq %rcx, 0x78(%rsp)
movl 0x1090(%rbx), %esi
movq %rsi, %rcx
movq %rsi, 0x10(%rsp)
xorq $0x1, %rcx
movl %r14d, %r13d
shrl $0x6, %r13d
andl $0x3f, %r13d
movl %r14d, %r15d
andl $0x3f, %r15d
movl (%rbx,%r13,4), %esi
movq %rsi, 0x80(%rsp)
andl $0x7, %esi
movq %rsi, 0x18(%rsp)
cmpl $0x8000, %r12d          # imm = 0x8000
movl %r8d, 0x3c(%rsp)
movq %rcx, 0x58(%rsp)
jne 0x19274
pushq $0x1
popq %r8
jmp 0x19282
movl (%rbx,%r15,4), %r8d
andl $0x7, %r8d
je 0x1992e
xorl %eax, %eax
cmpl $0x8000, %r12d          # imm = 0x8000
sete %al
movl %eax, (%rsp)
leaq 0x20(%rsp), %rbp
movq %rbx, %rdi
movq %rbp, %rsi
movl %r8d, 0x2c(%rsp)
movl %r8d, %edx
movl %r15d, %r8d
movl %r13d, %r9d
callq 0x19ca0
movq (%rbp), %rax
movq 0x1938(%rbx), %rdx
movl $0x0, 0xc(%rsp)
movq 0x10(%rsp), %rsi
shlq $0xc, %rsi
leaq 0x397cbe(%rip), %rcx    # 0x3b0f90
movq %rsi, 0x30(%rsp)
addq %rcx, %rsi
movq 0x18(%rsp), %rcx
shll $0x9, %ecx
addq %rsi, %rcx
movq (%rcx,%r15,8), %rbp
xorq (%rcx,%r13,8), %rbp
xorq %rax, %rbp
movq %rbp, 0x20(%rsp)
movslq 0x20(%rdx), %rax
cmpq $0x40, %rax
je 0x19316
leaq 0x399c8a(%rip), %rcx    # 0x3b2f90
xorq (%rcx,%rax,8), %rbp
movq %rbp, 0x20(%rsp)
movl $0x40, 0x20(%rdx)
movl 0x1778(%rbx,%r15,4), %eax
andl 0x1778(%rbx,%r13,4), %eax
cmpb $0x0, 0xc(%rsp)
jne 0x19338
leaq 0x10bcc(%rip), %rcx     # 0x29f00
andl (%rcx,%r15,4), %eax
cmpl $0xf, %eax
movq %rsi, 0x48(%rsp)
je 0x19368
movslq 0x10(%rdx), %rcx
andl %ecx, %eax
cmpl %ecx, %eax
je 0x19368
leaq 0x399e3d(%rip), %rsi    # 0x3b3190
movq (%rsi,%rcx,8), %rcx
movl %eax, 0x10(%rdx)
cltq
xorq (%rsi,%rax,8), %rcx
xorq %rcx, %rbp
movq %rbp, 0x20(%rsp)
leaq 0x3ab371(%rip), %rax    # 0x3c46e0
movl (%rax), %edi
decl %edi
andl %ebp, %edi
shlq $0x6, %rdi
addq 0x8(%rax), %rdi
callq 0x131e7
leaq 0xf7e17(%rip), %r9      # 0x1111a0
movq (%r9,%r15,8), %rax
orq (%r9,%r13,8), %rax
movq 0x10(%rsp), %rsi
xorq %rax, 0x140(%rbx,%rsi,8)
movq 0x18(%rsp), %rdi
xorq %rax, 0x100(%rbx,%rdi,8)
xorq %rax, 0x100(%rbx)
leal (,%r13,4), %eax
movl (%rbx,%rax), %ecx
leal (,%r15,4), %edx
movl %ecx, (%rbx,%rdx)
movl $0x10, (%rbx,%rax)
movslq 0x590(%rbx,%rax), %rax
movl %eax, 0x590(%rbx,%rdx)
leaq 0x190(%rbx), %rcx
movq %rcx, 0x50(%rsp)
shlq $0x9, %rsi
movq %rsi, 0x40(%rsp)
leaq (%rbx,%rsi), %rcx
addq $0x190, %rcx            # imm = 0x190
movl %edi, %edx
shll $0x6, %edx
addq %rcx, %rdx
movl %r15d, (%rdx,%rax,4)
cmpl $0x1, %edi
jne 0x1964f
movq 0x1938(%rbx), %rax
andl $0x0, 0x14(%rax)
movq 0x48(%rsp), %r8
movq 0x200(%r8,%r13,8), %rcx
cmpb $0x0, 0xc(%rsp)
movq 0x58(%rsp), %rdi
je 0x19444
movq 0x200(%r8,%r15,8), %rdx
xorq (%rax), %rdx
jmp 0x19447
movq (%rax), %rdx
xorq %rcx, %rdx
movq %rdx, (%rax)
movl %r13d, %ecx
xorl %r15d, %ecx
cmpl $0x10, %ecx
jne 0x194af
xorl %ecx, %ecx
movq 0x10(%rsp), %rdx
testq %rdx, %rdx
sete %cl
shll $0x4, %ecx
addl %r13d, %ecx
leal 0x1(,%rdx,8), %edx
shlq $0x9, %rdx
addq 0x1bb5b(%rip), %rdx     # 0x34fd8
movq 0x108(%rbx), %rsi
andq -0x40(%rdx,%rcx,8), %rsi
testq %rsi, 0x140(%rbx,%rdi,8)
je 0x194af
leal (%r15,%r13), %ecx
shrb %cl
movzbl %cl, %ecx
movl %ecx, 0x20(%rax)
leaq 0x399aea(%rip), %rdx    # 0x3b2f90
xorq (%rdx,%rcx,8), %rbp
movq %rbp, 0x20(%rsp)
cmpl $0x4000, %r12d          # imm = 0x4000
jne 0x1964f
shrl $0xc, %r14d
andl $0x3, %r14d
leal 0x2(%r14), %r8d
leal (,%r15,8), %edx
movq %rdx, 0x70(%rsp)
leaq 0xf7ed4(%rip), %rcx     # 0x1113b0
movq (%rcx,%rdx), %rcx
andq %rcx, 0x108(%rbx)
movq (%r9,%rdx), %rcx
orq %rcx, 0x100(%rbx,%r8,8)
movq 0x10(%rsp), %r9
leal (%r14,%r9,8), %ecx
addl $0x2, %ecx
leal (,%r15,4), %edx
movq %rdx, 0x68(%rsp)
movl %ecx, (%rbx,%rdx)
shlq $0x5, %r9
leaq (%rbx,%r9), %r10
leal 0x8(,%r14,4), %edx
movq %rdx, 0x60(%rsp)
movslq 0x150(%rdx,%r10), %r11
leal 0x1(%r11), %r14d
movl %r14d, 0x150(%rdx,%r10)
movslq 0x154(%rbx,%r9), %r14
leaq -0x1(%r14), %rsi
movl %esi, 0x154(%rbx,%r9)
movl %r8d, %esi
shll $0x9, %esi
leaq 0x397a37(%rip), %rdi    # 0x3b0f90
addq %rsi, %rdi
addq 0x30(%rsp), %rdi
movq 0x8(%rax), %rsi
movq 0x48(%rsp), %rdx
xorq 0x1f8(%rdx,%r14,8), %rsi
movq %rsi, 0x8(%rax)
xorq (%rdi,%r11,8), %rsi
movq %rsi, 0x8(%rax)
movq 0x50(%rsp), %rsi
movq 0x40(%rsp), %r11
addq %r11, %rsi
movslq 0x3c(%rsi,%r14,4), %r11
movq %rax, 0x30(%rsp)
movq 0x68(%rsp), %rax
movslq 0x590(%rbx,%rax), %r14
movl %r14d, 0x590(%rbx,%r11,4)
movl %r11d, 0x40(%rsi,%r14,4)
movslq 0x154(%rbx,%r9), %r9
movl $0x40, 0x40(%rsi,%r9,4)
movq 0x60(%rsp), %r11
movslq 0x150(%r11,%r10), %r9
leaq -0x1(%r9), %r10
movq %rax, %r14
movl %r10d, 0x590(%rbx,%rax)
shll $0x6, %r8d
addq %rsi, %r8
movl %r15d, -0x4(%r8,%r9,4)
movq 0x70(%rsp), %r8
movq 0x200(%rdx,%r8), %rsi
xorq (%r8,%rdi), %rbp
xorq %rsi, %rbp
movq %rbp, 0x20(%rsp)
movq 0x30(%rsp), %rax
xorq %rsi, (%rax)
movq 0x10(%rsp), %r9
leal 0x1(,%r9,8), %esi
shlq $0x8, %rsi
leaq 0x399bff(%rip), %rdi    # 0x3b3220
addq %rdi, %rsi
movl 0x24(%rax), %r8d
subl (%r14,%rsi), %r8d
shlq $0x8, %rcx
addq %rdi, %rcx
movl %r8d, 0x24(%rax)
addl (%r14,%rcx), %r8d
movl %r8d, 0x24(%rax)
leaq 0x39abda(%rip), %rcx    # 0x3b4220
movl (%r11,%rcx), %ecx
addl %ecx, 0x28(%rax,%r9,4)
cmpb $0x0, 0xc(%rsp)
jne 0x19676
leaq 0x20(%rsp), %r14
movq %rbx, %rdi
movq %r14, %rsi
movq 0x10(%rsp), %rdx
movl %r15d, %ecx
movq 0x18(%rsp), %r8
callq 0x19ece
movq (%r14), %rbp
movslq 0x192c(%rbx), %rax
imulq $0x560, %rax, %rax      # imm = 0x560
leaq 0x3a0405(%rip), %r14    # 0x3b9a90
leaq (%r14,%rax), %rdi
addq $0x58, %rdi
movq 0x1938(%rbx), %rax
movq (%rax), %rsi
callq 0x1ae30
movslq 0x192c(%rbx), %rax
imulq $0x560, %rax, %rax      # imm = 0x560
leaq (%r14,%rax), %rdi
addq $0x40, %rdi
movq 0x1938(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x1ae46
movq 0x80(%rsp), %rcx
shlq $0x8, %rcx
leaq 0x399b45(%rip), %rax    # 0x3b3220
addq %rcx, %rax
movl (%rax,%r15,4), %edx
subl (%rax,%r13,4), %edx
movq 0x1938(%rbx), %rcx
addl %edx, 0x24(%rcx)
movl 0x2c(%rsp), %eax
movl %eax, 0x30(%rcx)
movq 0x18(%rsp), %rax
movl %eax, 0x34(%rcx)
movq %rbp, 0x38(%rcx)
andq $0x0, 0x40(%rcx)
movl 0x58(%rsp), %eax
movq %rax, %rdx
shlq $0x5, %rdx
cmpl $0x0, 0x168(%rbx,%rdx)
sete %dl
movl 0x3c(%rsp), %esi
xorb $0x1, %sil
orb %dl, %sil
jne 0x198f8
cmpl $0x4000, %r12d          # imm = 0x4000
setne %dl
shlq $0x9, %rax
movq 0x50(%rsp), %rsi
movslq 0x180(%rsi,%rax), %r14
testb %dl, 0xc(%rsp)
je 0x1983e
cmpl $0x6, 0x18(%rsp)
jne 0x19787
movl %r13d, %eax
shll $0x6, %eax
addq 0x1b820(%rip), %rax     # 0x34f88
cmpb $0x0, (%r14,%rax)
je 0x19787
movl %r15d, %eax
shll $0x6, %eax
addq 0x1b80c(%rip), %rax     # 0x34f88
cmpb $0x0, (%r14,%rax)
je 0x19861
leaq 0xf7a12(%rip), %rsi     # 0x1111a0
movq (%rsi,%r15,8), %rax
movq 0x78(%rsp), %r14
movq 0x18(%rsp), %rdx
testq %rax, 0x8(%r14,%rdx,8)
je 0x197a7
movq %rax, 0x40(%rcx)
movq (%r14), %rax
testq %rax, %rax
je 0x198f8
testq %rax, (%rsi,%r13,8)
je 0x198f8
cmpl $0x4, 0x18(%rsp)
je 0x19804
movl 0x48(%r14), %esi
movq %rbx, %rdi
callq 0x12330
movq 0x128(%rbx), %rcx
orq 0x120(%rbx), %rcx
movq 0x10(%rsp), %rdx
andq 0x140(%rbx,%rdx,8), %rax
andq %rcx, %rax
movq 0x1938(%rbx), %rcx
orq %rax, 0x40(%rcx)
cmpl $0x3, 0x18(%rsp)
je 0x198f8
movl 0x48(%r14), %esi
movq %rbx, %rdi
callq 0xcf20
movq 0x128(%rbx), %rcx
orq 0x118(%rbx), %rcx
movq 0x10(%rsp), %rdx
andq 0x140(%rbx,%rdx,8), %rax
andq %rcx, %rax
movq 0x1938(%rbx), %rcx
orq %rax, 0x40(%rcx)
jmp 0x198f8
movq 0x40(%rsp), %rdx
movslq 0x180(%rsi,%rdx), %rax
shlq $0x6, %rax
addq 0x1b732(%rip), %rax     # 0x34f88
cmpb $0x0, (%r14,%rax)
jne 0x198f8
leaq 0xf7ee8(%rip), %rax     # 0x111750
movq 0x110(%rbx), %r12
movq 0x140(%rbx), %rcx
andq 0x1200(%rax,%r14,8), %rcx
movq 0x148(%rbx), %r15
andq 0x200(%rax,%r14,8), %r15
orq %rcx, %r15
andq 0x108(%rbx), %r15
andq 0x400(%rax,%r14,8), %r12
movq %rbx, %rdi
movl %r14d, %esi
callq 0x12330
movq 0x128(%rbx), %r13
orq 0x120(%rbx), %r13
andq %rax, %r13
orq %r12, %r13
movq %rbx, %rdi
movl %r14d, %esi
callq 0xcf20
movq 0x128(%rbx), %rdx
orq 0x118(%rbx), %rdx
andq %rax, %rdx
orq %r13, %rdx
orq %r15, %rdx
movq 0x10(%rsp), %rax
andq 0x140(%rbx,%rax,8), %rdx
movq 0x1938(%rbx), %rcx
movq %rdx, 0x40(%rcx)
movl 0x1090(%rbx), %eax
movl %eax, %edx
xorl $0x1, %edx
movl %edx, 0x1090(%rbx)
movl 0x39a9d1(%rip), %edx    # 0x3b42e0
movl %edx, %esi
negl %esi
cmpl $0x1, %eax
cmovel %edx, %esi
addl %esi, 0x24(%rcx)
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x0, 0x2c(%rsp)
movb $0x1, %cl
movl %ecx, 0xc(%rsp)
jmp 0x192c2
nop