// File: /workspace/github_cpp_makefile_star2_O1/codeandkey[P]neocortex/src/position.cpp
// Function: neocortex::Position::unmake_move(neocortex::Move)
void Position::unmake_move(Move move) {
	assert(ply.size() > 1);
	assert(ply.back().last_move == move);

	State last_state = ply.back();
	ply.pop_back();

	/* Flip CTM early for readability */
	color_to_move = !color_to_move;

	/* If unmaking null move, good to go */
	if (move == Move::null) {
		return;
	}

	/* Unpromote */
	if (piece::is_type(move.ptype())) {
		board.replace(move.dst(), piece::make_piece(color_to_move, piece::PAWN));
	}

	/* Move piece back to source */
	int dst_piece = board.remove(move.dst());
	board.place(move.src(), dst_piece);

	/* Unmove rook in castling */
	if (piece::type(dst_piece) == piece::KING && abs(square::file(move.src()) - square::file(move.dst())) > 1) {
		int is_ks = move.dst() > move.src();
		int castle_rank = (color_to_move == piece::WHITE) ? 0 : 7;
		int rook_file = is_ks ? 5 : 3;
		int rook_dstfile = is_ks ? 7 : 0;

		int rook_src = square::at(castle_rank, rook_file);
		int rook_dst = square::at(castle_rank, rook_dstfile);

		board.place(rook_dst, board.remove(rook_src));
	}

	/* Replace captured pieces */
	if (piece::is_valid(last_state.captured_piece)) {
		board.place(last_state.captured_square, last_state.captured_piece);
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movq %rsi, 0x8(%rsp)
movl %edx, 0x10(%rsp)
movq 0x160(%rdi), %rdi
movq %rdi, %rax
subq 0x158(%rbx), %rax
sarq $0x3, %rax
movabsq $0x6db6db6db6db6db7, %rcx # imm = 0x6DB6DB6DB6DB6DB7
imulq %rax, %rcx
cmpq $0x1, %rcx
jbe 0x9be0
addq $-0x38, %rdi
leaq 0x8(%rsp), %rsi
callq 0x79fa
testb %al, %al
je 0x9bff
movq 0x160(%rbx), %rax
leaq -0x38(%rax), %rcx
movl -0x24(%rax), %ebp
movl -0x20(%rax), %r14d
movq %rcx, 0x160(%rbx)
xorl %eax, %eax
cmpl $0x0, 0x170(%rbx)
sete %al
movl %eax, 0x170(%rbx)
leaq 0x210af(%rip), %rsi     # 0x2ab98
leaq 0x8(%rsp), %rdi
callq 0x79fa
testb %al, %al
jne 0x9bd5
cmpl $0x5, 0x10(%rsp)
ja 0x9b1d
movl 0x170(%rbx), %edx
cmpl $0x2, %edx
jae 0x9c5c
movl 0xc(%rsp), %esi
movq %rbx, %rdi
callq 0x6540
movl 0xc(%rsp), %esi
movq %rbx, %rdi
callq 0x647c
movl %eax, %r15d
movl 0x8(%rsp), %esi
movq %rbx, %rdi
movl %eax, %edx
callq 0x6320
cmpl $0xc, %r15d
jae 0x9c1e
andl $0xe, %r15d
cmpl $0xa, %r15d
jne 0x9bc3
movl 0x8(%rsp), %eax
cmpl $0x40, %eax
jae 0x9c3d
movl 0xc(%rsp), %ecx
cmpl $0x40, %ecx
jae 0x9c3d
movl %eax, %edx
andl $0x7, %edx
movl %ecx, %esi
andl $0x7, %esi
subl %esi, %edx
movl %edx, %esi
negl %esi
cmovsl %edx, %esi
cmpl $0x2, %esi
jb 0x9bc3
xorl %edx, %edx
xorl %esi, %esi
cmpl %eax, %ecx
movl $0x7, %eax
cmovlel %edx, %eax
setg %sil
movl 0x170(%rbx), %ecx
testl %ecx, %ecx
movl $0x38, %r15d
cmovel %ecx, %r15d
leal (%r15,%rsi,2), %esi
addl $0x3, %esi
orl %eax, %r15d
movq %rbx, %rdi
callq 0x647c
movq %rbx, %rdi
movl %r15d, %esi
movl %eax, %edx
callq 0x6320
cmpl $0xb, %ebp
ja 0x9bd5
movq %rbx, %rdi
movl %r14d, %esi
movl %ebp, %edx
callq 0x6320
addq $0x18, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0xf0f4(%rip), %rdi      # 0x18cdb
leaq 0xefb7(%rip), %rsi      # 0x18ba5
leaq 0xf0f5(%rip), %rcx      # 0x18cea
movl $0x126, %edx            # imm = 0x126
callq 0x4190
leaq 0xf110(%rip), %rdi      # 0x18d16
leaq 0xef98(%rip), %rsi      # 0x18ba5
leaq 0xf0d6(%rip), %rcx      # 0x18cea
movl $0x127, %edx            # imm = 0x127
callq 0x4190
leaq 0xe0c0(%rip), %rdi      # 0x17ce5
leaq 0xe0c9(%rip), %rsi      # 0x17cf5
leaq 0xe0ce(%rip), %rcx      # 0x17d01
movl $0x45, %edx
callq 0x4190
leaq 0xde47(%rip), %rdi      # 0x17a8b
leaq 0xde2b(%rip), %rsi      # 0x17a76
leaq 0xdeca(%rip), %rcx      # 0x17b1c
movl $0x40, %edx
callq 0x4190
leaq 0xf547(%rip), %rdi      # 0x191aa
leaq 0xe08b(%rip), %rsi      # 0x17cf5
leaq 0xf55a(%rip), %rcx      # 0x191cb
movl $0x2f, %edx
callq 0x4190
nop