// File: adamnovak[P]rlcsa/sampler_test.cpp
// Function: main
int main(int argc, char** argv)
{
  std::cout << "Sampler test" << std::endl;
  std::cout << std::endl;

  // Handle command line parameters.
  double multiplier = 1.0, greediness = 0.0;
  bool greedy = false, forward = true, write = false;
  char* base_name = 0;
  char* weights_name = 0;
  usint threads = 1;
  for(int i = 1; i < argc; i++)
  {
    if(argv[i][0] == '-')
    {
      switch(argv[i][1])
      {
        case 'b':
          forward = false; break;
        case 'g':
          greediness = atof(argv[i] + 2); greedy = true; break;
        case 'm':
          multiplier = atof(argv[i] + 2); break;
        case 't':
          threads = atoi(argv[i] + 2); break;
        case 'w':
          write = true; break;
        default:
          std::cout << "Invalid option: " << argv[i] << std::endl << std::endl;
          printUsage();
          return 1;
      }
    }
    else if(base_name == 0)
    {
      base_name = argv[i];
    }
    else if(weights_name == 0)
    {
      weights_name = argv[i];
    }
  }
  if(weights_name == 0) { printUsage(); return 2; }

  std::cout << "Options:";
  greediness = std::min(1.0, std::max(0.0, greediness));
  threads = std::max(threads, (usint)1); threads = std::min(threads, (usint)64);
  if(!forward) { std::cout << " backward"; }
  if(greedy) { std::cout << " greediness=" << greediness; }
  if(multiplier < 0) { multiplier = 1.0; }
  if(multiplier != 1.0) { std::cout << " multiplier=" << multiplier; }
  std::cout << " threads=" << threads;
  if(write) { std::cout << " write"; }
  std::cout << std::endl;
  std::cout << "Base name: " << base_name << std::endl;
  std::cout << "Weights: " << weights_name << std::endl;
  std::cout << std::endl;

  // Determine index parameters.
  std::string parameters_name = std::string(base_name) + PARAMETERS_EXTENSION;
  Parameters parameters;
  parameters.set(RLCSA_BLOCK_SIZE);
  parameters.set(SAMPLE_RATE);
  parameters.read(parameters_name);
  parameters.set(SUPPORT_LOCATE.first, 1);
  parameters.set(SUPPORT_DISPLAY.first, 1);
  parameters.set(WEIGHTED_SAMPLES.first, 1);
  // parameters.print();


  std::ifstream weights_file(weights_name, std::ios_base::binary);
  if(!weights_file)
  {
    std::cerr << "Error opening weights file!" << std::endl;
    return 3;
  }

  usint n = fileSize(weights_file) / sizeof(weight_type);
  weight_type* weights = new weight_type[n];
  weights_file.read((char*)weights, n * sizeof(weight_type));
  weights_file.close();
  for(usint i = 0; i < n; i++)
  {
    if(weights[i] >= 0)
    {
      weights[i] = ceil(weights[i] * multiplier);
    }
    else
    {
      std::cerr << "Negative value found: weights[" << i << "] == " << weights[i] << "!" << std::endl;
      delete[] weights;
      return 4;
    }
  }
  std::cout << "Input size:   " << n << std::endl;
  std::cout << "Sample rate:  " << parameters.get(SAMPLE_RATE) << std::endl;
  std::cout << std::endl;


  // Do the actual sampling.
  double start = readTimer();
  Sampler* sampler = 0;
  if(!greedy)
  {
    WeightedSampler* wsampler = new WeightedSampler(weights, n, forward);
    if(!(wsampler->buildSamples(parameters.get(SAMPLE_RATE), parameters.get(INITIAL_ADJUSTMENT), threads)))
    {
      delete wsampler; wsampler = 0;
      return 5;
    }
    sampler = wsampler; wsampler = 0;
  }
  else
  {
    SemiGreedySampler* gsampler = new SemiGreedySampler(weights, n);
    if(!(gsampler->buildSamples(parameters.get(SAMPLE_RATE), greediness)))
    {
      delete gsampler; gsampler = 0;
      return 5;
    }
    sampler = gsampler; gsampler = 0;
  }
  double sampled = readTimer();
  usint memory = memoryUsage();


  // Write the samples or build RLCSA.
  double stop;
  if(write)
  {
    stop = readTimer();
    sampler->writeTo(base_name);
  }
  else
  {
    std::ifstream input_file(base_name, std::ios_base::binary);
    if(!input_file)
    {
      std::cerr << "Error opening input file " << base_name << "!" << std::endl;
      return 5;
    }
    uchar* data = new uchar[n];
    input_file.read((char*)data, n);
    input_file.close();
    RLCSA rlcsa(data, n, parameters.get(RLCSA_BLOCK_SIZE), parameters.get(SAMPLE_RATE), threads, sampler, true);
    stop = readTimer();
    if(rlcsa.isOk())
    {
      rlcsa.printInfo();
      rlcsa.reportSize(true);
      rlcsa.writeTo(base_name);
    }
  }
  usint total_memory = memoryUsage();


  double sampling_time = sampled - start;
  double time = stop - start;
  double megabytes = n / (double)MEGABYTE;
  std::cout << "Total: " << time << " seconds (" << (megabytes / time) << " MB/s), " << total_memory << " kB" << std::endl;
  std::cout << "Sampling: " << sampling_time << " seconds (" << (megabytes / sampling_time) << " MB/s), " << memory << " kB" << std::endl;
  std::cout << std::endl;

  delete sampler; sampler = 0;
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1000, %rsp           # imm = 0x1000
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq 0x33270(%rip), %rdi     # 0x37fd0
leaq 0x244fe(%rip), %rsi     # 0x29265
callq 0x32a0
movq %rax, %rdi
movq 0x3323a(%rip), %rsi     # 0x37fb0
callq 0x3300
movq 0x3324e(%rip), %rdi     # 0x37fd0
movq 0x33227(%rip), %rsi     # 0x37fb0
callq 0x3300
movsd 0x24272(%rip), %xmm0    # 0x29008
movsd %xmm0, -0x18(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x20(%rbp)
movb $0x0, -0x21(%rbp)
movb $0x1, -0x22(%rbp)
movb $0x0, -0x23(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
movl $0x1, -0x3c(%rbp)
movl $0x1, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x4f2d
movq -0x10(%rbp), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
jne 0x4ee9
movq -0x10(%rbp), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbl 0x1(%rax), %eax
addl $-0x62, %eax
movl %eax, %ecx
movq %rcx, -0xde8(%rbp)
subl $0x15, %eax
ja 0x4e91
movq -0xde8(%rbp), %rax
leaq 0x241f8(%rip), %rcx     # 0x29018
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb $0x0, -0x22(%rbp)
jmp 0x4ee7
movq -0x10(%rbp), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
addq $0x2, %rdi
callq 0x33a0
movsd %xmm0, -0x20(%rbp)
movb $0x1, -0x21(%rbp)
jmp 0x4ee7
movq -0x10(%rbp), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
addq $0x2, %rdi
callq 0x33a0
movsd %xmm0, -0x18(%rbp)
jmp 0x4ee7
movq -0x10(%rbp), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
addq $0x2, %rdi
callq 0x34b0
movl %eax, -0x3c(%rbp)
jmp 0x4ee7
movb $0x1, -0x23(%rbp)
jmp 0x4ee7
movq 0x33138(%rip), %rdi     # 0x37fd0
leaq 0x243d3(%rip), %rsi     # 0x29272
callq 0x32a0
movq %rax, %rdi
movq -0x10(%rbp), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x32a0
movq %rax, %rdi
movq 0x330ee(%rip), %rsi     # 0x37fb0
callq 0x3300
movq %rax, %rdi
movq 0x330df(%rip), %rsi     # 0x37fb0
callq 0x3300
callq 0x4c60
movl $0x1, -0x4(%rbp)
jmp 0x5f75
jmp 0x4f1d
cmpq $0x0, -0x30(%rbp)
jne 0x4f02
movq -0x10(%rbp), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x30(%rbp)
jmp 0x4f1b
cmpq $0x0, -0x38(%rbp)
jne 0x4f19
movq -0x10(%rbp), %rax
movslq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x38(%rbp)
jmp 0x4f1b
jmp 0x4f1d
jmp 0x4f1f
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x4dcd
cmpq $0x0, -0x38(%rbp)
jne 0x4f45
callq 0x4c60
movl $0x2, -0x4(%rbp)
jmp 0x5f75
movq 0x33084(%rip), %rdi     # 0x37fd0
leaq 0x24330(%rip), %rsi     # 0x29283
callq 0x32a0
movsd 0x240a8(%rip), %xmm0    # 0x29008
movsd %xmm0, -0x48(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x50(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x6320
movq %rax, %rsi
leaq -0x48(%rbp), %rdi
callq 0x62e0
movsd (%rax), %xmm0
movsd %xmm0, -0x20(%rbp)
movl $0x1, -0x54(%rbp)
leaq -0x3c(%rbp), %rdi
leaq -0x54(%rbp), %rsi
callq 0x6360
movl (%rax), %eax
movl %eax, -0x3c(%rbp)
movl $0x40, -0x58(%rbp)
leaq -0x3c(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x63a0
movl (%rax), %eax
movl %eax, -0x3c(%rbp)
testb $0x1, -0x22(%rbp)
jne 0x4fda
movq 0x33002(%rip), %rdi     # 0x37fd0
leaq 0x242b7(%rip), %rsi     # 0x2928c
callq 0x32a0
testb $0x1, -0x21(%rbp)
je 0x5000
movq 0x32fe9(%rip), %rdi     # 0x37fd0
leaq 0x242a8(%rip), %rsi     # 0x29296
callq 0x32a0
movq %rax, %rdi
movsd -0x20(%rbp), %xmm0
callq 0x3570
xorps %xmm0, %xmm0
ucomisd -0x18(%rbp), %xmm0
jbe 0x5017
movsd 0x23ff6(%rip), %xmm0    # 0x29008
movsd %xmm0, -0x18(%rbp)
movsd -0x18(%rbp), %xmm0
movsd 0x23fe4(%rip), %xmm1    # 0x29008
ucomisd %xmm1, %xmm0
jne 0x502e
jp 0x502e
jmp 0x504e
movq 0x32f9b(%rip), %rdi     # 0x37fd0
leaq 0x24267(%rip), %rsi     # 0x292a3
callq 0x32a0
movq %rax, %rdi
movsd -0x18(%rbp), %xmm0
callq 0x3570
movq 0x32f7b(%rip), %rdi     # 0x37fd0
leaq 0x24254(%rip), %rsi     # 0x292b0
callq 0x32a0
movq %rax, %rdi
movl -0x3c(%rbp), %esi
callq 0x3400
testb $0x1, -0x23(%rbp)
je 0x5085
movq 0x32f57(%rip), %rdi     # 0x37fd0
leaq 0x2423a(%rip), %rsi     # 0x292ba
callq 0x32a0
movq 0x32f44(%rip), %rdi     # 0x37fd0
movq %rdi, -0xe08(%rbp)
movq 0x32f16(%rip), %rsi     # 0x37fb0
movq %rsi, -0xe00(%rbp)
callq 0x3300
movq -0xe08(%rbp), %rdi
leaq 0x2420d(%rip), %rsi     # 0x292c1
callq 0x32a0
movq %rax, %rdi
movq -0x30(%rbp), %rsi
callq 0x32a0
movq -0xe00(%rbp), %rsi
movq %rax, %rdi
callq 0x3300
movq -0xe08(%rbp), %rdi
leaq 0x241eb(%rip), %rsi     # 0x292cd
callq 0x32a0
movq %rax, %rdi
movq -0x38(%rbp), %rsi
callq 0x32a0
movq -0xe00(%rbp), %rsi
movq %rax, %rdi
callq 0x3300
movq -0xe08(%rbp), %rdi
movq -0xe00(%rbp), %rsi
callq 0x3300
movq -0x30(%rbp), %rax
movq %rax, -0xdf8(%rbp)
leaq -0x99(%rbp), %rdi
movq %rdi, -0xdf0(%rbp)
callq 0x3540
movq -0xdf8(%rbp), %rsi
movq -0xdf0(%rbp), %rdx
leaq -0x98(%rbp), %rdi
callq 0x5f90
jmp 0x514f
leaq 0x3323a(%rip), %rdx     # 0x38390
leaq -0x78(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x63e0
jmp 0x5168
leaq -0x98(%rbp), %rdi
callq 0x35d8
leaq -0x99(%rbp), %rdi
callq 0x3320
leaq -0xe0(%rbp), %rdi
callq 0x6430
jmp 0x518e
leaq 0x3327b(%rip), %rsi     # 0x38410
leaq -0xe0(%rbp), %rdi
callq 0x21830
jmp 0x51a3
leaq 0x3328e(%rip), %rsi     # 0x38438
leaq -0xe0(%rbp), %rdi
callq 0x21830
jmp 0x51b8
leaq -0xe0(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x21b70
jmp 0x51ca
leaq 0x3328f(%rip), %rsi     # 0x38460
leaq -0xe0(%rbp), %rdi
movl $0x1, %edx
callq 0x217f0
jmp 0x51e4
leaq 0x3329d(%rip), %rsi     # 0x38488
leaq -0xe0(%rbp), %rdi
movl $0x1, %edx
callq 0x217f0
jmp 0x51fe
leaq 0x332ab(%rip), %rsi     # 0x384b0
leaq -0xe0(%rbp), %rdi
movl $0x1, %edx
callq 0x217f0
jmp 0x5218
movq -0x38(%rbp), %rsi
leaq -0x2e8(%rbp), %rdi
movl $0x4, %edx
callq 0x3560
jmp 0x522f
movq -0x2e8(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x2e8(%rbp,%rax), %rdi
callq 0x3160
movb %al, -0xe09(%rbp)
jmp 0x524f
movb -0xe09(%rbp), %al
testb $0x1, %al
jne 0x525e
jmp 0x532d
movq 0x32d8b(%rip), %rdi     # 0x37ff0
leaq 0x2406b(%rip), %rsi     # 0x292d7
callq 0x32a0
movq %rax, -0xe18(%rbp)
jmp 0x527a
movq -0xe18(%rbp), %rdi
movq 0x32d28(%rip), %rsi     # 0x37fb0
callq 0x3300
jmp 0x528f
movl $0x3, -0x4(%rbp)
movl $0x1, -0x2ec(%rbp)
jmp 0x5f2f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x52d7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x35d8
leaq -0x99(%rbp), %rdi
callq 0x3320
jmp 0x5f81
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x5f6a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x5f5e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x5f52
leaq -0x2e8(%rbp), %rdi
callq 0x23550
movq %rax, -0xe20(%rbp)
jmp 0x5342
movq -0xe20(%rbp), %rax
shrq $0x2, %rax
movl %eax, -0x2f0(%rbp)
movl -0x2f0(%rbp), %eax
movl %eax, %edi
shlq $0x2, %rdi
callq 0x3030
movq %rax, -0xe28(%rbp)
jmp 0x536d
movq -0xe28(%rbp), %rax
movq %rax, -0x2f8(%rbp)
movq -0x2f8(%rbp), %rsi
movl -0x2f0(%rbp), %eax
movl %eax, %edx
shlq $0x2, %rdx
leaq -0x2e8(%rbp), %rdi
callq 0x33c0
jmp 0x539c
leaq -0x2e8(%rbp), %rdi
callq 0x30c0
jmp 0x53aa
movl $0x0, -0x2fc(%rbp)
movl -0x2fc(%rbp), %eax
cmpl -0x2f0(%rbp), %eax
jae 0x550d
movq -0x2f8(%rbp), %rax
movl -0x2fc(%rbp), %ecx
cmpl $0x0, (%rax,%rcx,4)
jb 0x5418
movq -0x2f8(%rbp), %rax
movl -0x2fc(%rbp), %ecx
movl (%rax,%rcx,4), %eax
cvtsi2sd %rax, %xmm0
movsd -0x18(%rbp), %xmm1
mulsd %xmm1, %xmm0
callq 0x3090
cvttsd2si %xmm0, %rax
movl %eax, %edx
movq -0x2f8(%rbp), %rax
movl -0x2fc(%rbp), %ecx
movl %edx, (%rax,%rcx,4)
jmp 0x54f7
movq 0x32bd1(%rip), %rdi     # 0x37ff0
leaq 0x23ecd(%rip), %rsi     # 0x292f3
callq 0x32a0
movq %rax, -0xe30(%rbp)
jmp 0x5434
movq -0xe30(%rbp), %rdi
movl -0x2fc(%rbp), %esi
callq 0x3400
movq %rax, -0xe38(%rbp)
jmp 0x544f
movq -0xe38(%rbp), %rdi
leaq 0x23eb5(%rip), %rsi     # 0x29312
callq 0x32a0
movq %rax, -0xe40(%rbp)
jmp 0x546b
movq -0xe40(%rbp), %rdi
movq -0x2f8(%rbp), %rax
movl -0x2fc(%rbp), %ecx
movl (%rax,%rcx,4), %esi
callq 0x3400
movq %rax, -0xe48(%rbp)
jmp 0x5490
movq -0xe48(%rbp), %rdi
leaq 0x24426(%rip), %rsi     # 0x298c4
callq 0x32a0
movq %rax, -0xe50(%rbp)
jmp 0x54ac
movq -0xe50(%rbp), %rdi
movq 0x32af6(%rip), %rsi     # 0x37fb0
callq 0x3300
jmp 0x54c1
movq -0x2f8(%rbp), %rax
movq %rax, -0xe58(%rbp)
cmpq $0x0, %rax
je 0x54e1
movq -0xe58(%rbp), %rdi
callq 0x33e0
movl $0x4, -0x4(%rbp)
movl $0x1, -0x2ec(%rbp)
jmp 0x5f2f
jmp 0x54f9
movl -0x2fc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2fc(%rbp)
jmp 0x53b4
movq 0x32abc(%rip), %rdi     # 0x37fd0
leaq 0x23dfd(%rip), %rsi     # 0x29318
callq 0x32a0
movq %rax, -0xe60(%rbp)
jmp 0x5529
movq -0xe60(%rbp), %rdi
movl -0x2f0(%rbp), %esi
callq 0x3400
movq %rax, -0xe68(%rbp)
jmp 0x5544
movq -0xe68(%rbp), %rdi
movq 0x32a5e(%rip), %rsi     # 0x37fb0
callq 0x3300
jmp 0x5559
movq 0x32a70(%rip), %rdi     # 0x37fd0
leaq 0x23dc0(%rip), %rsi     # 0x29327
callq 0x32a0
movq %rax, -0xe70(%rbp)
jmp 0x5575
leaq 0x32ebc(%rip), %rsi     # 0x38438
leaq -0xe0(%rbp), %rdi
callq 0x217c0
movl %eax, -0xe74(%rbp)
jmp 0x5590
movl -0xe74(%rbp), %esi
movq -0xe70(%rbp), %rdi
callq 0x3400
movq %rax, -0xe80(%rbp)
jmp 0x55ab
movq -0xe80(%rbp), %rdi
movq 0x329f7(%rip), %rsi     # 0x37fb0
callq 0x3300
jmp 0x55c0
movq 0x32a09(%rip), %rdi     # 0x37fd0
movq 0x329e2(%rip), %rsi     # 0x37fb0
callq 0x3300
jmp 0x55d5
callq 0x23af0
movsd %xmm0, -0xe88(%rbp)
jmp 0x55e4
movsd -0xe88(%rbp), %xmm0
movsd %xmm0, -0x308(%rbp)
movq $0x0, -0x310(%rbp)
testb $0x1, -0x21(%rbp)
jne 0x5747
movl $0x58, %edi
callq 0x32c0
movq %rax, -0xe90(%rbp)
jmp 0x561c
movq -0xe90(%rbp), %rdi
movq -0x2f8(%rbp), %rsi
movl -0x2f0(%rbp), %edx
movzbl -0x22(%rbp), %ecx
andl $0x1, %ecx
callq 0x175b0
jmp 0x563e
movq -0xe90(%rbp), %rax
movq %rax, -0x318(%rbp)
movq -0x318(%rbp), %rax
movq %rax, -0xea0(%rbp)
leaq 0x32dd7(%rip), %rsi     # 0x38438
leaq -0xe0(%rbp), %rdi
callq 0x217c0
movl %eax, -0xe94(%rbp)
jmp 0x5675
leaq 0x32e5c(%rip), %rsi     # 0x384d8
leaq -0xe0(%rbp), %rdi
callq 0x217c0
movl %eax, -0xea4(%rbp)
jmp 0x5690
movl -0xea4(%rbp), %edx
movl -0xe94(%rbp), %esi
movq -0xea0(%rbp), %rdi
movl -0x3c(%rbp), %ecx
callq 0x17b20
movb %al, -0xea5(%rbp)
jmp 0x56b3
movb -0xea5(%rbp), %al
testb $0x1, %al
jne 0x5729
jmp 0x56bf
movq -0x318(%rbp), %rax
movq %rax, -0xeb0(%rbp)
cmpq $0x0, %rax
je 0x56e0
movq -0xeb0(%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, -0x318(%rbp)
movl $0x5, -0x4(%rbp)
movl $0x1, -0x2ec(%rbp)
jmp 0x5f2f
movq -0xe90(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
movl $0x58, %esi
callq 0x32d0
jmp 0x5f52
movq -0x318(%rbp), %rax
movq %rax, -0x310(%rbp)
movq $0x0, -0x318(%rbp)
jmp 0x585a
movl $0x30, %edi
callq 0x32c0
movq %rax, -0xeb8(%rbp)
jmp 0x575a
movq -0xeb8(%rbp), %rdi
movq -0x2f8(%rbp), %rsi
movl -0x2f0(%rbp), %edx
callq 0x18ef0
jmp 0x5775
movq -0xeb8(%rbp), %rax
movq %rax, -0x320(%rbp)
movq -0x320(%rbp), %rax
movq %rax, -0xec8(%rbp)
leaq 0x32ca0(%rip), %rsi     # 0x38438
leaq -0xe0(%rbp), %rdi
callq 0x217c0
movl %eax, -0xebc(%rbp)
jmp 0x57ac
movl -0xebc(%rbp), %esi
movq -0xec8(%rbp), %rdi
movsd -0x20(%rbp), %xmm0
callq 0x19130
movb %al, -0xec9(%rbp)
jmp 0x57cb
movb -0xec9(%rbp), %al
testb $0x1, %al
jne 0x5841
jmp 0x57d7
movq -0x320(%rbp), %rax
movq %rax, -0xed8(%rbp)
cmpq $0x0, %rax
je 0x57f8
movq -0xed8(%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, -0x320(%rbp)
movl $0x5, -0x4(%rbp)
movl $0x1, -0x2ec(%rbp)
jmp 0x5f2f
movq -0xeb8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
movl $0x30, %esi
callq 0x32d0
jmp 0x5f52
movq -0x320(%rbp), %rax
movq %rax, -0x310(%rbp)
movq $0x0, -0x320(%rbp)
callq 0x23af0
movsd %xmm0, -0xee0(%rbp)
jmp 0x5869
movsd -0xee0(%rbp), %xmm0
movsd %xmm0, -0x328(%rbp)
callq 0x23b10
movl %eax, -0xee4(%rbp)
jmp 0x5886
movl -0xee4(%rbp), %eax
movl %eax, -0x32c(%rbp)
testb $0x1, -0x23(%rbp)
je 0x5978
callq 0x23af0
movsd %xmm0, -0xef0(%rbp)
jmp 0x58ab
movsd -0xef0(%rbp), %xmm0
movsd %xmm0, -0x338(%rbp)
movq -0x310(%rbp), %rax
movq %rax, -0xf08(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0xf00(%rbp)
leaq -0x359(%rbp), %rdi
movq %rdi, -0xef8(%rbp)
callq 0x3540
movq -0xf00(%rbp), %rsi
movq -0xef8(%rbp), %rdx
leaq -0x358(%rbp), %rdi
callq 0x5f90
jmp 0x5903
movq -0xf08(%rbp), %rdi
leaq -0x358(%rbp), %rsi
callq 0x17320
jmp 0x5918
leaq -0x358(%rbp), %rdi
callq 0x35d8
leaq -0x359(%rbp), %rdi
callq 0x3320
jmp 0x5ca1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x5967
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
leaq -0x358(%rbp), %rdi
callq 0x35d8
leaq -0x359(%rbp), %rdi
callq 0x3320
jmp 0x5f52
movq -0x30(%rbp), %rsi
leaq -0x568(%rbp), %rdi
movl $0x4, %edx
callq 0x3560
jmp 0x598f
movq -0x568(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x568(%rbp,%rax), %rdi
callq 0x3160
movb %al, -0xf09(%rbp)
jmp 0x59af
movb -0xf09(%rbp), %al
testb $0x1, %al
jne 0x59be
jmp 0x5a51
movq 0x3262b(%rip), %rdi     # 0x37ff0
leaq 0x2396a(%rip), %rsi     # 0x29336
callq 0x32a0
movq %rax, -0xf18(%rbp)
jmp 0x59da
movq -0xf18(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x32a0
movq %rax, -0xf20(%rbp)
jmp 0x59f3
movq -0xf20(%rbp), %rdi
leaq 0x23ec3(%rip), %rsi     # 0x298c4
callq 0x32a0
movq %rax, -0xf28(%rbp)
jmp 0x5a0f
movq -0xf28(%rbp), %rdi
movq 0x32593(%rip), %rsi     # 0x37fb0
callq 0x3300
jmp 0x5a24
movl $0x5, -0x4(%rbp)
movl $0x1, -0x2ec(%rbp)
jmp 0x5c66
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x5c90
movl -0x2f0(%rbp), %eax
movl %eax, %edi
callq 0x3030
movq %rax, -0xf30(%rbp)
jmp 0x5a67
movq -0xf30(%rbp), %rax
movq %rax, -0x570(%rbp)
movq -0x570(%rbp), %rsi
movl -0x2f0(%rbp), %eax
movl %eax, %edx
leaq -0x568(%rbp), %rdi
callq 0x33c0
jmp 0x5a92
leaq -0x568(%rbp), %rdi
callq 0x30c0
jmp 0x5aa0
movq -0x570(%rbp), %rax
movq %rax, -0xf40(%rbp)
movl -0x2f0(%rbp), %eax
movl %eax, -0xf38(%rbp)
leaq 0x3294f(%rip), %rsi     # 0x38410
leaq -0xe0(%rbp), %rdi
callq 0x217c0
movl %eax, -0xf34(%rbp)
jmp 0x5ad5
leaq 0x3295c(%rip), %rsi     # 0x38438
leaq -0xe0(%rbp), %rdi
callq 0x217c0
movl %eax, -0xf44(%rbp)
jmp 0x5af0
movl -0xf44(%rbp), %r8d
movl -0xf34(%rbp), %ecx
movl -0xf38(%rbp), %edx
movq -0xf40(%rbp), %rsi
movl -0x3c(%rbp), %r9d
movq -0x310(%rbp), %rdi
movq %rsp, %rax
movq %rdi, (%rax)
movl $0x1, 0x8(%rax)
leaq -0xda0(%rbp), %rdi
callq 0x81f0
jmp 0x5b30
callq 0x23af0
movsd %xmm0, -0xf50(%rbp)
jmp 0x5b3f
movsd -0xf50(%rbp), %xmm0
movsd %xmm0, -0x338(%rbp)
leaq -0xda0(%rbp), %rdi
callq 0x6450
movb %al, -0xf51(%rbp)
jmp 0x5b63
movb -0xf51(%rbp), %al
testb $0x1, %al
jne 0x5b72
jmp 0x5c50
leaq -0xda0(%rbp), %rdi
callq 0xbbc0
jmp 0x5b80
leaq -0xda0(%rbp), %rdi
movl $0x1, %esi
callq 0xb950
jmp 0x5b93
movq -0x30(%rbp), %rax
movq %rax, -0xf68(%rbp)
leaq -0xdc1(%rbp), %rdi
movq %rdi, -0xf60(%rbp)
callq 0x3540
movq -0xf68(%rbp), %rsi
movq -0xf60(%rbp), %rdx
leaq -0xdc0(%rbp), %rdi
callq 0x5f90
jmp 0x5bcd
leaq -0xda0(%rbp), %rdi
leaq -0xdc0(%rbp), %rsi
callq 0x8e80
jmp 0x5be2
leaq -0xdc0(%rbp), %rdi
callq 0x35d8
leaq -0xdc1(%rbp), %rdi
callq 0x3320
jmp 0x5c50
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x5c84
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x5c42
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
leaq -0xdc0(%rbp), %rdi
callq 0x35d8
leaq -0xdc1(%rbp), %rdi
callq 0x3320
jmp 0x5c84
leaq -0xda0(%rbp), %rdi
callq 0x8d60
movl $0x0, -0x2ec(%rbp)
leaq -0x568(%rbp), %rdi
callq 0x30e0
movl -0x2ec(%rbp), %eax
testl %eax, %eax
jne 0x5f2f
jmp 0x5c82
jmp 0x5ca1
leaq -0xda0(%rbp), %rdi
callq 0x8d60
leaq -0x568(%rbp), %rdi
callq 0x30e0
jmp 0x5f52
callq 0x23b10
movl %eax, -0xf6c(%rbp)
jmp 0x5cae
movl -0xf6c(%rbp), %eax
movl %eax, -0xdc8(%rbp)
movsd -0x328(%rbp), %xmm0
movsd -0x308(%rbp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0xdd0(%rbp)
movsd -0x338(%rbp), %xmm0
movsd -0x308(%rbp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0xdd8(%rbp)
movl -0x2f0(%rbp), %eax
cvtsi2sd %rax, %xmm0
movsd 0x2330b(%rip), %xmm1    # 0x29010
mulsd %xmm1, %xmm0
movsd %xmm0, -0xde0(%rbp)
movq 0x322b8(%rip), %rdi     # 0x37fd0
leaq 0x23631(%rip), %rsi     # 0x29350
callq 0x32a0
movq %rax, -0xf78(%rbp)
jmp 0x5d2d
movq -0xf78(%rbp), %rdi
movsd -0xdd8(%rbp), %xmm0
callq 0x3570
movq %rax, -0xf80(%rbp)
jmp 0x5d4a
movq -0xf80(%rbp), %rdi
leaq 0x23600(%rip), %rsi     # 0x29358
callq 0x32a0
movq %rax, -0xf88(%rbp)
jmp 0x5d66
movq -0xf88(%rbp), %rdi
movsd -0xde0(%rbp), %xmm0
movsd -0xdd8(%rbp), %xmm1
divsd %xmm1, %xmm0
callq 0x3570
movq %rax, -0xf90(%rbp)
jmp 0x5d8f
movq -0xf90(%rbp), %rdi
leaq 0x235c6(%rip), %rsi     # 0x29363
callq 0x32a0
movq %rax, -0xf98(%rbp)
jmp 0x5dab
movq -0xf98(%rbp), %rdi
movl -0xdc8(%rbp), %esi
callq 0x3400
movq %rax, -0xfa0(%rbp)
jmp 0x5dc6
movq -0xfa0(%rbp), %rdi
leaq 0x23598(%rip), %rsi     # 0x2936c
callq 0x32a0
movq %rax, -0xfa8(%rbp)
jmp 0x5de2
movq -0xfa8(%rbp), %rdi
movq 0x321c0(%rip), %rsi     # 0x37fb0
callq 0x3300
jmp 0x5df7
movq 0x321d2(%rip), %rdi     # 0x37fd0
leaq 0x2356b(%rip), %rsi     # 0x29370
callq 0x32a0
movq %rax, -0xfb0(%rbp)
jmp 0x5e13
movq -0xfb0(%rbp), %rdi
movsd -0xdd0(%rbp), %xmm0
callq 0x3570
movq %rax, -0xfb8(%rbp)
jmp 0x5e30
movq -0xfb8(%rbp), %rdi
leaq 0x2351a(%rip), %rsi     # 0x29358
callq 0x32a0
movq %rax, -0xfc0(%rbp)
jmp 0x5e4c
movq -0xfc0(%rbp), %rdi
movsd -0xde0(%rbp), %xmm0
movsd -0xdd0(%rbp), %xmm1
divsd %xmm1, %xmm0
callq 0x3570
movq %rax, -0xfc8(%rbp)
jmp 0x5e75
movq -0xfc8(%rbp), %rdi
leaq 0x234e0(%rip), %rsi     # 0x29363
callq 0x32a0
movq %rax, -0xfd0(%rbp)
jmp 0x5e91
movq -0xfd0(%rbp), %rdi
movl -0x32c(%rbp), %esi
callq 0x3400
movq %rax, -0xfd8(%rbp)
jmp 0x5eac
movq -0xfd8(%rbp), %rdi
leaq 0x234b2(%rip), %rsi     # 0x2936c
callq 0x32a0
movq %rax, -0xfe0(%rbp)
jmp 0x5ec8
movq -0xfe0(%rbp), %rdi
movq 0x320da(%rip), %rsi     # 0x37fb0
callq 0x3300
jmp 0x5edd
movq 0x320ec(%rip), %rdi     # 0x37fd0
movq 0x320c5(%rip), %rsi     # 0x37fb0
callq 0x3300
jmp 0x5ef2
movq -0x310(%rbp), %rax
movq %rax, -0xfe8(%rbp)
cmpq $0x0, %rax
je 0x5f13
movq -0xfe8(%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, -0x310(%rbp)
movl $0x0, -0x4(%rbp)
movl $0x1, -0x2ec(%rbp)
leaq -0x2e8(%rbp), %rdi
callq 0x30e0
leaq -0xe0(%rbp), %rdi
callq 0x6470
leaq -0x78(%rbp), %rdi
callq 0x35d8
jmp 0x5f75
leaq -0x2e8(%rbp), %rdi
callq 0x30e0
leaq -0xe0(%rbp), %rdi
callq 0x6470
leaq -0x78(%rbp), %rdi
callq 0x35d8
jmp 0x5f81
movl -0x4(%rbp), %eax
addq $0x1000, %rsp           # imm = 0x1000
popq %rbp
retq
movq -0xa8(%rbp), %rdi
callq 0x3530
nopl (%rax)