// File: /workspace/github_cpp_makefile_star2_O1/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, 0x60(%rsp)
movq %rcx, 0x58(%rsp)
movq %rdx, 0x38(%rsp)
movq %rsi, 0x68(%rsp)
xorl %ecx, %ecx
movw %cx, 0x15(%rsp)
movl %ecx, 0x11(%rsp)
leaq 0x32(%rsp), %rdx
movl %ecx, (%rdx)
movw %cx, 0x4(%rdx)
leaq 0x29(%rsp), %rsi
movl %ecx, -0x1(%rsi)
movw %cx, 0x3(%rsi)
movl (%rdi), %eax
movl %eax, 0x8(%rsp)
movzwl 0x4(%rdi), %eax
movw %ax, 0xc(%rsp)
movb $0x1, %al
movb %al, 0x5(%rsi)
movb %cl, 0xe(%rsp)
movb %al, 0x10(%rsp)
movb %cl, -0x1(%rdx)
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
xorl %esi, %esi
xorl %r15d, %r15d
movq %rsi, 0x70(%rsp)
movq 0x38(%rsp), %rcx
cmpq %rcx, %r15
setae %bl
movb 0xd(%rsp), %al
testb %al, %al
setne %r13b
movl %r12d, %r14d
testl %r12d, %r12d
sets %r12b
cmpq %rcx, %r15
jb 0x6024
movb 0x2e(%rsp), %bpl
movq %r15, 0x50(%rsp)
jmp 0x6040
leaq 0x1(%r15), %rax
movq %rax, 0x50(%rsp)
movq 0x68(%rsp), %rax
movzbl (%rax,%r15), %edi
callq 0x5c76
movl %eax, %ebp
movb $0x1, %al
andb %r12b, %bl
andb %r13b, %bl
movq 0x38(%rsp), %rdx
cmpq %rdx, %r15
movl %r14d, %r12d
movl %r14d, %ecx
notl %ecx
adcl $-0x1, %r12d
testb %bl, %bl
cmovnel %ecx, %r12d
movzbl %al, %r13d
cmpq %rdx, %r15
jb 0x60a9
xorl %r15d, %r15d
movzbl 0x28(%rsp,%r15), %edi
movl %r13d, %esi
callq 0x5b24
movb %al, 0x49(%rsp,%r15)
incq %r15
cmpq $0x7, %r15
jne 0x606c
xorl %r15d, %r15d
movzbl 0x31(%rsp,%r15), %edi
movl %r13d, %esi
callq 0x5b24
movb %al, 0x42(%rsp,%r15)
incq %r15
cmpq $0x7, %r15
jne 0x608b
jmp 0x60e7
xorl %r15d, %r15d
movzbl 0x8(%rsp,%r15), %edi
movl %r13d, %esi
callq 0x5b24
movb %al, 0x49(%rsp,%r15)
incq %r15
cmpq $0x7, %r15
jne 0x60ac
xorl %r15d, %r15d
movzbl 0x10(%rsp,%r15), %edi
movl %r13d, %esi
callq 0x5b24
movb %al, 0x42(%rsp,%r15)
incq %r15
cmpq $0x7, %r15
jne 0x60cb
movzwl 0xc(%rsp), %eax
leaq 0x22(%rsp), %rcx
movw %ax, 0x4(%rcx)
movl 0x8(%rsp), %eax
movl %eax, (%rcx)
xorl %ecx, %ecx
movb %cl, 0x21(%rsp)
movzwl 0x14(%rsp), %eax
leaq 0x1b(%rsp), %rdx
movw %ax, 0x4(%rdx)
movl 0x10(%rsp), %eax
movl %eax, (%rdx)
movb %cl, 0x1a(%rsp)
xorl %r15d, %r15d
movzbl 0x21(%rsp,%r15), %edi
movzbl %bpl, %r13d
movl %r13d, %esi
callq 0x5b24
movb %al, 0x21(%rsp,%r15)
incq %r15
cmpq $0x7, %r15
jne 0x611c
xorl %r15d, %r15d
movzbl 0x1a(%rsp,%r15), %edi
movl %r13d, %esi
callq 0x5b24
movb %al, 0x1a(%rsp,%r15)
incq %r15
cmpq $0x7, %r15
jne 0x613f
xorl %eax, %eax
movb 0x49(%rsp,%rax), %cl
xorb %cl, 0x21(%rsp,%rax)
incq %rax
cmpq $0x7, %rax
jne 0x615d
xorl %eax, %eax
movb 0x42(%rsp,%rax), %cl
xorb %cl, 0x1a(%rsp,%rax)
incq %rax
cmpq $0x7, %rax
jne 0x6170
testb %bl, %bl
movq 0x70(%rsp), %rsi
je 0x61bc
movzwl 0xc(%rsp), %eax
leaq 0x29(%rsp), %rcx
movw %ax, 0x4(%rcx)
movl 0x8(%rsp), %eax
movl %eax, (%rcx)
xorl %ecx, %ecx
movb %cl, 0x28(%rsp)
movzwl 0x14(%rsp), %eax
leaq 0x32(%rsp), %rdx
movw %ax, 0x4(%rdx)
movl 0x10(%rsp), %eax
movl %eax, (%rdx)
movb %cl, 0x31(%rsp)
movl 0x21(%rsp), %eax
movl 0x24(%rsp), %ecx
movl %ecx, 0xb(%rsp)
movl %eax, 0x8(%rsp)
movl 0x1a(%rsp), %eax
movl 0x1d(%rsp), %ecx
movl %eax, 0x10(%rsp)
movl %ecx, 0x13(%rsp)
incq %rsi
movq 0x50(%rsp), %rax
movq %rax, %r15
cmpq $0x6, %rsi
jne 0x5fef
testl %r12d, %r12d
sets %cl
cmpq 0x38(%rsp), %rax
sete %al
andb %cl, %al
cmpb $0x1, %al
jne 0x622b
movl 0x10(%rsp), %ecx
movl 0x13(%rsp), %edx
movq 0x58(%rsp), %rsi
movl %edx, 0x3(%rsi)
movl %ecx, (%rsi)
movzwl 0xc(%rsp), %ecx
movq 0x60(%rsp), %rdx
movw %cx, 0x4(%rdx)
movl 0x8(%rsp), %ecx
movl %ecx, (%rdx)
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq