// File: ke6jjj[P]r-dat/ECC_C2.cc
// Function: ECC_C2::Correct()
ECC_C2::Status
ECC_C2::Correct()
{
  uint8_t result_vector[kTwoT];
  uint8_t erasures_vector[kTwoT];
  size_t erasures;
  
  bool ok = true;
  bool corrected = false;
  
  //
  // Scan the input to determine how many erasures there are and where
  // they are located.
  //
  // Since this is the second level of error checking, we will be running
  // in erasures-only mode. It is assumed that all symbols are either
  // completely known or are definitely in error. There is no error-checking
  // capability left in the code in this mode.
  //
  erasures = 0;
  for (size_t i = 0; i < kN; i++) {
    if (!mDataIsValid[i]) {
      if (erasures >= kTwoT) {
        //
        // Too many erasures encountered. This vector will not be
        // correctable.
        //
        ok = false;
        break;
      }
      erasures_vector[erasures++] = kN - 1 - i;
    }
  }
  
  if (ok) {
    //
    // The known erasures (if any) are under control.
    //
    // Multiply the filled in vector by the check matrix to produce a
    // result vector.
    //
    ok = ComputeSyndrome(result_vector);
  
    if (!ok) {
      //
      // There's a non-zero syndrome. Attempt to correct the errors.
      //
      ok = HandleSyndrome(result_vector, erasures_vector, erasures);
      if (ok)
        corrected = true;
    }
  }
  
  if (ok) {
    if (erasures || corrected) {
      //
      // The data entered with some erasures. It has now been fully
      // validated, so mark every byte as good.
      //
      for (size_t j = 0; j < kN; j++)
        mDataIsValid[j] = true;

      return CORRECTED;
    }
    //
    // Everything came in good. No modifications necessary.
    //
    return NO_ERRORS;
  } else {
    //
    // There are uncorrectable errors. Mark the whole vector as
    // invalid.
    //
    for (size_t j = 0; j < kN; j++)
      mDataIsValid[j] = false;

    return UNCORRECTABLE;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
movb $0x1, -0x29(%rbp)
movb $0x0, -0x2a(%rbp)
movq $0x0, -0x28(%rbp)
movq $0x0, -0x38(%rbp)
cmpq $0x20, -0x38(%rbp)
jae 0x95dd
movq -0x50(%rbp), %rax
movq -0x38(%rbp), %rcx
testb $0x1, 0x20(%rax,%rcx)
jne 0x95cd
cmpq $0x6, -0x28(%rbp)
jb 0x95af
movb $0x0, -0x29(%rbp)
jmp 0x95dd
movl $0x1f, %eax
subq -0x38(%rbp), %rax
movb %al, %cl
movq -0x28(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x28(%rbp)
movb %cl, -0x1c(%rbp,%rax)
jmp 0x95cf
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x958c
testb $0x1, -0x29(%rbp)
je 0x9623
movq -0x50(%rbp), %rdi
leaq -0x16(%rbp), %rsi
callq 0x9480
andb $0x1, %al
movb %al, -0x29(%rbp)
testb $0x1, -0x29(%rbp)
jne 0x9621
movq -0x50(%rbp), %rdi
leaq -0x16(%rbp), %rsi
leaq -0x1c(%rbp), %rdx
movq -0x28(%rbp), %rcx
callq 0x96b0
andb $0x1, %al
movb %al, -0x29(%rbp)
testb $0x1, -0x29(%rbp)
je 0x961f
movb $0x1, -0x2a(%rbp)
jmp 0x9621
jmp 0x9623
testb $0x1, -0x29(%rbp)
je 0x9672
cmpq $0x0, -0x28(%rbp)
jne 0x9636
testb $0x1, -0x2a(%rbp)
je 0x9669
movq $0x0, -0x40(%rbp)
cmpq $0x20, -0x40(%rbp)
jae 0x9660
movq -0x50(%rbp), %rax
movq -0x40(%rbp), %rcx
movb $0x1, 0x20(%rax,%rcx)
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0x963e
movl $0x1, -0x4(%rbp)
jmp 0x96a3
movl $0x0, -0x4(%rbp)
jmp 0x96a3
movq $0x0, -0x48(%rbp)
cmpq $0x20, -0x48(%rbp)
jae 0x969c
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
movb $0x0, 0x20(%rax,%rcx)
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x967a
movl $0x2, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax)