// File: /workspace/github_cpp_makefile_star2_O3/Luthaf[P]zeopp/grid.cc
// Function: generateBOVGrid(ATOM_NETWORK*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
void generateBOVGrid(ATOM_NETWORK *atmnet, string name_f_dist, string name_g_dist, string name_h_dist, string name_f_bov, string name_g_bov, string name_h_bov) {

//-----declare large 3D array as a 3D pointer (i.e., ***) - we have to declare it as pointers otherwise we cannot declare an arbitrarily large grid - but if the grid is too large, you may not have enough RAM to store it, so watch the system monitor!
  double ***grid_distance;

//-----set the extent of the grid. If we know coordinate H (i.e. the coordinate in the abc plane that has all non-0 coordinates) we will know the maximum extent. 
//For my purposes, I defined a cube in terms of corners. A, B, and C correspond to defined unit cell vectors.
//D is the bottom corner between the B and C axes. E is the top corner between the A and C axes.
//F is the top corner between the B and C axes. G is the outermost corner. The innermost corner is simply (0, 0, 0).

  double origin_x = 0; 
  double origin_y = 0; 
  double origin_z = 0; 
  double Ax  = atmnet->v_a.x;
  double Bx = atmnet->v_b.x;
  double By  = atmnet->v_b.y;
  double Cx = atmnet->v_c.x;
  double Cy = atmnet->v_c.y;
  double Cz  = atmnet->v_c.z;

  double Dx = Ax + Bx; double Dy = By; double Dz = 0;
  double Ex = Ax + Cx; double Ey = Cy; double Ez = Cz;
  double Fx = Bx + Cx; double Fy = Cy; double Fz = Cz;
  double Gx = Ax + Bx + Cx; double Gy = By + Cy; double Gz = Cz;

  vector <double> xCoords;
  xCoords.push_back(origin_x); xCoords.push_back(Ax); xCoords.push_back(Bx); xCoords.push_back(Cx); xCoords.push_back(Dx); xCoords.push_back(Ex); xCoords.push_back(Fx); xCoords.push_back(Gx);
  vector <double> yCoords;
  yCoords.push_back(origin_y);yCoords.push_back(By); yCoords.push_back(Cy); yCoords.push_back(Gy);
	vector <double> zCoords;
	zCoords.push_back(origin_y); zCoords.push_back(Cz);

  double xMin = 1000; double xMax = 0;
  for (int a=0; a<xCoords.size(); a++){
    xMin = min(xMin, xCoords.at(a));
    xMax = max(xMax, xCoords.at(a));
  }

  double yMin = 1000; double yMax = 0;
  for (int b=0; b<yCoords.size(); b++){
    yMin = min(yMin, yCoords.at(b));
    yMax = max(yMax, yCoords.at(b));
  }
  double zMin = 1000; double zMax = 0;
  for (int c=0; c<zCoords.size(); c++){
    zMin = min(zMin, zCoords.at(c));
    zMax = max(zMax, zCoords.at(c));
  }

  double XGridDist = xMax - xMin; double YGridDist = yMax - yMin; double ZGridDist = zMax - zMin;


//-----set size that grid will take, i.e. the number of grid points in each dimension
  
  double tempXgrid = XGridDist/GRIDRES; double tempYgrid = YGridDist/GRIDRES; double tempZgrid = ZGridDist/GRIDRES;

  int x_grid_steps = ceil(tempXgrid);
  int y_grid_steps = ceil(tempYgrid); 
  int z_grid_steps = ceil(tempZgrid);

  double shiftInX = x_grid_steps - tempXgrid;
  double shiftInY = y_grid_steps - tempYgrid;
  double shiftInZ = z_grid_steps - tempZgrid;

  double xGridRes = XGridDist/x_grid_steps; double yGridRes = YGridDist/y_grid_steps; double zGridRes = ZGridDist/z_grid_steps;

  x_grid_steps++;
  y_grid_steps++;
  z_grid_steps++;

//-----create large 3D array
  printf("Declaring 3D array.\n\n");
	grid_distance = new double**[x_grid_steps];
	for(int i=0; i<x_grid_steps; i++) {
		grid_distance[i] = new double*[y_grid_steps];
		for(int j=0; j<y_grid_steps; j++) {
			grid_distance[i][j] = new double[z_grid_steps];
		}
	}

//-----fill it with values for the F function
  printf("Filling 3D array F with values.\n\n");
	for(int i=0; i<x_grid_steps; i++) {
		for(int j=0; j<y_grid_steps; j++) {
			for(int k=0; k<z_grid_steps; k++) {
				grid_distance[i][j][k] = calculate_distance_function(atmnet, i,j,k, xMin, yMin, 0, xGridRes, yGridRes, zGridRes, x_grid_steps, y_grid_steps, z_grid_steps, 'f'); 
			}
		}
	}

//-----Print structure_f.distances and structure_f.bov
  printf("Printing F grid.\n\n");
  FILE *file_distances_f, *file_bov_f; 
  char* distance_filename_f = new char [100];
  strcpy(distance_filename_f, name_f_dist.c_str()); 
  file_distances_f = fopen(distance_filename_f,"w");
  write_distances(file_distances_f, grid_distance, x_grid_steps, y_grid_steps, z_grid_steps);
  fclose(file_distances_f); 
  char* bov_filename_f = new char [100];
  strcpy(bov_filename_f, name_f_bov.c_str()); 
  file_bov_f = fopen(bov_filename_f,"w");
  write_bov(file_bov_f, distance_filename_f, x_grid_steps, y_grid_steps, z_grid_steps, xMin, yMin, zMin, XGridDist, YGridDist, ZGridDist);
  fclose(file_bov_f);

//-----fill it with values for the G function
/*
  printf("Filling 3D array G with values.\n\n");
	for(int i=0; i<x_grid_steps; i++) {
		for(int j=0; j<y_grid_steps; j++) {
			for(int k=0; k<z_grid_steps; k++) {
				grid_distance[i][j][k] = calculate_distance_function(atmnet, i,j,k, xMin, yMin, 0, xGridRes, yGridRes, zGridRes, x_grid_steps, y_grid_steps, z_grid_steps, 'g'); 
			}
		}
	}

//-----Print structure_g.distances and structure_g.bov
  printf("Printing G grid.\n\n");
  FILE *file_distances_g, *file_bov_g; 
  char* distance_filename_g = new char [100];
  strcpy(distance_filename_g, name_g_dist.c_str()); 
  file_distances_g = fopen(distance_filename_g,"w");
  write_distances(file_distances_g, grid_distance, x_grid_steps, y_grid_steps, z_grid_steps);
  fclose(file_distances_g); 
  char* bov_filename_g = new char [100];
  strcpy(bov_filename_g, name_g_bov.c_str()); 
  file_bov_g = fopen(bov_filename_g,"w");
  write_bov(file_bov_g, distance_filename_g, x_grid_steps, y_grid_steps, z_grid_steps, xMin, yMin, zMin, XGridDist, YGridDist, ZGridDist);
  fclose(file_bov_g);
*/


//-----fill it with values for the H function
/*
  printf("Filling 3D array H with values.\n\n");
	for(int i=0; i<x_grid_steps; i++) {
		for(int j=0; j<y_grid_steps; j++) {
			for(int k=0; k<z_grid_steps; k++) {
				grid_distance[i][j][k] = calculate_distance_function(atmnet, i,j,k, xMin, yMin, 0, xGridRes, yGridRes, zGridRes, x_grid_steps, y_grid_steps, z_grid_steps, 'h'); 
			}
		}
	}


//-----Print structure_h.distances and structure_h.bov

  printf("Printing H grid.\n\n");
  FILE *file_distances_h, *file_bov_h; 
  char* distance_filename_h = new char [100];
  strcpy(distance_filename_h, name_h_dist.c_str()); 
  file_distances_h = fopen(distance_filename_h,"w");
  write_distances(file_distances_h, grid_distance, x_grid_steps, y_grid_steps, z_grid_steps);
  fclose(file_distances_h); 
  char* bov_filename_h = new char [100];
  strcpy(bov_filename_h, name_h_bov.c_str()); 
  file_bov_h = fopen(bov_filename_h,"w");
  write_bov(file_bov_h, distance_filename_h, x_grid_steps, y_grid_steps, z_grid_steps, xMin, yMin, zMin, XGridDist, YGridDist, ZGridDist);
  fclose(file_bov_h);
*/


//-----free memory!
  printf("Freeing memory.\n\n");
	for(int i=0; i<x_grid_steps; i++) {
		for(int j=0; j<y_grid_steps; j++) {
			delete[] grid_distance[i][j];
		}
    delete[] grid_distance[i];
	}
  delete[] grid_distance; //important to have one "delete[]" per "new"
  delete[] distance_filename_f;
  //delete[] distance_filename_g;
  //delete[] distance_filename_h;
  delete[] bov_filename_f;
  //delete[] bov_filename_g;
  //delete[] bov_filename_h;

//---end successfully
  printf("Program complete.\n\n");


}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1b8, %rsp            # imm = 0x1B8
movq %r8, %rbx
movq %rsi, %r14
movq %rdi, %r15
xorl %eax, %eax
leaq 0x1b0(%rsp), %rdx
movq %rax, (%rdx)
movq %rax, 0x128(%rsp)
movsd 0x38(%rdi), %xmm0
movsd %xmm0, 0x120(%rsp)
movsd 0x50(%rdi), %xmm1
movsd %xmm1, 0x118(%rsp)
movsd 0x58(%rdi), %xmm2
movsd %xmm2, 0x110(%rsp)
movsd 0x68(%rdi), %xmm3
movsd %xmm3, 0x108(%rsp)
movsd 0x70(%rdi), %xmm4
movsd %xmm4, 0x100(%rsp)
movsd 0x78(%rdi), %xmm5
movsd %xmm5, 0xf8(%rsp)
movapd %xmm0, %xmm5
addsd %xmm1, %xmm5
movsd %xmm5, 0xf0(%rsp)
addsd %xmm3, %xmm0
movsd %xmm0, 0xe8(%rsp)
addsd %xmm3, %xmm1
movsd %xmm1, 0xe0(%rsp)
addsd %xmm3, %xmm5
movsd %xmm5, 0xd8(%rsp)
addsd %xmm4, %xmm2
movsd %xmm2, 0xd0(%rsp)
leaq 0x10(%rsp), %rdi
movq %rax, 0x10(%rdi)
xorpd %xmm0, %xmm0
movapd %xmm0, (%rdi)
xorl %esi, %esi
callq 0x1481e
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rax
cmpq %rax, %rsi
je 0x86b33
movsd 0x120(%rsp), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x86b4f
leaq 0x10(%rsp), %rdi
leaq 0x120(%rsp), %rdx
callq 0x1481e
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rax
cmpq %rax, %rsi
je 0x86b6c
movsd 0x118(%rsp), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x86b88
leaq 0x10(%rsp), %rdi
leaq 0x118(%rsp), %rdx
callq 0x1481e
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rax
cmpq %rax, %rsi
je 0x86ba5
movsd 0x108(%rsp), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x86bc1
leaq 0x10(%rsp), %rdi
leaq 0x108(%rsp), %rdx
callq 0x1481e
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rax
cmpq %rax, %rsi
je 0x86bde
movsd 0xf0(%rsp), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x86bfa
leaq 0x10(%rsp), %rdi
leaq 0xf0(%rsp), %rdx
callq 0x1481e
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rax
cmpq %rax, %rsi
je 0x86c17
movsd 0xe8(%rsp), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x86c33
leaq 0x10(%rsp), %rdi
leaq 0xe8(%rsp), %rdx
callq 0x1481e
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rax
cmpq %rax, %rsi
je 0x86c50
movsd 0xe0(%rsp), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x86c6c
leaq 0x10(%rsp), %rdi
leaq 0xe0(%rsp), %rdx
callq 0x1481e
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rax
cmpq %rax, %rsi
je 0x86c89
movsd 0xd8(%rsp), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x18(%rsp)
jmp 0x86c9b
leaq 0x10(%rsp), %rdi
leaq 0xd8(%rsp), %rdx
callq 0x1481e
xorpd %xmm0, %xmm0
leaq 0x30(%rsp), %rdi
movapd %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
leaq 0x128(%rsp), %rdx
xorl %esi, %esi
callq 0x1481e
movq 0x38(%rsp), %rsi
movq 0x40(%rsp), %rax
cmpq %rax, %rsi
je 0x86ce6
movsd 0x110(%rsp), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x38(%rsp)
jmp 0x86d02
leaq 0x30(%rsp), %rdi
leaq 0x110(%rsp), %rdx
callq 0x1481e
movq 0x38(%rsp), %rsi
movq 0x40(%rsp), %rax
cmpq %rax, %rsi
je 0x86d1f
movsd 0x100(%rsp), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x38(%rsp)
jmp 0x86d3b
leaq 0x30(%rsp), %rdi
leaq 0x100(%rsp), %rdx
callq 0x1481e
movq 0x38(%rsp), %rsi
movq 0x40(%rsp), %rax
cmpq %rax, %rsi
je 0x86d58
movsd 0xd0(%rsp), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x38(%rsp)
jmp 0x86d6a
leaq 0x30(%rsp), %rdi
leaq 0xd0(%rsp), %rdx
callq 0x1481e
xorpd %xmm0, %xmm0
leaq 0x80(%rsp), %rdi
movapd %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
leaq 0x128(%rsp), %rdx
xorl %esi, %esi
callq 0x1481e
movq 0x88(%rsp), %rsi
cmpq 0x90(%rsp), %rsi
je 0x86dbe
movsd 0xf8(%rsp), %xmm0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x88(%rsp)
jmp 0x86dd3
leaq 0x80(%rsp), %rdi
leaq 0xf8(%rsp), %rdx
callq 0x1481e
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rcx
xorpd %xmm0, %xmm0
movsd 0xcb9bf(%rip), %xmm3    # 0x1527a8
movapd %xmm3, %xmm5
xorpd %xmm4, %xmm4
subq %rax, %rcx
je 0x86e31
sarq $0x3, %rcx
cmpq $0x1, %rcx
adcq $0x0, %rcx
movsd 0xcb99e(%rip), %xmm2    # 0x1527a8
xorpd %xmm1, %xmm1
xorl %edx, %edx
movsd (%rax,%rdx,8), %xmm4
movapd %xmm4, %xmm5
minsd %xmm2, %xmm5
maxsd %xmm1, %xmm4
incq %rdx
movapd %xmm4, %xmm1
movapd %xmm5, %xmm2
cmpq %rdx, %rcx
jne 0x86e10
movq 0x30(%rsp), %rax
movq 0x38(%rsp), %rcx
movapd %xmm3, %xmm6
subq %rax, %rcx
je 0x86e7f
sarq $0x3, %rcx
cmpq $0x1, %rcx
adcq $0x0, %rcx
movsd 0xcb950(%rip), %xmm2    # 0x1527a8
xorpd %xmm1, %xmm1
xorl %edx, %edx
movsd (%rax,%rdx,8), %xmm0
movapd %xmm0, %xmm6
minsd %xmm2, %xmm6
maxsd %xmm1, %xmm0
incq %rdx
movapd %xmm0, %xmm1
movapd %xmm6, %xmm2
cmpq %rdx, %rcx
jne 0x86e5e
movq 0x80(%rsp), %rax
movq 0x88(%rsp), %rcx
subq %rax, %rcx
je 0x86ed1
sarq $0x3, %rcx
cmpq $0x1, %rcx
adcq $0x0, %rcx
movsd 0xcb900(%rip), %xmm2    # 0x1527a8
xorpd %xmm1, %xmm1
xorl %edx, %edx
movsd (%rax,%rdx,8), %xmm7
movapd %xmm7, %xmm3
minsd %xmm2, %xmm3
maxsd %xmm1, %xmm7
incq %rdx
movapd %xmm7, %xmm1
movapd %xmm3, %xmm2
cmpq %rdx, %rcx
jne 0x86eae
jmp 0x86ed5
xorpd %xmm7, %xmm7
unpcklpd %xmm0, %xmm7            # xmm7 = xmm7[0],xmm0[0]
movapd %xmm4, %xmm1
movsd %xmm5, 0x70(%rsp)
subsd %xmm5, %xmm1
movapd %xmm3, 0x1a0(%rsp)
movapd %xmm3, %xmm0
movapd %xmm6, 0x170(%rsp)
unpcklpd %xmm6, %xmm0            # xmm0 = xmm0[0],xmm6[0]
subpd %xmm0, %xmm7
movapd %xmm7, 0x130(%rsp)
movsd %xmm1, 0xc0(%rsp)
movapd %xmm1, %xmm0
divsd 0xce8ad(%rip), %xmm0    # 0x1557d0
callq 0x40d0
movapd %xmm0, 0x150(%rsp)
cvttsd2si %xmm0, %r13d
movapd 0x130(%rsp), %xmm0
divpd 0xce8b9(%rip), %xmm0    # 0x155800
movapd %xmm0, 0xa0(%rsp)
callq 0x40d0
movapd %xmm0, 0x160(%rsp)
movapd 0xa0(%rsp), %xmm0
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
callq 0x40d0
movapd %xmm0, 0xa0(%rsp)
leal 0x1(%r13), %ebp
leaq 0xcea90(%rip), %rdi     # 0x155a14
callq 0x4660
movslq %ebp, %rax
shlq $0x3, %rax
cmpl $-0x1, %r13d
movq $-0x1, %rdi
cmovgeq %rax, %rdi
callq 0x4030
movq %rax, %r12
movq %r14, 0x188(%rsp)
movq %rbx, 0x180(%rsp)
movapd 0x160(%rsp), %xmm0
unpcklpd 0xa0(%rsp), %xmm0       # xmm0 = xmm0[0],mem[0]
cvttpd2dq %xmm0, %xmm1
movd %xmm1, %eax
pshufd $0x55, %xmm1, %xmm0     # xmm0 = xmm1[1,1,1,1]
movd %xmm0, %ecx
movapd 0x130(%rsp), %xmm5
movapd %xmm5, %xmm3
unpckhpd %xmm5, %xmm3            # xmm3 = xmm3[1],xmm5[1]
leal 0x1(%rcx), %esi
leal 0x1(%rax), %edi
movl %ebp, 0x54(%rsp)
movl %ebp, %edx
movq %rdx, 0x58(%rsp)
movl %esi, %edx
movq %rdx, 0x68(%rsp)
movq %r13, 0xb8(%rsp)
testl %r13d, %r13d
movq %rcx, 0xc8(%rsp)
movapd %xmm3, 0x190(%rsp)
movl %esi, 0x7c(%rsp)
movl %edi, 0x50(%rsp)
js 0x871c0
movaps %xmm1, 0x140(%rsp)
cvttpd2dq 0x150(%rsp), %xmm0
cvtdq2pd %xmm0, %xmm0
xorps %xmm1, %xmm1
cvtsi2sd %ecx, %xmm1
cvtsi2sd %eax, %xmm2
movsd 0xc0(%rsp), %xmm4
divsd %xmm0, %xmm4
movsd %xmm4, 0xa0(%rsp)
divsd %xmm1, %xmm3
movapd %xmm3, 0x160(%rsp)
movapd %xmm5, %xmm0
divsd %xmm2, %xmm0
movapd %xmm0, 0x150(%rsp)
movslq %esi, %rdx
shlq $0x3, %rdx
cmpl $-0x1, %ecx
movq $-0x1, %rcx
cmovlq %rcx, %rdx
movq %rdx, 0x60(%rsp)
movslq %edi, %rbx
shlq $0x3, %rbx
cmpl $-0x1, %eax
cmovlq %rcx, %rbx
xorl %r13d, %r13d
movq 0x60(%rsp), %rdi
callq 0x4030
movq %rax, %rbp
movq %rax, (%r12,%r13,8)
cmpl $0x0, 0xc8(%rsp)
js 0x870e1
xorl %r14d, %r14d
movq %rbx, %rdi
callq 0x4030
movq %rax, (%rbp,%r14,8)
incq %r14
cmpq %r14, 0x68(%rsp)
jne 0x870ca
incq %r13
cmpq 0x58(%rsp), %r13
jne 0x870ac
leaq 0xce937(%rip), %rdi     # 0x155a29
callq 0x4660
cmpl $0x0, 0xb8(%rsp)
movq 0x70(%rsp), %xmm0
movapd 0x170(%rsp), %xmm1
js 0x871cc
pshufd $0x50, 0x140(%rsp), %xmm2 # xmm2 = mem[0,0,1,1]
movmskpd %xmm2, %eax
movl %eax, 0x60(%rsp)
shrb %al
movb %al, 0x140(%rsp)
movl 0x50(%rsp), %r13d
xorl %r14d, %r14d
cmpb $0x0, 0x140(%rsp)
jne 0x871b0
xorl %ebx, %ebx
testb $0x1, 0x60(%rsp)
jne 0x871a6
xorl %ebp, %ebp
movl $0x66, 0x8(%rsp)
xorpd %xmm2, %xmm2
movq %r15, %rdi
movl %r14d, %esi
movl %ebx, %edx
movl %ebp, %ecx
movsd 0xa0(%rsp), %xmm3
movapd 0x160(%rsp), %xmm4
movapd 0x150(%rsp), %xmm5
callq 0x873fd
movq (%r12,%r14,8), %rax
movq (%rax,%rbx,8), %rax
movq %xmm0, (%rax,%rbp,8)
incq %rbp
cmpq %rbp, %r13
movq 0x70(%rsp), %xmm0
movapd 0x170(%rsp), %xmm1
jne 0x8714c
incq %rbx
cmpq 0x68(%rsp), %rbx
jne 0x87143
incq %r14
cmpq 0x58(%rsp), %r14
jne 0x87137
jmp 0x871cc
leaq 0xce862(%rip), %rdi     # 0x155a29
callq 0x4660
leaq 0xce877(%rip), %rdi     # 0x155a4a
callq 0x4660
movl $0x64, %edi
callq 0x4030
movl 0x7c(%rsp), %ebp
movl 0x50(%rsp), %r13d
movq %rax, %r15
movq 0x188(%rsp), %rax
movq (%rax), %rsi
movq %r15, %rdi
callq 0x43f0
leaq 0xcaa3c(%rip), %rsi     # 0x151c44
movq %r15, %rdi
callq 0x4510
movq %rax, %rbx
movq %rax, %rdi
movq %r12, %rsi
movl 0x54(%rsp), %edx
movl %ebp, %ecx
movl %r13d, %r8d
callq 0x875fe
movq %rbx, %rdi
callq 0x4450
movl $0x64, %edi
callq 0x4030
movq %rax, %r14
movq 0x180(%rsp), %rax
movq (%rax), %rsi
movq %r14, %rdi
callq 0x43f0
leaq 0xca9ee(%rip), %rsi     # 0x151c44
movq %r14, %rdi
callq 0x4510
movq %rax, %rbx
leaq 0xce5a8(%rip), %rsi     # 0x155810
movq %rax, %rdi
movq %r15, %rdx
movl 0x54(%rsp), %ecx
movl %ebp, %r8d
movl %r13d, %r9d
movsd 0x70(%rsp), %xmm0
movaps 0x170(%rsp), %xmm1
movaps 0x1a0(%rsp), %xmm2
movsd 0xc0(%rsp), %xmm3
movaps 0x190(%rsp), %xmm4
movaps 0x130(%rsp), %xmm5
movb $0x6, %al
callq 0x45f0
movq %rbx, %rdi
callq 0x4450
leaq 0xce79f(%rip), %rdi     # 0x155a5c
callq 0x4660
cmpl $0x0, 0xb8(%rsp)
js 0x87310
xorl %r13d, %r13d
movq (%r12,%r13,8), %rbx
cmpl $0x0, 0xc8(%rsp)
js 0x872f9
xorl %ebp, %ebp
movq (%rbx,%rbp,8), %rdi
testq %rdi, %rdi
je 0x872ed
callq 0x4570
incq %rbp
cmpq %rbp, 0x68(%rsp)
jne 0x872df
jmp 0x872fe
testq %rbx, %rbx
je 0x87306
movq %rbx, %rdi
callq 0x4570
incq %r13
cmpq 0x58(%rsp), %r13
jne 0x872cf
movq %r12, %rdi
callq 0x4570
movq %r15, %rdi
callq 0x4570
movq %r14, %rdi
callq 0x4570
leaq 0xce73e(%rip), %rdi     # 0x155a6d
callq 0x4660
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x87351
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x87368
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x8737f
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
addq $0x1b8, %rsp            # imm = 0x1B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x873a7
jmp 0x873a7
jmp 0x873a7
jmp 0x873a7
movq %rax, %rbx
jmp 0x873c7
movq %rax, %rbx
jmp 0x873de
jmp 0x873a7
jmp 0x873a7
movq %rax, %rbx
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x873c7
movq 0x90(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x873de
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x873f5
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq %rbx, %rdi
callq 0x4780