// File: /workspace/github_c_makefile_star2_O0/felipelouza[P]egap/util.c
// Function: mergeBWT8
void mergeBWT8(g_data *g, bool lastRound)
{
  if(sizeof(symbol)>sizeof(palette)) die("Sorry, alphabet is too large (mergeBWT8)");
  symbol *bwtout = (symbol *) g->mergeColor;   // merged BWT stored in mergeColor
  assert(!g->lcpMerge);
  FILE *daOutFile=NULL;
  FILE *saOutFile=NULL;
  FILE *slOutFile=NULL;
  FILE *qsOutFile=NULL;

  check_g_data(g);
  array_clear(g->inCnt,g->numBwt,0); // clear counter inside each bwt
  if(g->outputSA && lastRound){
    saOutFile = openSAFile(g);    
    snprintf(g->safname,Filename_size,"%s.%d.%s",g->outPath,g->outputSA, SA_BL_EXT);
    open_sa_files(g);
    rewind_sa_files(g);   // set file pointers at the beginning of each SA
  }
  if(g->outputSL && lastRound){
    slOutFile = openSLFile(g);    
    snprintf(g->slfname,Filename_size,"%s.%d.%s",g->outPath,g->outputSL, SL_BL_EXT);
    open_sl_files(g);
    rewind_sl_files(g);   // set file pointers at the beginning of each SL
  }
  if(g->outputDA && lastRound){
    daOutFile = openDAFile(g);    
    snprintf(g->dafname,Filename_size,"%s.%d.%s",g->outPath,g->outputDA, DA_BL_EXT);
    open_da_files(g);
    rewind_da_files(g);   // set file pointers at the beginning of each DA
  }
  if(g->outputQS && lastRound){
    qsOutFile = openQSFile(g);    
    snprintf(g->qsfname,Filename_size,"%s.%s",g->outPath,QS_BL_EXT);
    open_qs_files(g);
    rewind_qs_files(g);   // set file pointers at the beginning of each QS
  }
  if(g->extMem) {
    open_bw_files(g);     // open files in read/write mode
    rewind_bw_files(g);   // set file pointers at the beginning of each BWT 
  }
  int shift = 3; (void) shift;  // shift is not used outside assertions
  for (customInt i = 0; i < g->mergeLen; ++i) {
    int currentColor = g->mergeColor[i] & 0x7;
    assert(currentColor == ((g->mergeColor[i]>>shift) & 0x7)); // we must have mergeColor==newMergeColor
    assert(currentColor < g->numBwt);
    // check that all LCP values have been obtained
    if(g->lcpCompute && lastRound)
      assert( ((g->mergeColor[i]>>2*shift) & 3)==3);    
    // if requested output merge array
    if(g->outputSA && lastRound){ 
      int sa_value=0;
      int e = fread(&sa_value, g->outputSA, 1, g->saf[currentColor]);
      if(e!=1) die(__func__);
      if(fwrite(&sa_value, g->outputSA, 1, saOutFile)==EOF)
        die("mergeBWT128ext: Error writing to Sufix Array file");   
    } 
    if(g->outputSL && lastRound){ 
      int sl_value=0;
      int e = fread(&sl_value, g->outputSL, 1, g->saf[currentColor]);
      if(e!=1) die(__func__);
      if(fwrite(&sl_value, g->outputSL, 1, slOutFile)==EOF)
        die("mergeBWT128ext: Error writing to Sufixes' lengths file");   
    } 
    if(g->outputDA && lastRound){ 
      int da_value=0;
      int e = fread(&da_value, g->outputDA, 1, g->daf[currentColor]);
      if(e!=1) die(__func__);
      //if(fputc(currentColor, daOutFile)==EOF)
      da_value+=g->bwtDocs[currentColor];
      if(fwrite(&da_value, g->outputDA, 1, daOutFile)==EOF)
        die("mergeBWT128ext: Error writing to Document Array file");   
      //printf("%d ==> %d\n", currentColor, da_value);
    } 
    if(g->outputQS && lastRound){ 
      symbol qs_value=0;
      int e = fread(&qs_value, sizeof(symbol), 1, g->qsf[currentColor]);
      if(e!=1) die(__func__);
      if(fwrite(&qs_value, sizeof(symbol), 1, qsOutFile)==EOF)
        die("mergeBWT128ext: Error writing to QS file");   
    } 
    // save new BWT char overwriting mergeColor[i]
    if(g->extMem) {
      int e = fread(bwtout+i,sizeof(symbol),1,g->bwf[currentColor]);
      if(e!=1) die(__func__);
    }      
    else bwtout[i] = g->bws[currentColor][g->inCnt[currentColor]];
    if(lastRound) bwtout[i] = alpha_enlarge(bwtout[i]); 
    g->inCnt[currentColor]++; // one more char read from currentColor BWT
  }
  // final check on the merging 
  for(int i=0;i<g->numBwt;i++) assert(g->inCnt[i]==g->bwtLen[i]);
  if(g->extMem) close_bw_files(g);
  // close suffix array file 
  if(g->outputSA && lastRound){
    if(fclose(saOutFile)!=0) die("mergeBWT8: Error closing Suffix Array file");       
    remove(g->safname);
  }
  // close suffixes' lengths file 
  if(g->outputSL && lastRound){
    if(fclose(slOutFile)!=0) die("mergeBWT8: Error closing Suffixes' lengths file");       
    remove(g->slfname);
  }
  // close document array file 
  if(g->outputDA && lastRound){
    if(fclose(daOutFile)!=0) die("mergeBWT8: Error closing Document Array file");       
    remove(g->dafname);
  }
  // close suffix array file 
  if(g->outputQS && lastRound){
    if(fclose(qsOutFile)!=0) die("mergeBWT8: Error closing QS file");       
    remove(g->qsfname);
  }

  // merging done: copy back to g->bws[0] or to file
  if(g->extMem) {
    if(g->verbose>1) printf("Copy back to file. Bytes: %zu, offset %zu\n",g->mergeLen, g->symb_offset);
    int fd = open(g->bwfname,O_WRONLY);
    if(fd == -1) die(__func__);
    huge_pwrite(fd, bwtout,sizeof(symbol)*g->mergeLen,sizeof(symbol)*g->symb_offset);
    if(close(fd)!=0) die(__func__);
  }
  else 
    memcpy(g->bws[0],bwtout,g->mergeLen*sizeof(symbol));
}

