// File: 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
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movb %cl, %al
movb %dl, %cl
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
andb $0x1, %cl
movb %cl, -0x11(%rbp)
andb $0x1, %al
movb %al, -0x12(%rbp)
movq -0x10(%rbp), %rax
movq 0x1a8(%rax), %rax
movq -0x10(%rbp), %rcx
orq 0x1b0(%rcx), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x1, 0x138(%rax)
jne 0xb22e
testb $0x1, -0x11(%rbp)
je 0xb11b
movq -0x10(%rbp), %rax
movq 0x1b0(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x40, 0x13c(%rax)
je 0xaf02
movq -0x10(%rbp), %rax
movl 0x13c(%rax), %eax
movl %eax, %ecx
leaq 0xfa77a(%rip), %rax     # 0x105670
movq (%rax,%rcx,8), %rax
orq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq 0x158(%rax), %rax
leaq 0xfa6dc(%rip), %rcx     # 0x1055f0
movq (%rcx), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
shrq $0x9, %rax
andq -0x30(%rbp), %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0xafc8
movq -0x28(%rbp), %rdi
callq 0x4a00
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x13c(%rcx), %eax
jne 0xaf5a
movl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0xaf67
movq -0x10(%rbp), %rax
movl -0x34(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
movl %eax, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x78(%rbp)
movl -0x34(%rbp), %edi
callq 0x126a0
movq -0x78(%rbp), %rdi
movl %eax, %esi
movl -0x34(%rbp), %edx
movl -0x38(%rbp), %ecx
movl -0x34(%rbp), %eax
movq -0x10(%rbp), %r8
cmpl 0x13c(%r8), %eax
sete %al
movzbl %al, %r8d
andl $0x1, %r8d
callq 0xbe00
movq %rax, -0x8(%rbp)
movl -0x34(%rbp), %eax
movl %eax, %ecx
leaq 0xfa6b9(%rip), %rax     # 0x105670
movq (%rax,%rcx,8), %rax
xorq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0xaf2a
movq -0x10(%rbp), %rax
movq 0x158(%rax), %rax
leaq 0xfa616(%rip), %rcx     # 0x1055f0
movq 0x38(%rcx), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
shrq $0x7, %rax
andq -0x30(%rbp), %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0xb095
movq -0x28(%rbp), %rdi
callq 0x4a00
movl %eax, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x13c(%rcx), %eax
jne 0xb021
movl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0xb02e
movq -0x10(%rbp), %rax
movl -0x3c(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0x7c(%rbp)
movl -0x7c(%rbp), %eax
movl %eax, -0x40(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x88(%rbp)
movl -0x3c(%rbp), %edi
callq 0x12730
movq -0x88(%rbp), %rdi
movl %eax, %esi
movl -0x3c(%rbp), %edx
movl -0x40(%rbp), %ecx
movl -0x3c(%rbp), %eax
movq -0x10(%rbp), %r8
cmpl 0x13c(%r8), %eax
sete %al
movzbl %al, %r8d
andl $0x1, %r8d
callq 0xbe00
movq %rax, -0x8(%rbp)
movl -0x3c(%rbp), %eax
movl %eax, %ecx
leaq 0xfa5ec(%rip), %rax     # 0x105670
movq (%rax,%rcx,8), %rax
xorq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0xaff1
movq -0x10(%rbp), %rax
movq 0x158(%rax), %rax
leaq 0xfa589(%rip), %rcx     # 0x105630
andq 0x8(%rcx), %rax
shrq $0x8, %rax
movq -0x20(%rbp), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0xb119
movq -0x28(%rbp), %rdi
callq 0x4a00
movl %eax, -0x44(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x90(%rbp)
movl -0x44(%rbp), %edi
callq 0x12490
movq -0x90(%rbp), %rdi
movl %eax, %esi
movl -0x44(%rbp), %edx
xorl %r8d, %r8d
movl %r8d, %ecx
callq 0xbe00
movq %rax, -0x8(%rbp)
movl -0x44(%rbp), %eax
movl %eax, %ecx
leaq 0xfa565(%rip), %rax     # 0x105670
movq (%rax,%rcx,8), %rax
xorq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0xb0be
jmp 0xb11b
testb $0x1, -0x12(%rbp)
je 0xb229
movq -0x10(%rbp), %rax
movq 0x158(%rax), %rax
leaq 0xfa4f9(%rip), %rcx     # 0x105630
movq 0x8(%rcx), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
shrq $0x8, %rax
movq -0x20(%rbp), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0xb227
movq -0x28(%rbp), %rdi
callq 0x4a00
movl %eax, -0x48(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x98(%rbp)
movl -0x48(%rbp), %edi
callq 0x12490
movq -0x98(%rbp), %rdi
movl %eax, %esi
movl -0x48(%rbp), %edx
xorl %r8d, %r8d
movl %r8d, %ecx
callq 0xbe00
movq %rax, -0x8(%rbp)
movl -0x48(%rbp), %edi
callq 0x120d0
cmpl $0x5, %eax
jne 0xb20a
movq -0x10(%rbp), %rax
movq %rax, -0xa0(%rbp)
movl -0x48(%rbp), %edi
callq 0x12410
movl %eax, %ecx
movq -0xa0(%rbp), %rax
movl %ecx, %ecx
cmpl $0x0, (%rax,%rcx,4)
jne 0xb20a
movq -0x8(%rbp), %rax
movq %rax, -0xb0(%rbp)
movl -0x48(%rbp), %edi
callq 0x12490
movl %eax, -0xa4(%rbp)
movl -0x48(%rbp), %edi
callq 0x12410
movq -0xb0(%rbp), %rdi
movl -0xa4(%rbp), %esi
movl %eax, %edx
xorl %r8d, %r8d
movl %r8d, %ecx
callq 0xbe00
movq %rax, -0x8(%rbp)
movl -0x48(%rbp), %eax
movl %eax, %ecx
leaq 0xfa45a(%rip), %rax     # 0x105670
movq (%rax,%rcx,8), %rax
xorq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0xb155
jmp 0xb229
jmp 0xb5b4
testb $0x1, -0x11(%rbp)
je 0xb4a4
movq -0x10(%rbp), %rax
movq 0x1a8(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x40, 0x13c(%rax)
je 0xb273
movq -0x10(%rbp), %rax
movl 0x13c(%rax), %eax
movl %eax, %ecx
leaq 0xfa409(%rip), %rax     # 0x105670
movq (%rax,%rcx,8), %rax
orq -0x50(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rax
movq 0x160(%rax), %rax
leaq 0xfa36b(%rip), %rcx     # 0x1055f0
movq (%rcx), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
shlq $0x7, %rax
andq -0x50(%rbp), %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0xb348
movq -0x28(%rbp), %rdi
callq 0x4870
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x13c(%rcx), %eax
jne 0xb2ce
movl $0x1, %eax
movl %eax, -0xb4(%rbp)
jmp 0xb2de
movq -0x10(%rbp), %rax
movl -0x54(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0xb4(%rbp)
movl -0xb4(%rbp), %eax
movl %eax, -0x58(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xc0(%rbp)
movl -0x54(%rbp), %edi
callq 0x12610
movq -0xc0(%rbp), %rdi
movl %eax, %esi
movl -0x54(%rbp), %edx
movl -0x58(%rbp), %ecx
movl -0x54(%rbp), %eax
movq -0x10(%rbp), %r8
cmpl 0x13c(%r8), %eax
sete %al
movzbl %al, %r8d
andl $0x1, %r8d
callq 0xbe00
movq %rax, -0x8(%rbp)
movl -0x54(%rbp), %eax
movl %eax, %ecx
leaq 0xfa339(%rip), %rax     # 0x105670
movq (%rax,%rcx,8), %rax
xorq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0xb29b
movq -0x10(%rbp), %rax
movq 0x160(%rax), %rax
leaq 0xfa296(%rip), %rcx     # 0x1055f0
movq 0x38(%rcx), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
shlq $0x9, %rax
andq -0x50(%rbp), %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0xb41e
movq -0x28(%rbp), %rdi
callq 0x4870
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x13c(%rcx), %eax
jne 0xb3a4
movl $0x1, %eax
movl %eax, -0xc4(%rbp)
jmp 0xb3b4
movq -0x10(%rbp), %rax
movl -0x5c(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0xc4(%rbp)
movl -0xc4(%rbp), %eax
movl %eax, -0x60(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xd0(%rbp)
movl -0x5c(%rbp), %edi
callq 0x127c0
movq -0xd0(%rbp), %rdi
movl %eax, %esi
movl -0x5c(%rbp), %edx
movl -0x60(%rbp), %ecx
movl -0x5c(%rbp), %eax
movq -0x10(%rbp), %r8
cmpl 0x13c(%r8), %eax
sete %al
movzbl %al, %r8d
andl $0x1, %r8d
callq 0xbe00
movq %rax, -0x8(%rbp)
movl -0x5c(%rbp), %eax
movl %eax, %ecx
leaq 0xfa263(%rip), %rax     # 0x105670
movq (%rax,%rcx,8), %rax
xorq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0xb371
movq -0x10(%rbp), %rax
movq 0x160(%rax), %rax
leaq 0xfa200(%rip), %rcx     # 0x105630
andq 0x30(%rcx), %rax
shlq $0x8, %rax
movq -0x20(%rbp), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0xb4a2
movq -0x28(%rbp), %rdi
callq 0x4870
movl %eax, -0x64(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xd8(%rbp)
movl -0x64(%rbp), %edi
callq 0x12410
movq -0xd8(%rbp), %rdi
movl %eax, %esi
movl -0x64(%rbp), %edx
xorl %r8d, %r8d
movl %r8d, %ecx
callq 0xbe00
movq %rax, -0x8(%rbp)
movl -0x64(%rbp), %eax
movl %eax, %ecx
leaq 0xfa1dc(%rip), %rax     # 0x105670
movq (%rax,%rcx,8), %rax
xorq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0xb447
jmp 0xb4a4
testb $0x1, -0x12(%rbp)
je 0xb5b2
movq -0x10(%rbp), %rax
movq 0x160(%rax), %rax
leaq 0xfa170(%rip), %rcx     # 0x105630
movq 0x30(%rcx), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
shlq $0x8, %rax
movq -0x20(%rbp), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0xb5b0
movq -0x28(%rbp), %rdi
callq 0x4870
movl %eax, -0x68(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xe0(%rbp)
movl -0x68(%rbp), %edi
callq 0x12410
movq -0xe0(%rbp), %rdi
movl %eax, %esi
movl -0x68(%rbp), %edx
xorl %r8d, %r8d
movl %r8d, %ecx
callq 0xbe00
movq %rax, -0x8(%rbp)
movl -0x68(%rbp), %edi
callq 0x120d0
cmpl $0x2, %eax
jne 0xb593
movq -0x10(%rbp), %rax
movq %rax, -0xe8(%rbp)
movl -0x68(%rbp), %edi
callq 0x12490
movl %eax, %ecx
movq -0xe8(%rbp), %rax
movl %ecx, %ecx
cmpl $0x0, (%rax,%rcx,4)
jne 0xb593
movq -0x8(%rbp), %rax
movq %rax, -0xf8(%rbp)
movl -0x68(%rbp), %edi
callq 0x12410
movl %eax, -0xec(%rbp)
movl -0x68(%rbp), %edi
callq 0x12490
movq -0xf8(%rbp), %rdi
movl -0xec(%rbp), %esi
movl %eax, %edx
xorl %r8d, %r8d
movl %r8d, %ecx
callq 0xbe00
movq %rax, -0x8(%rbp)
movl -0x68(%rbp), %eax
movl %eax, %ecx
leaq 0xfa0d1(%rip), %rax     # 0x105670
movq (%rax,%rcx,8), %rax
xorq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
jmp 0xb4de
jmp 0xb5b2
jmp 0xb5b4
movq -0x8(%rbp), %rax
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nopw %cs:(%rax,%rax)