// File: jswaff[P]prophet3/src/apply.cpp
// Function: apply_move(position*, unsigned long long, undo*)
void apply_move(position *p,move m,undo *undo_stack) {
    assert(p);
    assert(clear_score(m));
    assert(test_pos_consistency(p));
    assert(undo_stack);

    // capture information to undo move
    undo *u = undo_stack+p->move_counter;
    u->mv = m;
    u->hash_key = p->hash_key;
    u->ep_sq = p->ep_sq;
    u->fifty_counter = p->fifty_counter;
    u->castling_rights = p->castling_rights;

    // clear current values
    p->hash_key ^= zkeys.ptm[p->player];
    p->hash_key ^= zkeys.ep[p->ep_sq];
    p->hash_key ^= zkeys.casting_rights[p->castling_rights];

    p->player = opposite_player(p->player);
    p->move_counter++;
    p->fifty_counter++;  // may get reset

    if (is_capture(m)) {
        p->fifty_counter=0;
        u->captured = remove_captured_piece(p,m);
    } else {
        u->captured = NO_PIECE;
    }
    assert(abs(u->captured)==get_captured_piece(m));

    // this could get reset
    p->ep_sq=NO_SQUARE;

    add_piece_to_destination(p,m);
    remove_castling_availability(p,m);
    remove_piece(p,get_from_sq(m));

    // add in current values
    p->hash_key ^= zkeys.ptm[p->player];
    p->hash_key ^= zkeys.ep[p->ep_sq];
    p->hash_key ^= zkeys.casting_rights[p->castling_rights];

    assert(test_pos_consistency(p));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
cmpq $0x0, -0x8(%rbp)
je 0x363d
jmp 0x365c
leaq 0x3e55a(%rip), %rdi     # 0x41b9e
leaq 0x319fb(%rip), %rsi     # 0x35046
movl $0x67, %edx
leaq 0x31abc(%rip), %rcx     # 0x35113
callq 0x20c0
movq -0x10(%rbp), %rdi
callq 0xac50
cmpq $0x0, %rax
je 0x366d
jmp 0x368c
leaq 0x31ac9(%rip), %rdi     # 0x3513d
leaq 0x319cb(%rip), %rsi     # 0x35046
movl $0x68, %edx
leaq 0x31a8c(%rip), %rcx     # 0x35113
callq 0x20c0
movq -0x8(%rbp), %rdi
callq 0x2e0c0
testb $0x1, %al
jne 0x369b
jmp 0x369d
jmp 0x36bc
leaq 0x31aa8(%rip), %rdi     # 0x3514c
leaq 0x3199b(%rip), %rsi     # 0x35046
movl $0x69, %edx
leaq 0x31a5c(%rip), %rcx     # 0x35113
callq 0x20c0
cmpq $0x0, -0x18(%rbp)
je 0x36c5
jmp 0x36e4
leaq 0x31a98(%rip), %rdi     # 0x35164
leaq 0x31973(%rip), %rsi     # 0x35046
movl $0x6a, %edx
leaq 0x31a34(%rip), %rcx     # 0x35113
callq 0x20c0
movq -0x18(%rbp), %rax
movq -0x8(%rbp), %rcx
movl 0x144(%rcx), %ecx
shlq $0x5, %rcx
addq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x8(%rbp), %rax
movq 0x1b8(%rax), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rax
movl 0x13c(%rax), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x14(%rax)
movq -0x8(%rbp), %rax
movl 0x148(%rax), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x18(%rax)
movq -0x8(%rbp), %rax
movl 0x140(%rax), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x1c(%rax)
movq -0x8(%rbp), %rax
movl 0x138(%rax), %eax
movl %eax, %ecx
leaq 0xffff7(%rip), %rax     # 0x103758
movq 0x1c00(%rax,%rcx,8), %rcx
movq -0x8(%rbp), %rax
xorq 0x1b8(%rax), %rcx
movq %rcx, 0x1b8(%rax)
movq -0x8(%rbp), %rax
movl 0x13c(%rax), %eax
movl %eax, %ecx
leaq 0xfffca(%rip), %rax     # 0x103758
movq 0x1c90(%rax,%rcx,8), %rcx
movq -0x8(%rbp), %rax
xorq 0x1b8(%rax), %rcx
movq %rcx, 0x1b8(%rax)
movq -0x8(%rbp), %rax
movl 0x140(%rax), %eax
movl %eax, %ecx
leaq 0xfff9d(%rip), %rax     # 0x103758
movq 0x1c10(%rax,%rcx,8), %rcx
movq -0x8(%rbp), %rax
xorq 0x1b8(%rax), %rcx
movq %rcx, 0x1b8(%rax)
movq -0x8(%rbp), %rax
movl 0x138(%rax), %edi
callq 0x14130
movl %eax, %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x138(%rax)
movq -0x8(%rbp), %rax
movl 0x144(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x144(%rax)
movq -0x8(%rbp), %rax
movl 0x148(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x148(%rax)
movq -0x10(%rbp), %rdi
callq 0xab20
testb $0x1, %al
jne 0x3825
jmp 0x384b
movq -0x8(%rbp), %rax
movl $0x0, 0x148(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x3120
movl %eax, %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x10(%rax)
jmp 0x3856
movq -0x20(%rbp), %rax
movl $0x0, 0x10(%rax)
movq -0x20(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movl %eax, -0x24(%rbp)
movq -0x10(%rbp), %rdi
callq 0xab00
movl %eax, %ecx
movl -0x24(%rbp), %eax
cmpl %ecx, %eax
jne 0x387b
jmp 0x389a
leaq 0x318ed(%rip), %rdi     # 0x3516f
leaq 0x317bd(%rip), %rsi     # 0x35046
movl $0x83, %edx
leaq 0x3187e(%rip), %rcx     # 0x35113
callq 0x20c0
movq -0x8(%rbp), %rax
movl $0x40, 0x13c(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x3270
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0xf2e0
movq -0x8(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rdi
callq 0xaa80
movq -0x30(%rbp), %rdi
movl %eax, %esi
callq 0xee40
movq -0x8(%rbp), %rax
movl 0x138(%rax), %eax
movl %eax, %ecx
leaq 0xffe67(%rip), %rax     # 0x103758
movq 0x1c00(%rax,%rcx,8), %rcx
movq -0x8(%rbp), %rax
xorq 0x1b8(%rax), %rcx
movq %rcx, 0x1b8(%rax)
movq -0x8(%rbp), %rax
movl 0x13c(%rax), %eax
movl %eax, %ecx
leaq 0xffe3a(%rip), %rax     # 0x103758
movq 0x1c90(%rax,%rcx,8), %rcx
movq -0x8(%rbp), %rax
xorq 0x1b8(%rax), %rcx
movq %rcx, 0x1b8(%rax)
movq -0x8(%rbp), %rax
movl 0x140(%rax), %eax
movl %eax, %ecx
leaq 0xffe0d(%rip), %rax     # 0x103758
movq 0x1c10(%rax,%rcx,8), %rcx
movq -0x8(%rbp), %rax
xorq 0x1b8(%rax), %rcx
movq %rcx, 0x1b8(%rax)
movq -0x8(%rbp), %rdi
callq 0x2e0c0
testb $0x1, %al
jne 0x3974
jmp 0x3976
jmp 0x3995
leaq 0x317cf(%rip), %rdi     # 0x3514c
leaq 0x316c2(%rip), %rsi     # 0x35046
movl $0x91, %edx
leaq 0x31783(%rip), %rcx     # 0x35113
callq 0x20c0
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax,%rax)