// File: /workspace/github_cpp_makefile_star2_O3/jswaff[P]prophet3/src/apply.cpp
// Function: undo_last_move(position*, undo*)
void undo_last_move(position *p,undo *undo_stack) {
    assert(p);
    assert(p->move_counter > 0);
    assert(undo_stack);

    undo *u = undo_stack + p->move_counter - 1;

    p->player = opposite_player(p->player);
    p->ep_sq = u->ep_sq;
    p->castling_rights = u->castling_rights;
    p->fifty_counter = u->fifty_counter;
    p->move_counter--;

    move mv = u->mv;
    assert(abs(u->captured)==get_captured_piece(mv));

    // remove the moving piece from to_sq
    square_t to_sq = get_to_sq(mv);
    square_t from_sq = get_from_sq(mv);
    piece_t piece = get_piece(mv);

    if (p->piece[to_sq] != NO_PIECE) {
        remove_piece(p,to_sq);
    }

    // place the moving piece on from_sq
    add_piece(p,piece * (p->player==WHITE ? 1 : -1),from_sq);
    if (piece==KING) {
        if (p->player==WHITE) {
            p->white_king = from_sq;
        } else {
            p->black_king = from_sq;
        }
    }

    // restore the captured piece
    if (is_capture(mv)) {
        if (is_epcapture(mv)) {
            if (p->player==BLACK) {
                add_piece(p,PAWN,(square_t)(p->ep_sq-8));
            } else {
                add_piece(p,-PAWN,(square_t)(p->ep_sq+8));
            }
        } else {
            add_piece(p,u->captured,to_sq);
        }
    } else if (is_castle(mv)) {
        if (from_sq==E1) {
            if (to_sq==G1) {
                remove_piece(p,F1);
                add_piece(p,ROOK,H1);
            } else {
                remove_piece(p,D1);
                add_piece(p,ROOK,A1);
            }
        } else {
            if (to_sq==G8) {
                remove_piece(p,F8);
                add_piece(p,-ROOK,H8);
            } else {
                remove_piece(p,D8);
                add_piece(p,-ROOK,A8);
            }
        }
    }

    p->hash_key = u->hash_key;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
testq %rdi, %rdi
je 0x354c
movq %rdi, %rbx
movl 0x144(%rdi), %ebp
testq %rbp, %rbp
je 0x356b
movq %rsi, %r14
testq %rsi, %rsi
je 0x358a
shlq $0x5, %rbp
movl 0x138(%rbx), %edi
callq 0xdf74
movl %eax, 0x138(%rbx)
movl -0xc(%r14,%rbp), %eax
movl %eax, 0x13c(%rbx)
movl -0x4(%r14,%rbp), %eax
movl %eax, 0x140(%rbx)
movl -0x8(%r14,%rbp), %eax
movl %eax, 0x148(%rbx)
decl 0x144(%rbx)
movq -0x20(%r14,%rbp), %r15
movl -0x10(%r14,%rbp), %eax
movl %eax, %r12d
negl %r12d
cmovsl %eax, %r12d
movq %r15, %rdi
callq 0x7879
cmpl %eax, %r12d
jne 0x35a9
movq %r15, %rdi
callq 0x785b
movl %eax, %r12d
movq %r15, %rdi
callq 0x7854
movl %eax, 0x4(%rsp)
movq %r15, %rdi
callq 0x7865
movl %eax, %r13d
movl %r12d, %eax
cmpl $0x0, (%rbx,%rax,4)
je 0x3414
movq %rbx, %rdi
movl %r12d, %esi
callq 0xa78d
movl %r13d, %esi
negl %esi
cmpl $0x1, 0x138(%rbx)
cmovel %r13d, %esi
movq %rbx, %rdi
movl 0x4(%rsp), %edx
callq 0xa5f8
cmpl $0x6, %r13d
jne 0x3455
cmpl $0x1, 0x138(%rbx)
jne 0x344b
movl 0x4(%rsp), %eax
movl %eax, 0x14c(%rbx)
jmp 0x3455
movl 0x4(%rsp), %eax
movl %eax, 0x150(%rbx)
addq %rbp, %r14
movq %r15, %rdi
callq 0x7883
movq %r15, %rdi
testb %al, %al
je 0x348f
callq 0x788d
testb %al, %al
je 0x34c5
cmpl $0x0, 0x138(%rbx)
movl 0x13c(%rbx), %edx
je 0x34f3
addl $0x8, %edx
movq %rbx, %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
jmp 0x352d
callq 0x7897
testb %al, %al
je 0x3532
cmpl $0x3c, 0x4(%rsp)
jne 0x34d1
movq %rbx, %rdi
cmpl $0x3e, %r12d
jne 0x3500
movl $0x3d, %esi
callq 0xa78d
movq %rbx, %rdi
movl $0x4, %esi
movl $0x3f, %edx
jmp 0x352d
movl -0x10(%r14), %esi
movq %rbx, %rdi
movl %r12d, %edx
jmp 0x352d
movq %rbx, %rdi
cmpl $0x6, %r12d
jne 0x3519
movl $0x5, %esi
callq 0xa78d
movq %rbx, %rdi
movl $0xfffffffc, %esi       # imm = 0xFFFFFFFC
movl $0x7, %edx
jmp 0x352d
addl $-0x8, %edx
movq %rbx, %rdi
movl $0x1, %esi
jmp 0x352d
movl $0x3b, %esi
callq 0xa78d
movq %rbx, %rdi
movl $0x4, %esi
movl $0x38, %edx
jmp 0x352d
movl $0x3, %esi
callq 0xa78d
movq %rbx, %rdi
movl $0xfffffffc, %esi       # imm = 0xFFFFFFFC
xorl %edx, %edx
callq 0xa5f8
movq -0x18(%r14), %rax
movq %rax, 0x1b8(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x31da9(%rip), %rdi     # 0x352fc
leaq 0x25ab8(%rip), %rsi     # 0x29012
leaq 0x25c02(%rip), %rcx     # 0x29163
movl $0x95, %edx
callq 0x20d0
leaq 0x25c19(%rip), %rdi     # 0x2918b
leaq 0x25a99(%rip), %rsi     # 0x29012
leaq 0x25be3(%rip), %rcx     # 0x29163
movl $0x96, %edx
callq 0x20d0
leaq 0x25b9f(%rip), %rdi     # 0x29130
leaq 0x25a7a(%rip), %rsi     # 0x29012
leaq 0x25bc4(%rip), %rcx     # 0x29163
movl $0x97, %edx
callq 0x20d0
leaq 0x25bef(%rip), %rdi     # 0x2919f
leaq 0x25a5b(%rip), %rsi     # 0x29012
leaq 0x25ba5(%rip), %rcx     # 0x29163
movl $0xa2, %edx
callq 0x20d0