// File: /workspace/github_cpp_makefile_star2_O2/cpirc[P]Monochrome/src/move_gen.cpp
// Function: void add_moves<false, (Piece)0>(Position const&, unsigned int*, int&)
void add_moves<false, PAWN>(const Position& pos, Move* ml, int& idx) {
    std::uint64_t pawns = get_piece(pos, PAWN, US);
    std::uint64_t empty = ~get_occupancy(pos);
    std::uint64_t singles, doubles;

    // Single push
    singles = (pawns << 8) & empty;

    // Separate promotions
    singles &= ~rank_mask[RANK_8];

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

        ml[idx] = get_move(dest - 8, dest, NORMAL);
        idx++;

        singles &= singles - 1;
    }

    // Double push
    singles = ((pawns & rank_mask[RANK_2]) << 8) & empty;
    doubles = (singles << 8) & empty;

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

        ml[idx] = get_move(dest - 16, dest, DOUBLE_PUSH);
        idx++;

        doubles &= doubles - 1;
    }

    // Promotions
    singles = ((pawns & rank_mask[RANK_7]) << 8) & empty;

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

        ml[idx] = get_move(dest - 8, dest, PROMOTION, TO_KNIGHT);
        idx++;

        ml[idx] = get_move(dest - 8, dest, PROMOTION, TO_BISHOP);
        idx++;

        ml[idx] = get_move(dest - 8, dest, PROMOTION, TO_ROOK);
        idx++;

        ml[idx] = get_move(dest - 8, dest, PROMOTION, TO_QUEEN);
        idx++;

        singles &= singles - 1;
    }

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

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdx, %rbx
movq %rsi, %r14
movq 0x30(%rdi), %r13
movq (%rdi), %r12
andq %r13, %r12
movq %rdi, -0x30(%rbp)
orq 0x38(%rdi), %r13
notq %r13
shlq $0x8, %r12
andq %r13, %r12
movabsq $0xffffffffffff00, %r15 # imm = 0xFFFFFFFFFFFF00
andq %r12, %r15
testq %r15, %r15
je 0x4526
movq %r15, %rdi
callq 0x2939
leal -0x8(%rax), %ecx
movzbl %cl, %ecx
movzbl %al, %eax
shll $0x6, %eax
orl %ecx, %eax
movslq (%rbx), %rcx
movl %eax, (%r14,%rcx,4)
incl (%rbx)
leaq -0x1(%r15), %rax
andq %rax, %r15
jmp 0x44f9
movl %r12d, %eax
shll $0x8, %eax
andl %eax, %r13d
andl $0xff000000, %r13d      # imm = 0xFF000000
testq %r13, %r13
je 0x4568
movq %r13, %rdi
callq 0x2939
leal -0x10(%rax), %ecx
movzbl %cl, %ecx
movzbl %al, %eax
shll $0x6, %eax
orl %ecx, %eax
orl $0x5000, %eax           # imm = 0x5000
movslq (%rbx), %rcx
movl %eax, (%r14,%rcx,4)
incl (%rbx)
leaq -0x1(%r13), %rax
andq %rax, %r13
jmp 0x4536
movabsq $-0x100000000000000, %rax # imm = 0xFF00000000000000
andq %rax, %r12
testq %r12, %r12
je 0x45e1
movq %r12, %rdi
callq 0x2939
leal -0x8(%rax), %ecx
movzbl %cl, %ecx
movzbl %al, %eax
shll $0x6, %eax
orl %ecx, %eax
leal 0xc000(%rax), %ecx
movslq (%rbx), %rdx
movl %ecx, (%r14,%rdx,4)
movslq (%rbx), %rcx
leaq 0x1(%rcx), %rdx
movl %edx, (%rbx)
leal 0x14000(%rax), %edx
movl %edx, 0x4(%r14,%rcx,4)
movslq (%rbx), %rcx
leaq 0x1(%rcx), %rdx
movl %edx, (%rbx)
leal 0x1c000(%rax), %edx
movl %edx, 0x4(%r14,%rcx,4)
movslq (%rbx), %rcx
leaq 0x1(%rcx), %rdx
movl %edx, (%rbx)
orl $0x24000, %eax          # imm = 0x24000
movl %eax, 0x4(%r14,%rcx,4)
incl (%rbx)
leaq -0x1(%r12), %rax
jmp 0x4572
movq -0x30(%rbp), %rdi
movq %r14, %rsi
movq %rbx, %rdx
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4a08