// File: UCBASiCS[P]SPRIGHT/src/backend.cpp
// Function: BackEnd::peelFrom(int, std::complex<double>, int)
void BackEnd::peelFrom(int spectralIndex, ffast_complex amplitude, int binIndex)
{
    int hash;
    // peel the contribution of the ball from all stages
    
    std::vector<int> delays = frontEnd->getDelays();
    ffast_complex* toSubtract = (ffast_complex *) malloc(config->getDelaysNb() * sizeof(ffast_complex));
    
    for (int i =0; i < config->getDelaysNb(); i++) {
        int currDelay = delays[i];
        toSubtract[i] = amplitude * (numOnes(currDelay & spectralIndex) % 2 ? -1.0 : 1.0);
    }

    for (int stage = 0; stage < config->getBinsNb(); stage++)
    {
        // index of the bin the ball is connected to at this stage
        hash = getHash(stage, spectralIndex);
        for (int delayIndex = 0; delayIndex < config->getDelaysNb(); delayIndex++)
        {
            observationMatrix[hash + config->getBinOffset(stage)][delayIndex] -= toSubtract[delayIndex];
            if (hash + config->getBinOffset(stage) == binIndex)
                observationMatrix[hash + config->getBinOffset(stage)][delayIndex] = 0;
            
        }
        changed[hash + config->getBinOffset(stage)] = true;
    }

    free(toSubtract);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movsd %xmm0, -0x10(%rbp)
movsd %xmm1, -0x8(%rbp)
movq %rdi, -0x18(%rbp)
movl %esi, -0x1c(%rbp)
movl %edx, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x90(%rbp)
movq 0x18(%rax), %rsi
leaq -0x40(%rbp), %rdi
callq 0x1bb50
movq -0x90(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0xeb30
movl %eax, -0x84(%rbp)
jmp 0x521f
movl -0x84(%rbp), %eax
movslq %eax, %rdi
shlq $0x4, %rdi
callq 0x43e0
movq %rax, -0x48(%rbp)
movl $0x0, -0x58(%rbp)
movq -0x90(%rbp), %rax
movl -0x58(%rbp), %ecx
movl %ecx, -0x98(%rbp)
movq 0x10(%rax), %rdi
callq 0xeb30
movl %eax, -0x94(%rbp)
jmp 0x525d
movl -0x98(%rbp), %eax
movl -0x94(%rbp), %ecx
cmpl %ecx, %eax
jge 0x5344
movslq -0x58(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x5d60
movl (%rax), %eax
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %edi
movl -0x1c(%rbp), %eax
andl %eax, %edi
callq 0x5dc0
movl %eax, -0x9c(%rbp)
jmp 0x5298
movl -0x9c(%rbp), %eax
movl %eax, %edx
shrl $0x1f, %edx
movl %eax, %ecx
addl %edx, %ecx
andl $-0x2, %ecx
subl %ecx, %eax
setne %al
movzbl %al, %eax
movl %eax, %ecx
leaq 0x1ad4d(%rip), %rax     # 0x20008
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0x78(%rbp)
leaq -0x10(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x5d80
movsd %xmm1, -0xb0(%rbp)
movsd %xmm0, -0xa8(%rbp)
jmp 0x52e4
movsd -0xb0(%rbp), %xmm0
movsd -0xa8(%rbp), %xmm1
movsd %xmm1, -0x70(%rbp)
movsd %xmm0, -0x68(%rbp)
movq -0x48(%rbp), %rax
movslq -0x58(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq -0x70(%rbp), %rcx
movq %rcx, (%rax)
movq -0x68(%rbp), %rcx
movq %rcx, 0x8(%rax)
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x523c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x5ad0
jmp 0x5579
movl $0x0, -0x7c(%rbp)
movq -0x90(%rbp), %rax
movl -0x7c(%rbp), %ecx
movl %ecx, -0xb8(%rbp)
movq 0x10(%rax), %rdi
callq 0xeb10
movl %eax, -0xb4(%rbp)
jmp 0x536c
movl -0xb8(%rbp), %eax
movl -0xb4(%rbp), %ecx
cmpl %ecx, %eax
jge 0x555e
movq -0x90(%rbp), %rdi
movl -0x7c(%rbp), %esi
movl -0x1c(%rbp), %edx
callq 0x57a0
movl %eax, -0xbc(%rbp)
jmp 0x539a
movl -0xbc(%rbp), %eax
movl %eax, -0x24(%rbp)
movl $0x0, -0x80(%rbp)
movq -0x90(%rbp), %rax
movl -0x80(%rbp), %ecx
movl %ecx, -0xc4(%rbp)
movq 0x10(%rax), %rdi
callq 0xeb30
movl %eax, -0xc0(%rbp)
jmp 0x53cb
movl -0xc4(%rbp), %eax
movl -0xc0(%rbp), %ecx
cmpl %ecx, %eax
jge 0x5502
movq -0x90(%rbp), %rax
movq -0x48(%rbp), %rcx
movslq -0x80(%rbp), %rdx
shlq $0x4, %rdx
addq %rdx, %rcx
movq %rcx, -0xe0(%rbp)
movq 0x10(%rax), %rdi
movq 0x28(%rax), %rax
movq %rax, -0xd8(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0xcc(%rbp)
movl -0x7c(%rbp), %esi
callq 0xeac0
movl %eax, -0xc8(%rbp)
jmp 0x5424
movq -0xe0(%rbp), %rsi
movq -0xd8(%rbp), %rax
movl -0xc8(%rbp), %edx
movl -0xcc(%rbp), %ecx
addl %edx, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rdi
movslq -0x80(%rbp), %rax
shlq $0x4, %rax
addq %rax, %rdi
callq 0x5e10
jmp 0x5459
movq -0x90(%rbp), %rax
movl -0x24(%rbp), %ecx
movl %ecx, -0xe8(%rbp)
movq 0x10(%rax), %rdi
movl -0x7c(%rbp), %esi
callq 0xeac0
movl %eax, -0xe4(%rbp)
jmp 0x547d
movl -0xe4(%rbp), %ecx
movl -0xe8(%rbp), %eax
addl %ecx, %eax
cmpl -0x20(%rbp), %eax
jne 0x54f2
movq -0x90(%rbp), %rax
movq 0x10(%rax), %rdi
movq 0x28(%rax), %rax
movq %rax, -0xf8(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0xf0(%rbp)
movl -0x7c(%rbp), %esi
callq 0xeac0
movl %eax, -0xec(%rbp)
jmp 0x54bf
movq -0xf8(%rbp), %rax
movl -0xec(%rbp), %edx
movl -0xf0(%rbp), %ecx
addl %edx, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rdi
movslq -0x80(%rbp), %rax
shlq $0x4, %rax
addq %rax, %rdi
xorps %xmm0, %xmm0
callq 0x5e60
jmp 0x54f0
jmp 0x54f2
jmp 0x54f4
movl -0x80(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x80(%rbp)
jmp 0x53aa
movq -0x90(%rbp), %rax
movq 0x10(%rax), %rdi
movq 0x80(%rax), %rax
movq %rax, -0x108(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x100(%rbp)
movl -0x7c(%rbp), %esi
callq 0xeac0
movl %eax, -0xfc(%rbp)
jmp 0x5534
movq -0x108(%rbp), %rax
movl -0xfc(%rbp), %edx
movl -0x100(%rbp), %ecx
addl %edx, %ecx
movslq %ecx, %rcx
movb $0x1, (%rax,%rcx)
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x534b
movq -0x48(%rbp), %rdi
callq 0x4380
leaq -0x40(%rbp), %rdi
callq 0x5ad0
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq
movq -0x50(%rbp), %rdi
callq 0x4540
nopw %cs:(%rax,%rax)