// File: /workspace/github_cpp_makefile_star2_O3/ke6jjj[P]r-dat/./ReedSolomon_EUA.h
// Function: bool RS_Solve<3ul>(unsigned char const*, unsigned char const*, unsigned long, unsigned char (&) [2 * 3ul + 1], unsigned char (&) [2 * 3ul])
bool
RS_Solve(const uint8_t syndrome[2*kT], const uint8_t erasures[2*kT],
  size_t erasure_count, uint8_t (&r_sigma)[2*kT+1], uint8_t (&r_omega)[2*kT])
{
  const size_t kTwoT = kT * 2;
  uint8_t U[kTwoT+1];
  uint8_t V[kTwoT+1];
  uint8_t W[kTwoT+1];
  uint8_t X[kTwoT+1];
  
  for (size_t i = 0; i < kTwoT; i++) {
    //
    // Clear out the parts of the big polynomials that will not
    // be otherwise initialized.
    //
    X[i+1] = 0;    
    W[i+1] = 0;
    U[i] = 0;

    //
    // Copy in the syndrome value.
    //
    V[i] = syndrome[i];
  }
  
  U[kTwoT] = 1;
  V[kTwoT] = 0;
  X[0] = 1;
  W[0] = 0;
  int D = -1;
  size_t p = 0;
  
  for (size_t i = 0; i < kTwoT; i++) {
    //
    // During the first phase of this algorithm, we incorporate erasures.
    // Determine if we're still in erasure-processing phase.
    //
    bool first = (p < erasure_count);
    
    //
    // Next we determine if the Euclidean algorithm requires us to swap
    // the parameters being processed.
    //
    bool swap = !first && (V[kTwoT - 1] != 0) && (D < 0);
    
    //
    // Examine the next element to be processed. In the erasures
    // phase we pull in the next erasure locator. In the error locator
    // phase we pull in the next thingamjig.
    //
    uint8_t G, Z;
    if (first) {
      //
      // Erasures processing. Get next erasure symbol and convert it
      // into a power of alpha.
      //
      G = ECC_GF28_pow_alpha(erasures[p++]);
      Z = 1;
    } else {
      //
      // Done with erasures. Get a thingamjig.
      //
      G = U[kTwoT];
      Z = V[kTwoT-1];
    }
    
    if (swap) {
      D = -D - 1;
    } else if (!first) {
      D = D - 1;
    }
    
    uint8_t v_adjust[kTwoT+1];
    uint8_t x_adjust[kTwoT+1];
    if (first) {
      poly_multiply_scalar<kTwoT+1>(V, Z, v_adjust);
      poly_multiply_scalar<kTwoT+1>(X, Z, x_adjust);
    } else {
      poly_multiply_scalar<kTwoT+1>(U, Z, v_adjust);
      poly_multiply_scalar<kTwoT+1>(W, Z, x_adjust);
    }
    
    //
    // Compute z V(z) and
    //         z X(z)
    //
    uint8_t new_V[kTwoT+1];
    uint8_t new_X[kTwoT+1];

    poly_multiply_by_x<kTwoT+1>(V, new_V);
    poly_multiply_by_x<kTwoT+1>(X, new_X);

    //
    // Compute G z V(z) and
    //         G z X(z)
    //
    poly_multiply_scalar<kTwoT+1>(new_V, G, new_V);
    poly_multiply_scalar<kTwoT+1>(new_X, G, new_X);
    
    poly_add<kTwoT+1>(new_V, v_adjust, new_V);
    poly_add<kTwoT+1>(new_X, x_adjust, new_X);
    
    if (swap) {
      poly_multiply_by_x<kTwoT+1>(V, U);
      poly_multiply_by_x<kTwoT+1>(X, W);
    }
    
    poly_copy<kTwoT+1>(new_V, V);
    poly_copy<kTwoT+1>(new_X, X);
  }

  if (D < 0 && (p == erasure_count)) {
    //
    // Everything should be correctable.
    // Return the location polynomial and the magnitude polynomial.
    //
    poly_copy<kTwoT+1>(X, r_sigma);
    for (size_t i = 0; i < kTwoT; i++)
      r_omega[i] = V[i];
    
    return true;
  }
  
  return false;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %r8, 0x50(%rsp)
movq %rcx, 0x48(%rsp)
movq %rdx, %r8
movq %rsi, 0x58(%rsp)
xorl %ecx, %ecx
movw %cx, 0x19(%rsp)
movl %ecx, 0x15(%rsp)
leaq 0x34(%rsp), %rdx
movl %ecx, (%rdx)
movw %cx, 0x4(%rdx)
leaq 0x2d(%rsp), %rsi
movl %ecx, -0x1(%rsi)
movw %cx, 0x3(%rsi)
movl (%rdi), %eax
movl %eax, 0xc(%rsp)
movzwl 0x4(%rdi), %eax
movw %ax, 0x10(%rsp)
movb $0x1, %al
movb %al, 0x5(%rsi)
movb %cl, 0x12(%rsp)
movb %al, 0x14(%rsp)
movb %cl, -0x1(%rdx)
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
xorl %esi, %esi
xorl %ebx, %ebx
movq %r8, 0x68(%rsp)
movq %rsi, 0x70(%rsp)
cmpq %r8, %rbx
setae %cl
movb 0x11(%rsp), %al
testb %al, %al
setne %dl
testl %r12d, %r12d
sets %r15b
andb %cl, %r15b
andb %dl, %r15b
cmpq %r8, %rbx
jb 0x60b0
movq %rbx, 0x60(%rsp)
movb 0x32(%rsp), %bpl
movq %r12, %rbx
leal -0x1(%r12), %r14d
movzbl %al, %r13d
xorl %r12d, %r12d
movzbl 0x2c(%rsp,%r12), %edi
movl %r13d, %esi
callq 0x5b5c
movb %al, 0x41(%rsp,%r12)
incq %r12
cmpq $0x7, %r12
jne 0x6062
notl %ebx
xorl %r12d, %r12d
movzbl 0x33(%rsp,%r12), %edi
movl %r13d, %esi
callq 0x5b5c
movb %al, 0x3a(%rsp,%r12)
incq %r12
cmpq $0x7, %r12
jne 0x6083
testb %r15b, %r15b
cmovnel %ebx, %r14d
movl %r14d, %r12d
movq 0x60(%rsp), %rbx
jmp 0x6105
movq 0x58(%rsp), %rax
movzbl (%rax,%rbx), %edi
callq 0x5cbd
movl %eax, %ebp
xorl %r14d, %r14d
movzbl 0xc(%rsp,%r14), %edi
movl $0x1, %esi
callq 0x5b5c
movb %al, 0x41(%rsp,%r14)
incq %r14
cmpq $0x7, %r14
jne 0x60c3
xorl %r14d, %r14d
movzbl 0x14(%rsp,%r14), %edi
movl $0x1, %esi
callq 0x5b5c
movb %al, 0x3a(%rsp,%r14)
incq %r14
cmpq $0x7, %r14
jne 0x60e4
incq %rbx
movzwl 0x10(%rsp), %eax
leaq 0x26(%rsp), %rcx
movw %ax, 0x4(%rcx)
movl 0xc(%rsp), %eax
movl %eax, (%rcx)
xorl %ecx, %ecx
movb %cl, 0x25(%rsp)
movzwl 0x18(%rsp), %eax
leaq 0x1f(%rsp), %rdx
movw %ax, 0x4(%rdx)
movl 0x14(%rsp), %eax
movl %eax, (%rdx)
movb %cl, 0x1e(%rsp)
xorl %r14d, %r14d
movzbl 0x25(%rsp,%r14), %edi
movzbl %bpl, %r13d
movl %r13d, %esi
callq 0x5b5c
movb %al, 0x25(%rsp,%r14)
incq %r14
cmpq $0x7, %r14
jne 0x613a
xorl %r14d, %r14d
movzbl 0x1e(%rsp,%r14), %edi
movl %r13d, %esi
callq 0x5b5c
movb %al, 0x1e(%rsp,%r14)
incq %r14
cmpq $0x7, %r14
jne 0x615d
xorl %eax, %eax
movb 0x41(%rsp,%rax), %cl
xorb %cl, 0x25(%rsp,%rax)
incq %rax
cmpq $0x7, %rax
jne 0x617b
xorl %eax, %eax
movq 0x68(%rsp), %r8
movb 0x3a(%rsp,%rax), %cl
xorb %cl, 0x1e(%rsp,%rax)
incq %rax
cmpq $0x7, %rax
jne 0x6193
testb %r15b, %r15b
movq 0x70(%rsp), %rsi
je 0x61e0
movzwl 0x10(%rsp), %eax
leaq 0x2d(%rsp), %rcx
movw %ax, 0x4(%rcx)
movl 0xc(%rsp), %eax
movl %eax, (%rcx)
xorl %ecx, %ecx
movb %cl, 0x2c(%rsp)
movzwl 0x18(%rsp), %eax
leaq 0x34(%rsp), %rdx
movw %ax, 0x4(%rdx)
movl 0x14(%rsp), %eax
movl %eax, (%rdx)
movb %cl, 0x33(%rsp)
movl 0x25(%rsp), %eax
movl 0x28(%rsp), %ecx
movl %ecx, 0xf(%rsp)
movl %eax, 0xc(%rsp)
movl 0x1e(%rsp), %eax
movl 0x21(%rsp), %ecx
movl %eax, 0x14(%rsp)
movl %ecx, 0x17(%rsp)
incq %rsi
cmpq $0x6, %rsi
jne 0x6023
testl %r12d, %r12d
sets %cl
cmpq %r8, %rbx
sete %al
andb %cl, %al
cmpb $0x1, %al
jne 0x6245
movl 0x14(%rsp), %ecx
movl 0x17(%rsp), %edx
movq 0x48(%rsp), %rsi
movl %edx, 0x3(%rsi)
movl %ecx, (%rsi)
movzwl 0x10(%rsp), %ecx
movq 0x50(%rsp), %rdx
movw %cx, 0x4(%rdx)
movl 0xc(%rsp), %ecx
movl %ecx, (%rdx)
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq