// File: /workspace/github_cpp_makefile_star2_O3/sid1607[P]avx2-merge-sort/test_sort.cpp
// Function: test_merge_sort(int)
bool test_merge_sort(int len) {
  bool status = true;
  int *a = nullptr, *temp = nullptr;

  // 32-byte aligned allocation
  if (posix_memalign((void **)&a, 32, len*sizeof(int)) != 0) {
    throw std::bad_alloc();
  }

  if (posix_memalign((void **)&temp, 32, len*sizeof(int)) != 0) {
    throw std::bad_alloc();
  }

  std::vector<int> ref(len);
  generate_random_array(a, len);
  std::copy(a, a+len, &ref[0]);

  auto std_start = get_time();
  generate_reference(ref);
  auto std_end = get_time();

  auto res = merge_sort(a, temp, len);
  auto merge_end = get_time();
  // print_array(&res.first[0], "Out", len);
  if (is_sorted_array(&res.first[0], &ref[0], len) == false) {
      print_array(&ref[0], "Ref", len);
      print_array(&res.first[0], "Out", len);
      status = false;
  } else {
    status = true;
    std::cout << "std time:" << std_end-std_start << " Merge time:" 
      << merge_end - std_end << std::endl;
  }

  delete a;
  delete temp;
  return status;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %edi, %ebp
xorl %eax, %eax
leaq 0x8(%rsp), %rdi
movq %rax, (%rdi)
movq %rax, 0x18(%rsp)
movslq %ebp, %r14
leaq (,%r14,4), %r15
movl $0x20, %esi
movq %r15, %rdx
callq 0x2070
testl %eax, %eax
jne 0x31ee
leaq 0x18(%rsp), %rdi
movl $0x20, %esi
movq %r15, %rdx
callq 0x2070
testl %eax, %eax
jne 0x31ee
leaq 0x40(%rsp), %rdi
leaq 0x20(%rsp), %rdx
movq %r14, %rsi
callq 0x3336
movl %ebp, %ebx
testl %r14d, %r14d
jle 0x2fc4
movq 0x8(%rsp), %r12
xorl %r13d, %r13d
callq 0x2040
cltq
imulq $0x10624dd3, %rax, %rcx # imm = 0x10624DD3
movq %rcx, %rdx
shrq $0x3f, %rdx
sarq $0x27, %rcx
addl %edx, %ecx
imull $0x7d0, %ecx, %ecx      # imm = 0x7D0
subl %ecx, %eax
movl %eax, (%r12,%r13,4)
incq %r13
cmpq %r13, %rbx
jne 0x2f95
testl %ebp, %ebp
je 0x2fda
movq 0x8(%rsp), %rsi
movq 0x40(%rsp), %rdi
movq %r15, %rdx
callq 0x21a0
callq 0x2160
movabsq $0x20c49ba5e353f7cf, %r15 # imm = 0x20C49BA5E353F7CF
imulq %r15
movq %rdx, %r12
leaq 0x40(%rsp), %rdi
callq 0x2dd3
callq 0x2160
imulq %r15
movq %rdx, %r13
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rsi
movq %r14, %rdx
callq 0x28dd
movq %rax, %r14
callq 0x2160
imulq %r15
movq %rdx, %r15
movl %ebp, 0x10(%rsp)
testl %ebp, %ebp
jle 0x30ea
movq 0x40(%rsp), %rbp
movl (%r14), %eax
cmpl (%rbp), %eax
jne 0x3067
movl $0x1, %edx
movq %rdx, %rcx
cmpq %rdx, %rbx
je 0x305e
movl (%r14,%rcx,4), %esi
cmpl %eax, %esi
jl 0x305e
leaq 0x1(%rcx), %rdx
movl %esi, %eax
cmpl (%rbp,%rcx,4), %esi
je 0x3042
cmpq %rbx, %rcx
jae 0x30ea
leaq 0x30(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x104b(%rip), %rsi      # 0x40c2
leaq 0x1047(%rip), %rdx      # 0x40c5
leaq 0x20(%rsp), %rdi
callq 0x3740
leaq 0x20(%rsp), %rsi
movq %rbp, %rdi
movl 0x10(%rsp), %ebx
movl %ebx, %edx
callq 0x2acc
movq 0x20(%rsp), %rdi
cmpq %r15, %rdi
je 0x30aa
callq 0x2110
leaq 0x20(%rsp), %rdi
movq %r15, (%rdi)
leaq 0x100d(%rip), %rsi      # 0x40c6
leaq 0x1009(%rip), %rdx      # 0x40c9
callq 0x3740
leaq 0x20(%rsp), %rsi
movq %r14, %rdi
movl %ebx, %edx
callq 0x2acc
movq 0x20(%rsp), %rdi
cmpq %r15, %rdi
je 0x30e3
callq 0x2110
xorl %ebx, %ebx
jmp 0x31ba
movq 0x2edf(%rip), %rdi      # 0x5fd0
leaq 0xfd2(%rip), %rsi       # 0x40ca
movl $0x9, %edx
callq 0x2150
movq %r12, %rax
shrq $0x3f, %rax
sarq $0x7, %r12
addq %rax, %r12
vcvtsi2sd %r12, %xmm0, %xmm0
vdivsd 0xf9b(%rip), %xmm0, %xmm0 # 0x40b8
movq %r13, %rax
shrq $0x3f, %rax
sarq $0x7, %r13
addq %rax, %r13
vcvtsi2sd %r13, %xmm1, %xmm1
vdivsd 0xf80(%rip), %xmm1, %xmm1 # 0x40b8
vmovsd %xmm1, 0x10(%rsp)
vsubsd %xmm0, %xmm1, %xmm0
movq 0x2e87(%rip), %rdi      # 0x5fd0
callq 0x2190
movq %rax, %rbx
leaq 0xf7c(%rip), %rsi       # 0x40d4
movl $0xc, %edx
movq %rax, %rdi
callq 0x2150
movq %r15, %rax
shrq $0x3f, %rax
sarq $0x7, %r15
addq %rax, %r15
vcvtsi2sd %r15, %xmm2, %xmm0
vdivsd 0xf38(%rip), %xmm0, %xmm0 # 0x40b8
vsubsd 0x10(%rsp), %xmm0, %xmm0
movq %rbx, %rdi
callq 0x2190
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2130
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movb $0x1, %bl
movq %rax, %rdi
callq 0x20b0
movq 0x8(%rsp), %rdi
callq 0x2110
movq 0x18(%rsp), %rdi
callq 0x2110
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x31dd
callq 0x2110
movl %ebx, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x8, %edi
callq 0x2060
movq 0x2dc9(%rip), %rcx      # 0x5fc8
addq $0x10, %rcx
movq %rcx, (%rax)
movq 0x2dcb(%rip), %rsi      # 0x5fd8
movq 0x2da4(%rip), %rdx      # 0x5fb8
movq %rax, %rdi
callq 0x21b0
jmp 0x3220
jmp 0x323a
movq %rax, %rbx
movq 0x20(%rsp), %rdi
cmpq %r15, %rdi
je 0x323d
callq 0x2110
jmp 0x323d
jmp 0x323a
jmp 0x323a
jmp 0x323a
movq %rax, %rbx
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x324c
callq 0x2110
movq %rbx, %rdi
callq 0x21d0