// File: epfml[P]sent2vec/src/model.cc
// Function: fasttext::Model::update(std::vector<int, std::allocator<int>> const&, int, float)
void Model::update(const std::vector<int32_t>& input, int32_t target, real lr) {
  assert(target >= 0);
  assert(target < osz_);
  if (input.size() == 0) return;
  computeHidden(input, hidden_);
  if (args_->loss == loss_name::ns) {
    loss_ += negativeSampling(target, lr);
  } else if (args_->loss == loss_name::hs) {
    loss_ += hierarchicalSoftmax(target, lr);
  } else {
    loss_ += softmax(target, lr);
  }
  nexamples_ += 1;

  if (args_->model == model_name::sup || args_->model == model_name::sent2vec) {
    grad_.mul(1.0 / input.size());
  }
  for (auto it = input.cbegin(); it != input.cend(); ++it) {
    wi_->addRow(grad_, *it, 1.0);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movss %xmm0, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x30(%rbp)
cmpl $0x0, -0x14(%rbp)
jl 0x22d48
jmp 0x22d67
leaq 0x2084c(%rip), %rdi     # 0x4359b
leaq 0x20758(%rip), %rsi     # 0x434ae
movl $0xcc, %edx
leaq 0x20845(%rip), %rcx     # 0x435a7
callq 0x52d0
movq -0x30(%rbp), %rcx
movl -0x14(%rbp), %eax
cmpl 0x88(%rcx), %eax
jge 0x22d78
jmp 0x22d97
leaq 0x20872(%rip), %rdi     # 0x435f1
leaq 0x20728(%rip), %rsi     # 0x434ae
movl $0xcd, %edx
leaq 0x20815(%rip), %rcx     # 0x435a7
callq 0x52d0
movq -0x10(%rbp), %rdi
callq 0xf0e0
cmpq $0x0, %rax
jne 0x22dab
jmp 0x22f68
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq %rdi, %rdx
addq $0x50, %rdx
callq 0x22610
movq -0x30(%rbp), %rdi
addq $0x40, %rdi
callq 0xea70
cmpl $0x2, 0xbc(%rax)
jne 0x22dfc
movq -0x30(%rbp), %rdi
movl -0x14(%rbp), %esi
movss -0x18(%rbp), %xmm0
callq 0x220b0
movq -0x30(%rbp), %rax
addss 0x8c(%rax), %xmm0
movss %xmm0, 0x8c(%rax)
jmp 0x22e60
movq -0x30(%rbp), %rdi
addq $0x40, %rdi
callq 0xea70
cmpl $0x1, 0xbc(%rax)
jne 0x22e39
movq -0x30(%rbp), %rdi
movl -0x14(%rbp), %esi
movss -0x18(%rbp), %xmm0
callq 0x221f0
movq -0x30(%rbp), %rax
addss 0x8c(%rax), %xmm0
movss %xmm0, 0x8c(%rax)
jmp 0x22e5e
movq -0x30(%rbp), %rdi
movl -0x14(%rbp), %esi
movss -0x18(%rbp), %xmm0
callq 0x224c0
movq -0x30(%rbp), %rax
addss 0x8c(%rax), %xmm0
movss %xmm0, 0x8c(%rax)
jmp 0x22e60
movq -0x30(%rbp), %rdi
movq 0x90(%rdi), %rax
addq $0x1, %rax
movq %rax, 0x90(%rdi)
addq $0x40, %rdi
callq 0xea70
cmpl $0x3, 0xc0(%rax)
je 0x22e9e
movq -0x30(%rbp), %rdi
addq $0x40, %rdi
callq 0xea70
cmpl $0x4, 0xc0(%rax)
jne 0x22ef3
movq -0x30(%rbp), %rax
addq $0x70, %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
callq 0xf0e0
movq -0x38(%rbp), %rdi
movq %rax, %xmm1
movaps 0x1fa9d(%rip), %xmm0    # 0x42960
punpckldq %xmm0, %xmm1    # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
movapd 0x1faa1(%rip), %xmm0    # 0x42970
subpd %xmm0, %xmm1
movaps %xmm1, %xmm0
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm0, %xmm1
movsd 0x1fa4a(%rip), %xmm0    # 0x42930
divsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
callq 0x21110
movq -0x10(%rbp), %rdi
callq 0xf700
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0xf770
movq %rax, -0x28(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0xf730
testb $0x1, %al
jne 0x22f20
jmp 0x22f68
movq -0x30(%rbp), %rdi
callq 0x23990
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, -0x48(%rbp)
addq $0x70, %rax
movq %rax, -0x40(%rbp)
leaq -0x20(%rbp), %rdi
callq 0xf7a0
movq -0x48(%rbp), %rdi
movq -0x40(%rbp), %rsi
movslq (%rax), %rdx
movss 0x1f9e8(%rip), %xmm0    # 0x42940
callq 0x1e580
leaq -0x20(%rbp), %rdi
callq 0xf7c0
jmp 0x22f00
addq $0x50, %rsp
popq %rbp
retq
nop