// File: /workspace/github_cpp_makefile_star2_O1/jswaff[P]prophet3/src/movegen.cpp
// Function: gen_pawn_moves(unsigned long long*, position*, bool, bool)
move* gen_pawn_moves(move* m,position* p,bool caps,bool noncaps) {

    uint64 all_pieces = p->white_pieces | p->black_pieces;
    uint64 pmap;

    // captures
    if (p->player==WHITE) {
        if (caps) {
            uint64 targets = p->black_pieces;
            if (p->ep_sq != NO_SQUARE) targets |= bb_squares[p->ep_sq];

            // attacks west
            pmap = ((p->white_pawns & ~bb_files[FILE_A]) >> 9) & targets;
            while (pmap) {
                square_t sq = (square_t)get_msb(pmap);
                piece_t captured = sq==p->ep_sq ? PAWN : (piece_t)p->piece[sq];
                m = add_pawn_move(m,southeast(sq),sq,captured,sq==p->ep_sq);
                pmap ^= bb_squares[sq];
            }

            // attacks east
            pmap = ((p->white_pawns & ~bb_files[FILE_H]) >> 7) & targets;
            while (pmap) {
                square_t sq = (square_t)get_msb(pmap);
                piece_t captured = sq==p->ep_sq ? PAWN : (piece_t)p->piece[sq];
                m = add_pawn_move(m,southwest(sq),sq,captured,sq==p->ep_sq);
                pmap ^= bb_squares[sq];
            }

            // push promotions
            pmap = ((p->white_pawns & bb_ranks[RANK_7]) >> 8) & ~all_pieces;
            while (pmap) {
                square_t sq = (square_t)get_msb(pmap);
                m = add_pawn_move(m,south(sq),sq,NO_PIECE,false);
                pmap ^= bb_squares[sq];
            }
        }

        // pawn pushes less promotions
        if (noncaps) {
            pmap = ((p->white_pawns & ~bb_ranks[RANK_7]) >> 8) & ~all_pieces;
            while (pmap) {
                square_t sq = (square_t)get_msb(pmap);
                m = add_pawn_move(m,south(sq),sq,NO_PIECE,false);
                if (get_rank(sq)==RANK_3 && p->piece[north(sq)]==NO_PIECE) {
                    m = add_pawn_move(m,south(sq),north(sq),NO_PIECE,false);
                }
                pmap ^= bb_squares[sq];
            }
        }
    } else {
        if (caps) {
            uint64 targets = p->white_pieces;
            if (p->ep_sq != NO_SQUARE) targets |= bb_squares[p->ep_sq];

            // attacks west
            pmap = ((p->black_pawns & ~bb_files[FILE_A]) << 7) & targets;
            while (pmap) {
                square_t sq = (square_t)get_lsb(pmap);
                piece_t captured = sq==p->ep_sq ? PAWN : (piece_t)p->piece[sq];
                m = add_pawn_move(m,northeast(sq),sq,captured,sq==p->ep_sq);
                pmap ^= bb_squares[sq];
            }

            // attacks west
            pmap = ((p->black_pawns & ~bb_files[FILE_H]) << 9) & targets;
            while (pmap) {
                square_t sq = (square_t)get_lsb(pmap);
                piece_t captured = sq==p->ep_sq ? PAWN : (piece_t)p->piece[sq];
                m = add_pawn_move(m,northwest(sq),sq,captured,sq==p->ep_sq);
                pmap ^= bb_squares[sq];
            }

            // push promotions
            pmap = ((p->black_pawns & bb_ranks[RANK_2]) << 8) & ~all_pieces;
            while (pmap) {
                square_t sq = (square_t)get_lsb(pmap);
                m = add_pawn_move(m,north(sq),sq,NO_PIECE,false);
                pmap ^= bb_squares[sq];
            }
        }

        // pawn pushes less promotions
        if (noncaps) {
            pmap = ((p->black_pawns & ~bb_ranks[RANK_2]) << 8) & ~all_pieces;
            while (pmap) {
                square_t sq = (square_t)get_lsb(pmap);
                m = add_pawn_move(m,north(sq),sq,NO_PIECE,false);
                if (get_rank(sq)==RANK_6 && p->piece[south(sq)]==NO_PIECE) {
                    m = add_pawn_move(m,north(sq),south(sq),NO_PIECE,false);
                }
                pmap ^= bb_squares[sq];
            }
        }
    }

    return m;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movq 0x1a8(%rsi), %rsi
movq 0x1b0(%rbx), %rdi
movq %rdi, %r15
orq %rsi, %r15
cmpl $0x1, 0x138(%rbx)
movl %ecx, 0x4(%rsp)
jne 0x7bac
testb %dl, %dl
je 0x7af5
movl 0x13c(%rbx), %eax
cmpq $0x40, %rax
je 0x7987
leaq 0xf2b2d(%rip), %rcx     # 0xfa4b0
orq (%rcx,%rax,8), %rdi
leaq 0xf2aa2(%rip), %rax     # 0xfa430
movq (%rax), %r12
notq %r12
andq 0x158(%rbx), %r12
shrq $0x9, %r12
movq %rdi, 0x8(%rsp)
andq %rdi, %r12
movq %r15, 0x10(%rsp)
je 0x7a0e
movq %r12, %rdi
callq 0x3c25
movl %eax, %r13d
movl $0x1, %ebp
movl %eax, %r15d
cmpl 0x13c(%rbx), %eax
je 0x79cd
movl (%rbx,%r15,4), %ebp
movl %r13d, %edi
callq 0xcd3f
xorl %r8d, %r8d
cmpl 0x13c(%rbx), %r13d
sete %r8b
movq %r14, %rdi
movl %eax, %esi
movl %r13d, %edx
movl %ebp, %ecx
callq 0x8448
movq %rax, %r14
leaq 0xf2ab4(%rip), %rax     # 0xfa4b0
movq (%rax,%r15,8), %rax
movq %rax, %rcx
xorq %r12, %rcx
cmpq %r12, %rax
movq %rcx, %r12
jne 0x79ae
leaq 0xf2a1b(%rip), %rax     # 0xfa430
movq 0x38(%rax), %r12
notq %r12
andq 0x158(%rbx), %r12
shrq $0x7, %r12
andq 0x8(%rsp), %r12
je 0x7a8e
movq %r12, %rdi
callq 0x3c25
movl %eax, %r13d
movl $0x1, %ebp
movl %eax, %r15d
cmpl 0x13c(%rbx), %eax
je 0x7a4d
movl (%rbx,%r15,4), %ebp
movl %r13d, %edi
callq 0xcd87
xorl %r8d, %r8d
cmpl 0x13c(%rbx), %r13d
sete %r8b
movq %r14, %rdi
movl %eax, %esi
movl %r13d, %edx
movl %ebp, %ecx
callq 0x8448
movq %rax, %r14
leaq 0xf2a34(%rip), %rax     # 0xfa4b0
movq (%rax,%r15,8), %rax
movq %rax, %rcx
xorq %r12, %rcx
cmpq %r12, %rax
movq %rcx, %r12
jne 0x7a2e
leaq 0xf29db(%rip), %rax     # 0xfa470
movq 0x8(%rax), %rax
andq 0x158(%rbx), %rax
shrq $0x8, %rax
movq 0x10(%rsp), %r15
movq %r15, %r12
notq %r12
andq %rax, %r12
je 0x7af5
leaq 0xf29f5(%rip), %r13     # 0xfa4b0
movq %r12, %rdi
callq 0x3c25
movl %eax, %ebp
movl %eax, %edi
callq 0xcc4a
movq %r14, %rdi
movl %eax, %esi
movl %ebp, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x8448
movq %rax, %r14
movl %ebp, %eax
movq (%r13,%rax,8), %rax
movq %rax, %rcx
xorq %r12, %rcx
cmpq %r12, %rax
movq %rcx, %r12
jne 0x7abb
cmpb $0x0, 0x4(%rsp)
je 0x7de5
leaq 0xf2969(%rip), %rax     # 0xfa470
movq 0x8(%rax), %rax
notq %rax
andq 0x158(%rbx), %rax
shrq $0x8, %rax
notq %r15
andq %rax, %r15
je 0x7de5
leaq 0xf2984(%rip), %r13     # 0xfa4b0
movq %r15, %rdi
callq 0x3c25
movl %eax, %ebp
movl %eax, %edi
callq 0xcc4a
movq %r14, %rdi
movl %eax, %esi
movl %ebp, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x8448
movq %rax, %r14
movl %ebp, %edi
callq 0xca75
cmpl $0x5, %eax
jne 0x7b92
movl %ebp, %edi
callq 0xcc11
movl %eax, %eax
cmpl $0x0, (%rbx,%rax,4)
jne 0x7b92
movl %ebp, %edi
callq 0xcc4a
movl %eax, %r12d
movl %ebp, %edi
callq 0xcc11
movq %r14, %rdi
movl %r12d, %esi
movl %eax, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x8448
movq %rax, %r14
movl %ebp, %eax
movq (%r13,%rax,8), %rax
movq %rax, %rcx
xorq %r15, %rcx
cmpq %r15, %rax
movq %rcx, %r15
jne 0x7b2c
jmp 0x7de5
notq %r15
testb %dl, %dl
je 0x7d36
movl 0x13c(%rbx), %eax
cmpq $0x40, %rax
je 0x7bce
leaq 0xf28e6(%rip), %rcx     # 0xfa4b0
orq (%rcx,%rax,8), %rsi
leaq 0xf285b(%rip), %rax     # 0xfa430
movq (%rax), %r12
notq %r12
andq 0x160(%rbx), %r12
shlq $0x7, %r12
movq %rsi, 0x8(%rsp)
andq %rsi, %r12
movq %r15, 0x10(%rsp)
je 0x7c55
movq %r12, %rdi
callq 0x3b5b
movl %eax, %r13d
movl $0x1, %ebp
movl %eax, %r15d
cmpl 0x13c(%rbx), %eax
je 0x7c14
movl (%rbx,%r15,4), %ebp
movl %r13d, %edi
callq 0xccfc
xorl %r8d, %r8d
cmpl 0x13c(%rbx), %r13d
sete %r8b
movq %r14, %rdi
movl %eax, %esi
movl %r13d, %edx
movl %ebp, %ecx
callq 0x8448
movq %rax, %r14
leaq 0xf286d(%rip), %rax     # 0xfa4b0
movq (%rax,%r15,8), %rax
movq %rax, %rcx
xorq %r12, %rcx
cmpq %r12, %rax
movq %rcx, %r12
jne 0x7bf5
leaq 0xf27d4(%rip), %rax     # 0xfa430
movq 0x38(%rax), %r12
notq %r12
andq 0x160(%rbx), %r12
shlq $0x9, %r12
andq 0x8(%rsp), %r12
je 0x7cd5
movq %r12, %rdi
callq 0x3b5b
movl %eax, %r13d
movl $0x1, %ebp
movl %eax, %r15d
cmpl 0x13c(%rbx), %eax
je 0x7c94
movl (%rbx,%r15,4), %ebp
movl %r13d, %edi
callq 0xcdc7
xorl %r8d, %r8d
cmpl 0x13c(%rbx), %r13d
sete %r8b
movq %r14, %rdi
movl %eax, %esi
movl %r13d, %edx
movl %ebp, %ecx
callq 0x8448
movq %rax, %r14
leaq 0xf27ed(%rip), %rax     # 0xfa4b0
movq (%rax,%r15,8), %rax
movq %rax, %rcx
xorq %r12, %rcx
cmpq %r12, %rax
movq %rcx, %r12
jne 0x7c75
leaq 0xf2794(%rip), %rax     # 0xfa470
movq 0x30(%rax), %r12
andq 0x160(%rbx), %r12
shlq $0x8, %r12
movq 0x10(%rsp), %r15
andq %r15, %r12
je 0x7d36
leaq 0xf27b4(%rip), %r13     # 0xfa4b0
movq %r12, %rdi
callq 0x3b5b
movl %eax, %ebp
movl %eax, %edi
callq 0xcc11
movq %r14, %rdi
movl %eax, %esi
movl %ebp, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x8448
movq %rax, %r14
movl %ebp, %eax
movq (%r13,%rax,8), %rax
movq %rax, %rcx
xorq %r12, %rcx
cmpq %r12, %rax
movq %rcx, %r12
jne 0x7cfc
cmpb $0x0, 0x4(%rsp)
je 0x7de5
leaq 0xf2728(%rip), %rax     # 0xfa470
movq 0x30(%rax), %r12
notq %r12
andq 0x160(%rbx), %r12
shlq $0x8, %r12
andq %r15, %r12
je 0x7de5
leaq 0xf2746(%rip), %r13     # 0xfa4b0
movq %r12, %rdi
callq 0x3b5b
movl %eax, %ebp
movl %eax, %edi
callq 0xcc11
movq %r14, %rdi
movl %eax, %esi
movl %ebp, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x8448
movq %rax, %r14
movl %ebp, %edi
callq 0xca75
cmpl $0x2, %eax
jne 0x7dd0
movl %ebp, %edi
callq 0xcc4a
movl %eax, %eax
cmpl $0x0, (%rbx,%rax,4)
jne 0x7dd0
movl %ebp, %edi
callq 0xcc11
movl %eax, %r15d
movl %ebp, %edi
callq 0xcc4a
movq %r14, %rdi
movl %r15d, %esi
movl %eax, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x8448
movq %rax, %r14
movl %ebp, %eax
movq (%r13,%rax,8), %rax
movq %rax, %rcx
xorq %r12, %rcx
cmpq %r12, %rax
movq %rcx, %r12
jne 0x7d6a
movq %r14, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq