// File: SethKasmann[P]clever-girl/src/move_generator.cpp
// Function: void MoveList::pushPromotion<(MoveType)2>(Square, Square)
void MoveList::pushPromotion(Square src, Square dst)
{
    const Color C = mState.getOurColor();
    if (square_bb[dst] & Not_a_file && square_bb[dst+1] & mState.getOccupancyBB(!C))
    {
        if (T == MoveType::Attacks || T == MoveType::All)
            push(makeMove(src, dst+1, queen));

        if (T == MoveType::Quiets || T == MoveType::All)
        {
            push(makeMove(src, dst+1, knight));
            push(makeMove(src, dst+1, rook));
            push(makeMove(src, dst+1, bishop));
        }

        if (T == MoveType::Evasions)
        {
            if (square_bb[dst+1] & mValid)
            {
                push(makeMove(src, dst+1, queen));
                push(makeMove(src, dst+1, knight));
                push(makeMove(src, dst+1, rook));
                push(makeMove(src, dst+1, bishop));
            }
        }

        if (T == MoveType::QuietChecks)
        {
            if (mState.getCheckSquaresBB(knight) & square_bb[dst+1])
                push(makeMove(src, dst+1, knight));
        }
    }

    if (square_bb[dst] & Not_h_file && square_bb[dst-1] & mState.getOccupancyBB(!C))
    {
        if (T == MoveType::Attacks || T == MoveType::All)
            push(makeMove(src, dst-1, queen));

        if (T == MoveType::Quiets || T == MoveType::All)
        {
            push(makeMove(src, dst-1, knight));
            push(makeMove(src, dst-1, rook));
            push(makeMove(src, dst-1, bishop));
        }

        if (T == MoveType::Evasions)
        {
            if (square_bb[dst-1] & mValid)
            {
                push(makeMove(src, dst-1, queen));
                push(makeMove(src, dst-1, knight));
                push(makeMove(src, dst-1, rook));
                push(makeMove(src, dst-1, bishop));
            }
        }

        if (T == MoveType::QuietChecks)
        {
            if (mState.getCheckSquaresBB(knight) & square_bb[dst-1])
                push(makeMove(src, dst-1, knight));
        }
    }

    if (square_bb[dst] & mState.getEmptyBB())
    {
        if (T == MoveType::Attacks || T == MoveType::All)
            push(makeMove(src, dst, queen));

        if (T == MoveType::Quiets || T == MoveType::All)
        {
            push(makeMove(src, dst, knight));
            push(makeMove(src, dst, rook));
            push(makeMove(src, dst, bishop));
        }

        if (T == MoveType::Evasions)
        {
            if (square_bb[dst] & mValid)
            {
                push(makeMove(src, dst, queen));
                push(makeMove(src, dst, knight));
                push(makeMove(src, dst, rook));
                push(makeMove(src, dst, bishop));
            }
        }

        if (T == MoveType::QuietChecks)
        {
            if (mState.getCheckSquaresBB(knight) & square_bb[dst])
                push(makeMove(src, dst, knight));
        }
    }
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movl %esi, 0x5c(%rsp)
movl %edx, 0x58(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x18(%rax), %rdi
callq 0x24ca0
movl %eax, 0x54(%rsp)
movl 0x58(%rsp), %eax
movl %eax, %edx
leaq 0x12a30b(%rip), %rcx    # 0x154b10
movabsq $0x7f7f7f7f7f7f7f7f, %rax # imm = 0x7F7F7F7F7F7F7F7F
andq (%rcx,%rdx,8), %rax
cmpq $0x0, %rax
je 0x2a977
movl 0x58(%rsp), %edi
movl $0x1, %esi
callq 0x24e60
movl %eax, %ecx
movq 0x48(%rsp), %rax
movl %ecx, %ecx
movl %ecx, %edx
leaq 0x12a2d3(%rip), %rcx    # 0x154b10
movq (%rcx,%rdx,8), %rcx
movq %rcx, 0x40(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x38(%rsp)
movl 0x54(%rsp), %edi
callq 0x24ce0
movq 0x38(%rsp), %rdi
movl %eax, %esi
callq 0x25740
movq %rax, %rcx
movq 0x40(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x2a977
movl 0x58(%rsp), %edi
movl $0x1, %esi
callq 0x24e60
movq 0x48(%rsp), %rcx
movl %eax, %eax
movl %eax, %edx
leaq 0x12a279(%rip), %rax    # 0x154b10
movq (%rax,%rdx,8), %rax
andq 0x8(%rcx), %rax
cmpq $0x0, %rax
je 0x2a975
movl 0x5c(%rsp), %eax
movl %eax, 0x28(%rsp)
movl 0x58(%rsp), %edi
movl $0x1, %esi
callq 0x24e60
movl 0x28(%rsp), %edi
movl %eax, %esi
movl $0x4, %edx
callq 0x2abe0
movq 0x48(%rsp), %rdi
movzwl %ax, %esi
callq 0x26df0
movl 0x5c(%rsp), %eax
movl %eax, 0x2c(%rsp)
movl 0x58(%rsp), %edi
movl $0x1, %esi
callq 0x24e60
movl 0x2c(%rsp), %edi
movl %eax, %esi
movl $0x1, %edx
callq 0x2abe0
movq 0x48(%rsp), %rdi
movzwl %ax, %esi
callq 0x26df0
movl 0x5c(%rsp), %eax
movl %eax, 0x30(%rsp)
movl 0x58(%rsp), %edi
movl $0x1, %esi
callq 0x24e60
movl 0x30(%rsp), %edi
movl %eax, %esi
movl $0x3, %edx
callq 0x2abe0
movq 0x48(%rsp), %rdi
movzwl %ax, %esi
callq 0x26df0
movl 0x5c(%rsp), %eax
movl %eax, 0x34(%rsp)
movl 0x58(%rsp), %edi
movl $0x1, %esi
callq 0x24e60
movl 0x34(%rsp), %edi
movl %eax, %esi
movl $0x2, %edx
callq 0x2abe0
movq 0x48(%rsp), %rdi
movzwl %ax, %esi
callq 0x26df0
jmp 0x2a977
movl 0x58(%rsp), %eax
movl %eax, %edx
leaq 0x12a18c(%rip), %rcx    # 0x154b10
movabsq $-0x101010101010102, %rax # imm = 0xFEFEFEFEFEFEFEFE
andq (%rcx,%rdx,8), %rax
cmpq $0x0, %rax
je 0x2aaf6
movl 0x58(%rsp), %edi
movl $0x1, %esi
callq 0x24e80
movl %eax, %ecx
movq 0x48(%rsp), %rax
movl %ecx, %ecx
movl %ecx, %edx
leaq 0x12a154(%rip), %rcx    # 0x154b10
movq (%rcx,%rdx,8), %rcx
movq %rcx, 0x20(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
movl 0x54(%rsp), %edi
callq 0x24ce0
movq 0x18(%rsp), %rdi
movl %eax, %esi
callq 0x25740
movq %rax, %rcx
movq 0x20(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x2aaf6
movl 0x58(%rsp), %edi
movl $0x1, %esi
callq 0x24e80
movq 0x48(%rsp), %rcx
movl %eax, %eax
movl %eax, %edx
leaq 0x12a0fa(%rip), %rax    # 0x154b10
movq (%rax,%rdx,8), %rax
andq 0x8(%rcx), %rax
cmpq $0x0, %rax
je 0x2aaf4
movl 0x5c(%rsp), %eax
movl %eax, 0x8(%rsp)
movl 0x58(%rsp), %edi
movl $0x1, %esi
callq 0x24e80
movl 0x8(%rsp), %edi
movl %eax, %esi
movl $0x4, %edx
callq 0x2abe0
movq 0x48(%rsp), %rdi
movzwl %ax, %esi
callq 0x26df0
movl 0x5c(%rsp), %eax
movl %eax, 0xc(%rsp)
movl 0x58(%rsp), %edi
movl $0x1, %esi
callq 0x24e80
movl 0xc(%rsp), %edi
movl %eax, %esi
movl $0x1, %edx
callq 0x2abe0
movq 0x48(%rsp), %rdi
movzwl %ax, %esi
callq 0x26df0
movl 0x5c(%rsp), %eax
movl %eax, 0x10(%rsp)
movl 0x58(%rsp), %edi
movl $0x1, %esi
callq 0x24e80
movl 0x10(%rsp), %edi
movl %eax, %esi
movl $0x3, %edx
callq 0x2abe0
movq 0x48(%rsp), %rdi
movzwl %ax, %esi
callq 0x26df0
movl 0x5c(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x58(%rsp), %edi
movl $0x1, %esi
callq 0x24e80
movl 0x14(%rsp), %edi
movl %eax, %esi
movl $0x2, %edx
callq 0x2abe0
movq 0x48(%rsp), %rdi
movzwl %ax, %esi
callq 0x26df0
jmp 0x2aaf6
movq 0x48(%rsp), %rax
movl 0x58(%rsp), %ecx
movl %ecx, %edx
leaq 0x12a008(%rip), %rcx    # 0x154b10
movq (%rcx,%rdx,8), %rcx
movq %rcx, (%rsp)
movq 0x18(%rax), %rdi
callq 0x24ef0
movq %rax, %rcx
movq (%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x2abcb
movq 0x48(%rsp), %rcx
movl 0x58(%rsp), %eax
movl %eax, %edx
leaq 0x129fd1(%rip), %rax    # 0x154b10
movq (%rax,%rdx,8), %rax
andq 0x8(%rcx), %rax
cmpq $0x0, %rax
je 0x2abc9
movl 0x5c(%rsp), %edi
movl 0x58(%rsp), %esi
movl $0x4, %edx
callq 0x2abe0
movq 0x48(%rsp), %rdi
movzwl %ax, %esi
callq 0x26df0
movl 0x5c(%rsp), %edi
movl 0x58(%rsp), %esi
movl $0x1, %edx
callq 0x2abe0
movq 0x48(%rsp), %rdi
movzwl %ax, %esi
callq 0x26df0
movl 0x5c(%rsp), %edi
movl 0x58(%rsp), %esi
movl $0x3, %edx
callq 0x2abe0
movq 0x48(%rsp), %rdi
movzwl %ax, %esi
callq 0x26df0
movl 0x5c(%rsp), %edi
movl 0x58(%rsp), %esi
movl $0x2, %edx
callq 0x2abe0
movq 0x48(%rsp), %rdi
movzwl %ax, %esi
callq 0x26df0
jmp 0x2abcb
addq $0x68, %rsp
retq