// File: /workspace/github_cpp_makefile_star2_O3/cpirc[P]Monochrome/src/move_gen.cpp
// Function: void add_moves<true, (Piece)0>(Position const&, unsigned int*, int&)
void add_moves<true, PAWN>(const Position& pos, Move* ml, int& idx) {
    std::uint64_t pawns = get_piece(pos, PAWN, US);
    std::uint64_t them = get_colour(pos, THEM);
    std::uint64_t dest_bb;

    // Left captures
    dest_bb = ((pawns & ~file_mask[FILE_A]) << 7) & them & ~rank_mask[RANK_8];

    while (dest_bb) {
        Square dest = lsb(dest_bb);

        ml[idx] = get_move(dest - 7, dest, CAPTURE);
        idx++;

        dest_bb &= dest_bb - 1;
    }

    // Left capture-promotions
    dest_bb = ((pawns & ~file_mask[FILE_A]) << 7) & them & rank_mask[RANK_8];

    while (dest_bb) {
        Square dest = lsb(dest_bb);

        ml[idx] = get_move(dest - 7, dest, PROM_CAPTURE, TO_KNIGHT);
        idx++;

        ml[idx] = get_move(dest - 7, dest, PROM_CAPTURE, TO_BISHOP);
        idx++;

        ml[idx] = get_move(dest - 7, dest, PROM_CAPTURE, TO_ROOK);
        idx++;

        ml[idx] = get_move(dest - 7, dest, PROM_CAPTURE, TO_QUEEN);
        idx++;

        dest_bb &= dest_bb - 1;
    }

    // Right captures
    dest_bb = ((pawns & ~file_mask[FILE_H]) << 9) & them & ~rank_mask[RANK_8];

    while (dest_bb) {
        Square dest = lsb(dest_bb);

        ml[idx] = get_move(dest - 9, dest, CAPTURE);
        idx++;

        dest_bb &= dest_bb - 1;
    }

    // Right capture-promotions
    dest_bb = ((pawns & ~file_mask[FILE_H]) << 9) & them & rank_mask[RANK_8];

    while (dest_bb) {
        Square dest = lsb(dest_bb);

        ml[idx] = get_move(dest - 9, dest, PROM_CAPTURE, TO_KNIGHT);
        idx++;

        ml[idx] = get_move(dest - 9, dest, PROM_CAPTURE, TO_BISHOP);
        idx++;

        ml[idx] = get_move(dest - 9, dest, PROM_CAPTURE, TO_ROOK);
        idx++;

        ml[idx] = get_move(dest - 9, dest, PROM_CAPTURE, TO_QUEEN);
        idx++;

        dest_bb &= dest_bb - 1;
    }

    // En passant
    if (pos.epsq != INVALID_SQUARE) {
        pawns &= pawn_attacks(pos.epsq, THEM);

        while (pawns) {
            Square from = lsb(pawns);

            ml[idx] = get_move(from, pos.epsq, ENPASSANT);
            idx++;

            pawns &= pawns - 1;
        }
    }

    add_moves<true, KNIGHT>(pos, ml, idx);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
movq 0x30(%rdi), %rax
movq 0x38(%rdi), %rcx
andq (%rdi), %rax
movq %rax, %r8
shlq $0x7, %r8
andq %rcx, %r8
movabsq $0x7f7f7f7f7f7f00, %r9  # imm = 0x7F7F7F7F7F7F00
andq %r8, %r9
je 0x56ef
movl (%rdx), %r10d
bsfq %r9, %r11
leal 0xf9(%r11), %ebx
movzbl %bl, %ebx
shll $0x6, %r11d
orl %ebx, %r11d
orl $0x2000, %r11d          # imm = 0x2000
movslq %r10d, %r10
movl %r11d, (%rsi,%r10,4)
movl (%rdx), %r10d
incl %r10d
movl %r10d, (%rdx)
leaq -0x1(%r9), %r11
andq %r11, %r9
jne 0x56ba
movabsq $0x7f00000000000000, %r9 # imm = 0x7F00000000000000
andq %r9, %r8
je 0x5779
movl (%rdx), %r10d
bsfq %r8, %r9
leal 0xf9(%r9), %r11d
movzbl %r11b, %r11d
shll $0x6, %r9d
orl %r11d, %r9d
leal 0xe000(%r9), %r11d
movslq %r10d, %r10
movl %r11d, (%rsi,%r10,4)
movslq (%rdx), %r10
leaq 0x1(%r10), %r11
movl %r11d, (%rdx)
leal 0x16000(%r9), %r11d
movl %r11d, 0x4(%rsi,%r10,4)
movslq (%rdx), %r10
leaq 0x1(%r10), %r11
movl %r11d, (%rdx)
leal 0x1e000(%r9), %r11d
movl %r11d, 0x4(%rsi,%r10,4)
movslq (%rdx), %r10
leaq 0x1(%r10), %r11
movl %r11d, (%rdx)
orl $0x26000, %r9d          # imm = 0x26000
movl %r9d, 0x4(%rsi,%r10,4)
movl (%rdx), %r10d
incl %r10d
movl %r10d, (%rdx)
leaq -0x1(%r8), %r9
andq %r9, %r8
jne 0x5701
movq %rax, %r8
shlq $0x9, %r8
andq %r8, %rcx
movabsq $0xfefefefefefe00, %r8  # imm = 0xFEFEFEFEFEFE00
andq %rcx, %r8
je 0x57cb
movl (%rdx), %r9d
bsfq %r8, %r10
leal 0xf7(%r10), %r11d
movzbl %r11b, %r11d
shll $0x6, %r10d
orl %r11d, %r10d
orl $0x2000, %r10d          # imm = 0x2000
movslq %r9d, %r9
movl %r10d, (%rsi,%r9,4)
movl (%rdx), %r9d
incl %r9d
movl %r9d, (%rdx)
leaq -0x1(%r8), %r10
andq %r10, %r8
jne 0x5795
movabsq $-0x200000000000000, %r8 # imm = 0xFE00000000000000
andq %r8, %rcx
je 0x5855
movl (%rdx), %r9d
bsfq %rcx, %r8
leal 0xf7(%r8), %r10d
movzbl %r10b, %r10d
shll $0x6, %r8d
orl %r10d, %r8d
leal 0xe000(%r8), %r10d
movslq %r9d, %r9
movl %r10d, (%rsi,%r9,4)
movslq (%rdx), %r9
leaq 0x1(%r9), %r10
movl %r10d, (%rdx)
leal 0x16000(%r8), %r10d
movl %r10d, 0x4(%rsi,%r9,4)
movslq (%rdx), %r9
leaq 0x1(%r9), %r10
movl %r10d, (%rdx)
leal 0x1e000(%r8), %r10d
movl %r10d, 0x4(%rsi,%r9,4)
movslq (%rdx), %r9
leaq 0x1(%r9), %r10
movl %r10d, (%rdx)
orl $0x26000, %r8d          # imm = 0x26000
movl %r8d, 0x4(%rsi,%r9,4)
movl (%rdx), %r9d
incl %r9d
movl %r9d, (%rdx)
leaq -0x1(%rcx), %r8
andq %r8, %rcx
jne 0x57dd
movzbl 0x42(%rdi), %ecx
cmpq $0x40, %rcx
je 0x589d
leaq 0xb95a(%rip), %r8       # 0x111c0
andq 0x200(%r8,%rcx,8), %rax
je 0x589d
shll $0x6, %ecx
movl (%rdx), %r8d
bsfq %rax, %r9
orl %ecx, %r9d
orl $0x3000, %r9d           # imm = 0x3000
movslq %r8d, %r8
movl %r9d, (%rsi,%r8,4)
movl (%rdx), %r8d
incl %r8d
movl %r8d, (%rdx)
leaq -0x1(%rax), %r9
andq %r9, %rax
jne 0x5876
popq %rbx
popq %rbp
jmp 0x5e15