// File: ATOMIC-LICHESS[P]ATOMKRAFT/position.cpp
// Function: Position::flip()
void Position::flip() {

  assert(is_ok());

  // Make a copy of current position before to start changing
  const Position pos(*this, threadID);

  clear();
  threadID = pos.thread();

  // Board
  for (Square s = SQ_A1; s <= SQ_H8; s++)
      if (!pos.square_is_empty(s))
          put_piece(Piece(pos.piece_on(s) ^ 8), flip_square(s));

  // Side to move
  sideToMove = opposite_color(pos.side_to_move());

  // Castling rights
  if (pos.can_castle_kingside(WHITE))  do_allow_oo(BLACK);
  if (pos.can_castle_queenside(WHITE)) do_allow_ooo(BLACK);
  if (pos.can_castle_kingside(BLACK))  do_allow_oo(WHITE);
  if (pos.can_castle_queenside(BLACK)) do_allow_ooo(WHITE);

  initialKFile  = pos.initialKFile;
  initialKRFile = pos.initialKRFile;
  initialQRFile = pos.initialQRFile;

  castleRightsMask[make_square(initialKFile,  RANK_1)] ^= (WHITE_OO | WHITE_OOO);
  castleRightsMask[make_square(initialKFile,  RANK_8)] ^= (BLACK_OO | BLACK_OOO);
  castleRightsMask[make_square(initialKRFile, RANK_1)] ^=  WHITE_OO;
  castleRightsMask[make_square(initialKRFile, RANK_8)] ^=  BLACK_OO;
  castleRightsMask[make_square(initialQRFile, RANK_1)] ^=  WHITE_OOO;
  castleRightsMask[make_square(initialQRFile, RANK_8)] ^=  BLACK_OOO;

  // En passant square
  if (pos.st->epSquare != SQ_NONE)
      st->epSquare = flip_square(pos.st->epSquare);

  // Checkers
  find_checkers();

  // Hash keys
  st->key = compute_key();
  st->pawnKey = compute_pawn_key();
  st->materialKey = compute_material_key();

  // Incremental scores
  st->value = compute_value();

  // Material
  st->npMaterial[WHITE] = compute_non_pawn_material(WHITE);
  st->npMaterial[BLACK] = compute_non_pawn_material(BLACK);

  assert(is_ok());
}

