// File: UCBASiCS[P]SPRIGHT/src/main.cpp
// Function: main
int main(int argc, char** argv)
{
    // Sets a random seed for each run of SPRIGHT.
    srand48((long int) time (NULL));
    
    // Configurations are set through the command line arguments
    Config* configurations = new Config(argc, argv);
    // This is here measuring how long it takes to generate the input and output
    Chrono* mChrono = new Chrono();

    // Input object
    Input* input;
    // Output object
    Output* output;
     
    // In the experiment mode, program uses randomly generated input and
    // compare the SPRIGHT output to the input.
    // In the customized mode, program takes input from a file and outputs
    // the recovered signal to a file. 
    // Note that input and output to SPRIGHT is made modular and for using SPRIGHT
    // in other applications changing these objects would be enough.
    if ( configurations->isExperimentMode() )
    {
	   input  = new ExperimentInput(mChrono, configurations);
	   // output = new CustomizedOutput(mChrono, configurations);
	   output = new ExperimentOutput(mChrono, configurations, dynamic_cast<ExperimentInput*>(input));
    }
    else
    {
	   input  = new CustomizedInput(mChrono, configurations);    
	   output = new CustomizedOutput(mChrono, configurations);
    }

    SPRIGHT* spright = new SPRIGHT(configurations, input, output);
    
    if (!configurations->isHelpDisplayed())
    {
        // the number of iterations entered by the user
        int iterations = configurations->getIterations();

        configurations->display();

        // do the required number of iterations
        for (int iteration=0; iteration<iterations; iteration++)
        {
            input->process( spright->getDelays() );
            spright->process();

            if (configurations->isVerbose())
                std::cout << std::endl << "### Iteration "<< iteration << " results ###" << std::endl;
            output->process();
        }

        spright->displayResults();

        if ( configurations->isExperimentMode() )
        {
            std::cout << std::setprecision(3) << std::scientific << mChrono->average("Input") << " -> signal generation time"  << std::endl;
        }
    }

    std::cout << std::endl;
	
    delete spright;

    exit(EXIT_SUCCESS);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
xorl %eax, %eax
movl %eax, %edi
callq 0x42a0
movq %rax, %rdi
callq 0x44e0
movl $0xd0, %edi
callq 0x42c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xa0(%rbp)
movl -0x8(%rbp), %esi
movq -0x10(%rbp), %rdx
callq 0xdc30
jmp 0x1d15f
movq -0xa0(%rbp), %rax
movq %rax, -0x18(%rbp)
movl $0xa0, %edi
callq 0x42c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xa8(%rbp)
callq 0x1d6b0
jmp 0x1d188
movq -0xa8(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x18(%rbp), %rdi
callq 0xe960
testb $0x1, %al
jne 0x1d1a5
jmp 0x1d2ff
movl $0xd8, %edi
callq 0x42c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xb0(%rbp)
movq -0x30(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x14300
jmp 0x1d1cb
movq -0xb0(%rbp), %rax
movq %rax, -0x38(%rbp)
movl $0x160, %edi            # imm = 0x160
callq 0x42c0
movq %rax, -0xd0(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0xb8(%rbp)
cmpq $0x0, %rax
je 0x1d29f
movq -0xb8(%rbp), %rdi
leaq 0x129a0(%rip), %rsi     # 0x2fbc0
leaq 0x12a59(%rip), %rdx     # 0x2fc80
xorl %eax, %eax
movl %eax, %ecx
callq 0x4350
movq %rax, -0xd8(%rbp)
jmp 0x1d2aa
movq -0xa0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0xd0, %esi
callq 0x42d0
jmp 0x1d69c
movq -0xa8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0xa0, %esi
callq 0x42d0
jmp 0x1d69c
movq -0xb0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0xd8, %esi
callq 0x42d0
jmp 0x1d69c
xorl %eax, %eax
movq %rax, -0xd8(%rbp)
jmp 0x1d2aa
movq -0xc0(%rbp), %rdx
movq -0xc8(%rbp), %rsi
movq -0xd0(%rbp), %rdi
movq -0xd8(%rbp), %rcx
callq 0x15a70
jmp 0x1d2cd
movq -0xd0(%rbp), %rax
movq %rax, -0x40(%rbp)
jmp 0x1d3a7
movq -0xd0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x160, %esi            # imm = 0x160
callq 0x42d0
jmp 0x1d69c
movl $0x80, %edi
callq 0x42c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xe0(%rbp)
movq -0x30(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x11610
jmp 0x1d325
movq -0xe0(%rbp), %rax
movq %rax, -0x38(%rbp)
movl $0x20, %edi
callq 0x42c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xe8(%rbp)
movq -0x30(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x13770
jmp 0x1d356
movq -0xe8(%rbp), %rax
movq %rax, -0x40(%rbp)
jmp 0x1d3a7
movq -0xe0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x80, %esi
callq 0x42d0
jmp 0x1d69c
movq -0xe8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x20, %esi
callq 0x42d0
jmp 0x1d69c
movl $0x38, %edi
callq 0x42c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xf0(%rbp)
movq -0x18(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x40(%rbp), %rcx
callq 0x1e5c0
jmp 0x1d3d1
movq -0xf0(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rdi
callq 0xf760
testb $0x1, %al
jne 0x1d654
movq -0x18(%rbp), %rdi
callq 0xe980
movl %eax, -0x4c(%rbp)
movq -0x18(%rbp), %rdi
callq 0xecc0
movl $0x0, -0x50(%rbp)
movl -0x50(%rbp), %eax
cmpl -0x4c(%rbp), %eax
jge 0x1d512
movq -0x38(%rbp), %rax
movq %rax, -0x100(%rbp)
movq -0x48(%rbp), %rsi
leaq -0x68(%rbp), %rdi
movq %rdi, -0xf8(%rbp)
callq 0x1ee10
movq -0x100(%rbp), %rdi
movq -0xf8(%rbp), %rsi
movq (%rdi), %rax
movq 0x20(%rax), %rax
callq *%rax
jmp 0x1d44d
leaq -0x68(%rbp), %rdi
callq 0x5ad0
movq -0x48(%rbp), %rdi
callq 0x1e7f0
movq -0x18(%rbp), %rdi
callq 0xec10
testb $0x1, %al
jne 0x1d471
jmp 0x1d4fa
movq 0x12b50(%rip), %rdi     # 0x2ffc8
movq 0x12b31(%rip), %rsi     # 0x2ffb0
callq 0x42f0
movq %rax, %rdi
leaq 0x3ad2(%rip), %rsi      # 0x20f60
callq 0x42b0
movq %rax, %rdi
movl -0x50(%rbp), %esi
callq 0x4520
movq %rax, %rdi
leaq 0x3ac7(%rip), %rsi      # 0x20f6f
callq 0x42b0
movq %rax, %rdi
movq 0x12af9(%rip), %rsi     # 0x2ffb0
callq 0x42f0
jmp 0x1d4fa
movq -0xf0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x38, %esi
callq 0x42d0
jmp 0x1d69c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x5ad0
jmp 0x1d69c
movq -0x40(%rbp), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x1d409
movq -0x48(%rbp), %rdi
callq 0x1e950
movq -0x18(%rbp), %rdi
callq 0xe960
testb $0x1, %al
jne 0x1d52d
jmp 0x1d652
movl $0x3, %edi
callq 0x17270
movl %eax, -0x6c(%rbp)
movl -0x6c(%rbp), %esi
movq 0x12a84(%rip), %rdi     # 0x2ffc8
callq 0x44a0
movq %rax, %rdi
leaq 0x19d(%rip), %rsi       # 0x1d6f0
callq 0x40b0
movq %rax, -0x118(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x110(%rbp)
leaq -0x91(%rbp), %rdi
movq %rdi, -0x108(%rbp)
callq 0x4550
movq -0x108(%rbp), %rdx
leaq 0x3698(%rip), %rsi      # 0x20c23
leaq -0x90(%rbp), %rdi
callq 0x5a20
jmp 0x1d599
movq -0x110(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0xc4f0
movsd %xmm0, -0x120(%rbp)
jmp 0x1d5b6
movsd -0x120(%rbp), %xmm0
movq -0x118(%rbp), %rdi
callq 0x45b0
movq %rax, -0x128(%rbp)
jmp 0x1d5d3
movq -0x128(%rbp), %rdi
leaq 0x399b(%rip), %rsi      # 0x20f7c
callq 0x42b0
movq %rax, -0x130(%rbp)
jmp 0x1d5ef
movq -0x130(%rbp), %rdi
movq 0x129b3(%rip), %rsi     # 0x2ffb0
callq 0x42f0
jmp 0x1d604
leaq -0x90(%rbp), %rdi
callq 0x4180
leaq -0x91(%rbp), %rdi
callq 0x4310
jmp 0x1d652
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x1d644
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x4180
leaq -0x91(%rbp), %rdi
callq 0x4310
jmp 0x1d69c
jmp 0x1d654
movq 0x1296d(%rip), %rdi     # 0x2ffc8
movq 0x1294e(%rip), %rsi     # 0x2ffb0
callq 0x42f0
movq -0x48(%rbp), %rax
movq %rax, -0x138(%rbp)
cmpq $0x0, %rax
je 0x1d695
movq -0x138(%rbp), %rdi
callq 0x1e710
movq -0x138(%rbp), %rdi
movl $0x38, %esi
callq 0x42d0
xorl %edi, %edi
callq 0x4390
movq -0x20(%rbp), %rdi
callq 0x4540
nopw %cs:(%rax,%rax)
nop