// File: cpirc[P]Monochrome/src/move_gen.cpp
// Function: void add_moves<false, (Piece)5>(Position const&, unsigned int*, int&)
void add_moves<false, KING>(const Position& pos, Move* ml, int& idx) {
    std::uint64_t occ = get_occupancy(pos);

    Square from = lsb(get_piece(pos, KING, US));

    std::uint64_t attack_bb = attacks<KING>(from, occ) & ~occ;

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

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

        attack_bb &= attack_bb - 1;
    }

    if (!is_checked(pos, US)) {
        if (pos.castle & US_OO && !(occ & oo_castle_mask) &&
            !(attacks_to<>(pos, F1, occ, US) & get_colour(pos, THEM)) &&
            !(attacks_to<>(pos, G1, occ, US) & get_colour(pos, THEM))) {
            ml[idx] = get_move(E1, G1, CASTLE);
            idx++;
        }

        if (pos.castle & US_OOO && !(occ & ooo_castle_mask) &&
            !(attacks_to<>(pos, D1, occ, US) & get_colour(pos, THEM)) &&
            !(attacks_to<>(pos, C1, occ, US) & get_colour(pos, THEM))) {
            ml[idx] = get_move(E1, C1, CASTLE);
            idx++;
        }
    }

    // No tail call to end template recursion.
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rdi
callq 0x3ea0
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movl $0x5, %esi
xorl %edx, %edx
callq 0x3cf0
movq %rax, %rdi
callq 0x3e50
movb %al, -0x21(%rbp)
movb -0x21(%rbp), %al
movq -0x20(%rbp), %rsi
movzbl %al, %edi
callq 0x4440
movq -0x20(%rbp), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x888d
movq -0x30(%rbp), %rdi
callq 0x3e50
movb %al, -0x31(%rbp)
movb -0x21(%rbp), %al
xorl %ecx, %ecx
movzbl %al, %edi
movzbl -0x31(%rbp), %esi
movl %ecx, %edx
callq 0x69a0
movl %eax, %edx
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rcx
movslq (%rcx), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x30(%rbp), %rax
subq $0x1, %rax
andq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
jmp 0x883a
movq -0x8(%rbp), %rdi
xorl %esi, %esi
callq 0x6b80
testb $0x1, %al
jne 0x8a28
movq -0x8(%rbp), %rax
movzbl 0x40(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x8963
movq -0x20(%rbp), %rax
andq $0x60, %rax
cmpq $0x0, %rax
jne 0x8963
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rdx
movl $0x5, %esi
xorl %ecx, %ecx
callq 0x7560
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x4420
movq %rax, %rcx
movq -0x40(%rbp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
jne 0x8963
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rdx
movl $0x6, %esi
xorl %ecx, %ecx
callq 0x7560
movq %rax, -0x48(%rbp)
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x4420
movq %rax, %rcx
movq -0x48(%rbp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
jne 0x8963
movl $0x4, %edi
movl $0x6, %esi
movl $0x1000, %edx           # imm = 0x1000
xorl %ecx, %ecx
callq 0x69a0
movl %eax, %edx
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rcx
movslq (%rcx), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x8(%rbp), %rax
movzbl 0x40(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x8a26
movq -0x20(%rbp), %rax
andq $0xe, %rax
cmpq $0x0, %rax
jne 0x8a26
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rdx
movl $0x3, %esi
xorl %ecx, %ecx
callq 0x7560
movq %rax, -0x50(%rbp)
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x4420
movq %rax, %rcx
movq -0x50(%rbp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
jne 0x8a26
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rdx
movl $0x2, %esi
xorl %ecx, %ecx
callq 0x7560
movq %rax, -0x58(%rbp)
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x4420
movq %rax, %rcx
movq -0x58(%rbp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
jne 0x8a26
movl $0x4, %edi
movl $0x2, %esi
movl $0x1000, %edx           # imm = 0x1000
xorl %ecx, %ecx
callq 0x69a0
movl %eax, %edx
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rcx
movslq (%rcx), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x8a28
addq $0x60, %rsp
popq %rbp
retq
nop