// File: /workspace/github_cpp_makefile_star2_O2/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 %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %rbx
movq %rsi, %r14
movq 0x30(%rdi), %r12
movq 0x38(%rdi), %r13
movq %rdi, -0x38(%rbp)
andq (%rdi), %r12
movq %r12, -0x30(%rbp)
shlq $0x7, %r12
andq %r13, %r12
movabsq $0x7f7f7f7f7f7f00, %r15 # imm = 0x7F7F7F7F7F7F00
andq %r12, %r15
testq %r15, %r15
je 0x466e
movq %r15, %rdi
callq 0x2939
leal -0x7(%rax), %ecx
movzbl %cl, %ecx
movzbl %al, %eax
shll $0x6, %eax
orl %ecx, %eax
orl $0x2000, %eax           # imm = 0x2000
movslq (%rbx), %rcx
movl %eax, (%r14,%rcx,4)
incl (%rbx)
leaq -0x1(%r15), %rax
andq %rax, %r15
jmp 0x463c
movabsq $0x7f00000000000000, %rax # imm = 0x7F00000000000000
andq %rax, %r12
testq %r12, %r12
je 0x46ed
movq %r12, %rdi
callq 0x2939
leal -0x7(%rax), %ecx
movzbl %cl, %ecx
movzbl %al, %eax
shll $0x6, %eax
orl %ecx, %eax
movl %eax, %ecx
orl $0xe000, %ecx           # imm = 0xE000
movslq (%rbx), %rdx
movl %ecx, (%r14,%rdx,4)
movslq (%rbx), %rcx
leaq 0x1(%rcx), %rdx
movl %edx, (%rbx)
movl %eax, %edx
orl $0x16000, %edx          # imm = 0x16000
movl %edx, 0x4(%r14,%rcx,4)
movslq (%rbx), %rcx
leaq 0x1(%rcx), %rdx
movl %edx, (%rbx)
movl %eax, %edx
orl $0x1e000, %edx          # imm = 0x1E000
movl %edx, 0x4(%r14,%rcx,4)
movslq (%rbx), %rcx
leaq 0x1(%rcx), %rdx
movl %edx, (%rbx)
orl $0x26000, %eax          # imm = 0x26000
movl %eax, 0x4(%r14,%rcx,4)
incl (%rbx)
leaq -0x1(%r12), %rax
jmp 0x4678
movq -0x30(%rbp), %r12
movq %r12, %rax
shlq $0x9, %rax
andq %rax, %r13
movabsq $0xfefefefefefe00, %r15 # imm = 0xFEFEFEFEFEFE00
andq %r13, %r15
testq %r15, %r15
je 0x473a
movq %r15, %rdi
callq 0x2939
leal -0x9(%rax), %ecx
movzbl %cl, %ecx
movzbl %al, %eax
shll $0x6, %eax
orl %ecx, %eax
orl $0x2000, %eax           # imm = 0x2000
movslq (%rbx), %rcx
movl %eax, (%r14,%rcx,4)
incl (%rbx)
leaq -0x1(%r15), %rax
andq %rax, %r15
jmp 0x4708
movabsq $-0x200000000000000, %rax # imm = 0xFE00000000000000
andq %rax, %r13
movq -0x38(%rbp), %r15
testq %r13, %r13
je 0x47bf
movq %r13, %rdi
callq 0x2939
leal -0x9(%rax), %ecx
movzbl %cl, %ecx
movzbl %al, %eax
shll $0x6, %eax
orl %ecx, %eax
movl %eax, %ecx
orl $0xe000, %ecx           # imm = 0xE000
movslq (%rbx), %rdx
movl %ecx, (%r14,%rdx,4)
movslq (%rbx), %rcx
leaq 0x1(%rcx), %rdx
movl %edx, (%rbx)
movl %eax, %edx
orl $0x16000, %edx          # imm = 0x16000
movl %edx, 0x4(%r14,%rcx,4)
movslq (%rbx), %rcx
leaq 0x1(%rcx), %rdx
movl %edx, (%rbx)
movl %eax, %edx
orl $0x1e000, %edx          # imm = 0x1E000
movl %edx, 0x4(%r14,%rcx,4)
movslq (%rbx), %rcx
leaq 0x1(%rcx), %rdx
movl %edx, (%rbx)
orl $0x26000, %eax          # imm = 0x26000
movl %eax, 0x4(%r14,%rcx,4)
incl (%rbx)
leaq -0x1(%r13), %rax
andq %rax, %r13
jmp 0x474b
movzbl 0x42(%r15), %eax
cmpq $0x40, %rax
jne 0x47e6
movq %r15, %rdi
movq %r14, %rsi
movq %rbx, %rdx
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4aa8
leaq 0xa9b3(%rip), %rcx      # 0xf1a0
andq 0x200(%rcx,%rax,8), %r12
testq %r12, %r12
je 0x47ca
movq %r12, %rdi
callq 0x2939
movzbl 0x42(%r15), %ecx
movzbl %al, %eax
shll $0x6, %ecx
orl %eax, %ecx
orl $0x3000, %ecx           # imm = 0x3000
movslq (%rbx), %rax
movl %ecx, (%r14,%rax,4)
incl (%rbx)
leaq -0x1(%r12), %rax
andq %rax, %r12
jmp 0x47f5