// File: /workspace/github_c_makefile_star2_O3/ryancdotorg[P]bloomslice/bfstool.c
// Function: main
int main(int argc, char **argv) {
  hash160_t hash;
  FILE *ifile = stdin, *ofile = stdout;
  FILE *dfile = NULL, *hfile = NULL, *bfile = NULL, *ffile = NULL, *rfile = NULL;

  mmapf_ctx bloom_mmapf, reference_mmapf, diff_mmapf;
  struct stat sb;

  uint8_t kopt = 0;
  uint8_t wopt = DEFAULT_MAX_BIT_WIDTH;
  double sopt = DEFAULT_MAX_SATURATION;
  double eopt = DEFAULT_MAX_ERROR_RATE;

  unsigned char *bopt = NULL, *xopt = NULL, *ropt = NULL;
  unsigned char *dopt = NULL, *iopt = NULL, *oopt = NULL;

  char mode = 0;
  char hfmt = 0;

  unsigned char *bloom;

  char *line = NULL;
  size_t line_sz = 0;

  unsigned char buf[41];

  double pct, err_rate, sat;
  uint64_t mask = 0, bloom_size = 0, i, items;
  uint8_t h = 254;

  int c, r;

  while ((c = getopt(argc, argv, "hABHWRDPb:x:d:r:f:i:o:w:k:e:s:")) != -1) {
    switch (c) {
      case 'A':
        for (int i = 0; i < 256; ++i) {
          printf("%3u: %8s        ", i, bloom_deschash(i));
          if (i % 4 == 3) printf("\n");
        }
        return 0;
      case 'W':
      case 'R':
      case 'D':
      case 'P':
        if (mode) bail(1, "[!] Mode '%c' already selected, can't also specify '%c'\n", mode, c);
        mode = c; break;
      case 'H':
      case 'B':
        if (hfmt) bail(1, "[!] Format '%c' already selected, can't also specify '%c'\n", hfmt, c);
        hfmt = c; break;
      case 'b':
        bopt = optarg; break;
      case 'x':
        xopt = optarg; break;
      case 'r':
        ropt = optarg; break;
      case 'd':
        dopt = optarg; break;
      case 'i':
        iopt = optarg; break;
      case 'o':
        oopt = optarg; break;
      case 'w':
        wopt = atoi(optarg); break;
      case 'k':
        kopt = atoi(optarg); break;
      case 'e':
        eopt = atof(optarg); break;
      case 's':
        sopt = atof(optarg); break;
      case 'h':
        // show help
        usage(argv[0]);
        return 0;
      case '?':
        // show error
        return 1;
      default:
        // should never be reached...
        printf("got option '%c' (%d)\n", c, c);
        return 1;
    }
  }

  if (mode == 'W') {
    // #####################
    // ##                 ##
    // ##   CREATE MODE   ##
    // ##                 ##
    // #####################
    if (!bopt) bail(1, "[!] Bloom filter file must be specified with '-b'\n");
    if (!xopt) bail(1, "[!] Hash file must be specified with '-x'\n");
    if (dopt || ropt || iopt || oopt) {
      bail(1, "[!] Invalid combination of file options for create mode\n");
    }

    // manually specified number of hashes
    if (kopt) {
      fprintf(stderr, "bloom_pick_hash_wk w:%u k:%u\n", wopt, kopt);
      if ((h = bloom_pick_hash_wk(wopt, kopt)) == 255) {
        bail(1, "[!] No hash routine found for specified parameters\n");
      }
    }

    // open input hash file
    if ((hfile = fopen(xopt, "r")) == NULL) {
      bail(1, "[!] Failed to open hash file '%s': %s\n", xopt, strerror(errno));
    }
    if ((r = fstat(fileno(hfile), &sb)) != 0) {
      bail(1, "[!] Failed to stat hash file '%s': %s\n", xopt, strerror(errno));
    }
    if ((sb.st_size % 20) && (sb.st_size % 41)) {
      bail(1, "[!] Hash file '%s' is not a valid size\n", xopt);
    }
    if (hfmt == 0) {
      if (!(sb.st_size % 20) != !(sb.st_size % 41)) {
        hfmt = !(sb.st_size % 20) ? 'B' : 'H';
        fprintf(stderr, "[*] Auto-detected hash format %c by size\n", hfmt);
      } else {
        if ((hfmt = hash_file_type(hfile)) < 0) {
          bail(1, "[!] fgetc/ungetc failed on hash file\n");
        }
        if (hfmt == 0) {
          bail(1, "[!] Unable to determine type of hash file, please specify -B or -H\n");
        }
        fprintf(stderr, "[*] Auto-detected hash format %c by content\n", hfmt);
      }
    }

    items = sb.st_size / (hfmt == 'H' ? 41 : 20);

    fprintf(stderr, "defaults h:%u w:%u\n", h, wopt);
    // if a hash routine still hasn't been chosen, pick one now
    if (items == 0) {
      bail(1, "[!] No hashes to load\n");
    } else if (items == 1) {
      bloom_size = bloom_width_to_size(BFS_TYPE_SINGLE);
      h = BFS_TYPE_SINGLE;
    } else if (h >= 254) {
      if (eopt < 0) {
        fprintf(stderr, "bloom_pick_hash_wi w:%u i:%lu\n", wopt, items);
        if ((h = bloom_pick_hash_wi(wopt, items, &kopt)) >= 254) {
          bail(1, "[!] No hash routine found for specified parameters\n");
        }
      } else {
        fprintf(stderr, "bloom_pick_hash_es e:%.3e s:%.3f i:%lu w:%u k:%u\n", eopt, sopt, items, wopt, kopt);
        if ((h = bloom_pick_hash_es(eopt, sopt, items, &wopt, &kopt)) >= 254) {
          bail(1, "[!] No hash routine found for specified parameters\n");
        }
      }
    }

    if (bloom_size == 0 && (bloom_size = bloom_width_to_size(wopt)) == 0) {
      bail(1, "[!] Failed to compute bloom filter file size (bug?)\n");
    }

    if (stat(bopt, &sb) == 0) {
      bail(1, "[!] Bloom filter file '%s' already exists\n", bopt);
    } else {
      if ((r = open64(bopt, O_RDWR|O_CREAT|O_EXCL, 0644)) < 0) {
        bail(1, "[!] Failed to create bloom filter file '%s': %s\n", bopt, strerror(errno));
      } else if ((bfile = fdopen(r, "w+")) == NULL) {
        bail(1, "[!] Failed fdopen on bloom filter file descriptor\n");
      }
    }

    fprintf(stderr, "parameters h:%u w:%u k:%u i:%lu\n", h, wopt, kopt, items);
    mask = bloom_width_to_mask(wopt);
    sat = bloom_saturation(kopt, 1ULL<<wopt, items);
    err_rate = pow(sat, kopt);

    fprintf(stderr, "[*] Selected function %s (%u) with mask 0x%zx\n", bloom_deschash(h), h, mask);
    fprintf(stderr, "[*] Have %zu hashes to load into %zu bit filter (%zu bytes)\n", items, (bloom_size - 9) * 8, bloom_size);
    if (items > 0) {
      fprintf(stderr, "[*] Saturation: ~%.3f\n", sat);
      fprintf(stderr, "[*] False positive rate: ~%.3e (1 in ~%.3e)\n", err_rate, 1/err_rate);
    }

    bloom = chkmalloc(bloom_size);
    fprintf(stderr, "[*] Zeroing memory...\n");
    memset(bloom, 0, bloom_size);

    fprintf(stderr, "[*] Loading hash160s from '%s'   0.0%%", xopt);
    for (i = 0; i < items; ++i) {
      if (hfmt == 'H') {
        if ((r = fread(buf, 41, 1, hfile)) != 1) {
          bail(1, "[!] Error reading hex hashes\n");
        }
        unhex(buf, 40, hash.uc, sizeof(hash.uc));
      } else { // hfmt == 'B'
        if ((r = fread(hash.uc, 20, 1, hfile)) != 1) {
          bail(1, "[!] Error reading binary hashes\n");
        }
      }

      bloom_h160_set(bloom, hash.uc, h, mask);

      if ((i & 0x7ffff) == 0) {
        pct = 100.0 * i / items;
        fprintf(stderr, "\033[7D %5.1f%%", pct);
        fflush(stderr);
      }
    }

    fprintf(stderr, "\033[7D 100.0%%\n");

    bloom_set_hash(bloom, bloom_size, h);
    bloom_set_items(bloom, bloom_size, items);

    fprintf(stderr, "[*] Writing bloom filter to '%s'...\n", bopt);
    if (fwrite(bloom, bloom_size, 1, bfile) != 1) {
      bail(1, "[!] Failed to write bloom filter file '%s'\n", bopt);
    }
    fprintf(stderr, "[+] Success!\n");

    return 0;
  } else if (mode == 'R') {
    // ####################
    // ##                ##
    // ##   CHECK MODE   ##
    // ##                ##
    // ####################
    if (!bopt) bail(1, "[!] Bloom filter file must be specified with '-b'\n");
    if (dopt || xopt || ropt) {
      bail(1, "[!] Invalid combination of file options for check mode\n");
    }
    if (iopt && (ifile = fopen(iopt, "r")) == NULL) {
      bail(1, "[!] Failed to open input file '%s': %s\n", iopt, strerror(errno));
    }

    if (stat(bopt, &sb) == 0) {
      if (!S_ISREG(sb.st_mode)) {
        bail(1, "[!] Bloom filter file '%s' is not a regular file\n", bopt);
      }
      bloom_size = sb.st_size;
      if (!bloom_chk_size(bloom_size)) {
        bail(1, "[!] Bloom filter file '%s' is not a valid size\n", bopt);
      }
    } else {
      bail(1, "[!] Failed to stat '%s': %s\n", bopt, strerror(errno));
    }

    if ((r = mmapf(&bloom_mmapf, bopt, bloom_size, MMAPF_RNDRD)) != MMAPF_OKAY) {
      bail(1, "[!] Failed to open bloom filter '%s': %s\n", bopt, mmapf_strerror(r));
    } else if (bloom_mmapf.mem == NULL) {
      bail(1, "[!] Got NULL pointer trying to set up bloom filter\n");
    }

    bloom = bloom_mmapf.mem;
    h = bloom_get_hash(bloom, bloom_size);

    mask = bloom_size_to_mask(sb.st_size); // h == BFS_TYPE_SINGLE ? 0 : ((sb.st_size<<3ULL) & 0xffffffffff00)-1;
    //items = bloom_get_items(bloom, bloom_size);

    fprintf(stderr, "[*] Using function %s (0x%02x) with mask 0x%zx\n", bloom_deschash(h), h, mask);

    while ((r = getline(&line, &line_sz, ifile)) > 0) {
      if (r > 40) {
        unhex(line, 40, hash.uc, sizeof(hash.uc));
        if (bloom_h160_chk(bloom, hash.ul, h, mask)) {
          fprintf(ofile, "%s", line);
        }
      }
    }
  } else if (mode == 'D') {
    // ###################
    // ##               ##
    // ##   DIFF MODE   ##
    // ##               ##
    // ###################
    if (!ropt) bail(1, "[!] Old bloom filter file must be specified with '-r'\n");
    if (!bopt) bail(1, "[!] New bloom filter file must be specified with '-b'\n");
    if (!dopt) bail(1, "[!] Bloom filter diff file must be specified with '-d'\n");
    if (xopt) {
      bail(1, "[!] Invalid combination of file options for diff mode\n");
    }

    if (stat(bopt, &sb) == 0) {
      if (!S_ISREG(sb.st_mode)) {
        bail(1, "[!] Bloom filter file '%s' is not a regular file\n", bopt);
      }
      if (!bloom_chk_size(sb.st_size)) {
        bail(1, "[!] Bloom filter file '%s' is not a valid size\n", bopt);
      }
    } else {
      bail(1, "[!] Failed to stat '%s': %s\n", bopt, strerror(errno));
    }

    if ((r = mmapf(&bloom_mmapf, bopt, sb.st_size, MMAPF_SEQRD)) != MMAPF_OKAY) {
      bail(1, "[!] Failed to open bloom filter '%s': %s\n", bopt, mmapf_strerror(r));
    } else if (bloom_mmapf.mem == NULL) {
      bail(1, "[!] Got NULL pointer trying to set up bloom filter '%s'\n", bopt);
    }

    if (stat(ropt, &sb) == 0) {
      if (!S_ISREG(sb.st_mode)) {
        bail(1, "[!] Bloom filter file '%s' is not a regular file\n", ropt);
      }
      if (!bloom_chk_size(sb.st_size)) {
        bail(1, "[!] Bloom filter file '%s' is not a valid size\n", ropt);
      }
    } else {
      bail(1, "[!] Failed to stat '%s': %s\n", ropt, strerror(errno));
    }

    if ((r = mmapf(&reference_mmapf, ropt, sb.st_size, MMAPF_SEQRD)) != MMAPF_OKAY) {
      bail(1, "[!] Failed to open bloom filter '%s': %s\n", ropt, mmapf_strerror(r));
    } else if (reference_mmapf.mem == NULL) {
      bail(1, "[!] Got NULL pointer trying to set up bloom filter '%s'\n", ropt);
    }

    if (bloom_mmapf.file_sz != reference_mmapf.file_sz) {
      bail(1, "[!] Old and new bloom filter files are different sizes!\n");
    }

    if ((r = mmapf(&diff_mmapf, dopt, bloom_mmapf.file_sz, MMAPF_SEQCR)) != MMAPF_OKAY) {
      bail(1, "[!] Failed to open bloom filter diff '%s': %s\n", dopt, mmapf_strerror(r));
    } else if (diff_mmapf.mem == NULL) {
      bail(1, "[!] Got NULL pointer trying to set up bloom filter diff '%s'\n", ropt);
    }

    fprintf(stderr, "[*] Generating diff between '%s' and '%s'   0.0%%", ropt, bopt);
    for (int i = 0; i < bloom_mmapf.file_sz; ++i) {
      ((unsigned char *)diff_mmapf.mem)[i] = ((unsigned char *)reference_mmapf.mem)[i] ^ ((unsigned char *)bloom_mmapf.mem)[i];
      if ((i & 0x7ffff) == 0) {
        pct = 100.0 * i / bloom_mmapf.file_sz;
        fprintf(stderr, "\033[7D %5.1f%%", pct);
        fflush(stderr);
      }
    }
    fprintf(stderr, "\033[7D 100.0%%\n");
  } else if (mode == 'P') {
    // ####################
    // ##                ##
    // ##   PATCH MODE   ##
    // ##                ##
    // ####################
    if (!ropt) bail(1, "[!] Old bloom filter file must be specified with '-r'\n");
    if (!bopt) bail(1, "[!] New bloom filter file must be specified with '-b'\n");
    if (!dopt) bail(1, "[!] Bloom filter diff file must be specified with '-d'\n");
    if (xopt) {
      bail(1, "[!] Invalid combination of file options for diff mode\n");
    }
  } else {
    bail(1, "[!] No valid mode selected\n");
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x188, %rsp            # imm = 0x188
movq %rsi, %r15
movl %edi, %r12d
movq 0x9262(%rip), %rax      # 0xafc8
movq (%rax), %rax
movq %rax, 0x68(%rsp)
movq 0x924b(%rip), %rax      # 0xafc0
movq (%rax), %rax
movq %rax, 0xb0(%rsp)
xorl %eax, %eax
movq %rax, 0x48(%rsp)
movq $0x0, 0x20(%rsp)
movq %rax, 0x78(%rsp)
movsd 0x526b(%rip), %xmm0     # 0x7008
movsd %xmm0, 0x30(%rsp)
movsd 0x5265(%rip), %xmm0     # 0x7010
movsd %xmm0, 0x70(%rsp)
movb $0x23, %al
movl %eax, 0x4(%rsp)
leaq 0x553a(%rip), %rbx      # 0x72f8
leaq 0x528b(%rip), %r14      # 0x7050
leaq 0x52ac(%rip), %r13      # 0x7078
movq $0x0, 0x40(%rsp)
movq $0x0, 0x50(%rsp)
movq $0x0, 0x10(%rsp)
movq $0x0, 0x8(%rsp)
movq $0x0, 0x28(%rsp)
movq $0x0, 0x38(%rsp)
xorl %ebp, %ebp
movl $0x0, 0x18(%rsp)
movl %r12d, %edi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x1210
cmpl $0x51, %eax
jle 0x1e42
leal -0x62(%rax), %ecx
cmpl $0x16, %ecx
ja 0x1e65
movslq (%r13,%rcx,4), %rcx
addq %r13, %rcx
jmpq *%rcx
movq 0x91a0(%rip), %rax      # 0xafd8
movq (%rax), %rax
movq %rax, 0x40(%rsp)
jmp 0x1e0c
leal -0x3f(%rax), %ecx
cmpl $0x9, %ecx
ja 0x1e74
movslq (%r14,%rcx,4), %rcx
addq %r14, %rcx
jmpq *%rcx
movl 0x18(%rsp), %ecx
testb %cl, %cl
jne 0x29da
movl %eax, 0x18(%rsp)
jmp 0x1e0c
cmpl $0x52, %eax
je 0x1e7d
cmpl $0x57, %eax
je 0x1e7d
jmp 0x1fef
cmpl $0x50, %eax
jne 0x1f53
testb %bpl, %bpl
jne 0x29cf
movl %eax, %ebp
jmp 0x1e0c
movq 0x9147(%rip), %rax      # 0xafd8
movq (%rax), %rdi
callq 0x1230
movl %eax, 0x4(%rsp)
jmp 0x1e0c
movq 0x912f(%rip), %rax      # 0xafd8
movq (%rax), %rax
movq %rax, 0x50(%rsp)
jmp 0x1e0c
movq 0x911b(%rip), %rax      # 0xafd8
movq (%rax), %rax
movq %rax, 0x38(%rsp)
jmp 0x1e0c
movq 0x9107(%rip), %rax      # 0xafd8
movq (%rax), %rdi
callq 0x1070
movsd %xmm0, 0x30(%rsp)
jmp 0x1e0c
movq 0x90ed(%rip), %rax      # 0xafd8
movq (%rax), %rax
movq %rax, 0x28(%rsp)
jmp 0x1e0c
movq 0x90d9(%rip), %rax      # 0xafd8
movq (%rax), %rax
movq %rax, 0x8(%rsp)
jmp 0x1e0c
movq 0x90c5(%rip), %rax      # 0xafd8
movq (%rax), %rax
movq %rax, 0x10(%rsp)
jmp 0x1e0c
movq 0x90b1(%rip), %rax      # 0xafd8
movq (%rax), %rdi
callq 0x1070
movsd %xmm0, 0x70(%rsp)
jmp 0x1e0c
movq 0x9097(%rip), %rax      # 0xafd8
movq (%rax), %rdi
callq 0x1230
movq %rax, 0x20(%rsp)
jmp 0x1e0c
cmpl $-0x1, %eax
jne 0x1fef
movq 0x20(%rsp), %rdx
movb %dl, 0x3(%rsp)
movl 0x4(%rsp), %ecx
movb %cl, 0x2(%rsp)
cmpb $0x50, %bpl
jne 0x201a
cmpq $0x0, 0x10(%rsp)
movq 0x40(%rsp), %rax
movq 0x50(%rsp), %rcx
je 0x2a09
testq %rax, %rax
movq 0x8(%rsp), %rax
je 0x2a0e
testq %rax, %rax
je 0x2a13
testq %rcx, %rcx
je 0x1feb
callq 0x12f4
leaq 0x5362(%rip), %rbx      # 0x7317
xorl %ebp, %ebp
movzbl %bpl, %edi
callq 0x5c2c
movq %rbx, %rdi
movl %ebp, %esi
movq %rax, %rdx
xorl %eax, %eax
callq 0x10c0
movl %ebp, %eax
notl %eax
testb $0x3, %al
jne 0x1fe1
movl $0xa, %edi
callq 0x1030
incl %ebp
cmpl $0x100, %ebp            # imm = 0x100
jne 0x1fb7
xorl %ebp, %ebp
jmp 0x2006
leaq 0x53a6(%rip), %rdi      # 0x739c
movl %eax, %esi
movl %eax, %edx
xorl %eax, %eax
callq 0x10c0
movl $0x1, %ebp
movl %ebp, %eax
addq $0x188, %rsp            # imm = 0x188
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movzbl %bpl, %eax
cmpl $0x44, %eax
movq 0x40(%rsp), %r12
movq 0x50(%rsp), %r13
movq 0x10(%rsp), %r14
je 0x2378
cmpl $0x52, %eax
movq 0x8(%rsp), %rsi
je 0x21b2
cmpl $0x57, %eax
jne 0x2b08
testq %r12, %r12
je 0x2a18
testq %r13, %r13
je 0x2a27
testq %rsi, %rsi
jne 0x2a3b
testq %r14, %r14
jne 0x2a3b
cmpq $0x0, 0x28(%rsp)
jne 0x2a3b
cmpq $0x0, 0x38(%rsp)
jne 0x2a3b
movb $-0x2, %r15b
movzbl %cl, %r14d
testb %dl, %dl
je 0x20af
movzbl 0x20(%rsp), %esi
leaq 0xd8(%rsp), %rbx
movl %r14d, %edi
movq %rbx, %rdx
callq 0x17e6
movb (%rbx), %r15b
leaq 0x6026(%rip), %rsi      # 0x80dc
movq %r13, %rdi
callq 0x11f0
testq %rax, %rax
je 0x2a48
movq %rax, %rbx
movq %rax, %rdi
callq 0x1160
leaq 0xd8(%rsp), %rsi
movl %eax, %edi
callq 0x1280
testl %eax, %eax
jne 0x2a5d
movq %rbx, 0x10(%rsp)
movq 0x108(%rsp), %rbx
movabsq $0x6666666666666667, %rcx # imm = 0x6666666666666667
movq %rbx, %rax
imulq %rcx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x3, %rdx
addq %rax, %rdx
shlq $0x2, %rdx
leaq (%rdx,%rdx,4), %rax
movq %rbx, %rcx
subq %rax, %rcx
sete %sil
movabsq $0x63e7063e7063e707, %rdx # imm = 0x63E7063E7063E707
movq %rbx, %rax
imulq %rdx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x4, %rdx
addq %rax, %rdx
leaq (%rdx,%rdx,4), %rax
leaq (%rdx,%rax,8), %rdx
movq %rbx, %rax
subq %rdx, %rax
sete %dl
orb %sil, %dl
je 0x2a75
movl 0x18(%rsp), %ebp
testb %bpl, %bpl
jne 0x258e
testq %rcx, %rcx
sete %dl
testq %rax, %rax
setne %al
xorb %dl, %al
je 0x2564
movq 0x10(%rsp), %rdi
callq 0x1cec
testb %al, %al
js 0x2b35
movq 0x8e60(%rip), %rcx      # 0xaff8
movq (%rcx), %rdi
je 0x2b3a
movl %eax, %ebp
movsbl %al, %edx
leaq 0x53f8(%rip), %rsi      # 0x75a5
jmp 0x2587
testq %r12, %r12
je 0x2a1d
testq %rsi, %rsi
jne 0x2a31
testq %r13, %r13
jne 0x2a31
testq %r14, %r14
jne 0x2a31
movq 0x28(%rsp), %rbx
testq %rbx, %rbx
je 0x21fd
leaq 0x5ef5(%rip), %rsi      # 0x80dc
movq %rbx, %rdi
callq 0x11f0
movq %rax, 0x68(%rsp)
testq %rax, %rax
je 0x2b28
leaq 0xd8(%rsp), %rsi
movq %r12, %rdi
callq 0x1140
testl %eax, %eax
jne 0x2a40
movl $0xf000, %eax           # imm = 0xF000
andl 0xf0(%rsp), %eax
cmpl $0x8000, %eax           # imm = 0x8000
jne 0x2a55
movq 0x108(%rsp), %r14
movq %r14, %rdi
callq 0x5cbf
testl %eax, %eax
je 0x2a6d
leaq 0x80(%rsp), %rdi
movq %r12, %rsi
movq %r14, %rdx
movl $0x2501, %ecx           # imm = 0x2501
callq 0x61af
testl %eax, %eax
jne 0x2a85
movq 0x80(%rsp), %rdi
testq %rdi, %rdi
je 0x2a97
movq %rdi, 0x18(%rsp)
movq %r14, %rsi
callq 0x5ceb
movl %eax, %ebp
movq 0x108(%rsp), %rdi
callq 0x5c92
movq %rax, %rbx
movq 0x8d5d(%rip), %rax      # 0xaff8
movq (%rax), %r12
movzbl %bpl, %r15d
movl %r15d, %edi
callq 0x5c2c
leaq 0x5773(%rip), %rsi      # 0x7a24
xorl %ebp, %ebp
movq %r12, %rdi
movq %rax, %rdx
movl %r15d, %ecx
movq %rbx, 0x50(%rsp)
movq %rbx, %r8
xorl %eax, %eax
callq 0x1130
leaq 0x48(%rsp), %rdi
leaq 0x78(%rsp), %rsi
movq 0x68(%rsp), %rdx
callq 0x1240
testl %eax, %eax
jle 0x2006
leaq 0x4df2(%rip), %rbx      # 0x70e0
leaq 0x4eeb(%rip), %r14      # 0x71e0
leaq 0x48(%rsp), %r13
leaq 0x78(%rsp), %r12
xorl %ebp, %ebp
cmpl $0x29, %eax
jb 0x235f
movq 0x48(%rsp), %rax
xorl %ecx, %ecx
movq 0x18(%rsp), %rdi
movzbl (%rax,%rcx,2), %edx
movzbl 0x1(%rax,%rcx,2), %esi
movb (%rsi,%r14), %sil
orb (%rdx,%rbx), %sil
movb %sil, 0xb8(%rsp,%rcx)
incq %rcx
cmpq $0x14, %rcx
jne 0x2312
leaq 0xb8(%rsp), %rsi
movl %r15d, %edx
movq 0x50(%rsp), %rcx
callq 0x2b5c
testl %eax, %eax
je 0x235f
movq 0x48(%rsp), %rdi
movq 0xb0(%rsp), %rsi
callq 0x10e0
movq %r13, %rdi
movq %r12, %rsi
movq 0x68(%rsp), %rdx
callq 0x1240
testl %eax, %eax
jg 0x2301
jmp 0x2006
testq %r14, %r14
movq 0x8(%rsp), %r15
je 0x2a22
testq %r12, %r12
je 0x2a2c
testq %r15, %r15
je 0x2a36
testq %r13, %r13
jne 0x2a50
leaq 0xd8(%rsp), %rsi
movq %r12, %rdi
callq 0x1140
testl %eax, %eax
jne 0x2a65
movl $0xf000, %eax           # imm = 0xF000
andl 0xf0(%rsp), %eax
cmpl $0x8000, %eax           # imm = 0x8000
jne 0x2a7d
movq 0x108(%rsp), %rbx
movq %rbx, %rdi
callq 0x5cbf
testl %eax, %eax
je 0x2a8f
leaq 0x80(%rsp), %rdi
movq %r12, %rsi
movq %rbx, %rdx
movl $0x2201, %ecx           # imm = 0x2201
callq 0x61af
testl %eax, %eax
jne 0x2a9c
cmpq $0x0, 0x80(%rsp)
je 0x2aa6
leaq 0xd8(%rsp), %rsi
movq %r14, %rdi
callq 0x1140
testl %eax, %eax
jne 0x2ab6
movl $0xf000, %eax           # imm = 0xF000
andl 0xf0(%rsp), %eax
cmpl $0x8000, %eax           # imm = 0x8000
jne 0x2ac6
movq 0x108(%rsp), %rbx
movq %rbx, %rdi
callq 0x5cbf
testl %eax, %eax
je 0x2ad3
leaq 0xb8(%rsp), %rdi
movq %r14, %rsi
movq %rbx, %rdx
movl $0x2201, %ecx           # imm = 0x2201
callq 0x61af
testl %eax, %eax
jne 0x2adb
cmpq $0x0, 0xb8(%rsp)
je 0x2ae5
movq 0x90(%rsp), %rdx
cmpq 0xc8(%rsp), %rdx
jne 0x2aed
leaq 0x168(%rsp), %rdi
movq %r15, %rsi
movl $0x20e, %ecx            # imm = 0x20E
callq 0x61af
testl %eax, %eax
jne 0x2af2
cmpq $0x0, 0x168(%rsp)
movq 0x8b28(%rip), %r15      # 0xaff8
movq (%r15), %rdi
je 0x2afc
leaq 0x5730(%rip), %rsi      # 0x7c10
xorl %ebp, %ebp
movq %r14, %rdx
movq %r12, %rcx
xorl %eax, %eax
callq 0x1130
cmpq $0x0, 0x90(%rsp)
jne 0x2510
movq (%r15), %rdi
leaq 0x5376(%rip), %rsi      # 0x787a
xorl %eax, %eax
callq 0x1130
jmp 0x2006
leaq 0x90(%rsp), %rbx
xorl %r14d, %r14d
movq 0xb8(%rsp), %rax
movq 0x80(%rsp), %rcx
movb (%rcx,%r14), %cl
xorb (%rax,%r14), %cl
movq 0x168(%rsp), %rax
movb %cl, (%rax,%r14)
testl $0x7ffff, %r14d         # imm = 0x7FFFF
je 0x2557
incq %r14
cmpq %r14, 0x90(%rsp)
ja 0x251b
jmp 0x24fa
movl %r14d, %edi
movq %rbx, %rsi
callq 0x1531
jmp 0x2548
testq %rcx, %rcx
movl $0x42, %eax
movl $0x48, %ebp
cmovel %eax, %ebp
movq 0x8a7d(%rip), %rax      # 0xaff8
movq (%rax), %rdi
leaq 0x4f8c(%rip), %rsi      # 0x7511
movl %ebp, %edx
xorl %eax, %eax
callq 0x1130
movl %ebp, 0x18(%rsp)
cmpb $0x48, %bpl
movl $0x29, %eax
movl $0x14, %ecx
cmoveq %rax, %rcx
movq %rbx, %rax
cqto
idivq %rcx
movq %rax, %rbx
movq 0x8a42(%rip), %rbp      # 0xaff8
movq (%rbp), %rdi
movzbl %r15b, %edx
leaq 0x500d(%rip), %rsi      # 0x75d2
movl %r14d, %ecx
xorl %eax, %eax
callq 0x1130
cmpq $0x1, %rbx
je 0x2630
testq %rbx, %rbx
je 0x2b30
cmpb $-0x2, %r15b
jb 0x2642
xorpd %xmm0, %xmm0
movsd 0x30(%rsp), %xmm1
ucomisd %xmm1, %xmm0
movq (%rbp), %rdi
jbe 0x2973
leaq 0x4ffa(%rip), %rsi      # 0x75fd
movl %r14d, %edx
movq %rbx, %rcx
xorl %eax, %eax
callq 0x1130
leaq 0x3(%rsp), %rdx
movl %r14d, %edi
movq %rbx, %rsi
callq 0x5dc2
movl %eax, %r15d
cmpb $-0x2, %al
movl 0x4(%rsp), %eax
jb 0x2646
callq 0x1a56
movl $0x1, %edi
callq 0x5c3b
movb $0x1, %r15b
testq %rax, %rax
jne 0x2657
movl 0x4(%rsp), %eax
movzbl %al, %edi
callq 0x5c3b
testq %rax, %rax
je 0x2b23
movq %rax, %r13
leaq 0xd8(%rsp), %rsi
movq %r12, %rdi
callq 0x1140
testl %eax, %eax
je 0x2aae
movq %r12, %rdi
movl $0xc2, %esi
movl $0x1a4, %edx            # imm = 0x1A4
xorl %eax, %eax
callq 0x11d0
testl %eax, %eax
js 0x2abe
leaq 0x504a(%rip), %rsi      # 0x76df
movl %eax, %edi
callq 0x11a0
movq (%rbp), %rdi
testq %rax, %rax
je 0x2ace
movq %rax, 0x38(%rsp)
movzbl %r15b, %r14d
movzbl 0x2(%rsp), %ecx
movzbl 0x3(%rsp), %r8d
leaq 0x5051(%rip), %rsi      # 0x7715
movl %r14d, %edx
movq %rbx, %r9
xorl %eax, %eax
callq 0x1130
movzbl 0x2(%rsp), %edi
callq 0x5c6d
movq %rbx, %r15
movq %rax, %r12
movzbl 0x3(%rsp), %edi
movb 0x2(%rsp), %cl
movl $0x1, %esi
shlq %cl, %rsi
movq %rbx, %rdx
callq 0x5bb0
movsd %xmm0, 0x28(%rsp)
movzbl 0x3(%rsp), %eax
xorps %xmm1, %xmm1
cvtsi2sd %eax, %xmm1
callq 0x1090
movsd %xmm0, 0x8(%rsp)
movq (%rbp), %rbx
movl %r14d, %edi
callq 0x5c2c
leaq 0x500c(%rip), %rsi      # 0x7736
movq %rbx, %rdi
movq %rax, %rdx
movl %r14d, 0x4(%rsp)
movl %r14d, %ecx
movq %r12, 0x20(%rsp)
movq %r12, %r8
xorl %eax, %eax
callq 0x1130
movq (%rbp), %rdi
leaq -0x48(,%r13,8), %rcx
leaq 0x500b(%rip), %rsi      # 0x7765
movq %r15, %rdx
movq %r13, %r8
xorl %eax, %eax
callq 0x1130
movq (%rbp), %rdi
leaq 0x5030(%rip), %rsi      # 0x77a2
movsd 0x28(%rsp), %xmm0
movb $0x1, %al
callq 0x1130
movq (%rbp), %rdi
movsd 0x488d(%rip), %xmm1     # 0x7018
movsd 0x8(%rsp), %xmm0
divsd %xmm0, %xmm1
leaq 0x501d(%rip), %rsi      # 0x77b9
movb $0x2, %al
callq 0x1130
movq %r13, %rdi
callq 0x2b44
movq %rax, %r14
movq (%rbp), %rcx
leaq 0x5037(%rip), %rdi      # 0x77f0
movl $0x16, %esi
movl $0x1, %edx
callq 0x1260
movq %r14, %rdi
xorl %esi, %esi
movq %r13, 0x8(%rsp)
movq %r13, %rdx
callq 0x10f0
movq (%rbp), %rdi
leaq 0x5022(%rip), %rsi      # 0x7807
movq 0x50(%rsp), %rdx
xorl %eax, %eax
callq 0x1130
movq %r15, %r13
testq %r15, %r15
jne 0x287e
movq 0x87f4(%rip), %r15      # 0xaff8
movq (%r15), %rdi
leaq 0x506c(%rip), %rsi      # 0x787a
xorl %ebp, %ebp
xorl %eax, %eax
callq 0x1130
movq %r14, %rdi
movq 0x8(%rsp), %r12
movq %r12, %rsi
movl 0x4(%rsp), %edx
callq 0x5cfc
movq %r14, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0x5d13
movq (%r15), %rdi
leaq 0x5045(%rip), %rsi      # 0x7888
movq 0x40(%rsp), %rbx
movq %rbx, %rdx
xorl %eax, %eax
callq 0x1130
movl $0x1, %edx
movq %r14, %rdi
movq %r12, %rsi
movq 0x38(%rsp), %rcx
callq 0x1260
movq (%r15), %rdi
cmpq $0x1, %rax
jne 0x2b0d
callq 0x1998
jmp 0x2006
movq %r13, %xmm0
punpckldq 0x47a5(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x47ad(%rip), %xmm0     # 0x7040
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd %xmm1, 0x50(%rsp)
xorl %r12d, %r12d
leaq 0x4831(%rip), %rbp      # 0x70e0
leaq 0x492a(%rip), %r15      # 0x71e0
leaq 0xb8(%rsp), %rbx
cmpb $0x48, 0x18(%rsp)
jne 0x2915
movl $0x29, %esi
movl $0x1, %edx
leaq 0x80(%rsp), %rdi
movq 0x10(%rsp), %rcx
callq 0x1060
cmpl $0x1, %eax
jne 0x29ff
xorl %eax, %eax
movzbl 0x80(%rsp,%rax,2), %ecx
movzbl 0x81(%rsp,%rax,2), %edx
movb (%rdx,%r15), %dl
orb (%rcx,%rbp), %dl
movb %dl, 0xb8(%rsp,%rax)
incq %rax
cmpq $0x14, %rax
jne 0x28ec
jmp 0x2935
movl $0x14, %esi
movl $0x1, %edx
movq %rbx, %rdi
movq 0x10(%rsp), %rcx
callq 0x1060
cmpl $0x1, %eax
jne 0x2a04
movq %r14, %rdi
movq %rbx, %rsi
movl 0x4(%rsp), %edx
movq 0x20(%rsp), %rcx
callq 0x57a0
movq %r12, %rax
shlq $0x2d, %rax
je 0x2963
incq %r12
cmpq %r13, %r12
jne 0x28be
jmp 0x27fd
movq %r12, %rdi
movapd 0x50(%rsp), %xmm0
callq 0x1944
jmp 0x2952
movapd %xmm1, %xmm0
movzbl 0x20(%rsp), %r8d
leaq 0x4c98(%rip), %rsi      # 0x761c
movsd %xmm1, 0x30(%rsp)
movsd 0x70(%rsp), %xmm1
movq %rbx, %rdx
movl %r14d, %ecx
movb $0x2, %al
callq 0x1130
leaq 0x2(%rsp), %rsi
leaq 0x3(%rsp), %rdx
movsd 0x30(%rsp), %xmm0
movsd 0x70(%rsp), %xmm1
movq %rbx, %rdi
callq 0x5ec8
cmpb $-0x3, %al
ja 0x2b3f
movl %eax, %r15d
movb 0x2(%rsp), %al
jmp 0x2646
movzbl %bpl, %edi
movl %eax, %esi
callq 0x12ca
movzbl %cl, %edi
movl %eax, %esi
callq 0x12a0
movq (%r15), %rsi
leaq 0x48f2(%rip), %rdi      # 0x72e0
xorl %eax, %eax
callq 0x10c0
movl $0x1, %edi
callq 0x1250
callq 0x191f
callq 0x18fa
callq 0x1363
callq 0x133e
callq 0x1319
callq 0x1b44
callq 0x17c1
callq 0x165d
callq 0x1b1f
callq 0x1638
callq 0x179c
callq 0x1613
callq 0x1afa
movq %r12, %rdi
callq 0x16be
movq %r13, %rdi
callq 0x1abe
callq 0x1388
movq %r12, %rdi
callq 0x16fa
movq %r13, %rdi
callq 0x1850
movq %r12, %rdi
callq 0x13ad
movq %r12, %rdi
callq 0x1778
movq %r13, %rdi
callq 0x188c
movq %r12, %rdi
callq 0x13e9
movl %eax, %edi
movq %r12, %rsi
callq 0x171e
movq %r12, %rdi
callq 0x15ef
callq 0x1753
movl %eax, %edi
movq %r12, %rsi
callq 0x140d
movq %r12, %rdi
callq 0x15cb
movq %r12, %rdi
callq 0x1a0d
movq %r14, %rdi
callq 0x1442
movq %r12, %rdi
callq 0x19d1
movq %r14, %rdi
callq 0x147e
callq 0x19b3
movq %r14, %rdi
callq 0x15a7
movl %eax, %edi
movq %r14, %rsi
callq 0x14a2
movq %r14, %rdi
callq 0x1583
callq 0x14d7
movl %eax, %edi
movq %r15, %rsi
callq 0x14fc
leaq 0x50cf(%rip), %rsi      # 0x7bd2
movq %r14, %rdx
jmp 0x2b17
callq 0x1b69
leaq 0x4d99(%rip), %rsi      # 0x78ad
movq %rbx, %rdx
xorl %eax, %eax
callq 0x1130
jmp 0x29f5
callq 0x1a31
movq %rbx, %rdi
callq 0x1682
callq 0x18b0
callq 0x1a99
callq 0x1a7b
callq 0x18d5