// File: /workspace/github_c_makefile_star2_O3/radforddc[P]icpc_siggen/mjd_fieldgen.c
// Function: main
int main(int argc, char **argv)
{

  MJD_Siggen_Setup setup, setup1, setup2;

  float BV;      // bias voltage
  int   WV = 0;  // 0: do not write the V and E values to ppc_ev.dat
                 // 1: write the V and E values to ppc_ev.dat
                 // 2: write the V and E values for both +r, -r (for gnuplot, NOT for siggen)
  int   WD = 0;  // 0: do not write out depletion surface
                 // 1: write out depletion surface to depl_<HV>.dat

  int   i, j, k;
  FILE  *fp;


  if (argc < 2 || argc%2 != 0 || read_config(argv[1], &setup)) {
    printf("Usage: %s <config_file_name> [options]\n"
           "   Possible options:\n"
	   "      -b bias_volts\n"
	   "      -w {0,1}  (do_not/do write the field file)\n"
	   "      -d {0,1}  (do_not/do write the depletion surface)\n"
	   "      -p {0,1}  (do_not/do write the WP file)\n"
           "      -r rho_spectrum_file_name\n"
           "      -z <rho_spectrum_offset_mm>\n", argv[0]);
    return 1;
  }
  strncpy(setup.config_file_name, argv[1], sizeof(setup.config_file_name));

  if (setup.xtal_grid < 0.001) setup.xtal_grid = 0.5;
  BV = setup.xtal_HV;
  WV = setup.write_field;
  setup.rho_z_spe[0] = 0;

  for (i=2; i<argc-1; i++) {
    if (strstr(argv[i], "-b")) {
      BV = setup.xtal_HV = atof(argv[++i]);   // bias volts
    } else if (strstr(argv[i], "-w")) {
      WV = atoi(argv[++i]);               // write-out options
    } else if (strstr(argv[i], "-d")) {
      WD = atoi(argv[++i]);               // write-out options
    } else if (strstr(argv[i], "-p")) {
      setup.write_WP = atoi(argv[++i]);   // weighting-potential options
    } else if (strstr(argv[i], "-r")) {
      if (!(fp = fopen(argv[++i], "r"))) {   // impurity-profile-spectrum file name
        printf("\nERROR: cannot open impurity profile spectrum file %s\n\n", argv[i]);
        return 1;
      }
      if (strstr(argv[i], ".spe")) fread(setup.rho_z_spe, 36, 1, fp); // skip over .spe-format header
      for (j=0; j<1024; j++) setup.rho_z_spe[j] = 0;
      fread(setup.rho_z_spe, sizeof(setup.rho_z_spe), 1, fp);
      fclose(fp);
    } else if (strstr(argv[i], "-z")) {
      j = atoi(argv[++i]);
      if (j >= 199) {
        printf("Error; rho_spectrum_offset_mm = %d is too large! max = 200\n", j);
        return 1;
      }
      for (k=j; k <200; k++) setup.rho_z_spe[k-j] = setup.rho_z_spe[k];
    } else if (strstr(argv[i], "-g") || strstr(argv[i], "-o")) { // ignore these
      continue;
    } else {
      printf("Possible options:\n"
	     "      -b bias_volts\n"
	     "      -w {0,1,2} (for WV options)\n"
	     "      -p {0,1}   (for WP options)\n"
             "      -r rho_spectrum_file_name\n"
             "      -z <rho_spectrum_offset_mm>\n");
      return 1;
    }
  }

  if (setup.inner_taper_length > setup.hole_length) {
    setup.inner_taper_length = setup.hole_length;
    printf(" Warning: inner_taper_length limited to hole_length = %.1f\n", setup.hole_length);
  }

  if (setup.verbosity >= CHATTY && setup.rho_z_spe[0] != 0) {
    printf(" z(mm)   rho\n");
    for (j=0; j < (int) setup.xtal_length; j++)
      printf(" %3d  %7.3f\n", j, setup.rho_z_spe[j]);
  }

  if (setup.xtal_length/setup.xtal_grid * setup.xtal_radius/setup.xtal_grid > 2500*2500) {
    printf("Error: Crystal size divided by grid size is too large!\n");
    return 1;
  }
  if (WV < 0 || WV > 2) WV = 0;

  /* -------------- give details of detector geometry */
  if (setup.verbosity >= CHATTY) {
    printf("\n\n"
           "      Crystal: Radius x Length: %.1f x %.1f mm\n",
	   setup.xtal_radius, setup.xtal_length);
    if (setup.hole_length > 0) {
      if (setup.inner_taper_length > 0)
        printf("    Core hole: Radius x length: %.1f x %.1f mm,"
               " taper %.1f x %.1f mm (%2.f degrees)\n",
               setup.hole_radius, setup.hole_length,
               setup.inner_taper_width, setup.inner_taper_length, setup.taper_angle);
      else
        printf("    Core hole: Radius x length: %.1f x %.1f mm\n",
               setup.hole_radius, setup.hole_length);
    }
    printf("Point contact: Radius x length: %.1f x %.1f mm\n",
           setup.pc_radius, setup.pc_length);
    if (setup.ditch_depth > 0) {
      printf("  Wrap-around: Radius x ditch x gap:  %.1f x %.1f x %.1f mm\n",
             setup.wrap_around_radius, setup.ditch_depth, setup.ditch_thickness);
    }
    printf("         Bias: %.0f V\n", BV);
  }
    
  if ((BV < 0 && setup.impurity_z0 < 0) || (BV > 0 && setup.impurity_z0 > 0)) {
    printf("ERROR: Expect bias and impurity to be opposite sign!\n");
    return 1;
  } 
  if (setup.impurity_z0 > 0) {
    // swap polarity for n-type material; this lets me assume all voltages are positive
    BV = -BV;
    setup.xtal_HV *= -1.0;
    setup.impurity_z0         *= -1.0;
    setup.impurity_gradient   *= -1.0;
    setup.impurity_quadratic  *= -1.0;
    setup.impurity_surface    *= -1.0;
    setup.impurity_radial_add *= -1.0;
  }
  /* use an adaptive grid; start out coarse and then refine the grid */
  memcpy(&setup1, &setup, sizeof(setup));
  memcpy(&setup2, &setup, sizeof(setup));
  setup1.xtal_grid *= 9.0;
  setup2.xtal_grid *= 3.0;
  if (grid_init(&setup1) != 0 ||
      grid_init(&setup2) != 0 ||
      grid_init(&setup)  != 0) {
    printf("failed to init field calculations\n");
    return 1;
  }

  /* -------------- calculate electric potential/field */
  if (setup.write_field) {
    setup1.write_field = 0; // no need to save intermediate calculations
    setup2.write_field = 0;
    if (setup.xtal_grid > 0.4) {
      ev_calc(&setup2, NULL);
    } else {
      ev_calc(&setup1, NULL);
      ev_calc(&setup2, &setup1);
    }
    ev_calc(&setup, &setup2);
  }

  /* -------------- calculate weighting potential */
  if (setup.write_WP) {
    setup1.write_WP = 0; // no need to save intermediate calculations
    setup2.write_WP = 0;
    if (setup.xtal_grid > 0.4) {
      wp_calc(&setup2, NULL);
    } else {
      wp_calc(&setup1, NULL);
      wp_calc(&setup2, &setup1);
    }
    wp_calc(&setup, &setup2);
  }

  /* -------------- calculate capacitance
     1/2 * epsilon * integral(E^2) = 1/2 * C * V^2
     so    C = epsilon * integral(E^2) / V^2    V = 1 volt
  */
  double esum, esum2, pi=3.14159, Epsilon=(8.85*16.0/1000.0);  // permittivity of Ge in pF/mm
  float  E_r, E_z;
  float  grid = setup.xtal_grid;
  int    r, z, test;
  int    L  = lrint(setup.xtal_length/grid)+1;
  int    R  = lrint(setup.xtal_radius/grid)+1;
  int    LC = lrint(setup.pc_length/grid)+1;
  int    RC = lrint(setup.pc_radius/grid)+1;

  if (setup.write_WP) {
    esum = esum2 = test = 0;
    for (z=1; z<L; z++) {
      for (r=2; r<R; r++) {
        E_r = setup.eps_dr[z][r]/16.0 * (setup.v[1][z][r] - setup.v[1][z][r+1])/(0.1*grid);
        E_z = setup.eps_dz[z][r]/16.0 * (setup.v[1][z][r] - setup.v[1][z+1][r])/(0.1*grid);
        esum += (E_r*E_r + E_z*E_z) * (double) (r-1);
        if ((r == RC   && z <= LC)   || (r <= RC   && z == LC)   ||
            (r == RC+1 && z <= LC+1) || (r <= RC+1 && z == LC+1)) { // average over two different surfaces
          if (setup.point_type[z+1][r+1] == PC) test = 1;
          esum2 += 0.5 * sqrt(E_r*E_r + E_z*E_z) * (double) (r-1);  // 0.5 since averaging over 2 surfaces
        }
      }
    }
    esum  *= 2.0 * pi * 0.01 * Epsilon * pow(grid, 3.0);
    // Epsilon is in pF/mm
    // 0.01 converts (V/cm)^2 to (V/mm)^2, pow() converts to grid^3 to mm3
    esum2 *= 2.0 * pi * 0.1 * Epsilon * pow(grid, 2.0);
    // 0.1 converts (V/cm) to (V/mm),  grid^2 to  mm2
    printf("  >>  Calculated capacitance at %.0f V: %.3lf pF\n", BV, esum);
    if (!test)
      printf("  >>  Alternative calculation of capacitance: %.3lf pF\n", esum2);
  }

  /* -------------- estimate depletion voltage */
  double min = BV, min2 = BV, dV, dW, testv;
  int    vminr=0, vminz=0;
  int    dz[4] = {1, -1, 0, 0}, dr[4] = {0, 0, 1, -1};
  if (setup.write_WP) {
    if (setup.fully_depleted) {
      // find minimum potential
      for (z=1; z<LC+2; z++) {
        for (r=1; r<RC+2; r++) {
          if (setup.vsave[z][r] > 0 &&
              min > setup.vsave[z][r] / (1.0 - setup.v[1][z][r])) {
            min = setup.vsave[z][r] / (1.0 - setup.v[1][z][r]);
          }
        }
      }
      /* check for bubble depletion / pinch-off by seeing how much the bias
         must be reduced for any pixel to be in a local potential minimum  */
      for (z=LC+2; z<L-2; z++) {
        for (r=1; r<R-2; r++) {
          if (setup.point_type[z][r] == INSIDE && setup.v[1][z][r] > 0.0001) {
            testv = -1;
            for (i=0; i<4; i++) {
              if (r==1 && i==2) break;  // do not check dr for r=1 (=0.0)
              dV = setup.vsave[z+dz[i]][r+dr[i]]  - setup.vsave[z][r];  // potential
              dW = setup.v[1][z+dz[i]][r+dr[i]]   - setup.v[1][z][r];   // WP
              if (dW*grid > 0.00001 && dV < 0 && testv < -dV/dW) testv = -dV/dW;
            }
            if (testv >= 0 && min2 > testv) {
              min2 = testv;
              vminr = r; vminz = z;
            }
          }
        }
      }
      if (min2 < min) {
        printf("Estimated pinch-off voltage = %.0f V\n", BV - min);
        printf(" min2 = %.1f at (r,z) = (%.1f, %.1f), so\n",
               min2, (vminr-1)*grid, (vminz-1)*grid);
        printf("   Full depletion (max pinch-off voltage) = %.0f\n", BV - min2);
        min = min2;
      } else {
        printf("Estimated depletion voltage = %.0f V\n", BV - min);
      }
    }

    printf("Minimum bulk field = %.2f V/cm at (r,z) = (%.1f, %.1f) mm\n\n",
           setup.Emin, setup.rmin, setup.zmin);
  }

#ifdef EMIN_OVERBIAS
  // calculate a new minimum electric field at a specified bias above depletion (usually 500 V)

  if (min > 0) {
    double db = EMIN_OVERBIAS - min;
    int k = 3.0/grid;
    float E, ez, er, r, z;
    // adjust potential
    for (j = 1; j < R; j++) {
      for (i = 1; i < L; i++) {
        setup.vsave[i][j] -= db * setup.v[1][i][j];
      }
    }
    setup.Emin = 99999.9;
    setup.rmin = setup.zmin = 999.9;
    /* calculate new field */
    for (j = 1; j < R-k-1; j++) {
      r = (j-1) * grid;
      for (i = k+1; i < L-k-1; i++) {
        z = (i-1) * grid;
        if (setup.point_type[i][j]     != INSIDE ||
            setup.point_type[i + k][j] != INSIDE ||  // point is at least 3 mm from a boundary
            setup.point_type[i - k][j] != INSIDE ||
            setup.point_type[i][j + k] != INSIDE ||
            (j > k+1 && setup.point_type[i][j - k] != INSIDE)) continue;
        // calc E
        er = 0;
        if (j>1) er = (setup.vsave[i][j-1] - setup.vsave[i][j+1])/(0.2*grid);
        ez = (setup.vsave[i-1][j] - setup.vsave[i+1][j])/(0.2*grid);
        E = sqrt(er*er + ez*ez);
        /* check for minimum field inside bulk of detector */
        if (E > 0.1 && E < setup.Emin) {
          setup.Emin = E;
          setup.rmin = r;
          setup.zmin = z;
        }
      }
    }
    printf("Minimum bulk field at %.0fV (%dV overbias) is %.2f V/cm at (r,z) = (%.1f, %.1f) mm\n\n",
           BV-min+EMIN_OVERBIAS, EMIN_OVERBIAS, setup.Emin, setup.rmin, setup.zmin);
  }
#endif
 
  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x41d8, %rsp           # imm = 0x41D8
movq %rsi, %rbx
movl %edi, %ebp
cmpl $0x2, %edi
setl %al
movl %ebp, %ecx
orb %al, %cl
testb $0x1, %cl
jne 0x1316
movq 0x8(%rbx), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x6604
testl %eax, %eax
je 0x1340
movq (%rbx), %rsi
leaq 0x6ec0(%rip), %rdi      # 0x81e0
xorl %eax, %eax
callq 0x10f0
movl $0x1, %ebx
movl %ebx, %eax
addq $0x41d8, %rsp           # imm = 0x41D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1548(%rsp), %r14
movq 0x8(%rbx), %rsi
movl $0x100, %edx            # imm = 0x100
movq %r14, %rdi
callq 0x1040
cvtss2sd -0x142c(%r14), %xmm0
movsd 0x6c9e(%rip), %xmm1     # 0x8008
ucomisd %xmm0, %xmm1
jbe 0x137b
movl $0x3f000000, 0x11c(%rsp) # imm = 0x3F000000
movss 0x13c(%rsp), %xmm0
movaps %xmm0, 0x20(%rsp)
movl $0x0, 0x514(%rsp)
cmpl $0x4, %ebp
jb 0x1574
leaq 0x514(%rsp), %r15
decl %ebp
movl $0x2, %r13d
movslq %r13d, %r12
movq (%rbx,%r12,8), %r14
movq %r14, %rdi
leaq 0x6f4c(%rip), %rsi      # 0x830a
callq 0x11d0
testq %rax, %rax
je 0x13eb
leal 0x1(%r12), %r13d
movq 0x8(%rbx,%r12,8), %rdi
callq 0x1090
cvtsd2ss %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movss %xmm0, 0x13c(%rsp)
jmp 0x1416
movq %r14, %rdi
leaq 0x6f18(%rip), %rsi      # 0x830d
callq 0x11d0
testq %rax, %rax
jne 0x1413
movq %r14, %rdi
leaq 0x6f07(%rip), %rsi      # 0x8310
callq 0x11d0
testq %rax, %rax
je 0x1423
incl %r13d
incl %r13d
cmpl %ebp, %r13d
jl 0x13ad
jmp 0x1574
movq %r14, %rdi
leaq 0x6ee6(%rip), %rsi      # 0x8313
callq 0x11d0
testq %rax, %rax
je 0x144d
incl %r13d
movq 0x8(%rbx,%r12,8), %rdi
callq 0x11b0
movl %eax, 0x148(%rsp)
jmp 0x1416
movq %r14, %rdi
leaq 0x6ebf(%rip), %rsi      # 0x8316
callq 0x11d0
testq %rax, %rax
je 0x14e0
movq 0x8(%rbx,%r12,8), %rdi
leaq 0x6eaa(%rip), %rsi      # 0x8317
callq 0x11a0
movq 0x8(%rbx,%r12,8), %rsi
testq %rax, %rax
je 0x18d2
movq %rax, %r14
movq %rsi, %rdi
leaq 0x6ec4(%rip), %rsi      # 0x8351
callq 0x11d0
testq %rax, %rax
je 0x14ac
movl $0x24, %esi
movl $0x1, %edx
movq %r15, %rdi
movq %r14, %rcx
callq 0x1080
incl %r13d
movl $0x1000, %edx           # imm = 0x1000
movq %r15, %rdi
xorl %esi, %esi
callq 0x1110
movl $0x1000, %esi           # imm = 0x1000
movl $0x1, %edx
movq %r15, %rdi
movq %r14, %rcx
callq 0x1080
movq %r14, %rdi
callq 0x10c0
jmp 0x1416
movq %r14, %rdi
leaq 0x6e6c(%rip), %rsi      # 0x8356
callq 0x11d0
testq %rax, %rax
je 0x1538
movq 0x8(%rbx,%r12,8), %rdi
callq 0x11b0
cmpl $0xc6, %eax
jg 0x18de
incl %r13d
cltq
leaq 0x1(%rax), %rcx
movq %r15, %rdx
movq %rcx, %rsi
movss (%rdx,%rax,4), %xmm0
movss %xmm0, (%rdx)
addq $0x4, %rdx
incq %rsi
cmpl $0xc8, %ecx
movq %rsi, %rcx
jne 0x1518
jmp 0x1416
movq %r14, %rdi
leaq 0x6e53(%rip), %rsi      # 0x8395
callq 0x11d0
testq %rax, %rax
jne 0x1416
movq %r14, %rdi
leaq 0x6e3e(%rip), %rsi      # 0x8398
callq 0x11d0
testq %rax, %rax
jne 0x1416
leaq 0x74cf(%rip), %rdi      # 0x8a3e
jmp 0x1888
movss 0xec(%rsp), %xmm0
movss 0xfc(%rsp), %xmm1
ucomiss %xmm0, %xmm1
jbe 0x15a6
movss %xmm0, 0xfc(%rsp)
cvtss2sd %xmm0, %xmm0
leaq 0x6dfc(%rip), %rdi      # 0x839b
movb $0x1, %al
callq 0x10f0
cmpl $0x2, 0xc8(%rsp)
jl 0x161a
movss 0x514(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0x15c3
jnp 0x161a
leaq 0x73d9(%rip), %rdi      # 0x89a3
callq 0x1070
movss 0xcc(%rsp), %xmm1
cvttss2si %xmm1, %eax
testl %eax, %eax
jle 0x1623
xorl %ebx, %ebx
leaq 0x6dee(%rip), %r14      # 0x83d7
xorps %xmm0, %xmm0
cvtss2sd 0x514(%rsp,%rbx,4), %xmm0
movq %r14, %rdi
movl %ebx, %esi
movb $0x1, %al
callq 0x10f0
incq %rbx
movss 0xcc(%rsp), %xmm1
cvttss2si %xmm1, %eax
cltq
cmpq %rax, %rbx
jl 0x15e9
jmp 0x1623
movss 0xcc(%rsp), %xmm1
movss 0xd0(%rsp), %xmm0
movss 0x11c(%rsp), %xmm2
movaps %xmm1, %xmm3
divss %xmm2, %xmm3
mulss %xmm0, %xmm3
divss %xmm2, %xmm3
ucomiss 0x6aad(%rip), %xmm3     # 0x80f8
jbe 0x1659
leaq 0x73b3(%rip), %rdi      # 0x8a07
jmp 0x1888
cmpl $0x2, 0xc8(%rsp)
jl 0x1760
cvtss2sd %xmm0, %xmm0
cvtss2sd %xmm1, %xmm1
leaq 0x6d6e(%rip), %rdi      # 0x83e4
movb $0x2, %al
callq 0x10f0
movss 0xec(%rsp), %xmm1
xorps %xmm0, %xmm0
ucomiss %xmm0, %xmm1
jbe 0x16e7
movss 0xfc(%rsp), %xmm3
ucomiss 0x6a6a(%rip), %xmm3     # 0x8108
xorps %xmm0, %xmm0
cvtss2sd 0xf0(%rsp), %xmm0
cvtss2sd %xmm1, %xmm1
jbe 0x16d9
xorps %xmm2, %xmm2
cvtss2sd 0x104(%rsp), %xmm2
cvtss2sd %xmm3, %xmm3
cvtss2sd 0xf8(%rsp), %xmm4
leaq 0x6d46(%rip), %rdi      # 0x8416
movb $0x5, %al
callq 0x10f0
jmp 0x16e7
leaq 0x6d8b(%rip), %rdi      # 0x846b
movb $0x2, %al
callq 0x10f0
xorps %xmm0, %xmm0
cvtss2sd 0xd8(%rsp), %xmm0
xorps %xmm1, %xmm1
cvtss2sd 0xd4(%rsp), %xmm1
leaq 0x6d95(%rip), %rdi      # 0x849b
movb $0x2, %al
callq 0x10f0
movss 0xe0(%rsp), %xmm1
ucomiss 0x69eb(%rip), %xmm1     # 0x8108
jbe 0x1749
xorps %xmm0, %xmm0
cvtss2sd 0xdc(%rsp), %xmm0
cvtss2sd %xmm1, %xmm1
xorps %xmm2, %xmm2
cvtss2sd 0xe4(%rsp), %xmm2
leaq 0x6d89(%rip), %rdi      # 0x84cb
movb $0x3, %al
callq 0x10f0
xorps %xmm0, %xmm0
cvtss2sd 0x20(%rsp), %xmm0
leaq 0x6daf(%rip), %rdi      # 0x8508
movb $0x1, %al
callq 0x10f0
xorps %xmm1, %xmm1
ucomiss 0x20(%rsp), %xmm1
movss 0x120(%rsp), %xmm0
jbe 0x1778
ucomiss %xmm0, %xmm1
ja 0x1787
movaps 0x20(%rsp), %xmm2
ucomiss %xmm1, %xmm2
jbe 0x1793
ucomiss %xmm1, %xmm0
jbe 0x1793
leaq 0x7244(%rip), %rdi      # 0x89d2
jmp 0x1888
ucomiss %xmm1, %xmm0
jbe 0x17f5
movaps 0x6981(%rip), %xmm1     # 0x8120
movaps 0x20(%rsp), %xmm2
xorps %xmm1, %xmm2
movaps %xmm2, 0x20(%rsp)
movss 0x124(%rsp), %xmm2
movss 0x130(%rsp), %xmm3
movss 0x13c(%rsp), %xmm4
xorps %xmm1, %xmm4
movss %xmm4, 0x13c(%rsp)
unpcklps %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
movhps 0x128(%rsp), %xmm0      # xmm0 = xmm0[0,1],mem[0,1]
xorps %xmm1, %xmm0
movups %xmm0, 0x120(%rsp)
xorps %xmm1, %xmm3
movss %xmm3, 0x130(%rsp)
leaq 0x2c28(%rsp), %rbx
leaq 0xc8(%rsp), %r14
movl $0x15b0, %edx           # imm = 0x15B0
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1160
leaq 0x1678(%rsp), %r15
movl $0x15b0, %edx           # imm = 0x15B0
movq %r15, %rdi
movq %r14, %rsi
callq 0x1160
movss 0x54(%rbx), %xmm0
mulss 0x68c2(%rip), %xmm0     # 0x80fc
movss %xmm0, 0x54(%rbx)
movss 0x54(%r15), %xmm0
mulss 0x68b3(%rip), %xmm0     # 0x8100
movss %xmm0, 0x54(%r15)
movq %rbx, %rdi
callq 0x207d
testl %eax, %eax
jne 0x1881
leaq 0x1678(%rsp), %rdi
callq 0x207d
testl %eax, %eax
jne 0x1881
leaq 0xc8(%rsp), %rdi
callq 0x207d
testl %eax, %eax
je 0x1892
leaq 0x7128(%rip), %rdi      # 0x89b0
callq 0x1070
jmp 0x1327
cmpl $0x0, 0x144(%rsp)
je 0x192a
xorl %eax, %eax
movl %eax, 0x2ca4(%rsp)
xorps %xmm0, %xmm0
cvtss2sd 0x11c(%rsp), %xmm0
movl %eax, 0x16f4(%rsp)
ucomisd 0x674c(%rip), %xmm0     # 0x8010
jbe 0x18f3
leaq 0x1678(%rsp), %rdi
xorl %esi, %esi
jmp 0x1910
leaq 0x6a40(%rip), %rdi      # 0x8319
jmp 0x1320
leaq 0x6a74(%rip), %rdi      # 0x8359
movl %eax, %esi
xorl %eax, %eax
callq 0x10f0
jmp 0x1327
leaq 0x2c28(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x339b
leaq 0x1678(%rsp), %rdi
movq %rbx, %rsi
callq 0x339b
leaq 0xc8(%rsp), %rdi
leaq 0x1678(%rsp), %rsi
callq 0x339b
cmpl $0x0, 0x148(%rsp)
je 0x199d
xorl %eax, %eax
movl %eax, 0x2ca8(%rsp)
xorps %xmm0, %xmm0
cvtss2sd 0x11c(%rsp), %xmm0
movl %eax, 0x16f8(%rsp)
ucomisd 0x66b8(%rip), %xmm0     # 0x8010
jbe 0x1966
leaq 0x1678(%rsp), %rdi
xorl %esi, %esi
jmp 0x1983
leaq 0x2c28(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x4268
leaq 0x1678(%rsp), %rdi
movq %rbx, %rsi
callq 0x4268
leaq 0xc8(%rsp), %rdi
leaq 0x1678(%rsp), %rsi
callq 0x4268
movss 0xcc(%rsp), %xmm0
movss 0x11c(%rsp), %xmm1
movss %xmm1, 0xc(%rsp)
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
callq 0x1100
movq %rax, %r14
movss 0xd0(%rsp), %xmm0
divss 0xc(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
callq 0x1100
movq %rax, %r15
movss 0xd4(%rsp), %xmm0
divss 0xc(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
callq 0x1100
movq %rax, 0x50(%rsp)
movss 0xd8(%rsp), %xmm0
divss 0xc(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
callq 0x1100
xorl %ebx, %ebx
cmpl $0x0, 0x148(%rsp)
je 0x132c
movq %rax, %r12
movq %r14, 0x40(%rsp)
leal 0x1(%r14), %eax
cmpl $0x1, %eax
jle 0x1cd8
movq %r15, 0x58(%rsp)
leal 0x1(%r15), %edi
movq 0x50(%rsp), %rsi
leal 0x1(%rsi), %ecx
leal 0x1(%r12), %edx
movq 0x4b0(%rsp), %r8
movq %r8, 0x78(%rsp)
movq 0x4c0(%rsp), %r8
movq %r8, 0x70(%rsp)
xorps %xmm0, %xmm0
cvtss2sd 0xc(%rsp), %xmm0
movsd 0x659d(%rip), %xmm7     # 0x8018
mulsd %xmm0, %xmm7
movq 0x4c8(%rsp), %r8
movq %r8, 0x68(%rsp)
leal 0x2(%r12), %r8d
leal 0x2(%rsi), %esi
movq 0x4f8(%rsp), %r9
movq %r9, 0x90(%rsp)
movl %edx, %r9d
movq %r9, 0x30(%rsp)
movslq %edx, %rdx
movq %rdx, 0xc0(%rsp)
movq %r8, 0x18(%rsp)
movslq %r8d, %rdx
movq %rdx, 0xb8(%rsp)
movq %rsi, 0x38(%rsp)
movslq %esi, %rdx
movq %rdx, 0xb0(%rsp)
movl %ecx, %edx
movq %rdx, 0xa8(%rsp)
movslq %ecx, %rcx
movq %rcx, 0xa0(%rsp)
movl %eax, %eax
movl %edi, %ecx
movq %rcx, 0x98(%rsp)
xorpd %xmm9, %xmm9
movsd 0x651b(%rip), %xmm1     # 0x8020
movsd 0x651b(%rip), %xmm2     # 0x8028
xorpd %xmm8, %xmm8
movl $0x0, 0x10(%rsp)
movl $0x1, %r15d
movq %r12, 0x80(%rsp)
movl %edi, 0x4c(%rsp)
movq %rax, 0x60(%rsp)
cmpl $0x2, %edi
jle 0x1cab
movq 0x70(%rsp), %rax
movq (%rax,%r15,8), %r13
movq 0x78(%rsp), %rax
movq (%rax,%r15,8), %rsi
movq 0x8(%rax,%r15,8), %r9
movq 0x68(%rsp), %rax
movq (%rax,%r15,8), %rdi
leaq 0x1(%r15), %rax
movq %rax, 0x88(%rsp)
movsd 0x10(%rsi), %xmm3
movl $0x2, %r8d
cmpq 0x38(%rsp), %r15
sete %r10b
cmpq 0xb0(%rsp), %r15
setle %r11b
cmpq 0xa8(%rsp), %r15
sete %bpl
cmpq 0xa0(%rsp), %r15
setle %r12b
movsd (%r13,%r8,8), %xmm4
mulsd %xmm1, %xmm4
movapd %xmm3, %xmm5
movsd (%rdi,%r8,8), %xmm6
mulsd %xmm1, %xmm6
subsd (%r9,%r8,8), %xmm3
mulsd %xmm6, %xmm3
divsd %xmm7, %xmm3
xorps %xmm6, %xmm6
cvtsd2ss %xmm3, %xmm6
movsd 0x8(%rsi,%r8,8), %xmm3
subsd %xmm3, %xmm5
mulsd %xmm4, %xmm5
divsd %xmm7, %xmm5
xorps %xmm4, %xmm4
cvtsd2ss %xmm5, %xmm4
mulss %xmm6, %xmm6
mulss %xmm4, %xmm4
addss %xmm6, %xmm4
cvtss2sd %xmm4, %xmm4
leal -0x1(%r8), %ecx
xorps %xmm5, %xmm5
cvtsi2sd %ecx, %xmm5
cmpq %r8, 0x30(%rsp)
sete %al
cmpq 0xc0(%rsp), %r8
setle %cl
cmpq %r8, 0x18(%rsp)
sete %dl
cmpq 0xb8(%rsp), %r8
setle %r14b
testb %r12b, %al
jne 0x1c3c
andb %bpl, %cl
jne 0x1c3c
andb %r11b, %dl
jne 0x1c3c
andb %r10b, %r14b
je 0x1c73
movq 0x90(%rsp), %rax
movq 0x8(%rax,%r15,8), %rax
cmpb $0x0, 0x1(%rax,%r8)
movl 0x10(%rsp), %eax
movl $0x1, %ecx
cmovel %ecx, %eax
movl %eax, 0x10(%rsp)
xorps %xmm6, %xmm6
sqrtsd %xmm4, %xmm6
mulsd %xmm2, %xmm6
mulsd %xmm5, %xmm6
addsd %xmm6, %xmm8
incq %r8
mulsd %xmm5, %xmm4
addsd %xmm4, %xmm9
cmpq %r8, 0x98(%rsp)
jne 0x1b71
movq 0x88(%rsp), %rcx
movq %rcx, %r15
movq 0x80(%rsp), %r12
movl 0x4c(%rsp), %edi
movq 0x60(%rsp), %rax
jmp 0x1cb1
incq %r15
movq %r15, %rcx
cmpq %rax, %rcx
jne 0x1b31
movsd %xmm8, 0x18(%rsp)
cmpl $0x0, 0x10(%rsp)
sete %bpl
movq 0x58(%rsp), %r15
movsd %xmm9, 0x10(%rsp)
jmp 0x1cf3
xorps %xmm0, %xmm0
cvtss2sd 0xc(%rsp), %xmm0
movb $0x1, %bpl
xorps %xmm1, %xmm1
movsd %xmm1, 0x18(%rsp)
movsd %xmm1, 0x10(%rsp)
movsd 0x6335(%rip), %xmm1     # 0x8030
movsd %xmm0, 0x38(%rsp)
callq 0x10b0
mulsd 0x632a(%rip), %xmm0     # 0x8038
movsd 0x10(%rsp), %xmm1
mulsd %xmm0, %xmm1
xorps %xmm0, %xmm0
cvtss2sd 0x20(%rsp), %xmm0
leaq 0x67f7(%rip), %rdi      # 0x851f
movsd %xmm0, 0x30(%rsp)
movb $0x2, %al
callq 0x10f0
testb %bpl, %bpl
je 0x1d60
movsd 0x38(%rsp), %xmm0
mulsd %xmm0, %xmm0
mulsd 0x62f4(%rip), %xmm0     # 0x8040
mulsd 0x18(%rsp), %xmm0
leaq 0x67f8(%rip), %rdi      # 0x8551
movb $0x1, %al
callq 0x10f0
cmpl $0x0, 0x148(%rsp)
movq 0x50(%rsp), %rax
je 0x132c
cmpl $0x0, 0x508(%rsp)
je 0x2046
addl $0x3, %eax
movsd 0x30(%rsp), %xmm11
movapd %xmm11, %xmm1
movq %rax, %r10
cmpl $0x2, %eax
movsd 0x38(%rsp), %xmm10
jl 0x1e13
addl $0x3, %r12d
movq 0x4b0(%rsp), %rax
movq 0x4f0(%rsp), %rcx
movl %r10d, %edx
movl $0x1, %esi
xorps %xmm0, %xmm0
movsd 0x6282(%rip), %xmm2     # 0x8048
movapd %xmm11, %xmm1
cmpl $0x2, %r12d
jl 0x1e0b
movq (%rcx,%rsi,8), %rdi
movl $0x1, %r8d
movsd (%rdi,%r8,8), %xmm3
ucomisd %xmm0, %xmm3
jbe 0x1e03
movq (%rax,%rsi,8), %r9
movapd %xmm2, %xmm4
subsd (%r9,%r8,8), %xmm4
divsd %xmm4, %xmm3
ucomisd %xmm3, %xmm1
jbe 0x1e03
movapd %xmm3, %xmm1
incq %r8
cmpq %r8, %r12
jne 0x1ddb
incq %rsi
cmpq %rdx, %rsi
jne 0x1dcb
movq 0x40(%rsp), %rax
decl %eax
cmpl %eax, %r10d
jge 0x1fac
movq %rax, 0x40(%rsp)
decl %r15d
movq 0x4f8(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x4b0(%rsp), %rcx
movq 0x4f0(%rsp), %rdx
movslq %r10d, %rdi
movq $0x0, 0x20(%rsp)
movsd 0x61f4(%rip), %xmm0     # 0x8050
movsd 0x61f4(%rip), %xmm2     # 0x8058
xorps %xmm3, %xmm3
leaq 0x6352(%rip), %r8       # 0x81c0
leaq 0x635b(%rip), %r9       # 0x81d0
movsd 0x61e3(%rip), %xmm4     # 0x8060
movapd 0x62ab(%rip), %xmm5     # 0x8130
movl $0x0, 0x10(%rsp)
movapd %xmm11, %xmm12
cmpl $0x2, %r15d
jl 0x1f82
movq 0x18(%rsp), %rax
movq (%rax,%rdi,8), %r11
movl $0x1, %r14d
cmpb $0x2, (%r11,%r14)
jne 0x1f76
movq (%rcx,%rdi,8), %rax
movsd (%rax,%r14,8), %xmm7
ucomisd %xmm0, %xmm7
jbe 0x1f76
movq %r15, %r10
movq %r14, %r15
xorq $0x1, %r15
movslq %r14d, %r12
xorl %r13d, %r13d
movapd %xmm2, %xmm6
movq %r13, %rax
xorq $0x8, %rax
orq %r15, %rax
je 0x1f55
movslq (%r13,%r8), %rbp
addq %rdi, %rbp
movslq (%r13,%r9), %rax
addq %r12, %rax
movq (%rcx,%rbp,8), %rsi
movsd (%rsi,%rax,8), %xmm8
subsd %xmm7, %xmm8
movapd %xmm8, %xmm9
mulsd %xmm10, %xmm9
ucomisd %xmm4, %xmm9
jbe 0x1f4b
movq (%rdx,%rbp,8), %rsi
movsd (%rsi,%rax,8), %xmm9
movq (%rdx,%rdi,8), %rax
subsd (%rax,%r14,8), %xmm9
ucomisd %xmm9, %xmm3
jbe 0x1f4b
xorpd %xmm5, %xmm9
divsd %xmm8, %xmm9
ucomisd %xmm6, %xmm9
jbe 0x1f4b
movapd %xmm9, %xmm6
addq $0x4, %r13
cmpq $0x10, %r13
jne 0x1ede
ucomisd %xmm3, %xmm6
movq %r10, %r15
jb 0x1f76
ucomisd %xmm6, %xmm12
jbe 0x1f76
movapd %xmm6, %xmm12
movl %r14d, 0x10(%rsp)
movl %edi, %eax
movq %rax, 0x20(%rsp)
incq %r14
cmpq %r15, %r14
jne 0x1eab
incq %rdi
cmpl %edi, 0x40(%rsp)
jne 0x1e92
movl 0x10(%rsp), %eax
decl %eax
xorps %xmm2, %xmm2
cvtsi2ss %eax, %xmm2
movq 0x20(%rsp), %rax
decl %eax
xorps %xmm3, %xmm3
cvtsi2ss %eax, %xmm3
jmp 0x1fbc
movss 0x6150(%rip), %xmm2     # 0x8104
movapd %xmm11, %xmm12
movaps %xmm2, %xmm3
ucomisd %xmm12, %xmm1
movapd %xmm11, %xmm0
subsd %xmm1, %xmm0
jbe 0x2038
leaq 0x65b6(%rip), %rdi      # 0x8589
movb $0x1, %al
movsd %xmm12, 0x20(%rsp)
movss %xmm2, 0x18(%rsp)
movss %xmm3, 0x10(%rsp)
callq 0x10f0
movss 0xc(%rsp), %xmm0
movss 0x18(%rsp), %xmm1
mulss %xmm0, %xmm1
cvtss2sd %xmm1, %xmm1
movss 0x10(%rsp), %xmm2
mulss %xmm0, %xmm2
cvtss2sd %xmm2, %xmm2
leaq 0x6599(%rip), %rdi      # 0x85af
movsd 0x20(%rsp), %xmm0
movb $0x3, %al
callq 0x10f0
movsd 0x30(%rsp), %xmm0
subsd 0x20(%rsp), %xmm0
leaq 0x65a3(%rip), %rdi      # 0x85d9
jmp 0x203f
leaq 0x65cc(%rip), %rdi      # 0x860b
movb $0x1, %al
callq 0x10f0
xorps %xmm0, %xmm0
cvtss2sd 0x510(%rsp), %xmm0
xorps %xmm1, %xmm1
cvtss2sd 0x478(%rsp), %xmm1
xorps %xmm2, %xmm2
cvtss2sd 0x484(%rsp), %xmm2
leaq 0x6809(%rip), %rdi      # 0x887a
movb $0x3, %al
callq 0x10f0
jmp 0x132c