// File: 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
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rax
movb $0x40, 0x42(%rax)
movl -0xc(%rbp), %edi
callq 0x66b0
movb %al, -0xd(%rbp)
movl -0xc(%rbp), %edi
callq 0x66c0
movb %al, -0xe(%rbp)
movl -0xc(%rbp), %edi
callq 0x66e0
movl %eax, -0x14(%rbp)
movzbl -0xd(%rbp), %eax
leaq 0xdf2a(%rip), %rcx      # 0x13870
movzbl (%rax,%rcx), %edx
movzbl -0xe(%rbp), %eax
movzbl (%rax,%rcx), %eax
andl %eax, %edx
movq -0x8(%rbp), %rax
movl 0x40(%rax), %ecx
andl %edx, %ecx
movb %cl, 0x40(%rax)
movl -0x14(%rbp), %eax
movl %eax, -0x18(%rbp)
testl %eax, %eax
je 0x59cf
jmp 0x596c
movl -0x18(%rbp), %eax
subl $0x1000, %eax           # imm = 0x1000
je 0x5aff
jmp 0x597c
movl -0x18(%rbp), %eax
subl $0x2000, %eax           # imm = 0x2000
je 0x5a10
jmp 0x598c
movl -0x18(%rbp), %eax
subl $0x3000, %eax           # imm = 0x3000
je 0x5ab8
jmp 0x599c
movl -0x18(%rbp), %eax
subl $0x4000, %eax           # imm = 0x4000
je 0x5bdb
jmp 0x59ac
movl -0x18(%rbp), %eax
subl $0x5000, %eax           # imm = 0x5000
je 0x5a83
jmp 0x59bc
movl -0x18(%rbp), %eax
subl $0x6000, %eax           # imm = 0x6000
je 0x5b6c
jmp 0x5c18
movq -0x8(%rbp), %rax
movq %rax, -0x28(%rbp)
movb -0xd(%rbp), %al
movb %al, -0x1a(%rbp)
movb -0xe(%rbp), %al
movb %al, -0x19(%rbp)
movq -0x8(%rbp), %rdi
movzbl -0xd(%rbp), %esi
callq 0x67b0
movq -0x28(%rbp), %rdi
movb -0x1a(%rbp), %dl
movb -0x19(%rbp), %cl
xorl %r8d, %r8d
movzbl %dl, %esi
movzbl %cl, %edx
movzbl %al, %ecx
callq 0x6700
jmp 0x5c24
movq -0x8(%rbp), %rax
movq %rax, -0x48(%rbp)
movb -0xe(%rbp), %al
movb %al, -0x39(%rbp)
movq -0x8(%rbp), %rdi
movzbl -0xe(%rbp), %esi
callq 0x67b0
movq -0x48(%rbp), %rdi
movb -0x39(%rbp), %dl
movl $0x1, %ecx
movzbl %dl, %esi
movzbl %al, %edx
callq 0x67f0
movq -0x8(%rbp), %rax
movq %rax, -0x38(%rbp)
movb -0xd(%rbp), %al
movb %al, -0x2a(%rbp)
movb -0xe(%rbp), %al
movb %al, -0x29(%rbp)
movq -0x8(%rbp), %rdi
movzbl -0xd(%rbp), %esi
callq 0x67b0
movq -0x38(%rbp), %rdi
movb -0x2a(%rbp), %dl
movb -0x29(%rbp), %cl
xorl %r8d, %r8d
movzbl %dl, %esi
movzbl %cl, %edx
movzbl %al, %ecx
callq 0x6700
jmp 0x5c24
movq -0x8(%rbp), %rdi
movb -0xd(%rbp), %al
xorl %r8d, %r8d
movzbl %al, %esi
movzbl -0xe(%rbp), %edx
movl %r8d, %ecx
callq 0x6700
movl $0x8, %esi
movzbl -0xd(%rbp), %edi
callq 0x6850
movb %al, %cl
movq -0x8(%rbp), %rax
movb %cl, 0x42(%rax)
jmp 0x5c24
movq -0x8(%rbp), %rdi
movb -0xd(%rbp), %al
xorl %r8d, %r8d
movzbl %al, %esi
movzbl -0xe(%rbp), %edx
movl %r8d, %ecx
callq 0x6700
movq -0x8(%rbp), %rax
movq %rax, -0x50(%rbp)
movl $0x8, %esi
movzbl -0xe(%rbp), %edi
callq 0x6870
movq -0x50(%rbp), %rdi
xorl %edx, %edx
movl $0x1, %ecx
movzbl %al, %esi
callq 0x67f0
jmp 0x5c24
movq -0x8(%rbp), %rdi
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movl $0x5, %ecx
xorl %r8d, %r8d
callq 0x6700
movzbl -0xe(%rbp), %eax
movl %eax, -0x54(%rbp)
subl $0x2, %eax
je 0x5b30
jmp 0x5b26
movl -0x54(%rbp), %eax
subl $0x6, %eax
je 0x5b48
jmp 0x5b65
movq -0x8(%rbp), %rdi
xorl %r8d, %r8d
movl $0x3, %ecx
movl %r8d, %esi
movl %ecx, %edx
callq 0x6700
jmp 0x5b67
movq -0x8(%rbp), %rdi
movl $0x7, %esi
movl $0x5, %edx
movl $0x3, %ecx
xorl %r8d, %r8d
callq 0x6700
jmp 0x5b67
jmp 0x5b67
jmp 0x5c24
movq -0x8(%rbp), %rax
movq %rax, -0x70(%rbp)
movb -0xe(%rbp), %al
movb %al, -0x61(%rbp)
movq -0x8(%rbp), %rdi
movzbl -0xe(%rbp), %esi
callq 0x67b0
movq -0x70(%rbp), %rdi
movb -0x61(%rbp), %dl
movl $0x1, %ecx
movzbl %dl, %esi
movzbl %al, %edx
callq 0x67f0
movq -0x8(%rbp), %rdi
xorl %ecx, %ecx
movzbl -0xd(%rbp), %esi
movl %ecx, %edx
callq 0x67f0
movq -0x8(%rbp), %rax
movq %rax, -0x60(%rbp)
movb -0xe(%rbp), %al
movb %al, -0x55(%rbp)
movl -0xc(%rbp), %edi
callq 0x68f0
movq -0x60(%rbp), %rdi
movb -0x55(%rbp), %dl
xorl %ecx, %ecx
movzbl %dl, %esi
movzbl %al, %edx
callq 0x6890
jmp 0x5c24
movq -0x8(%rbp), %rdi
xorl %ecx, %ecx
movzbl -0xd(%rbp), %esi
movl %ecx, %edx
callq 0x67f0
movq -0x8(%rbp), %rax
movq %rax, -0x80(%rbp)
movb -0xe(%rbp), %al
movb %al, -0x71(%rbp)
movl -0xc(%rbp), %edi
callq 0x68f0
movq -0x80(%rbp), %rdi
movb -0x71(%rbp), %dl
xorl %ecx, %ecx
movzbl %dl, %esi
movzbl %al, %edx
callq 0x6890
jmp 0x5c24
leaq 0xdc91(%rip), %rdi      # 0x138b0
callq 0x32f0
movq -0x8(%rbp), %rax
movb 0x43(%rax), %cl
addb $0x1, %cl
movb %cl, 0x43(%rax)
cmpl $0x0, -0x14(%rbp)
je 0x5c40
cmpl $0x1000, -0x14(%rbp)    # imm = 0x1000
jne 0x5c5b
cmpl $0x0, -0x14(%rbp)
jne 0x5c70
movq -0x8(%rbp), %rdi
movzbl -0xe(%rbp), %esi
callq 0x67b0
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x5c70
movq -0x8(%rbp), %rdi
addq $0x50, %rdi
callq 0x6910
movq -0x8(%rbp), %rax
movb $0x0, 0x43(%rax)
movq -0x8(%rbp), %rdi
callq 0x42a0
movq -0x8(%rbp), %rdi
callq 0x9a00
movq -0x8(%rbp), %rdi
addq $0x50, %rdi
movq -0x8(%rbp), %rsi
addq $0x48, %rsi
callq 0x6930
addq $0x80, %rsp
popq %rbp
retq