// Assembly:
subq $0x78, %rsp
movb %sil, %al
movq %rdi, 0x70(%rsp)
andb $0x1, %al
movb %al, 0x6f(%rsp)
movq 0x70(%rsp), %rax
movq 0x50e8(%rax), %rax
movq %rax, 0x60(%rsp)
movq $0x0, 0x58(%rsp)
movq $0x0, 0x50(%rsp)
movq $0x0, 0x48(%rsp)
movq $0x0, 0x40(%rsp)
movq 0x70(%rsp), %rdi
callq 0x3dd0
movq 0x70(%rsp), %rax
movq 0x5118(%rax), %rdi
movq 0x70(%rsp), %rax
movslq 0x20(%rax), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x3310
movq 0x70(%rsp), %rax
cmpl $0x0, 0x4c(%rax)
je 0x593f
testb $0x1, 0x6f(%rsp)
je 0x593f
movq 0x70(%rsp), %rdi
callq 0x53a0
movq %rax, 0x50(%rsp)
movq 0x70(%rsp), %rdi
addq $0x20a0, %rdi           # imm = 0x20A0
movq 0x70(%rsp), %rax
movq 0x80(%rax), %rcx
movq 0x70(%rsp), %rax
movl 0x4c(%rax), %r8d
movl $0x1000, %esi           # imm = 0x1000
leaq 0xf240(%rip), %rdx      # 0x14b5d
leaq 0xf242(%rip), %r9       # 0x14b66
movb $0x0, %al
callq 0x2130
movq 0x70(%rsp), %rdi
callq 0x6f90
movq 0x70(%rsp), %rdi
callq 0x7060
movq 0x70(%rsp), %rax
cmpl $0x0, 0x50(%rax)
je 0x59af
testb $0x1, 0x6f(%rsp)
je 0x59af
movq 0x70(%rsp), %rdi
callq 0x5440
movq %rax, 0x48(%rsp)
movq 0x70(%rsp), %rdi
addq $0x30a0, %rdi           # imm = 0x30A0
movq 0x70(%rsp), %rax
movq 0x80(%rax), %rcx
movq 0x70(%rsp), %rax
movl 0x50(%rax), %r8d
movl $0x1000, %esi           # imm = 0x1000
leaq 0xf1d0(%rip), %rdx      # 0x14b5d
leaq 0xf22a(%rip), %r9       # 0x14bbe
movb $0x0, %al
callq 0x2130
movq 0x70(%rsp), %rdi
callq 0x7180
movq 0x70(%rsp), %rdi
callq 0x7250
movq 0x70(%rsp), %rax
cmpl $0x0, 0x44(%rax)
je 0x5a1f
testb $0x1, 0x6f(%rsp)
je 0x5a1f
movq 0x70(%rsp), %rdi
callq 0x4870
movq %rax, 0x58(%rsp)
movq 0x70(%rsp), %rdi
addq $0x10a0, %rdi           # imm = 0x10A0
movq 0x70(%rsp), %rax
movq 0x80(%rax), %rcx
movq 0x70(%rsp), %rax
movl 0x44(%rax), %r8d
movl $0x1000, %esi           # imm = 0x1000
leaq 0xf160(%rip), %rdx      # 0x14b5d
leaq 0xf17e(%rip), %r9       # 0x14b82
movb $0x0, %al
callq 0x2130
movq 0x70(%rsp), %rdi
callq 0x7560
movq 0x70(%rsp), %rdi
callq 0x7630
movq 0x70(%rsp), %rax
cmpl $0x0, 0x54(%rax)
je 0x5a86
testb $0x1, 0x6f(%rsp)
je 0x5a86
movq 0x70(%rsp), %rdi
callq 0x5580
movq %rax, 0x40(%rsp)
movq 0x70(%rsp), %rdi
addq $0x40a0, %rdi           # imm = 0x40A0
movq 0x70(%rsp), %rax
movq 0x80(%rax), %rcx
movl $0x1000, %esi           # imm = 0x1000
leaq 0xf07b(%rip), %rdx      # 0x14adf
leaq 0xf133(%rip), %r8       # 0x14b9e
movb $0x0, %al
callq 0x2130
movq 0x70(%rsp), %rdi
callq 0x7370
movq 0x70(%rsp), %rdi
callq 0x7440
movq 0x70(%rsp), %rax
testb $0x1, 0x69(%rax)
je 0x5aa5
movq 0x70(%rsp), %rdi
callq 0x6da0
movq 0x70(%rsp), %rdi
callq 0x6e70
movl $0x3, 0x3c(%rsp)
movq $0x0, 0x30(%rsp)
movq 0x30(%rsp), %rax
movq 0x70(%rsp), %rcx
cmpq 0x28(%rcx), %rax
jae 0x5e34
movq 0x70(%rsp), %rax
movq 0x50e8(%rax), %rax
movq 0x30(%rsp), %rcx
movzbl (%rax,%rcx), %eax
andl $0x7, %eax
movl %eax, 0x2c(%rsp)
movq 0x70(%rsp), %rax
testb $0x1, 0x3e(%rax)
je 0x5afa
testb $0x1, 0x6f(%rsp)
je 0x5afa
jmp 0x5afa
movq 0x70(%rsp), %rax
cmpl $0x0, 0x4c(%rax)
je 0x5b8d
testb $0x1, 0x6f(%rsp)
je 0x5b8d
movl $0x0, 0x28(%rsp)
movq 0x70(%rsp), %rax
movslq 0x4c(%rax), %rsi
movq 0x70(%rsp), %rax
movq 0x50b0(%rax), %rax
movslq 0x2c(%rsp), %rcx
movq (%rax,%rcx,8), %rcx
leaq 0x28(%rsp), %rdi
movl $0x1, %edx
callq 0x2090
movl %eax, 0x24(%rsp)
cmpl $0x1, 0x24(%rsp)
je 0x5b5c
leaq 0xf408(%rip), %rdi      # 0x14f5f
callq 0x3ce0
movq 0x70(%rsp), %rax
movslq 0x4c(%rax), %rsi
movq 0x50(%rsp), %rcx
leaq 0x28(%rsp), %rdi
movl $0x1, %edx
callq 0x2380
cmpq $-0x1, %rax
jne 0x5b8b
leaq 0xf3e3(%rip), %rdi      # 0x14f69
callq 0x3ce0
jmp 0x5b8d
movq 0x70(%rsp), %rax
cmpl $0x0, 0x50(%rax)
je 0x5c20
testb $0x1, 0x6f(%rsp)
je 0x5c20
movl $0x0, 0x20(%rsp)
movq 0x70(%rsp), %rax
movslq 0x50(%rax), %rsi
movq 0x70(%rsp), %rax
movq 0x50b0(%rax), %rax
movslq 0x2c(%rsp), %rcx
movq (%rax,%rcx,8), %rcx
leaq 0x20(%rsp), %rdi
movl $0x1, %edx
callq 0x2090
movl %eax, 0x1c(%rsp)
cmpl $0x1, 0x1c(%rsp)
je 0x5bef
leaq 0xf375(%rip), %rdi      # 0x14f5f
callq 0x3ce0
movq 0x70(%rsp), %rax
movslq 0x50(%rax), %rsi
movq 0x48(%rsp), %rcx
leaq 0x20(%rsp), %rdi
movl $0x1, %edx
callq 0x2380
cmpq $-0x1, %rax
jne 0x5c1e
leaq 0xf382(%rip), %rdi      # 0x14f9b
callq 0x3ce0
jmp 0x5c20
movq 0x70(%rsp), %rax
cmpl $0x0, 0x44(%rax)
je 0x5cd5
testb $0x1, 0x6f(%rsp)
je 0x5cd5
movl $0x0, 0x18(%rsp)
movq 0x70(%rsp), %rax
movslq 0x44(%rax), %rsi
movq 0x70(%rsp), %rax
movq 0x50a8(%rax), %rax
movslq 0x2c(%rsp), %rcx
movq (%rax,%rcx,8), %rcx
leaq 0x18(%rsp), %rdi
movl $0x1, %edx
callq 0x2090
movl %eax, 0x14(%rsp)
cmpl $0x1, 0x14(%rsp)
je 0x5c86
leaq 0xf2de(%rip), %rdi      # 0x14f5f
callq 0x3ce0
movq 0x70(%rsp), %rax
movq 0x10(%rax), %rax
movslq 0x2c(%rsp), %rcx
movq (%rax,%rcx,8), %rcx
movslq 0x18(%rsp), %rax
addq %rcx, %rax
movl %eax, 0x18(%rsp)
movq 0x70(%rsp), %rax
movslq 0x44(%rax), %rsi
movq 0x58(%rsp), %rcx
leaq 0x18(%rsp), %rdi
movl $0x1, %edx
callq 0x2380
cmpq $-0x1, %rax
jne 0x5cd3
leaq 0xf09e(%rip), %rdi      # 0x14d6c
callq 0x3ce0
jmp 0x5cd5
movq 0x70(%rsp), %rax
cmpl $0x0, 0x54(%rax)
je 0x5d55
testb $0x1, 0x6f(%rsp)
je 0x5d55
movb $0x0, 0x13(%rsp)
movq 0x70(%rsp), %rax
movq 0x50c0(%rax), %rax
movslq 0x2c(%rsp), %rcx
movq (%rax,%rcx,8), %rcx
leaq 0x13(%rsp), %rdi
movl $0x1, %edx
movq %rdx, %rsi
callq 0x2090
movl %eax, 0xc(%rsp)
cmpl $0x1, 0xc(%rsp)
je 0x5d2a
leaq 0xf23a(%rip), %rdi      # 0x14f5f
callq 0x3ce0
movq 0x40(%rsp), %rcx
leaq 0x13(%rsp), %rdi
movl $0x1, %edx
movq %rdx, %rsi
callq 0x2380
cmpq $-0x1, %rax
jne 0x5d53
leaq 0xf090(%rip), %rdi      # 0x14dde
callq 0x3ce0
jmp 0x5d55
movq 0x70(%rsp), %rax
testb $0x1, 0x69(%rax)
je 0x5da5
movq 0x60(%rsp), %rdi
addq 0x30(%rsp), %rdi
movq 0x70(%rsp), %rax
movq 0x50a0(%rax), %rax
movslq 0x2c(%rsp), %rcx
movq (%rax,%rcx,8), %rcx
movl $0x1, %edx
movq %rdx, %rsi
callq 0x2090
movl %eax, 0x8(%rsp)
cmpl $0x1, 0x8(%rsp)
je 0x5da3
leaq 0xf1c1(%rip), %rdi      # 0x14f5f
callq 0x3ce0
jmp 0x5ddb
movq 0x70(%rsp), %rax
movq (%rax), %rax
movslq 0x2c(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x70(%rsp), %rcx
movq 0x5118(%rcx), %rcx
movslq 0x2c(%rsp), %rdx
movq (%rcx,%rdx,8), %rcx
movb (%rax,%rcx), %dl
movq 0x60(%rsp), %rax
movq 0x30(%rsp), %rcx
movb %dl, (%rax,%rcx)
testb $0x1, 0x6f(%rsp)
je 0x5e04
movq 0x60(%rsp), %rax
movq 0x30(%rsp), %rcx
movzbl (%rax,%rcx), %edi
callq 0x124e0
movb %al, %dl
movq 0x60(%rsp), %rax
movq 0x30(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x70(%rsp), %rax
movq 0x5118(%rax), %rax
movslq 0x2c(%rsp), %rcx
movq (%rax,%rcx,8), %rdx
addq $0x1, %rdx
movq %rdx, (%rax,%rcx,8)
movq 0x30(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x30(%rsp)
jmp 0x5ab6
movl $0x0, 0x4(%rsp)
movl 0x4(%rsp), %eax
movq 0x70(%rsp), %rcx
cmpl 0x20(%rcx), %eax
jge 0x5e59
jmp 0x5e4c
movl 0x4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4(%rsp)
jmp 0x5e3c
movq 0x70(%rsp), %rax
testb $0x1, 0x69(%rax)
je 0x5e6e
movq 0x70(%rsp), %rdi
callq 0x6f10
movq 0x70(%rsp), %rax
cmpl $0x0, 0x4c(%rax)
je 0x5eac
testb $0x1, 0x6f(%rsp)
je 0x5eac
movq 0x50(%rsp), %rdi
callq 0x20d0
cmpl $0x0, %eax
je 0x5e9b
leaq 0xf13c(%rip), %rdi      # 0x14fd2
callq 0x3ce0
movq 0x70(%rsp), %rdi
addq $0x20a0, %rdi           # imm = 0x20A0
callq 0x2060
movq 0x70(%rsp), %rax
cmpl $0x0, 0x50(%rax)
je 0x5eea
testb $0x1, 0x6f(%rsp)
je 0x5eea
movq 0x48(%rsp), %rdi
callq 0x20d0
cmpl $0x0, %eax
je 0x5ed9
leaq 0xf129(%rip), %rdi      # 0x14ffd
callq 0x3ce0
movq 0x70(%rsp), %rdi
addq $0x30a0, %rdi           # imm = 0x30A0
callq 0x2060
movq 0x70(%rsp), %rax
cmpl $0x0, 0x44(%rax)
je 0x5f28
testb $0x1, 0x6f(%rsp)
je 0x5f28
movq 0x58(%rsp), %rdi
callq 0x20d0
cmpl $0x0, %eax
je 0x5f17
leaq 0xf11b(%rip), %rdi      # 0x1502d
callq 0x3ce0
movq 0x70(%rsp), %rdi
addq $0x10a0, %rdi           # imm = 0x10A0
callq 0x2060
movq 0x70(%rsp), %rax
cmpl $0x0, 0x54(%rax)
je 0x5f66
testb $0x1, 0x6f(%rsp)
je 0x5f66
movq 0x40(%rsp), %rdi
callq 0x20d0
cmpl $0x0, %eax
je 0x5f55
leaq 0xf10a(%rip), %rdi      # 0x1505a
callq 0x3ce0
movq 0x70(%rsp), %rdi
addq $0x40a0, %rdi           # imm = 0x40A0
callq 0x2060
movq 0x70(%rsp), %rax
testb $0x1, 0x69(%rax)
je 0x6012
movq 0x70(%rsp), %rax
cmpl $0x1, 0x94(%rax)
jle 0x5fa3
movq 0x70(%rsp), %rax
movq 0x28(%rax), %rsi
movq 0x70(%rsp), %rax
movq 0x30(%rax), %rdx
leaq 0xf0df(%rip), %rdi      # 0x1507b
movb $0x0, %al
callq 0x20f0
movq 0x70(%rsp), %rdi
addq $0xa0, %rdi
movl $0x1, %esi
movb $0x0, %al
callq 0x22e0
movl %eax, (%rsp)
cmpl $-0x1, (%rsp)
jne 0x5fd0
leaq 0xef94(%rip), %rdi      # 0x14f5f
callq 0x3ce0
movl (%rsp), %edi
movq 0x60(%rsp), %rsi
movq 0x70(%rsp), %rax
movq 0x28(%rax), %rdx
shlq $0x0, %rdx
movq 0x70(%rsp), %rax
movq 0x30(%rax), %rcx
shlq $0x0, %rcx
callq 0x7820
movl (%rsp), %edi
callq 0x2150
cmpl $0x0, %eax
je 0x6010
leaq 0xef54(%rip), %rdi      # 0x14f5f
callq 0x3ce0
jmp 0x6034
movq 0x70(%rsp), %rax
movq (%rax), %rax
movq (%rax), %rdi
movq 0x60(%rsp), %rsi
movq 0x70(%rsp), %rax
movq 0x28(%rax), %rdx
shlq $0x0, %rdx
callq 0x21e0
addq $0x78, %rsp
retq
nopl (%rax)