// File: /workspace/github_cpp_makefile_star2_O3/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 0x9ca1
addq $-0x38, %rdi
leaq 0x8(%rsp), %rsi
callq 0x7b06
testb %al, %al
je 0x9cc0
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 0x21fed(%rip), %rsi     # 0x2bb98
leaq 0x8(%rsp), %rdi
callq 0x7b06
testb %al, %al
jne 0x9c96
cmpl $0x5, 0x10(%rsp)
ja 0x9bdf
movl 0x170(%rbx), %edx
cmpl $0x2, %edx
jae 0x9d1d
movl 0xc(%rsp), %esi
movq %rbx, %rdi
callq 0x664c
movl 0xc(%rsp), %esi
movq %rbx, %rdi
callq 0x6586
movl %eax, %r15d
movl 0x8(%rsp), %esi
movq %rbx, %rdi
movl %eax, %edx
callq 0x642c
cmpl $0xc, %r15d
jae 0x9cdf
andl $0xe, %r15d
cmpl $0xa, %r15d
jne 0x9c84
movl 0x8(%rsp), %eax
cmpl $0x40, %eax
jae 0x9cfe
movl 0xc(%rsp), %ecx
cmpl $0x40, %ecx
jae 0x9cfe
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 0x9c84
movl 0x170(%rbx), %edx
testl %edx, %edx
movl $0x38, %edi
cmovel %edx, %edi
xorl %edx, %edx
xorl %esi, %esi
cmpl %eax, %ecx
movl $0x7, %r15d
cmovbel %edx, %r15d
seta %sil
leal (%rdi,%rsi,2), %esi
addl $0x3, %esi
orl %edi, %r15d
movq %rbx, %rdi
callq 0x6586
movq %rbx, %rdi
movl %r15d, %esi
movl %eax, %edx
callq 0x642c
cmpl $0xb, %ebp
ja 0x9c96
movq %rbx, %rdi
movl %r14d, %esi
movl %ebp, %edx
callq 0x642c
addq $0x18, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x100f3(%rip), %rdi     # 0x19d9b
leaq 0xffb6(%rip), %rsi      # 0x19c65
leaq 0x100f4(%rip), %rcx     # 0x19daa
movl $0x126, %edx            # imm = 0x126
callq 0x4190
leaq 0x1010f(%rip), %rdi     # 0x19dd6
leaq 0xff97(%rip), %rsi      # 0x19c65
leaq 0x100d5(%rip), %rcx     # 0x19daa
movl $0x127, %edx            # imm = 0x127
callq 0x4190
leaq 0xf038(%rip), %rdi      # 0x18d1e
leaq 0xf041(%rip), %rsi      # 0x18d2e
leaq 0xf046(%rip), %rcx      # 0x18d3a
movl $0x45, %edx
callq 0x4190
leaq 0xef1b(%rip), %rdi      # 0x18c20
leaq 0xed6a(%rip), %rsi      # 0x18a76
leaq 0xee2d(%rip), %rcx      # 0x18b40
movl $0x40, %edx
callq 0x4190
leaq 0x10546(%rip), %rdi     # 0x1a26a
leaq 0xf003(%rip), %rsi      # 0x18d2e
leaq 0x10559(%rip), %rcx     # 0x1a28b
movl $0x2f, %edx
callq 0x4190