// Assembly:
subq $0x1968, %rsp           # imm = 0x1968
movq %rdi, 0x1960(%rsp)
movq 0x1960(%rsp), %rsi
movq %rsi, 0x10(%rsp)
movl 0x192c(%rsi), %edx
leaq 0x20(%rsp), %rdi
callq 0x36460
movq 0x10(%rsp), %rdi
callq 0x36f10
leaq 0x20(%rsp), %rdi
callq 0x297f0
movl %eax, %ecx
movq 0x10(%rsp), %rax
movl %ecx, 0x192c(%rax)
movl $0x0, 0x1c(%rsp)
cmpl $0x3f, 0x1c(%rsp)
jg 0x3d88c
movl 0x1c(%rsp), %esi
leaq 0x20(%rsp), %rdi
callq 0x29b30
testb $0x1, %al
jne 0x3d87c
movl 0x1c(%rsp), %esi
leaq 0x20(%rsp), %rdi
callq 0xf530
xorl $0x8, %eax
movl %eax, 0xc(%rsp)
movl 0x1c(%rsp), %edi
callq 0x1b2f0
movq 0x10(%rsp), %rdi
movl 0xc(%rsp), %esi
movl %eax, %edx
callq 0x370f0
jmp 0x3d87e
leaq 0x1c(%rsp), %rdi
xorl %esi, %esi
callq 0xe5c0
jmp 0x3d835
leaq 0x20(%rsp), %rdi
callq 0xf5d0
movl %eax, %edi
callq 0x122b0
movl %eax, %ecx
movq 0x10(%rsp), %rax
movl %ecx, 0x1090(%rax)
leaq 0x20(%rsp), %rdi
xorl %esi, %esi
callq 0xf550
testb $0x1, %al
jne 0x3d8bc
jmp 0x3d8cb
movq 0x10(%rsp), %rdi
movl $0x1, %esi
callq 0x3dff0
leaq 0x20(%rsp), %rdi
xorl %esi, %esi
callq 0xf580
testb $0x1, %al
jne 0x3d8dd
jmp 0x3d8ec
movq 0x10(%rsp), %rdi
movl $0x1, %esi
callq 0x3e050
leaq 0x20(%rsp), %rdi
movl $0x1, %esi
callq 0xf550
testb $0x1, %al
jne 0x3d901
jmp 0x3d90d
movq 0x10(%rsp), %rdi
xorl %esi, %esi
callq 0x3dff0
leaq 0x20(%rsp), %rdi
movl $0x1, %esi
callq 0xf580
testb $0x1, %al
jne 0x3d922
jmp 0x3d92e
movq 0x10(%rsp), %rdi
xorl %esi, %esi
callq 0x3e050
movq 0x10(%rsp), %rax
movl 0x1938(%rsp), %ecx
movl %ecx, 0x1918(%rax)
movl 0x193c(%rsp), %ecx
movl %ecx, 0x191c(%rax)
movl 0x1940(%rsp), %ecx
movl %ecx, 0x1920(%rax)
movl 0x1918(%rax), %edi
xorl %esi, %esi
callq 0xd740
movl %eax, %ecx
movq 0x10(%rsp), %rax
movslq %ecx, %rcx
movl 0x1778(%rax,%rcx,4), %edx
xorl $0x5, %edx
movl %edx, 0x1778(%rax,%rcx,4)
movl 0x1918(%rax), %edi
movl $0x7, %esi
callq 0xd740
movl %eax, %ecx
movq 0x10(%rsp), %rax
movslq %ecx, %rcx
movl 0x1778(%rax,%rcx,4), %edx
xorl $0xa, %edx
movl %edx, 0x1778(%rax,%rcx,4)
movl 0x191c(%rax), %edi
xorl %esi, %esi
callq 0xd740
movl %eax, %ecx
movq 0x10(%rsp), %rax
movslq %ecx, %rcx
movl 0x1778(%rax,%rcx,4), %edx
xorl $0x1, %edx
movl %edx, 0x1778(%rax,%rcx,4)
movl 0x191c(%rax), %edi
movl $0x7, %esi
callq 0xd740
movl %eax, %ecx
movq 0x10(%rsp), %rax
movslq %ecx, %rcx
movl 0x1778(%rax,%rcx,4), %edx
xorl $0x2, %edx
movl %edx, 0x1778(%rax,%rcx,4)
movl 0x1920(%rax), %edi
xorl %esi, %esi
callq 0xd740
movl %eax, %ecx
movq 0x10(%rsp), %rax
movslq %ecx, %rcx
movl 0x1778(%rax,%rcx,4), %edx
xorl $0x4, %edx
movl %edx, 0x1778(%rax,%rcx,4)
movl 0x1920(%rax), %edi
movl $0x7, %esi
callq 0xd740
movl %eax, %ecx
movq 0x10(%rsp), %rax
movslq %ecx, %rcx
movl 0x1778(%rax,%rcx,4), %edx
xorl $0x8, %edx
movl %edx, 0x1778(%rax,%rcx,4)
movq 0x1958(%rsp), %rax
cmpl $0x40, 0x20(%rax)
je 0x3da82
movq 0x1958(%rsp), %rax
movl 0x20(%rax), %edi
callq 0x1b2f0
movl %eax, %ecx
movq 0x10(%rsp), %rax
movq 0x1938(%rax), %rax
movl %ecx, 0x20(%rax)
movq 0x10(%rsp), %rdi
callq 0x37410
movq 0x10(%rsp), %rdi
callq 0x37630
movq 0x10(%rsp), %rdi
movq %rax, %rcx
movq 0x1938(%rdi), %rax
movq %rcx, 0x38(%rax)
callq 0x37740
movq 0x10(%rsp), %rdi
movq %rax, %rcx
movq 0x1938(%rdi), %rax
movq %rcx, (%rax)
callq 0x377f0
movq 0x10(%rsp), %rdi
movq %rax, %rcx
movq 0x1938(%rdi), %rax
movq %rcx, 0x8(%rax)
callq 0x378d0
movq 0x10(%rsp), %rdi
movl %eax, %ecx
movq 0x1938(%rdi), %rax
movl %ecx, 0x24(%rax)
xorl %esi, %esi
callq 0x379e0
movq 0x10(%rsp), %rdi
movl %eax, %ecx
movq 0x1938(%rdi), %rax
movl %ecx, 0x28(%rax)
movl $0x1, %esi
callq 0x379e0
movl %eax, %ecx
movq 0x10(%rsp), %rax
movq 0x1938(%rax), %rax
movl %ecx, 0x2c(%rax)
addq $0x1968, %rsp           # imm = 0x1968
retq
nopl (%rax)