// File: /workspace/github_c_makefile_star2_O1/WereCatf[P]Gonzales/bench.c
// Function: main
int main(int argc, char* argv[])
{
	struct timespec timeStart, timeEnd;
	uint32_t counter;
	double accum;

	int error=initGpio();
	if(error==1){
		printf("Error opening /dev/mem!\n");
		return 1;
	} else if(error==2){
		printf("Error mmapping memory!\n");
		return 2;
	}

	int origMux, origValue;
	origMux = readMux(3, 25);
	origValue = readPin(3, 25);
	writeMux(3, 25, _GPIO_MUX_OUT);

#ifdef _WITH_LIBSOC
	gpio *testPin;
	int libsocOrigMux;
	testPin = libsoc_gpio_request(121, LS_SHARED);
	if(testPin == NULL)
	{
			printf("Error setting up libsoc!\n");
			return 1;
	}
	libsocOrigMux = libsoc_gpio_get_direction(testPin);
	libsoc_gpio_set_direction(testPin, OUTPUT);
	printf("Test 10 million pin-togglings using libsoc on PD25...\n");
	clock_gettime(CLOCK_MONOTONIC, &timeStart);
	for(counter=0; counter<5000000; counter++){
		libsoc_gpio_set_level(testPin, LOW);
		libsoc_gpio_set_level(testPin, HIGH);
	}
	clock_gettime(CLOCK_MONOTONIC, &timeEnd);
	accum = ( timeEnd.tv_sec - timeStart.tv_sec )
		+ ( timeEnd.tv_nsec - timeStart.tv_nsec )
		/ 1E9;
	printf( "That took %.02lf seconds at ~%.02lfMbps\n", accum,  1E7 / accum / 1E6);
#endif

	printf("Test 10 million pin-togglings using writePin on PD25...\n");
	clock_gettime(CLOCK_MONOTONIC, &timeStart);
	for(counter=0; counter<5000000; counter++){
		writePin(3, 25, _GPIO_LOW);
		writePin(3, 25, _GPIO_HIGH);
	}
	clock_gettime(CLOCK_MONOTONIC, &timeEnd);
	accum = ( timeEnd.tv_sec - timeStart.tv_sec )
		+ ( timeEnd.tv_nsec - timeStart.tv_nsec )
		/ 1E9;
	printf( "That took %.02lf seconds at ~%.02lfMbps\n", accum,  1E7 / accum / 1E6);

	printf("Test 10 million pin-togglings using clearPort and setPort on PD25...\n");
	uint32_t mask = 1 << 25;
	clock_gettime(CLOCK_MONOTONIC, &timeStart);
	for(counter=0; counter<5000000; counter++){
		clearPort(3, mask); //Toggle pin LOW
		setPort(3, mask); //Toggle pin HIGH
	}
	clock_gettime(CLOCK_MONOTONIC, &timeEnd);
	accum = ( timeEnd.tv_sec - timeStart.tv_sec )
		+ ( timeEnd.tv_nsec - timeStart.tv_nsec )
		/ 1E9;
	printf( "That took %.02lf seconds at ~%.02lfMbps\n", accum,  1E7 / accum / 1E6);

#ifdef _WITH_LIBSOC
	libsoc_gpio_set_direction(testPin, libsocOrigMux);
	libsoc_gpio_free(testPin);
#endif

	writeMux(3, 25, origMux);
	writePin(3, 25, origValue);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x20, %rsp
xorl %eax, %eax
callq 0x2467
cmpl $0x2, %eax
je 0x21cf
cmpl $0x1, %eax
jne 0x21e5
leaq 0xf1d(%rip), %rdi       # 0x30dd
callq 0x2030
movl $0x1, %eax
jmp 0x2392
leaq 0xef0(%rip), %rdi       # 0x30c6
callq 0x2030
movl $0x2, %eax
jmp 0x2392
movl $0x3, %edi
movl $0x19, %esi
callq 0x24dc
movl %eax, %ebx
leaq 0x38b3(%rip), %r15      # 0x5ab0
movq (%r15), %rax
leaq 0x3897(%rip), %r12      # 0x5a9e
movzbl 0x3(%r12), %ecx
movl (%rax,%rcx), %ebp
movl $0x3, %edi
movl $0x19, %esi
movl $0x1, %edx
callq 0x2506
leaq 0xe1e(%rip), %rdi       # 0x3049
callq 0x2030
movq %rsp, %rsi
movl $0x1, %edi
callq 0x2040
movq (%r15), %rax
movl $0x4c4b40, %ecx         # imm = 0x4C4B40
movl $0xfdffffff, %edx       # imm = 0xFDFFFFFF
movzbl 0x3(%r12), %esi
andl %edx, (%rax,%rsi)
movzbl 0x3(%r12), %esi
andl %edx, (%rax,%rsi)
orl $0x2000000, (%rax,%rsi) # imm = 0x2000000
decl %ecx
jne 0x224a
leaq 0x10(%rsp), %r14
movl $0x1, %edi
movq %r14, %rsi
callq 0x2040
movq (%r14), %rax
movq 0x8(%r14), %rcx
movq %rsp, %r14
subq (%r14), %rax
cvtsi2sd %rax, %xmm1
subq 0x8(%r14), %rcx
cvtsi2sd %rcx, %xmm0
divsd 0xd6c(%rip), %xmm0      # 0x3008
addsd %xmm1, %xmm0
movsd 0xd68(%rip), %xmm1      # 0x3010
divsd %xmm0, %xmm1
divsd 0xd64(%rip), %xmm1      # 0x3018
leaq 0xd65(%rip), %rdi       # 0x3020
movb $0x2, %al
callq 0x2060
leaq 0xdb8(%rip), %rdi       # 0x3081
callq 0x2030
movl $0x1, %edi
movq %r14, %rsi
callq 0x2040
movq (%r15), %rax
movl $0x4c4b40, %ecx         # imm = 0x4C4B40
movzbl 0x3(%r12), %edx
andl $0xfdffffff, (%rax,%rdx) # imm = 0xFDFFFFFF
movzbl 0x3(%r12), %edx
orl $0x2000000, (%rax,%rdx) # imm = 0x2000000
decl %ecx
jne 0x22e3
leaq 0x10(%rsp), %r14
movl $0x1, %edi
movq %r14, %rsi
callq 0x2040
movq (%r14), %rax
movq 0x8(%r14), %rcx
subq (%rsp), %rax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
subq 0x8(%rsp), %rcx
xorps %xmm0, %xmm0
cvtsi2sd %rcx, %xmm0
divsd 0xccd(%rip), %xmm0      # 0x3008
addsd %xmm1, %xmm0
movsd 0xcc9(%rip), %xmm1      # 0x3010
divsd %xmm0, %xmm1
divsd 0xcc5(%rip), %xmm1      # 0x3018
leaq 0xcc6(%rip), %rdi       # 0x3020
movb $0x2, %al
callq 0x2060
movzbl %bl, %edx
movl $0x3, %edi
movl $0x19, %esi
callq 0x2506
movq (%r15), %rcx
movzbl 0x3(%r12), %edx
andl $0xfdffffff, (%rcx,%rdx) # imm = 0xFDFFFFFF
xorl %eax, %eax
btl $0x19, %ebp
jae 0x2392
orl $0x2000000, (%rcx,%rdx) # imm = 0x2000000
addq $0x20, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nop