// File: /workspace/github_c_makefile_star2_O0/Tarsnap[P]libcperciva/liball/../crypto/crypto_aesctr_aesni.c
// Function: crypto_aesctr_aesni_stream_wholeblocks
static void
crypto_aesctr_aesni_stream_wholeblocks(struct crypto_aesctr * stream,
    const uint8_t ** inbuf, uint8_t ** outbuf, size_t * buflen)
{
	__m128i bufsse;
	__m128i inbufsse;
	__m128i nonce_be;
	uint8_t block_counter_be_arr[8];
	uint64_t block_counter;
	size_t num_blocks;
	size_t i;

	/* Load local variables from stream. */
	nonce_be = load_si64(stream->pblk);
	block_counter = stream->bytectr / 16;

	/* How many blocks should we process? */
	num_blocks = (*buflen) / 16;

	/*
	 * This is 'for (i = num_blocks; i > 0; i--)', but ensuring that the
	 * compiler knows that we will execute the loop at least once.
	 */
	i = num_blocks;
	do {
		/* Prepare counter. */
		be64enc(block_counter_be_arr, block_counter);

		/* Encrypt the cipherblock. */
		bufsse = load_si64(block_counter_be_arr);
		bufsse = _mm_unpacklo_epi64(nonce_be, bufsse);
		bufsse = crypto_aes_encrypt_block_aesni_m128i(bufsse,
		    stream->key);

		/* Encrypt the byte(s). */
		inbufsse = _mm_loadu_si128((const __m128i *)(*inbuf));
		bufsse = _mm_xor_si128(inbufsse, bufsse);
		_mm_storeu_si128((__m128i *)(*outbuf), bufsse);

		/* Update the positions. */
		block_counter++;
		*inbuf += 16;
		*outbuf += 16;

		/* Update the counter. */
		i--;
	} while (i > 0);

	/* Update the overall buffer length. */
	*buflen -= 16 * num_blocks;

	/* Update variables in stream. */
	memcpy(stream->pblk + 8, block_counter_be_arr, 8);
	stream->bytectr += 16 * num_blocks;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x78(%rbp)
movq %rsi, -0x80(%rbp)
movq %rdx, -0x88(%rbp)
movq %rcx, -0x90(%rbp)
movq -0x78(%rbp), %rdi
addq $0x20, %rdi
callq 0x61f0
movdqa %xmm0, -0xc0(%rbp)
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0x4, %rax
movq %rax, -0xd0(%rbp)
movq -0x90(%rbp), %rax
movq (%rax), %rax
shrq $0x4, %rax
movq %rax, -0xd8(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xd0(%rbp), %rsi
leaq -0xc8(%rbp), %rdi
movq %rdi, -0xe8(%rbp)
callq 0x6220
movq -0xe8(%rbp), %rdi
callq 0x61f0
movaps %xmm0, -0xa0(%rbp)
movaps -0xc0(%rbp), %xmm1
movaps -0xa0(%rbp), %xmm0
movaps %xmm1, -0x60(%rbp)
movaps %xmm0, -0x70(%rbp)
movaps -0x60(%rbp), %xmm0
movaps -0x70(%rbp), %xmm1
punpcklqdq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0]
movdqa %xmm0, -0xa0(%rbp)
movdqa -0xa0(%rbp), %xmm0
movq -0x78(%rbp), %rax
movq (%rax), %rdi
callq 0x51d0
movdqa %xmm0, -0xa0(%rbp)
movq -0x80(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movdqu (%rax), %xmm0
movdqa %xmm0, -0xb0(%rbp)
movdqa -0xb0(%rbp), %xmm1
movdqa -0xa0(%rbp), %xmm0
movdqa %xmm1, -0x30(%rbp)
movdqa %xmm0, -0x40(%rbp)
movdqa -0x30(%rbp), %xmm0
pxor -0x40(%rbp), %xmm0
movdqa %xmm0, -0xa0(%rbp)
movq -0x88(%rbp), %rax
movq (%rax), %rax
movdqa -0xa0(%rbp), %xmm0
movq %rax, -0x8(%rbp)
movdqa %xmm0, -0x20(%rbp)
movdqa -0x20(%rbp), %xmm0
movq -0x8(%rbp), %rax
movdqu %xmm0, (%rax)
movq -0xd0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xd0(%rbp)
movq -0x80(%rbp), %rax
movq (%rax), %rcx
addq $0x10, %rcx
movq %rcx, (%rax)
movq -0x88(%rbp), %rax
movq (%rax), %rcx
addq $0x10, %rcx
movq %rcx, (%rax)
movq -0xe0(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0xe0(%rbp)
cmpq $0x0, -0xe0(%rbp)
ja 0x5f5c
movq -0xd8(%rbp), %rdx
shlq $0x4, %rdx
movq -0x90(%rbp), %rax
movq (%rax), %rcx
subq %rdx, %rcx
movq %rcx, (%rax)
movq -0x78(%rbp), %rax
movq -0xc8(%rbp), %rcx
movq %rcx, 0x28(%rax)
movq -0xd8(%rbp), %rcx
shlq $0x4, %rcx
movq -0x78(%rbp), %rax
addq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
addq $0xf0, %rsp
popq %rbp
retq
nopl (%rax)