// File: ATOMIC-LICHESS[P]ATOMKRAFT/movegen.cpp
// Function: MoveStack* generate<(MoveType)3>(Position const&, MoveStack*)
MoveStack* generate<MV_NON_CAPTURE_CHECK>(const Position& pos, MoveStack* mlist) {
  NEW assert(pos.piece_count(WHITE, KING) && pos.piece_count(BLACK, KING));
		
  assert(pos.is_ok());
  assert(!pos.in_check());

  Bitboard b, dc;
  Square from;
  Color us = pos.side_to_move();
  NEW assert(pos.piece_count(opposite_color(us), KING));
  Square ksq = pos.king_square(opposite_color(us));

  assert(pos.piece_on(ksq) == make_piece(opposite_color(us), KING));

  // Discovered non-capture checks
  b = dc = pos.discovered_check_candidates(us);

  while (b)
  {
     from = pop_1st_bit(&b);
     switch (pos.type_of_piece_on(from))
     {
      case PAWN:   /* Will be generated togheter with pawns direct checks */     break;
      case KNIGHT: mlist = generate_discovered_checks<KNIGHT>(pos, mlist, from); break;
      case BISHOP: mlist = generate_discovered_checks<BISHOP>(pos, mlist, from); break;
      case ROOK:   mlist = generate_discovered_checks<ROOK>(pos, mlist, from);   break;
      case KING:   mlist = generate_discovered_checks<KING>(pos, mlist, from);   break;
      default: assert(false); break;
     }
  }

  // Direct non-capture checks
  mlist = generate_direct_checks<PAWN>(pos, mlist, us, dc, ksq);
  mlist = generate_direct_checks<KNIGHT>(pos, mlist, us, dc, ksq);
  mlist = generate_direct_checks<BISHOP>(pos, mlist, us, dc, ksq);
  mlist = generate_direct_checks<ROOK>(pos, mlist, us, dc, ksq);
  return  generate_direct_checks<QUEEN>(pos, mlist, us, dc, ksq);
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x48(%rsp)
movq %rsi, 0x40(%rsp)
movq 0x48(%rsp), %rdi
callq 0xf5d0
movl %eax, 0x28(%rsp)
movq 0x48(%rsp), %rax
movq %rax, 0x18(%rsp)
movl 0x28(%rsp), %edi
callq 0x122b0
movq 0x18(%rsp), %rdi
movl %eax, %esi
callq 0x1b250
movl %eax, 0x24(%rsp)
movq 0x48(%rsp), %rdi
movl 0x28(%rsp), %esi
callq 0x36440
movq %rax, 0x30(%rsp)
movq %rax, 0x38(%rsp)
cmpq $0x0, 0x38(%rsp)
je 0x2f153
leaq 0x38(%rsp), %rdi
callq 0xd940
movl %eax, 0x2c(%rsp)
movq 0x48(%rsp), %rdi
movl 0x2c(%rsp), %esi
callq 0x11f10
decl %eax
movl %eax, %ecx
movq %rcx, 0x10(%rsp)
subl $0x5, %eax
ja 0x2f14c
movq 0x10(%rsp), %rax
leaq 0x2b7a7(%rip), %rcx     # 0x5a880
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
jmp 0x2f14e
movq 0x48(%rsp), %rdi
movq 0x40(%rsp), %rsi
movl 0x2c(%rsp), %edx
callq 0x2f260
movq %rax, 0x40(%rsp)
jmp 0x2f14e
movq 0x48(%rsp), %rdi
movq 0x40(%rsp), %rsi
movl 0x2c(%rsp), %edx
callq 0x2f2f0
movq %rax, 0x40(%rsp)
jmp 0x2f14e
movq 0x48(%rsp), %rdi
movq 0x40(%rsp), %rsi
movl 0x2c(%rsp), %edx
callq 0x2f380
movq %rax, 0x40(%rsp)
jmp 0x2f14e
movq 0x48(%rsp), %rdi
movq 0x40(%rsp), %rsi
movl 0x2c(%rsp), %edx
callq 0x2f410
movq %rax, 0x40(%rsp)
jmp 0x2f14e
jmp 0x2f14e
jmp 0x2f097
movq 0x48(%rsp), %rdi
movq 0x40(%rsp), %rsi
movl 0x28(%rsp), %edx
movq 0x30(%rsp), %rcx
movl 0x24(%rsp), %eax
movq %rdi, 0x70(%rsp)
movq %rsi, 0x68(%rsp)
movl %edx, 0x64(%rsp)
movq %rcx, 0x58(%rsp)
movl %eax, 0x54(%rsp)
cmpl $0x0, 0x64(%rsp)
jne 0x2f1a7
movq 0x70(%rsp), %rdi
movq 0x68(%rsp), %rsi
movq 0x58(%rsp), %rdx
movl 0x54(%rsp), %ecx
callq 0x30520
movq %rax, 0x8(%rsp)
jmp 0x2f1c4
movq 0x70(%rsp), %rdi
movq 0x68(%rsp), %rsi
movq 0x58(%rsp), %rdx
movl 0x54(%rsp), %ecx
callq 0x307e0
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x48(%rsp), %rdi
movq 0x40(%rsp), %rsi
movl 0x28(%rsp), %edx
movq 0x30(%rsp), %rcx
movl 0x24(%rsp), %r8d
callq 0x2f4e0
movq %rax, 0x40(%rsp)
movq 0x48(%rsp), %rdi
movq 0x40(%rsp), %rsi
movl 0x28(%rsp), %edx
movq 0x30(%rsp), %rcx
movl 0x24(%rsp), %r8d
callq 0x2f620
movq %rax, 0x40(%rsp)
movq 0x48(%rsp), %rdi
movq 0x40(%rsp), %rsi
movl 0x28(%rsp), %edx
movq 0x30(%rsp), %rcx
movl 0x24(%rsp), %r8d
callq 0x2f780
movq %rax, 0x40(%rsp)
movq 0x48(%rsp), %rdi
movq 0x40(%rsp), %rsi
movl 0x28(%rsp), %edx
movq 0x30(%rsp), %rcx
movl 0x24(%rsp), %r8d
callq 0x2f8e0
addq $0x78, %rsp
retq
nopw %cs:(%rax,%rax)