// File: /workspace/github_c_makefile_star2_O2/Tarsnap[P]libcperciva/tests/crypto_aes/main.c
// Function: selftest
static int
selftest(void)
{
	struct crypto_aes_key * key_exp;
	uint8_t plaintext_arr[MAX_PLAINTEXT_LENGTH];
	uint8_t ciphertext_arr[MAX_PLAINTEXT_LENGTH];
	uint8_t cbuf[MAX_PLAINTEXT_LENGTH];
	size_t keylen;
	size_t i;
	size_t failures = 0;
	size_t num_tests = sizeof(tests) / sizeof(tests[0]);
#ifdef CPUSUPPORT_X86_AESNI
	__m128i bufsse;
#endif
#ifdef CPUSUPPORT_ARM_AES
	uint8x16_t bufarm;
#endif

	/* Sanity check. */
#ifdef CPUSUPPORT_X86_AESNI
	if (cpusupport_x86_aesni()) {
		if (crypto_aes_can_use_intrinsics() != 1) {
			warn0("Unexpected error with AESNI");
			goto err0;
		}
	}
#endif

	/* Inform user about the hardware optimization status. */
	print_hardware("Checking test vectors of AES");

	/* Run regular test cases. */
	for (i = 0; i < num_tests; i++) {
		/* Prepare for the test case. */
		if (parse_testcase(tests[i], &key_exp, &keylen,
		    plaintext_arr, ciphertext_arr)) {
			warn0("parse_testcase");
			goto err0;
		}
		printf("Computing %zu-bit AES of \"%s\"...",
		    keylen * 8, tests[i].plaintext_hex);

		/* Run AES. */
#ifdef CPUSUPPORT_X86_AESNI
		if (crypto_aes_can_use_intrinsics() == 1) {
			bufsse = _mm_loadu_si128(
			    (const __m128i *)plaintext_arr);
			bufsse = crypto_aes_encrypt_block_aesni_m128i(bufsse,
			    key_exp);
			_mm_storeu_si128((__m128i *)cbuf, bufsse);
		} else
#endif
#ifdef CPUSUPPORT_ARM_AES
		if (crypto_aes_can_use_intrinsics() == 2) {
			bufarm = vld1q_u8(plaintext_arr);
			bufarm = crypto_aes_encrypt_block_arm_u8(bufarm,
			    key_exp);
			vst1q_u8(cbuf, bufarm);
		} else
#endif
		crypto_aes_encrypt_block(plaintext_arr, cbuf, key_exp);

		/* Check result. */
		if (memcmp(cbuf, ciphertext_arr, 16)) {
			printf(" FAILED!\n");
			print_arr("Computed AES:\t", cbuf, 16);
			print_arr("Correct AES:\t", ciphertext_arr, 16);
			failures++;
		} else {
			printf(" PASSED!\n");
		}

		/* Clean up. */
		crypto_aes_key_free(key_exp);
	}

	/* Report overall success to exit code. */
	if (failures)
		return (1);
	else
		return (0);

err0:
	/* Failure! */
	return (1);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
callq 0x16ff
testl %eax, %eax
je 0x1566
callq 0x19c0
cmpl $0x1, %eax
jne 0x1692
leaq 0x2c63(%rip), %rdi      # 0x41d0
callq 0x1739
leaq 0x5827(%rip), %rbp      # 0x6da0
leaq 0x50(%rsp), %r15
leaq 0x40(%rsp), %r12
xorl %r13d, %r13d
xorl %r14d, %r14d
cmpq $0x30, %r13
je 0x167f
movq 0x10(%r13,%rbp), %rax
movq %rax, 0x10(%rsp)
movups (%r13,%rbp), %xmm0
movups %xmm0, (%rsp)
leaq 0x18(%rsp), %rdi
leaq 0x38(%rsp), %rsi
movq %r15, %rdx
movq %r12, %rcx
callq 0x176a
testl %eax, %eax
jne 0x1689
movq 0x38(%rsp), %rsi
shlq $0x3, %rsi
leaq 0x2c19(%rip), %rdi      # 0x41ed
leaq 0x2b79(%rip), %rdx      # 0x4154
xorl %eax, %eax
callq 0x1030
callq 0x19c0
cmpl $0x1, %eax
jne 0x1605
movaps 0x50(%rsp), %xmm0
movq 0x18(%rsp), %rbx
movq %rbx, %rdi
callq 0x216e
movaps %xmm0, 0x20(%rsp)
jmp 0x161a
movq 0x18(%rsp), %rbx
movq %r15, %rdi
leaq 0x20(%rsp), %rsi
movq %rbx, %rdx
callq 0x1b0c
movdqa 0x20(%rsp), %xmm0
pcmpeqb 0x40(%rsp), %xmm0
pmovmskb %xmm0, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
je 0x1662
leaq 0x2c9a(%rip), %rdi      # 0x42d2
callq 0x1070
leaq 0x2bca(%rip), %rdi      # 0x420e
leaq 0x20(%rsp), %rsi
callq 0x194c
leaq 0x2bc8(%rip), %rdi      # 0x421d
movq %r12, %rsi
callq 0x194c
incq %r14
jmp 0x166e
leaq 0x2c60(%rip), %rdi      # 0x42c9
callq 0x1070
movq %rbx, %rdi
callq 0x1b1e
addq $0x18, %r13
jmp 0x1589
xorl %eax, %eax
testq %r14, %r14
setne %al
jmp 0x16ab
leaq 0x29ae(%rip), %rdi      # 0x403e
jmp 0x1699
leaq 0x2971(%rip), %rdi      # 0x400a
xorl %eax, %eax
callq 0x31a4
callq 0x1190
andl $0x0, (%rax)
pushq $0x1
popq %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq