// File: /workspace/github_cpp_makefile_star2_O3/ATOMIC-LICHESS[P]ATOMKRAFT/position.cpp
// Function: Position::undo_move(Move)
void Position::undo_move(Move m) {

  assert(is_ok());
  assert(move_is_ok(m));

  sideToMove = opposite_color(sideToMove);

  if (move_is_castle(m))
  {
      undo_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);
  
  STARTNEW
  if (st->capturedType) {
	  // Restore the attacking piece 
	  restore_piece(us, to, st->attackingType);
  }
  ENDNEW
  
  PieceType pt = type_of_piece_on(to);

  assert(square_is_empty(from));
  assert(color_of_piece_on(to) == us);
  //NEW assert(st->capturedType ? color_of_piece_on(to) == COLOR_NONE : color_of_piece_on(to) == us);
  assert(!pm || relative_rank(us, to) == RANK_8);
  assert(!ep || to == st->previous->epSquare);
  assert(!ep || relative_rank(us, to) == RANK_6);
  assert(!ep || piece_on(to) == make_piece(us, PAWN));

  if (pm) // promotion ?
  {
	  NEW assert(!st->capturedType); // a promotion with capture is not possible in atomic 
      PieceType promotion = move_promotion_piece(m);
      pt = PAWN;

      assert(promotion >= KNIGHT && promotion <= QUEEN);
      assert(piece_on(to) == make_piece(us, promotion));

      // Replace promoted piece with a pawn
      clear_bit(&(byTypeBB[promotion]), to);
      set_bit(&(byTypeBB[PAWN]), to);

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

      // Update piece list replacing promotion piece with a pawn
      Square lastPromotionSquare = pieceList[us][promotion][pieceCount[us][promotion]];
      index[lastPromotionSquare] = index[to];
      pieceList[us][promotion][index[lastPromotionSquare]] = lastPromotionSquare;
      pieceList[us][promotion][pieceCount[us][promotion]] = SQ_NONE;
      index[to] = pieceCount[us][PAWN] - 1;
      pieceList[us][PAWN][index[to]] = to;
  }
	  
  
  // Put the piece back at the source square
  Bitboard move_bb = make_move_bb(to, from);
  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[from] = make_piece(us, pt);
  board[to] = PIECE_NONE;

  // Update piece list
  index[from] = index[to];
  pieceList[us][pt][index[from]] = from;

  if (st->capturedType)
  {
      Square capsq = to;

      if (ep)
          capsq = (us == WHITE)? (to - DELTA_N) : (to - DELTA_S);

      assert(st->capturedType != KING);
      assert(!ep || square_is_empty(capsq));

      // Restore the captured piece
      set_bit(&(byColorBB[them]), capsq);
      set_bit(&(byTypeBB[st->capturedType]), capsq);
      set_bit(&(byTypeBB[0]), capsq);

      board[capsq] = make_piece(them, st->capturedType);

      // Update piece count
      pieceCount[them][st->capturedType]++;

      // Update piece list, add a new captured piece in capsq square
      index[capsq] = pieceCount[them][st->capturedType] - 1;
      pieceList[them][st->capturedType][index[capsq]] = capsq;
      
      STARTNEW
      // the first obligatory piece was restored above, TODO: merge this
      Color color;
      Square square;
      PieceType type;
      
      for (int k = 1; k < st->expl.size; ++k) {
    	  color = color_of_piece(st->expl.piece[k]);
    	  type = type_of_piece(st->expl.piece[k]);
    	  square = st->expl.square[k];
    	  restore_piece(color, square, type);
      }
      ENDNEW
  }

  // Finally point our state pointer back to the previous state
  st = st->previous;

  assert(is_ok());
}

