// File: /workspace/github_cpp_makefile_star2_O2/cpirc[P]Monochrome/src/move.cpp
// Function: make_move(Position&, unsigned int)
void make_move(Position& pos, const Move move) {
    pos.epsq = INVALID_SQUARE;

    const Square from = from_square(move), to = to_square(move);
    const MoveType mt = move_type(move);

    pos.castle &= castling_lookup[from] & castling_lookup[to];

    switch (mt) {
        case NORMAL:
            move_piece(pos, from, to, get_piece_on_square(pos, from), US);
            break;
        case CAPTURE:
            remove_piece(pos, to, get_piece_on_square(pos, to), THEM);
            move_piece(pos, from, to, get_piece_on_square(pos, from), US);
            break;
        case DOUBLE_PUSH:
            move_piece(pos, from, to, PAWN, US);
            pos.epsq = from + 8;
            break;
        case ENPASSANT:
            move_piece(pos, from, to, PAWN, US);
            remove_piece(pos, to - 8, PAWN, THEM);
            break;
        case CASTLE:
            move_piece(pos, from, to, KING, US);
            switch (to) {
                case C1:
                    move_piece(pos, A1, D1, ROOK, US);
                    break;
                case G1:
                    move_piece(pos, H1, F1, ROOK, US);
                    break;
                default:
                    break;
            }
            break;
        case PROM_CAPTURE:
            remove_piece(pos, to, get_piece_on_square(pos, to), THEM);
            remove_piece(pos, from, PAWN, US);
            put_piece(pos, to, promotion_type(move), US);
            break;
        case PROMOTION:
            remove_piece(pos, from, PAWN, US);
            put_piece(pos, to, promotion_type(move), US);
            break;
        default:
            std::puts("MOVE TYPE ERROR");
            break;
    }

    pos.halfmoves++;
    if ((mt != NORMAL && mt != CASTLE) ||
        (mt == NORMAL && get_piece_on_square(pos, to) == PAWN)) {
        pos.history.clear();
        pos.halfmoves = 0;
    }

    flip_position(pos);
    calculate_key(pos);

    pos.history.push_back(pos.hash_key);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %esi, %r14d
movq %rdi, %rbx
movb $0x40, 0x42(%rdi)
movl %esi, %r12d
andl $0x3f, %r12d
movl %esi, %r13d
shrl $0x6, %r13d
andl $0x3f, %r13d
leaq 0x6d67(%rip), %rax      # 0xa720
movb (%r13,%rax), %cl
andb (%r12,%rax), %cl
andb %cl, 0x40(%rdi)
movl %esi, %r15d
andl $0x7000, %r15d          # imm = 0x7000
movl %r15d, %eax
shrl $0xc, %eax
leaq 0x6d04(%rip), %rcx      # 0xa6e0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
movzbl %r13b, %edx
movq %rdx, -0x30(%rbp)
jmpq *%rax
movzbl %r12b, %esi
movq %rbx, %rdi
movq %rdx, %r13
callq 0x4091
movzbl %al, %ecx
movq %rbx, %rdi
movl %r12d, %esi
movl %r13d, %edx
jmp 0x3a73
pushq $0x1
popq %rax
movq %rax, %rdx
movl %r12d, %ecx
shlq %cl, %rdx
xorq %rdx, (%rbx)
xorq %rdx, 0x30(%rbx)
movl %r13d, %ecx
shlq %cl, %rax
movl %r14d, %ecx
shrl $0xc, %ecx
andl $0x38, %ecx
orq %rax, (%rbx,%rcx)
orq %rax, 0x30(%rbx)
jmp 0x3b48
movq %rbx, %rdi
movl %edx, %esi
callq 0x4091
pushq $0x1
popq %rdx
movl %r13d, %ecx
shlq %cl, %rdx
movzbl %al, %eax
xorq %rdx, (%rbx,%rax,8)
xorq %rdx, 0x38(%rbx)
movzbl %r12b, %r12d
movq %rbx, %rdi
movl %r12d, %esi
callq 0x4091
movzbl %al, %ecx
movq %rbx, %rdi
movl %r12d, %esi
movq -0x30(%rbp), %rdx
xorl %r8d, %r8d
callq 0x404b
jmp 0x3b48
movzbl %r12b, %esi
movq %rbx, %rdi
movq %rdx, %r12
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x404b
leal -0x8(%r12), %ecx
pushq $0x1
popq %rax
shlq %cl, %rax
xorq %rax, (%rbx)
xorq %rax, 0x38(%rbx)
jmp 0x3b48
leaq 0x6cce(%rip), %rdi      # 0xa780
callq 0x2230
jmp 0x3b48
movzbl %r12b, %esi
pushq $0x5
popq %rcx
movq %rbx, %rdi
xorl %r8d, %r8d
callq 0x404b
cmpq $0x6, %r13
je 0x3b40
cmpl $0x2, %r13d
jne 0x3b48
xorb $0x9, 0x18(%rbx)
xorb $0x9, 0x30(%rbx)
jmp 0x3b48
movzbl %r12b, %esi
movq %rbx, %rdi
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x404b
addb $0x8, %r12b
movb %r12b, 0x42(%rbx)
jmp 0x3b48
movq %rbx, %rdi
movl %edx, %esi
callq 0x4091
pushq $0x1
popq %rdx
movq %rdx, %rsi
movl %r13d, %ecx
shlq %cl, %rsi
movzbl %al, %eax
xorq %rsi, (%rbx,%rax,8)
xorq %rsi, 0x38(%rbx)
movl %r12d, %ecx
shlq %cl, %rdx
xorq %rdx, (%rbx)
xorq %rdx, 0x30(%rbx)
movl %r14d, %eax
shrl $0xc, %eax
andl $0x38, %eax
orq %rsi, (%rbx,%rax)
orq %rsi, 0x30(%rbx)
jmp 0x3b48
xorb $-0x60, 0x18(%rbx)
xorb $-0x60, 0x30(%rbx)
incb 0x43(%rbx)
testw $0x6000, %r14w          # imm = 0x6000
je 0x3b67
movq 0x50(%rbx), %rax
cmpq %rax, 0x58(%rbx)
je 0x3b61
movq %rax, 0x58(%rbx)
movb $0x0, 0x43(%rbx)
jmp 0x3b7c
testl %r15d, %r15d
jne 0x3b7c
movq %rbx, %rdi
movq -0x30(%rbp), %rsi
callq 0x4091
testb %al, %al
je 0x3b53
movq %rbx, %rdi
callq 0x2c63
movq %rbx, %rdi
callq 0x528e
leaq 0x50(%rbx), %rdi
addq $0x48, %rbx
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x40aa