// File: /workspace/github_c_makefile_star2_O0/oreparaz[P]dudect/examples/donna/curve25519-donna.c
// Function: fcontract
static void
fcontract(u8 *output, limb *input_limbs) {
  int i;
  int j;
  s32 input[10];
  s32 mask;

  /* |input_limbs[i]| < 2^26, so it's valid to convert to an s32. */
  for (i = 0; i < 10; i++) {
    input[i] = input_limbs[i];
  }

  for (j = 0; j < 2; ++j) {
    for (i = 0; i < 9; ++i) {
      if ((i & 1) == 1) {
        /* This calculation is a time-invariant way to make input[i]
         * non-negative by borrowing from the next-larger limb. */
        const s32 mask = input[i] >> 31;
        const s32 carry = -((input[i] & mask) >> 25);
        input[i] = input[i] + (carry << 25);
        input[i+1] = input[i+1] - carry;
      } else {
        const s32 mask = input[i] >> 31;
        const s32 carry = -((input[i] & mask) >> 26);
        input[i] = input[i] + (carry << 26);
        input[i+1] = input[i+1] - carry;
      }
    }

    /* There's no greater limb for input[9] to borrow from, but we can multiply
     * by 19 and borrow from input[0], which is valid mod 2^255-19. */
    {
      const s32 mask = input[9] >> 31;
      const s32 carry = -((input[9] & mask) >> 25);
      input[9] = input[9] + (carry << 25);
      input[0] = input[0] - (carry * 19);
    }

    /* After the first iteration, input[1..9] are non-negative and fit within
     * 25 or 26 bits, depending on position. However, input[0] may be
     * negative. */
  }

  /* The first borrow-propagation pass above ended with every limb
     except (possibly) input[0] non-negative.

     If input[0] was negative after the first pass, then it was because of a
     carry from input[9]. On entry, input[9] < 2^26 so the carry was, at most,
     one, since (2**26-1) >> 25 = 1. Thus input[0] >= -19.

     In the second pass, each limb is decreased by at most one. Thus the second
     borrow-propagation pass could only have wrapped around to decrease
     input[0] again if the first pass left input[0] negative *and* input[1]
     through input[9] were all zero.  In that case, input[1] is now 2^25 - 1,
     and this last borrow-propagation step will leave input[1] non-negative. */
  {
    const s32 mask = input[0] >> 31;
    const s32 carry = -((input[0] & mask) >> 26);
    input[0] = input[0] + (carry << 26);
    input[1] = input[1] - carry;
  }

  /* All input[i] are now non-negative. However, there might be values between
   * 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */
  for (j = 0; j < 2; j++) {
    for (i = 0; i < 9; i++) {
      if ((i & 1) == 1) {
        const s32 carry = input[i] >> 25;
        input[i] &= 0x1ffffff;
        input[i+1] += carry;
      } else {
        const s32 carry = input[i] >> 26;
        input[i] &= 0x3ffffff;
        input[i+1] += carry;
      }
    }

    {
      const s32 carry = input[9] >> 25;
      input[9] &= 0x1ffffff;
      input[0] += 19*carry;
    }
  }

  /* If the first carry-chain pass, just above, ended up with a carry from
   * input[9], and that caused input[0] to be out-of-bounds, then input[0] was
   * < 2^26 + 2*19, because the carry was, at most, two.
   *
   * If the second pass carried from input[9] again then input[0] is < 2*19 and
   * the input[9] -> input[0] carry didn't push input[0] out of bounds. */

  /* It still remains the case that input might be between 2^255-19 and 2^255.
   * In this case, input[1..9] must take their maximum value and input[0] must
   * be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */
  mask = s32_gte(input[0], 0x3ffffed);
  for (i = 1; i < 10; i++) {
    if ((i & 1) == 1) {
      mask &= s32_eq(input[i], 0x1ffffff);
    } else {
      mask &= s32_eq(input[i], 0x3ffffff);
    }
  }

  /* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus
   * this conditionally subtracts 2^255-19. */
  input[0] -= mask & 0x3ffffed;

  for (i = 1; i < 10; i++) {
    if ((i & 1) == 1) {
      input[i] -= mask & 0x1ffffff;
    } else {
      input[i] -= mask & 0x3ffffff;
    }
  }

  input[1] <<= 2;
  input[2] <<= 3;
  input[3] <<= 5;
  input[4] <<= 6;
  input[6] <<= 1;
  input[7] <<= 3;
  input[8] <<= 4;
  input[9] <<= 6;
#define F(i, s) \
  output[s+0] |=  input[i] & 0xff; \
  output[s+1]  = (input[i] >> 8) & 0xff; \
  output[s+2]  = (input[i] >> 16) & 0xff; \
  output[s+3]  = (input[i] >> 24) & 0xff;
  output[0] = 0;
  output[16] = 0;
  F(0,0);
  F(1,3);
  F(2,6);
  F(3,9);
  F(4,12);
  F(5,16);
  F(6,19);
  F(7,22);
  F(8,25);
  F(9,28);
#undef F
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x70(%rsp)
movq %rsi, 0x68(%rsp)
movl $0x0, 0x64(%rsp)
cmpl $0xa, 0x64(%rsp)
jge 0x2e83
movq 0x68(%rsp), %rax
movslq 0x64(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %ecx
movslq 0x64(%rsp), %rax
movl %ecx, 0x30(%rsp,%rax,4)
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x2e56
movl $0x0, 0x60(%rsp)
cmpl $0x2, 0x60(%rsp)
jge 0x2fd9
movl $0x0, 0x64(%rsp)
cmpl $0x9, 0x64(%rsp)
jge 0x2f8b
movl 0x64(%rsp), %eax
andl $0x1, %eax
cmpl $0x1, %eax
jne 0x2f18
movslq 0x64(%rsp), %rax
movl 0x30(%rsp,%rax,4), %eax
sarl $0x1f, %eax
movl %eax, 0x28(%rsp)
movslq 0x64(%rsp), %rax
movl 0x30(%rsp,%rax,4), %ecx
andl 0x28(%rsp), %ecx
sarl $0x19, %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, 0x24(%rsp)
movslq 0x64(%rsp), %rax
movl 0x30(%rsp,%rax,4), %ecx
movl 0x24(%rsp), %eax
shll $0x19, %eax
addl %eax, %ecx
movslq 0x64(%rsp), %rax
movl %ecx, 0x30(%rsp,%rax,4)
movl 0x64(%rsp), %eax
addl $0x1, %eax
cltq
movl 0x30(%rsp,%rax,4), %ecx
subl 0x24(%rsp), %ecx
movl 0x64(%rsp), %eax
addl $0x1, %eax
cltq
movl %ecx, 0x30(%rsp,%rax,4)
jmp 0x2f79
movslq 0x64(%rsp), %rax
movl 0x30(%rsp,%rax,4), %eax
sarl $0x1f, %eax
movl %eax, 0x20(%rsp)
movslq 0x64(%rsp), %rax
movl 0x30(%rsp,%rax,4), %ecx
andl 0x20(%rsp), %ecx
sarl $0x1a, %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, 0x1c(%rsp)
movslq 0x64(%rsp), %rax
movl 0x30(%rsp,%rax,4), %ecx
movl 0x1c(%rsp), %eax
shll $0x1a, %eax
addl %eax, %ecx
movslq 0x64(%rsp), %rax
movl %ecx, 0x30(%rsp,%rax,4)
movl 0x64(%rsp), %eax
addl $0x1, %eax
cltq
movl 0x30(%rsp,%rax,4), %ecx
subl 0x1c(%rsp), %ecx
movl 0x64(%rsp), %eax
addl $0x1, %eax
cltq
movl %ecx, 0x30(%rsp,%rax,4)
jmp 0x2f7b
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x2e9e
movl 0x54(%rsp), %eax
sarl $0x1f, %eax
movl %eax, 0x18(%rsp)
movl 0x54(%rsp), %ecx
andl 0x18(%rsp), %ecx
sarl $0x19, %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, 0x14(%rsp)
movl 0x54(%rsp), %eax
movl 0x14(%rsp), %ecx
shll $0x19, %ecx
addl %ecx, %eax
movl %eax, 0x54(%rsp)
movl 0x30(%rsp), %eax
imull $0x13, 0x14(%rsp), %ecx
subl %ecx, %eax
movl %eax, 0x30(%rsp)
movl 0x60(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x60(%rsp)
jmp 0x2e8b
movl 0x30(%rsp), %eax
sarl $0x1f, %eax
movl %eax, 0x10(%rsp)
movl 0x30(%rsp), %ecx
andl 0x10(%rsp), %ecx
sarl $0x1a, %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, 0xc(%rsp)
movl 0x30(%rsp), %eax
movl 0xc(%rsp), %ecx
shll $0x1a, %ecx
addl %ecx, %eax
movl %eax, 0x30(%rsp)
movl 0x34(%rsp), %eax
subl 0xc(%rsp), %eax
movl %eax, 0x34(%rsp)
movl $0x0, 0x60(%rsp)
cmpl $0x2, 0x60(%rsp)
jge 0x30fd
movl $0x0, 0x64(%rsp)
cmpl $0x9, 0x64(%rsp)
jge 0x30ca
movl 0x64(%rsp), %eax
andl $0x1, %eax
cmpl $0x1, %eax
jne 0x3080
movslq 0x64(%rsp), %rax
movl 0x30(%rsp,%rax,4), %eax
sarl $0x19, %eax
movl %eax, 0x8(%rsp)
movslq 0x64(%rsp), %rax
movl 0x30(%rsp,%rax,4), %ecx
andl $0x1ffffff, %ecx        # imm = 0x1FFFFFF
movl %ecx, 0x30(%rsp,%rax,4)
movl 0x8(%rsp), %ecx
movl 0x64(%rsp), %eax
addl $0x1, %eax
cltq
addl 0x30(%rsp,%rax,4), %ecx
movl %ecx, 0x30(%rsp,%rax,4)
jmp 0x30b8
movslq 0x64(%rsp), %rax
movl 0x30(%rsp,%rax,4), %eax
sarl $0x1a, %eax
movl %eax, 0x4(%rsp)
movslq 0x64(%rsp), %rax
movl 0x30(%rsp,%rax,4), %ecx
andl $0x3ffffff, %ecx        # imm = 0x3FFFFFF
movl %ecx, 0x30(%rsp,%rax,4)
movl 0x4(%rsp), %ecx
movl 0x64(%rsp), %eax
addl $0x1, %eax
cltq
addl 0x30(%rsp,%rax,4), %ecx
movl %ecx, 0x30(%rsp,%rax,4)
jmp 0x30ba
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x302f
movl 0x54(%rsp), %eax
sarl $0x19, %eax
movl %eax, (%rsp)
movl 0x54(%rsp), %eax
andl $0x1ffffff, %eax        # imm = 0x1FFFFFF
movl %eax, 0x54(%rsp)
imull $0x13, (%rsp), %eax
addl 0x30(%rsp), %eax
movl %eax, 0x30(%rsp)
movl 0x60(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x60(%rsp)
jmp 0x301c
movl 0x30(%rsp), %edi
movl $0x3ffffed, %esi        # imm = 0x3FFFFED
callq 0x5390
movl %eax, 0x2c(%rsp)
movl $0x1, 0x64(%rsp)
cmpl $0xa, 0x64(%rsp)
jge 0x3171
movl 0x64(%rsp), %eax
andl $0x1, %eax
cmpl $0x1, %eax
jne 0x3147
movslq 0x64(%rsp), %rax
movl 0x30(%rsp,%rax,4), %edi
movl $0x1ffffff, %esi        # imm = 0x1FFFFFF
callq 0x53c0
andl 0x2c(%rsp), %eax
movl %eax, 0x2c(%rsp)
jmp 0x3162
movslq 0x64(%rsp), %rax
movl 0x30(%rsp,%rax,4), %edi
movl $0x3ffffff, %esi        # imm = 0x3FFFFFF
callq 0x53c0
andl 0x2c(%rsp), %eax
movl %eax, 0x2c(%rsp)
jmp 0x3164
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x3117
movl 0x2c(%rsp), %ecx
andl $0x3ffffed, %ecx        # imm = 0x3FFFFED
movl 0x30(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x30(%rsp)
movl $0x1, 0x64(%rsp)
cmpl $0xa, 0x64(%rsp)
jge 0x31e3
movl 0x64(%rsp), %eax
andl $0x1, %eax
cmpl $0x1, %eax
jne 0x31bb
movl 0x2c(%rsp), %edx
andl $0x1ffffff, %edx        # imm = 0x1FFFFFF
movslq 0x64(%rsp), %rax
movl 0x30(%rsp,%rax,4), %ecx
subl %edx, %ecx
movl %ecx, 0x30(%rsp,%rax,4)
jmp 0x31d4
movl 0x2c(%rsp), %edx
andl $0x3ffffff, %edx        # imm = 0x3FFFFFF
movslq 0x64(%rsp), %rax
movl 0x30(%rsp,%rax,4), %ecx
subl %edx, %ecx
movl %ecx, 0x30(%rsp,%rax,4)
jmp 0x31d6
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x318d
movl 0x34(%rsp), %eax
shll $0x2, %eax
movl %eax, 0x34(%rsp)
movl 0x38(%rsp), %eax
shll $0x3, %eax
movl %eax, 0x38(%rsp)
movl 0x3c(%rsp), %eax
shll $0x5, %eax
movl %eax, 0x3c(%rsp)
movl 0x40(%rsp), %eax
shll $0x6, %eax
movl %eax, 0x40(%rsp)
movl 0x48(%rsp), %eax
shll %eax
movl %eax, 0x48(%rsp)
movl 0x4c(%rsp), %eax
shll $0x3, %eax
movl %eax, 0x4c(%rsp)
movl 0x50(%rsp), %eax
shll $0x4, %eax
movl %eax, 0x50(%rsp)
movl 0x54(%rsp), %eax
shll $0x6, %eax
movl %eax, 0x54(%rsp)
movq 0x70(%rsp), %rax
movb $0x0, (%rax)
movq 0x70(%rsp), %rax
movb $0x0, 0x10(%rax)
movl 0x30(%rsp), %edx
andl $0xff, %edx
movq 0x70(%rsp), %rax
movzbl (%rax), %ecx
orl %edx, %ecx
movb %cl, (%rax)
movl 0x30(%rsp), %eax
sarl $0x8, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x1(%rax)
movl 0x30(%rsp), %eax
sarl $0x10, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x2(%rax)
movl 0x30(%rsp), %eax
sarl $0x18, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x3(%rax)
movl 0x34(%rsp), %edx
andl $0xff, %edx
movq 0x70(%rsp), %rax
movzbl 0x3(%rax), %ecx
orl %edx, %ecx
movb %cl, 0x3(%rax)
movl 0x34(%rsp), %eax
sarl $0x8, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x4(%rax)
movl 0x34(%rsp), %eax
sarl $0x10, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x5(%rax)
movl 0x34(%rsp), %eax
sarl $0x18, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x6(%rax)
movl 0x38(%rsp), %edx
andl $0xff, %edx
movq 0x70(%rsp), %rax
movzbl 0x6(%rax), %ecx
orl %edx, %ecx
movb %cl, 0x6(%rax)
movl 0x38(%rsp), %eax
sarl $0x8, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x7(%rax)
movl 0x38(%rsp), %eax
sarl $0x10, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x8(%rax)
movl 0x38(%rsp), %eax
sarl $0x18, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x9(%rax)
movl 0x3c(%rsp), %edx
andl $0xff, %edx
movq 0x70(%rsp), %rax
movzbl 0x9(%rax), %ecx
orl %edx, %ecx
movb %cl, 0x9(%rax)
movl 0x3c(%rsp), %eax
sarl $0x8, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0xa(%rax)
movl 0x3c(%rsp), %eax
sarl $0x10, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0xb(%rax)
movl 0x3c(%rsp), %eax
sarl $0x18, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0xc(%rax)
movl 0x40(%rsp), %edx
andl $0xff, %edx
movq 0x70(%rsp), %rax
movzbl 0xc(%rax), %ecx
orl %edx, %ecx
movb %cl, 0xc(%rax)
movl 0x40(%rsp), %eax
sarl $0x8, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0xd(%rax)
movl 0x40(%rsp), %eax
sarl $0x10, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0xe(%rax)
movl 0x40(%rsp), %eax
sarl $0x18, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0xf(%rax)
movl 0x44(%rsp), %edx
andl $0xff, %edx
movq 0x70(%rsp), %rax
movzbl 0x10(%rax), %ecx
orl %edx, %ecx
movb %cl, 0x10(%rax)
movl 0x44(%rsp), %eax
sarl $0x8, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x11(%rax)
movl 0x44(%rsp), %eax
sarl $0x10, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x12(%rax)
movl 0x44(%rsp), %eax
sarl $0x18, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x13(%rax)
movl 0x48(%rsp), %edx
andl $0xff, %edx
movq 0x70(%rsp), %rax
movzbl 0x13(%rax), %ecx
orl %edx, %ecx
movb %cl, 0x13(%rax)
movl 0x48(%rsp), %eax
sarl $0x8, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x14(%rax)
movl 0x48(%rsp), %eax
sarl $0x10, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x15(%rax)
movl 0x48(%rsp), %eax
sarl $0x18, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x16(%rax)
movl 0x4c(%rsp), %edx
andl $0xff, %edx
movq 0x70(%rsp), %rax
movzbl 0x16(%rax), %ecx
orl %edx, %ecx
movb %cl, 0x16(%rax)
movl 0x4c(%rsp), %eax
sarl $0x8, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x17(%rax)
movl 0x4c(%rsp), %eax
sarl $0x10, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x18(%rax)
movl 0x4c(%rsp), %eax
sarl $0x18, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x19(%rax)
movl 0x50(%rsp), %edx
andl $0xff, %edx
movq 0x70(%rsp), %rax
movzbl 0x19(%rax), %ecx
orl %edx, %ecx
movb %cl, 0x19(%rax)
movl 0x50(%rsp), %eax
sarl $0x8, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x1a(%rax)
movl 0x50(%rsp), %eax
sarl $0x10, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x1b(%rax)
movl 0x50(%rsp), %eax
sarl $0x18, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x1c(%rax)
movl 0x54(%rsp), %edx
andl $0xff, %edx
movq 0x70(%rsp), %rax
movzbl 0x1c(%rax), %ecx
orl %edx, %ecx
movb %cl, 0x1c(%rax)
movl 0x54(%rsp), %eax
sarl $0x8, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x1d(%rax)
movl 0x54(%rsp), %eax
sarl $0x10, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x1e(%rax)
movl 0x54(%rsp), %eax
sarl $0x18, %eax
andl $0xff, %eax
movb %al, %cl
movq 0x70(%rsp), %rax
movb %cl, 0x1f(%rax)
addq $0x78, %rsp
retq
nopw %cs:(%rax,%rax)