// Assembly:
movl %esi, %r8d
movl 0x1090(%rdi), %ecx
movq %rcx, %r10
xorq $0x1, %r10
movl %r10d, 0x1090(%rdi)
movl $0xc000, %eax           # imm = 0xC000
movl %esi, %r9d
andl %eax, %r9d
cmpl %eax, %r9d
jne 0x20549
movl %r8d, %esi
jmp 0x208b8
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movl %r8d, %r11d
shrl $0x6, %r11d
movl %r8d, %esi
andl $0x3f, %esi
movq 0x1938(%rdi), %rax
movl 0x30(%rax), %edx
movq %rdx, -0x8(%rsp)
testq %rdx, %rdx
je 0x205f8
movl 0x34(%rax), %r15d
movl %esi, %ebx
leaq 0xf8c1b(%rip), %r14     # 0x1191a0
movq (%r14,%rbx,8), %r12
orq %r12, 0x140(%rdi,%r10,8)
movq (%r14,%rbx,8), %r12
orq %r12, 0x100(%rdi,%r15,8)
movq (%r14,%rbx,8), %r14
orq %r14, 0x100(%rdi)
leal (,%r10,8), %r14d
orl %r15d, %r14d
movl %r14d, (%rdi,%rbx,4)
movq %r10, %r12
shlq $0x5, %r12
addq %rdi, %r12
movslq 0x150(%r12,%r15,4), %r13
leal 0x1(%r13), %ebp
movl %ebp, 0x150(%r12,%r15,4)
movl %r13d, 0x590(%rdi,%rbx,4)
movq %r10, %r12
shlq $0x9, %r12
addq %rdi, %r12
shlq $0x6, %r15
addq %r12, %r15
movl %esi, 0x190(%r15,%r13,4)
jmp 0x205fe
movl %esi, %ebx
movl (%rdi,%rbx,4), %r14d
movl %esi, -0xc(%rsp)
andl $0x3f, %r11d
cmpl $0x4000, %r9d           # imm = 0x4000
jne 0x206e2
shrl $0xc, %r8d
andl $0x3, %r8d
addl $0x2, %r8d
leal (,%rbx,8), %r14d
leaq 0xf8d82(%rip), %r15     # 0x1193b0
movq (%r15,%r14), %r15
andq %r15, 0x100(%rdi,%r8,8)
leaq 0xf8b5f(%rip), %r15     # 0x1191a0
movq (%r15,%r14), %r14
orq %r14, 0x108(%rdi)
movl %r10d, %r15d
movq %r15, %r14
shlq $0x5, %r14
leaq (%rdi,%r14), %r12
movslq 0x150(%r12,%r8,4), %r13
leaq -0x1(%r13), %rbp
movl %ebp, 0x150(%r12,%r8,4)
incl 0x154(%rdi,%r14)
movq %r15, %rbp
shlq $0x9, %rbp
addq %rdi, %rbp
movl %r8d, %esi
shll $0x6, %esi
addq %rbp, %rsi
addq $0x190, %rsi            # imm = 0x190
movslq -0x4(%rsi,%r13,4), %r13
movslq 0x590(%rdi,%rbx,4), %rdx
movl %edx, 0x590(%rdi,%r13,4)
movl %r13d, (%rsi,%rdx,4)
movslq 0x150(%r12,%r8,4), %rdx
movl $0x40, (%rsi,%rdx,4)
movslq 0x154(%rdi,%r14), %rdx
leaq -0x1(%rdx), %r13
movl %r13d, 0x590(%rdi,%rbx,4)
movl -0xc(%rsp), %esi
movl %esi, 0x1cc(%rbp,%rdx,4)
movl $0x1, %r14d
movl %r13d, %ebp
jmp 0x206f3
andl $0x7, %r14d
movl 0x590(%rdi,%rbx,4), %ebp
movl %r10d, %r15d
movslq %ebp, %r13
leaq 0xf8aa6(%rip), %rsi     # 0x1191a0
movl %r11d, %edx
movq (%rsi,%rdx,8), %r12
orq (%rsi,%rbx,8), %r12
xorq %r12, 0x140(%rdi,%r15,8)
movl %r14d, %r8d
xorq %r12, 0x100(%rdi,%r8,8)
xorq 0x100(%rdi), %r12
shlq $0x9, %r15
leaq (%rdi,%r15), %r8
addq $0x190, %r8             # imm = 0x190
movl %r14d, %r15d
shll $0x6, %r15d
addq %r8, %r15
movq %r12, 0x100(%rdi)
leal (%r14,%r10,8), %r8d
movl %r8d, (%rdi,%rdx,4)
movl $0x10, (%rdi,%rbx,4)
movl %ebp, 0x590(%rdi,%rdx,4)
movl %r11d, (%r15,%r13,4)
movq -0x8(%rsp), %rbx
testq %rbx, %rbx
je 0x2089e
leaq 0x190(%rdi), %r10
cmpl $0x8000, %r9d           # imm = 0x8000
jne 0x20785
cmpl $0x1, %ecx
jne 0x2078b
movl -0xc(%rsp), %edx
addl $-0x8, %edx
jmp 0x20792
movl -0xc(%rsp), %edx
jmp 0x20792
movl -0xc(%rsp), %edx
addl $0x8, %edx
movslq %edx, %r8
movq (%rsi,%r8,8), %rdx
orq %rdx, 0x140(%rdi,%rcx,8)
movq (%rsi,%r8,8), %rdx
orq %rdx, 0x100(%rdi,%rbx,8)
orq (%rsi,%r8,8), %r12
movq %r12, 0x100(%rdi)
leal (,%rcx,8), %edx
orl %ebx, %edx
movl %edx, (%rdi,%r8,4)
movq %rcx, %rdx
shlq $0x5, %rdx
addq %rdi, %rdx
addq $0x150, %rdx            # imm = 0x150
movslq (%rdx,%rbx,4), %r9
leal 0x1(%r9), %r11d
movl %r11d, (%rdx,%rbx,4)
movl %r9d, 0x590(%rdi,%r8,4)
shlq $0x9, %rcx
addq %r10, %rcx
shlq $0x6, %rbx
addq %rcx, %rbx
movl %r8d, (%rbx,%r9,4)
cmpl $0x2, 0x90(%rax)
jl 0x2089e
leaq 0x150(%rdi), %rcx
movl $0x13, %edx
movl 0x24(%rax,%rdx,4), %r11d
movl %r11d, %r8d
sarl $0x3, %r8d
movl %r11d, %r9d
andl $0x7, %r9d
movslq (%rax,%rdx,4), %rbx
movq (%rsi,%rbx,8), %r14
orq %r14, 0x140(%rdi,%r8,8)
movq (%rsi,%rbx,8), %r14
orq %r14, 0x100(%rdi,%r9,8)
movq (%rsi,%rbx,8), %r14
orq %r14, 0x100(%rdi)
movl %r11d, (%rdi,%rbx,4)
movq %r8, %r11
shlq $0x5, %r11
addq %rcx, %r11
movslq (%r11,%r9,4), %r14
leal 0x1(%r14), %ebp
movl %ebp, (%r11,%r9,4)
movl %r14d, 0x590(%rdi,%rbx,4)
shlq $0x9, %r8
addq %r10, %r8
shll $0x6, %r9d
addq %r8, %r9
movl %ebx, (%r9,%r14,4)
movslq 0x90(%rax), %r8
leaq 0x1(%rdx), %r9
addq $-0x11, %rdx
cmpq %r8, %rdx
movq %r9, %rdx
jl 0x20815
movq 0x98(%rax), %rax
movq %rax, 0x1938(%rdi)
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop