// File: /workspace/github_cpp_makefile_star2_O2/bitwiseshiftleft[P]crandom/chacha.c
// Function: crandom_chacha_expand
extern_c void
crandom_chacha_expand(u_int64_t iv,
                      u_int64_t ctr,
                      int nr,
                      int output_size,
                      const unsigned char *key_,
                      unsigned char *output_) {
# if MIGHT_HAVE_SSE2
  if (HAVE(SSE2)) {
    ssereg *key = (ssereg *)key_;
    ssereg *output = (ssereg *)output_;
                     
    ssereg a1 = key[0], a2 = a1, aa = a1,
           b1 = key[1], b2 = b1, bb = b1,
           c1 = {iv, ctr}, c2 = {iv, ctr+1}, cc = c1,
           d1 = {0x3320646e61707865ull, 0x6b20657479622d32ull}, d2 = d1, dd = d1,
           p = {0, 1};
     
    int i,r;
#   if (NEED_XOP)
      if (HAVE(XOP)) {
        for (i=0; i<output_size; i+=128) {
          for (r=nr; r>0; r-=2)
            DOUBLE_ROUND(quarter_round_xop);
          OUTPUT_FUNCTION;
        }
        return;
      }
#   endif
#   if (NEED_SSSE3)
      if (HAVE(SSSE3)) {
        for (i=0; i<output_size; i+=128) {
          for (r=nr; r>0; r-=2)
            DOUBLE_ROUND(quarter_round_ssse3);
          OUTPUT_FUNCTION;
        }
        return;
      }
#   endif
#   if (NEED_SSE2)
      if (HAVE(SSE2)) {
        for (i=0; i<output_size; i+=128) {
          for (r=nr; r>0; r-=2)
            DOUBLE_ROUND(quarter_round_sse2);
          OUTPUT_FUNCTION;
        }
        return;
      }
#   endif
  }
# endif

# if NEED_CONV
  {
    const u_int32_t *key = (const u_int32_t *)key_;
    u_int32_t
      x[16],
      input[16] = {
        key[0], key[1], key[2], key[3],
        key[4], key[5], key[6], key[7],
        iv, iv>>32, ctr, ctr>>32,
        0x61707865, 0x3320646e, 0x79622d32, 0x6b206574
      },
      *output = (u_int32_t *)output_;
    int i, r;
  
    for (i=0; i<output_size; i+= 64) {
      for (r=0; r<16; r++) {
        x[r] = input[r];
      }
      for (r=nr; r>0; r-=2) {
        quarter_round(&x[0], &x[4],  &x[8], &x[12]);
        quarter_round(&x[1], &x[5],  &x[9], &x[13]);
        quarter_round(&x[2], &x[6], &x[10], &x[14]);
        quarter_round(&x[3], &x[7], &x[11], &x[15]);
        
        quarter_round(&x[0], &x[5], &x[10], &x[15]);
        quarter_round(&x[1], &x[6], &x[11], &x[12]);
        quarter_round(&x[2], &x[7],  &x[8], &x[13]);
        quarter_round(&x[3], &x[4],  &x[9], &x[14]);
      }
      for (r=0; r<16; r++) {
        output[r] = x[r] + input[r];
      }
      
      output += 16;
      input[11] ++;
      if (!input[11]) input[12]++;
    }
  }
  
#endif // NEED_CONV
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x138, %rsp            # imm = 0x138
movq %r9, %rbp
movq %r8, %r14
movl %ecx, 0x4(%rsp)
movl %edx, (%rsp)
movq %rsi, %r15
movq %rdi, %rbx
callq 0x34e6
testl %eax, %eax
je 0x32f9
movaps (%r14), %xmm0
movaps %xmm0, 0x10(%rsp)
movaps %xmm0, 0x120(%rsp)
movaps %xmm0, 0xe0(%rsp)
movaps 0x10(%r14), %xmm0
movaps %xmm0, 0xc0(%rsp)
movaps %xmm0, 0xd0(%rsp)
movaps %xmm0, 0x70(%rsp)
movq %rbx, %xmm2
movq %r15, %xmm0
movdqa %xmm2, %xmm1
punpcklqdq %xmm0, %xmm1    # xmm1 = xmm1[0],xmm0[0]
movdqa %xmm1, 0x90(%rsp)
movdqa %xmm1, 0xb0(%rsp)
leaq 0x1(%r15), %rax
movq %rax, %xmm0
punpcklqdq %xmm0, %xmm2    # xmm2 = xmm2[0],xmm0[0]
movdqa %xmm2, 0x80(%rsp)
movdqa %xmm2, 0x60(%rsp)
movdqa 0x1260(%rip), %xmm0     # 0x42b0
movdqa %xmm0, 0xa0(%rsp)
movdqa %xmm0, 0x50(%rsp)
callq 0x34e6
testl %eax, %eax
je 0x32f9
movq %rbp, 0x8(%rsp)
xorl %eax, %eax
movdqa 0x90(%rsp), %xmm3
movdqa 0x80(%rsp), %xmm7
cmpl 0x4(%rsp), %eax
jge 0x34d4
movl %eax, 0x80(%rsp)
movdqa 0x1212(%rip), %xmm2     # 0x42b0
movdqa %xmm2, %xmm0
movdqa 0xd0(%rsp), %xmm4
movdqa %xmm4, %xmm1
movdqa %xmm3, 0x90(%rsp)
movl (%rsp), %r13d
testl %r13d, %r13d
jle 0x3203
leaq 0x10(%rsp), %r14
movq %r14, %rdi
leaq 0xc0(%rsp), %rbp
movq %rbp, %rsi
leaq 0xb0(%rsp), %rbx
movq %rbx, %rdx
leaq 0xa0(%rsp), %r15
movq %r15, %rcx
callq 0x3506
leaq 0xe0(%rsp), %r12
movq %r12, %rdi
leaq 0x70(%rsp), %rsi
leaq 0x60(%rsp), %rdx
leaq 0x50(%rsp), %rcx
callq 0x3506
pshufd $0x39, 0xc0(%rsp), %xmm0 # xmm0 = mem[1,2,3,0]
movdqa %xmm0, 0xc0(%rsp)
pshufd $0x4e, 0xb0(%rsp), %xmm0 # xmm0 = mem[2,3,0,1]
movdqa %xmm0, 0xb0(%rsp)
pshufd $0x93, 0xa0(%rsp), %xmm0 # xmm0 = mem[3,0,1,2]
pshufd $0x39, 0x70(%rsp), %xmm1 # xmm1 = mem[1,2,3,0]
movdqa %xmm0, 0xa0(%rsp)
movdqa %xmm1, 0x70(%rsp)
pshufd $0x4e, 0x60(%rsp), %xmm0 # xmm0 = mem[2,3,0,1]
movdqa %xmm0, 0x60(%rsp)
pshufd $0x93, 0x50(%rsp), %xmm0 # xmm0 = mem[3,0,1,2]
movdqa %xmm0, 0x50(%rsp)
movq %r14, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
movq %r15, %rcx
callq 0x3506
movq %r12, %rdi
leaq 0x70(%rsp), %rsi
leaq 0x60(%rsp), %rdx
leaq 0x50(%rsp), %rcx
callq 0x3506
pshufd $0x93, 0xc0(%rsp), %xmm4 # xmm4 = mem[3,0,1,2]
movdqa %xmm4, 0xc0(%rsp)
pshufd $0x4e, 0xb0(%rsp), %xmm3 # xmm3 = mem[2,3,0,1]
pshufd $0x39, 0xa0(%rsp), %xmm2 # xmm2 = mem[1,2,3,0]
movdqa %xmm3, 0xb0(%rsp)
movdqa %xmm2, 0xa0(%rsp)
pshufd $0x93, 0x70(%rsp), %xmm1 # xmm1 = mem[3,0,1,2]
movdqa %xmm1, 0x70(%rsp)
pshufd $0x4e, 0x60(%rsp), %xmm7 # xmm7 = mem[2,3,0,1]
movdqa %xmm7, 0x60(%rsp)
pshufd $0x39, 0x50(%rsp), %xmm0 # xmm0 = mem[1,2,3,0]
movdqa %xmm0, 0x50(%rsp)
addl $-0x2, %r13d
jmp 0x30bc
movdqa 0x10(%rsp), %xmm5
movdqa 0x120(%rsp), %xmm6
paddd %xmm6, %xmm5
movq 0x8(%rsp), %rax
movdqa %xmm5, (%rax)
movdqa 0xd0(%rsp), %xmm5
paddd %xmm5, %xmm4
movdqa %xmm4, 0x10(%rax)
movdqa 0x90(%rsp), %xmm4
paddd %xmm4, %xmm3
movdqa %xmm3, 0x20(%rax)
movdqa 0x1065(%rip), %xmm3     # 0x42b0
paddd %xmm3, %xmm2
movdqa %xmm2, 0x30(%rax)
movdqa 0xe0(%rsp), %xmm2
paddd %xmm6, %xmm2
movdqa %xmm2, 0x40(%rax)
paddd %xmm5, %xmm1
movdqa %xmm1, 0x50(%rax)
paddd %xmm4, %xmm7
paddd 0x1045(%rip), %xmm7     # 0x42c0
movdqa %xmm7, 0x60(%rax)
paddd %xmm3, %xmm0
movdqa %xmm0, 0x70(%rax)
subq $-0x80, %rax
movq %rax, 0x8(%rsp)
movdqa %xmm4, %xmm0
paddq 0x1032(%rip), %xmm0     # 0x42d0
movdqa %xmm6, 0xe0(%rsp)
movdqa %xmm6, 0x10(%rsp)
movdqa %xmm5, 0x70(%rsp)
movdqa %xmm5, 0xc0(%rsp)
movdqa %xmm0, 0xb0(%rsp)
paddq 0x1013(%rip), %xmm4     # 0x42e0
movdqa %xmm4, 0x60(%rsp)
movdqa %xmm3, 0x50(%rsp)
movdqa %xmm3, 0xa0(%rsp)
movl 0x80(%rsp), %eax
subl $-0x80, %eax
movdqa %xmm4, %xmm7
movdqa %xmm0, %xmm3
jmp 0x3085
movups (%r14), %xmm0
movaps %xmm0, 0xe0(%rsp)
movups 0x10(%r14), %xmm0
movaps %xmm0, 0xf0(%rsp)
movl %ebx, 0x100(%rsp)
shrq $0x20, %rbx
movl %ebx, 0x104(%rsp)
movl %r15d, 0x108(%rsp)
shrq $0x20, %r15
movq %r15, 0x90(%rsp)
movl %r15d, 0x10c(%rsp)
movdqa 0xf68(%rip), %xmm0      # 0x42b0
movdqa %xmm0, 0x110(%rsp)
xorl %eax, %eax
movl $0x61707865, 0x80(%rsp) # imm = 0x61707865
cmpl 0x4(%rsp), %eax
jge 0x34d4
movq %rax, 0xd0(%rsp)
xorl %eax, %eax
cmpq $0x10, %rax
je 0x3388
movl 0xe0(%rsp,%rax,4), %ecx
movl %ecx, 0x10(%rsp,%rax,4)
incq %rax
jmp 0x3372
movq %rbp, 0x8(%rsp)
movl (%rsp), %ebp
testl %ebp, %ebp
jle 0x346d
leaq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rsi
leaq 0x30(%rsp), %rdx
leaq 0x40(%rsp), %rcx
callq 0x3593
leaq 0x14(%rsp), %rdi
leaq 0x24(%rsp), %r13
movq %r13, %rsi
leaq 0x34(%rsp), %rdx
leaq 0x44(%rsp), %rcx
callq 0x3593
leaq 0x18(%rsp), %rdi
leaq 0x28(%rsp), %rsi
leaq 0x38(%rsp), %r14
movq %r14, %rdx
leaq 0x48(%rsp), %rcx
callq 0x3593
leaq 0x1c(%rsp), %rdi
leaq 0x2c(%rsp), %r15
movq %r15, %rsi
leaq 0x3c(%rsp), %r12
movq %r12, %rdx
leaq 0x4c(%rsp), %rbx
movq %rbx, %rcx
callq 0x3593
leaq 0x10(%rsp), %rdi
movq %r13, %rsi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x3593
leaq 0x14(%rsp), %rdi
leaq 0x28(%rsp), %rsi
movq %r12, %rdx
leaq 0x40(%rsp), %rcx
callq 0x3593
leaq 0x18(%rsp), %rdi
movq %r15, %rsi
leaq 0x30(%rsp), %rdx
leaq 0x44(%rsp), %rcx
callq 0x3593
leaq 0x1c(%rsp), %rdi
leaq 0x20(%rsp), %rsi
leaq 0x34(%rsp), %rdx
leaq 0x48(%rsp), %rcx
callq 0x3593
addl $-0x2, %ebp
jmp 0x3390
xorl %eax, %eax
movq 0x8(%rsp), %rbp
cmpq $0x10, %rax
je 0x348e
movl 0xe0(%rsp,%rax,4), %ecx
addl 0x10(%rsp,%rax,4), %ecx
movl %ecx, (%rbp,%rax,4)
incq %rax
jmp 0x3474
movq 0x90(%rsp), %rax
incl %eax
movq %rax, 0x90(%rsp)
movl %eax, 0x10c(%rsp)
jne 0x34c0
movl 0x80(%rsp), %eax
incl %eax
movl %eax, 0x80(%rsp)
movl %eax, 0x110(%rsp)
movq 0xd0(%rsp), %rax
addq $0x40, %rbp
addl $0x40, %eax
jmp 0x335e
addq $0x138, %rsp            # imm = 0x138
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq