// File: /workspace/github_cpp_makefile_star2_O2/ke6jjj[P]r-dat/./ReedSolomon_EUA.h
// Function: bool RS_Solve<2ul>(unsigned char const*, unsigned char const*, unsigned long, unsigned char (&) [2 * 2ul + 1], unsigned char (&) [2 * 2ul])
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 $0x68, %rsp
movq %rcx, 0x48(%rsp)
movq %rdx, 0x18(%rsp)
movq %rsi, 0x58(%rsp)
pushq $0x1
popq %rax
xorl %ecx, %ecx
cmpq $0x5, %rax
je 0x5442
movb %cl, 0x13(%rsp,%rax)
movb %cl, 0xe(%rsp,%rax)
movb %cl, 0x8(%rsp,%rax)
movb -0x1(%rdi,%rax), %dl
movb %dl, 0x3(%rsp,%rax)
incq %rax
jmp 0x5423
movq %r8, 0x50(%rsp)
movb $0x1, %al
leaq 0x9(%rsp), %rcx
movb %al, 0x4(%rcx)
xorl %ebp, %ebp
leaq 0x4(%rsp), %r14
movb %bpl, 0x4(%r14)
leaq 0x13(%rsp), %r12
movb %al, (%r12)
leaq 0xe(%rsp), %rax
movb %bpl, (%rax)
pushq $-0x1
popq %r15
pushq $0x4
popq %rax
subq $0x1, %rax
jb 0x55de
movq %rax, 0x60(%rsp)
movq %r12, %r13
movq 0x18(%rsp), %rcx
cmpq %rcx, %rbp
setae %bl
movb 0x7(%rsp), %al
testb %al, %al
setne %dl
movl %r15d, 0x28(%rsp)
testl %r15d, %r15d
sets %r15b
cmpq %rcx, %rbp
jb 0x54ca
movb 0xd(%rsp), %cl
movb %cl, 0x3(%rsp)
leaq 0xe(%rsp), %rcx
leaq 0x9(%rsp), %rdi
movq %rbp, 0x40(%rsp)
movq %r13, %r12
movq %rcx, %r13
jmp 0x54f3
leaq 0x1(%rbp), %rax
movq %rax, 0x40(%rsp)
movq 0x58(%rsp), %rax
movzbl (%rax,%rbp), %edi
movl %edx, %r12d
callq 0x5a67
movl %r12d, %edx
movb %al, 0x3(%rsp)
movb $0x1, %al
movq %r13, %r12
movq %r14, %rdi
andb %r15b, %bl
andb %dl, %bl
cmpq 0x18(%rsp), %rbp
movl 0x28(%rsp), %r15d
movl %r15d, %ecx
notl %ecx
movl %ecx, 0x24(%rsp)
adcl $-0x1, %r15d
movzbl %al, %ebp
movl %ebp, %esi
leaq 0x3b(%rsp), %rdx
callq 0x56ae
movq %r13, %rdi
movl %ebp, %esi
leaq 0x36(%rsp), %rdx
callq 0x56ae
movq %r14, %rdi
leaq 0x31(%rsp), %r13
movq %r13, %rsi
callq 0x56e8
movq %r12, %rdi
leaq 0x2c(%rsp), %r14
movq %r14, %rsi
callq 0x56e8
movzbl 0x3(%rsp), %ebp
movq %r13, %rdi
movl %ebp, %esi
movq %r13, %rdx
callq 0x56ae
movq %r14, %rdi
movl %ebp, %esi
movq %r14, %rdx
callq 0x56ae
movq %r13, %rdi
leaq 0x3b(%rsp), %rsi
movq %r13, %rdx
callq 0x5704
movq %r14, %rdi
leaq 0x36(%rsp), %rsi
movq %r14, %rdx
callq 0x5704
testb %bl, %bl
cmovnel 0x24(%rsp), %r15d
leaq 0x4(%rsp), %r14
je 0x55b5
movq %r14, %rdi
leaq 0x9(%rsp), %rsi
callq 0x56e8
movq %r12, %rdi
leaq 0xe(%rsp), %rsi
callq 0x56e8
leaq 0x31(%rsp), %rdi
movq %r14, %rsi
callq 0x571b
leaq 0x2c(%rsp), %rdi
movq %r12, %rsi
callq 0x571b
movq 0x40(%rsp), %rbp
movq 0x60(%rsp), %rax
jmp 0x5474
testl %r15d, %r15d
sets %al
cmpq 0x18(%rsp), %rbp
sete %bl
andb %al, %bl
movq 0x50(%rsp), %r14
je 0x5619
leaq 0x13(%rsp), %rdi
movq 0x48(%rsp), %rsi
callq 0x571b
xorl %eax, %eax
cmpq $0x4, %rax
je 0x5619
movb 0x4(%rsp,%rax), %cl
movb %cl, (%r14,%rax)
incq %rax
jmp 0x5606
movl %ebx, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq