// File: tomfunkhouser[P]gaps/pkgs/RNMath/RNPolynomial.cpp
// Function: gaps::RNPolynomial::AddTerm(double, int, int const*, double const*, int, int)
void RNPolynomial::
AddTerm(RNScalar c, int n, const int *v, const RNScalar *e, 
  RNBoolean already_sorted, RNBoolean already_unique)
{
  // Check coefficient
  if (c == 0) return;

  // Check everything else
  assert((n == 0) || ((v != NULL) && (e != NULL)));

  // Check if term is constant (handle separately for efficiency)
  if (n == 0) {
    // Add constant term
    if (NTerms() > 0) {
      // Check for existing constant term
      RNPolynomialTerm *match = Term(0);
      if (match->IsConstant()) {
        // Add constant to existing constant term
        match->c += c;
        if (match->c == 0.0) {
          // Remove unneeded term
          terms.Remove(match);
          delete match;
        }
      }
      else {
        // Create new constant term (put first in list)
        RNPolynomialTerm *term = new RNPolynomialTerm(c, 0, NULL, NULL, TRUE, TRUE);
        terms.InsertHead(term);
        term->polynomial = this; 
      }
    }
    else {
      // Create new constant term 
      RNPolynomialTerm *term = new RNPolynomialTerm(c, 0, NULL, NULL, TRUE, TRUE);
      terms.InsertHead(term);
      term->polynomial = this; 
    }
  }
  else {
    // Add variable term
    RNPolynomialTerm *term = new RNPolynomialTerm(c, n, v, e, already_sorted, already_unique);
    RNPolynomialTerm *match = FindTermWithSameVariables(term);
    if (match) { 
      // Update existing term
      match->c += c;
      delete term; 
      if (match->c == 0.0) {
        // Remove unneeded term
        terms.Remove(match);
        delete match;
      }
    }
    else { 
      // Insert new term
      terms.Insert(term);
      term->polynomial = this; 
    }
  }
}

// Assembly:
subq $0xa8, %rsp
movq %rdi, 0xa0(%rsp)
movsd %xmm0, 0x98(%rsp)
movl %esi, 0x94(%rsp)
movq %rdx, 0x88(%rsp)
movq %rcx, 0x80(%rsp)
movl %r8d, 0x7c(%rsp)
movl %r9d, 0x78(%rsp)
movq 0xa0(%rsp), %rax
movq %rax, 0x38(%rsp)
movsd 0x98(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x3c7bf
jp 0x3c7bf
jmp 0x3caad
cmpl $0x0, 0x94(%rsp)
jne 0x3c96e
movq 0x38(%rsp), %rdi
callq 0x3f5c0
cmpl $0x0, %eax
jle 0x3c8ea
movq 0x38(%rsp), %rdi
xorl %esi, %esi
callq 0x3f5d0
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rdi
callq 0x3d0f0
cmpl $0x0, %eax
je 0x3c869
movsd 0x98(%rsp), %xmm0
movq 0x70(%rsp), %rax
addsd 0x10(%rax), %xmm0
movsd %xmm0, 0x10(%rax)
movq 0x70(%rsp), %rax
movsd 0x10(%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x3c867
jp 0x3c867
movq 0x38(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x3f720
movq 0x70(%rsp), %rax
movq %rax, 0x30(%rsp)
cmpq $0x0, %rax
je 0x3c865
movq 0x30(%rsp), %rdi
callq 0x3f480
movq 0x30(%rsp), %rdi
movl $0x28, %esi
callq 0x4290
jmp 0x3c867
jmp 0x3c8e8
movl $0x28, %edi
callq 0x4280
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x28(%rsp)
movsd 0x98(%rsp), %xmm0
xorl %esi, %esi
movl %esi, %ecx
movl $0x1, %r9d
movq %rcx, %rdx
movl %r9d, %r8d
callq 0x3ef10
jmp 0x3c89e
movq 0x38(%rsp), %rdi
movq 0x28(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rsi
callq 0x3f750
movq 0x38(%rsp), %rcx
movq 0x68(%rsp), %rax
movq %rcx, (%rax)
jmp 0x3c8e8
movq 0x28(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x60(%rsp)
movl %eax, 0x5c(%rsp)
movl $0x28, %esi
callq 0x4290
jmp 0x3cab5
jmp 0x3c969
movl $0x28, %edi
callq 0x4280
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x20(%rsp)
movsd 0x98(%rsp), %xmm0
xorl %esi, %esi
movl %esi, %ecx
movl $0x1, %r9d
movq %rcx, %rdx
movl %r9d, %r8d
callq 0x3ef10
jmp 0x3c91f
movq 0x38(%rsp), %rdi
movq 0x20(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rsi
callq 0x3f750
movq 0x38(%rsp), %rcx
movq 0x50(%rsp), %rax
movq %rcx, (%rax)
jmp 0x3c969
movq 0x20(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x60(%rsp)
movl %eax, 0x5c(%rsp)
movl $0x28, %esi
callq 0x4290
jmp 0x3cab5
jmp 0x3caad
movl $0x28, %edi
callq 0x4280
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x18(%rsp)
movsd 0x98(%rsp), %xmm0
movl 0x94(%rsp), %esi
movq 0x88(%rsp), %rdx
movq 0x80(%rsp), %rcx
movl 0x7c(%rsp), %r8d
movl 0x78(%rsp), %r9d
callq 0x3ef10
jmp 0x3c9b4
movq 0x38(%rsp), %rdi
movq 0x18(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x48(%rsp), %rsi
callq 0x3dcd0
movq %rax, 0x40(%rsp)
cmpq $0x0, 0x40(%rsp)
je 0x3ca8f
movsd 0x98(%rsp), %xmm0
movq 0x40(%rsp), %rax
addsd 0x10(%rax), %xmm0
movsd %xmm0, 0x10(%rax)
movq 0x48(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x3ca1f
movq 0x10(%rsp), %rdi
callq 0x3f480
movq 0x10(%rsp), %rdi
movl $0x28, %esi
callq 0x4290
movq 0x40(%rsp), %rax
movsd 0x10(%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x3ca8d
jp 0x3ca8d
movq 0x38(%rsp), %rdi
movq 0x40(%rsp), %rsi
callq 0x3f720
movq 0x40(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x3ca6c
movq 0x8(%rsp), %rdi
callq 0x3f480
movq 0x8(%rsp), %rdi
movl $0x28, %esi
callq 0x4290
jmp 0x3ca8d
movq 0x18(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x60(%rsp)
movl %eax, 0x5c(%rsp)
movl $0x28, %esi
callq 0x4290
jmp 0x3cab5
jmp 0x3caab
movq 0x38(%rsp), %rdi
movq 0x48(%rsp), %rsi
callq 0x3f5f0
movq 0x38(%rsp), %rcx
movq 0x48(%rsp), %rax
movq %rcx, (%rax)
jmp 0x3caad
addq $0xa8, %rsp
retq
movq 0x60(%rsp), %rdi
callq 0x44b0
nop