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

  assert(move_is_ok(m));
  assert(move_is_castle(m));

  // When we have arrived here, some work has already been done by
  // Position::undo_move.  In particular, the side to move has been switched,
  // so the code below is correct.
  Color us = side_to_move();

  // Find source squares for king and rook
  Square kfrom = move_from(m);
  Square rfrom = move_to(m);  // HACK: See comment at beginning of function
  Square kto, rto;

  // Find destination squares for king and rook
  if (rfrom > kfrom) // O-O
  {
      kto = relative_square(us, SQ_G1);
      rto = relative_square(us, SQ_F1);
  } else { // O-O-O
      kto = relative_square(us, SQ_C1);
      rto = relative_square(us, SQ_D1);
  }

  assert(piece_on(kto) == make_piece(us, KING));
  assert(piece_on(rto) == make_piece(us, ROOK));

  // Remove pieces from destination squares:
  clear_bit(&(byColorBB[us]), kto);
  clear_bit(&(byTypeBB[KING]), kto);
  clear_bit(&(byTypeBB[0]), kto); // HACK: byTypeBB[0] == occupied squares
  clear_bit(&(byColorBB[us]), rto);
  clear_bit(&(byTypeBB[ROOK]), rto);
  clear_bit(&(byTypeBB[0]), rto); // HACK: byTypeBB[0] == occupied squares

  // Put pieces on source squares:
  set_bit(&(byColorBB[us]), kfrom);
  set_bit(&(byTypeBB[KING]), kfrom);
  set_bit(&(byTypeBB[0]), kfrom); // HACK: byTypeBB[0] == occupied squares
  set_bit(&(byColorBB[us]), rfrom);
  set_bit(&(byTypeBB[ROOK]), rfrom);
  set_bit(&(byTypeBB[0]), rfrom); // HACK: byTypeBB[0] == occupied squares

  // Update board
  board[rto] = board[kto] = PIECE_NONE;
  board[rfrom] = make_piece(us, ROOK);
  board[kfrom] = make_piece(us, KING);

  // Update piece lists
  pieceList[us][KING][index[kto]] = kfrom;
  pieceList[us][ROOK][index[rto]] = rfrom;
  int tmp = index[rto];  // In Chess960 could be rto == kfrom
  index[kfrom] = index[kto];
  index[rfrom] = tmp;

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

  assert(is_ok());
}

// Assembly:
pushq %r14
pushq %rbx
movl 0x1090(%rdi), %eax
movl %esi, %ecx
shrl $0x6, %ecx
andl $0x3f, %ecx
andl $0x3f, %esi
xorl %edx, %edx
cmpl %ecx, %esi
seta %dl
imull $0x38, %eax, %r8d
leal (%r8,%rdx,4), %r9d
addl $0x2, %r9d
leal 0x3(%r8,%rdx,2), %r8d
movslq %r9d, %rdx
leaq 0xf7f8a(%rip), %r11     # 0x1183b0
movq 0x140(%rdi,%rax,8), %r9
andq (%r11,%rdx,8), %r9
movq %r9, 0x140(%rdi,%rax,8)
movq 0x130(%rdi), %rbx
andq (%r11,%rdx,8), %rbx
movq 0x100(%rdi), %r10
movq %rbx, 0x130(%rdi)
andq (%r11,%rdx,8), %r10
movq %r10, 0x100(%rdi)
movslq %r8d, %r8
andq (%r11,%r8,8), %r9
movq %r9, 0x140(%rdi,%rax,8)
movq 0x120(%rdi), %r14
andq (%r11,%r8,8), %r14
movq %r14, 0x120(%rdi)
andq (%r11,%r8,8), %r10
movq %r10, 0x100(%rdi)
leaq 0xf7d0f(%rip), %r11     # 0x1181a0
orq (%r11,%rcx,8), %r9
movq %r9, 0x140(%rdi,%rax,8)
orq (%r11,%rcx,8), %rbx
movq %rbx, 0x130(%rdi)
orq (%r11,%rcx,8), %r10
movq %r10, 0x100(%rdi)
orq (%r11,%rsi,8), %r9
movq %r9, 0x140(%rdi,%rax,8)
orq (%r11,%rsi,8), %r14
movq %r14, 0x120(%rdi)
orq (%r11,%rsi,8), %r10
movq %r10, 0x100(%rdi)
movl $0x10, %r9d
movl %r9d, (%rdi,%rdx,4)
movl %r9d, (%rdi,%r8,4)
leal 0x4(,%rax,8), %r9d
leal (,%rsi,4), %r10d
movl %r9d, (%rdi,%r10)
leal 0x6(,%rax,8), %r9d
leal (,%rcx,4), %r11d
movl %r9d, (%rdi,%r11)
shlq $0x9, %rax
addq %rdi, %rax
movslq 0x590(%rdi,%rdx,4), %rdx
movl %ecx, 0x310(%rax,%rdx,4)
movslq 0x590(%rdi,%r8,4), %rcx
movl %esi, 0x290(%rax,%rcx,4)
movl %edx, 0x590(%rdi,%r11)
movl %ecx, 0x590(%rdi,%r10)
movq 0x1938(%rdi), %rax
movq 0x98(%rax), %rax
movq %rax, 0x1938(%rdi)
popq %rbx
popq %r14
retq
nop