// File: /workspace/github_cpp_makefile_star2_O2/gauravtewari[P]netlist/main.cpp
// Function: main
int main(int argc, char **argv){
	class circuit c;

	if(argc != 2){
		cout<<"Error: No input file specified.\n";
		cout<<"Usage: ./parser <input_file_name>\n";
		return 1;
	}

	/* Parse the input file and generate the graph data structures */
	if(c.parse_input(argv[1]) != 0){
		cerr<<"Error while Parsing input \n";
		return 1;
	}

	/* Figuring the name of the outfile */
	char *ofile = strtok(argv[1],".");
	char *out_file = new char[strlen(ofile)+5];
	strncpy(out_file, ofile, strlen(ofile));
	strncpy(out_file+strlen(ofile), ".out",4);
	out_file[strlen(ofile)+4]='\0';

	/* Opening the output file for storing result */
	ofstream fout(out_file);
	if(!fout.is_open()){
		cerr<<"Can't open output file for writing\n";
		return -1;
	}
	
	/* Calculate the fan out for all the gates in the netlist */
	c.update_fan_out();
	
	/* Calculating the maximum fanout */
	u32 max_fout=0;
	for(vector<struct gate>::const_iterator i = c.gate_list.begin(); i != c.gate_list.end(); i++)
		if(i->fan_out > max_fout)
			max_fout = i->fan_out;
	fout<<max_fout<<endl;
	
	
	/* find the number of gates with similar fanouts */
	int *fan_count = new int[max_fout+1];
	for(u32 i=0; i<max_fout+1; i++) fan_count[i]=0;
	for(vector<struct gate>::const_iterator i = c.gate_list.begin(); i != c.gate_list.end(); i++)
		fan_count[i->fan_out]++;
	
	/* Printing result for number of gates with similar fanout */
	for(u32 i=0; i<max_fout+1; i++){
		fout<<fan_count[i]<<endl;
	}
	
	/* Generating the index of adjacency list entries for INPUT gates */
	u32 gtype = c.get_gate_type("INPUT");
	fout<<c.gate_type[gtype]<<" ";
	for(vector<struct gate>::const_iterator i = c.gate_list.begin(); i != c.gate_list.end(); i++)
		if(i->type==gtype) {
			fout<<i->id<<" ";
		}
	fout<<endl;

	/* Generating the index of adjacency list entries for OUTPUT gates */
	gtype=c.get_gate_type("OUTPUT");
	fout<<c.gate_type[gtype]<<" ";
	for(vector<struct gate>::const_iterator i = c.gate_list.begin(); i != c.gate_list.end(); i++)
		if(i->type==gtype){
			fout<<i->id<<" ";
		}
	fout<<endl;
	
	/* Calculate the number of gate types that drive the same type gate, and the fanin counterpart */
	c.update_same_faninout();
	for (u32 i=0; i<c.gate_t.size(); i++){
		if((c.gate_type[i]!=0) && (i != c.get_gate_type("INPUT")) && (i != c.get_gate_type("OUTPUT"))){
			fout<<c.get_gate_name(i)<<" "<<c.gate_type[i]<<" "<<c.same_fanout[i]<<" "<<c.same_fanin[i]<<endl;

		}
	}
	
	/* Clean up */
	fout.close();
	delete []out_file;
	delete []fan_count;
	cout<<"Statistics Generated, check output file\n";
	cout<<"Output file generated: "<<ofile<<".out\n";
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x3e8, %rsp            # imm = 0x3E8
movq %rsi, %rbx
movl %edi, %ebp
leaq 0x88(%rsp), %rdi
callq 0x2a02
cmpl $0x2, %ebp
jne 0x2499
movq 0x8(%rbx), %rsi
leaq 0x88(%rsp), %rdi
callq 0x2dbc
testl %eax, %eax
je 0x24e2
leaq 0x2bb8(%rip), %rsi      # 0x5048
movq 0x5b59(%rip), %rbx      # 0x7ff0
jmp 0x24b6
movq 0x5b30(%rip), %rbx      # 0x7fd0
leaq 0x2b5d(%rip), %rsi      # 0x5004
movq %rbx, %rdi
callq 0x21d0
leaq 0x2b6f(%rip), %rsi      # 0x5025
movq %rbx, %rdi
callq 0x21d0
pushq $0x1
popq %rbx
leaq 0x88(%rsp), %rdi
callq 0x2ae6
movl %ebx, %eax
addq $0x3e8, %rsp            # imm = 0x3E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8(%rbx), %rdi
leaq 0x2b77(%rip), %rsi      # 0x5064
callq 0x22a0
movq %rax, %rbp
movq %rax, %rdi
callq 0x2100
leaq 0x5(%rax), %rdi
callq 0x2030
movq %rax, %rbx
movq %rbp, %rdi
callq 0x2100
movq %rbx, %rdi
movq %rbp, %rsi
movq %rax, %rdx
callq 0x2140
movq %rbp, %rdi
callq 0x2100
movl $0x74756f2e, (%rbx,%rax) # imm = 0x74756F2E
movq %rbp, %rdi
callq 0x2100
movb $0x0, 0x4(%rbx,%rax)
leaq 0x1e8(%rsp), %rdi
pushq $0x10
popq %rdx
movq %rbx, %rsi
callq 0x2210
leaq 0x258(%rsp), %rdi
callq 0x20a0
testb %al, %al
je 0x2594
leaq 0x88(%rsp), %rdi
callq 0x3868
movq 0x118(%rsp), %rax
movq 0x120(%rsp), %rcx
xorl %r14d, %r14d
cmpq %rcx, %rax
je 0x25af
movl 0xc(%rax), %edx
cmpl %r14d, %edx
cmoval %edx, %r14d
addq $0x28, %rax
jmp 0x257f
movq 0x5a55(%rip), %rdi      # 0x7ff0
leaq 0x2ac4(%rip), %rsi      # 0x5066
callq 0x21d0
pushq $-0x1
popq %rbx
jmp 0x2969
movl %r14d, %esi
leaq 0x1e8(%rsp), %rdi
callq 0x2160
movq %rax, %rdi
callq 0x2130
incl %r14d
leaq (,%r14,4), %rdi
callq 0x2030
movq %rax, %r15
xorl %eax, %eax
cmpq %rax, %r14
je 0x25eb
andl $0x0, (%r15,%rax,4)
incq %rax
jmp 0x25dc
movq 0x118(%rsp), %rax
movq 0x120(%rsp), %rcx
cmpq %rcx, %rax
je 0x260d
movl 0xc(%rax), %edx
incl (%r15,%rdx,4)
addq $0x28, %rax
jmp 0x25fb
movq %rbx, 0x20(%rsp)
xorl %r12d, %r12d
leaq 0x1e8(%rsp), %rbx
cmpq %r12, %r14
je 0x263b
movl (%r15,%r12,4), %esi
movq %rbx, %rdi
callq 0x22c0
movq %rax, %rdi
callq 0x2130
incq %r12
jmp 0x261d
leaq 0x2a48(%rip), %rsi      # 0x508a
leaq 0x68(%rsp), %rdi
leaq 0x28(%rsp), %rdx
callq 0x2aaa
leaq 0x88(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0x35d4
movl %eax, %ebx
leaq 0x68(%rsp), %rdi
callq 0x2110
movl %ebx, %eax
movl 0x90(%rsp,%rax,4), %esi
leaq 0x1e8(%rsp), %rdi
callq 0x2160
leaq 0x2a4a(%rip), %rsi      # 0x50d6
movq %rax, %rdi
callq 0x21d0
movq 0x118(%rsp), %r13
leaq 0x1e8(%rsp), %r14
leaq 0x2a2b(%rip), %r12      # 0x50d6
cmpq 0x120(%rsp), %r13
je 0x26d8
cmpl %ebx, 0x4(%r13)
jne 0x26d2
movl (%r13), %esi
movq %r14, %rdi
callq 0x2160
movq %rax, %rdi
movq %r12, %rsi
callq 0x21d0
addq $0x28, %r13
jmp 0x26ab
leaq 0x1e8(%rsp), %rdi
callq 0x2130
leaq 0x29a4(%rip), %rsi      # 0x5090
leaq 0x48(%rsp), %rdi
leaq 0x28(%rsp), %rdx
callq 0x2aaa
leaq 0x88(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x35d4
movl %eax, %ebx
leaq 0x48(%rsp), %rdi
callq 0x2110
movl %ebx, %eax
movl 0x90(%rsp,%rax,4), %esi
leaq 0x1e8(%rsp), %rdi
callq 0x2160
leaq 0x29a0(%rip), %rsi      # 0x50d6
movq %rax, %rdi
callq 0x21d0
movq 0x118(%rsp), %r13
leaq 0x1e8(%rsp), %r14
leaq 0x2981(%rip), %r12      # 0x50d6
cmpq 0x120(%rsp), %r13
je 0x2782
cmpl %ebx, 0x4(%r13)
jne 0x277c
movl (%r13), %esi
movq %r14, %rdi
callq 0x2160
movq %rax, %rdi
movq %r12, %rsi
callq 0x21d0
addq $0x28, %r13
jmp 0x2755
leaq 0x1e8(%rsp), %rdi
callq 0x2130
leaq 0x88(%rsp), %rdi
callq 0x36b8
movq %r15, 0x10(%rsp)
movq %rbp, 0x18(%rsp)
xorl %r12d, %r12d
leaq 0x1c8(%rsp), %r15
leaq 0x28(%rsp), %rax
leaq 0x88(%rsp), %r14
leaq 0x1a8(%rsp), %r13
movl %r12d, %r12d
cmpq %r12, 0x1a0(%rsp)
jbe 0x28fe
cmpl $0x0, 0x90(%rsp,%r12,4)
je 0x28f6
movq %r15, %rbp
movq %r15, %rdi
leaq 0x2897(%rip), %rsi      # 0x508a
movq %rax, %rbx
movq %rax, %rdx
callq 0x2aaa
movq %r14, %rdi
movq %rbp, %rsi
callq 0x35d4
cmpl %eax, %r12d
jne 0x281e
movq %r15, %rdi
callq 0x2110
movq %rbx, %rax
jmp 0x28f6
movq %r13, %rdi
leaq 0x2868(%rip), %rsi      # 0x5090
leaq 0xf(%rsp), %rdx
callq 0x2aaa
movq %r14, %rbp
movq %r14, %rdi
movq %r13, %rsi
callq 0x35d4
movl %eax, %r14d
movq %r13, %rdi
callq 0x2110
movq %r15, %rdi
callq 0x2110
cmpl %r14d, %r12d
movq %rbx, %rax
movq %rbp, %r14
je 0x28f6
movq %rax, %rdi
movq %r14, %rsi
movq %rax, %r14
movl %r12d, %edx
callq 0x3912
leaq 0x1e8(%rsp), %rdi
movq %r14, %rsi
callq 0x21c0
movq %rax, %rdi
leaq 0x2849(%rip), %rsi      # 0x50d6
callq 0x21d0
movl 0x90(%rsp,%r12,4), %esi
movq %rax, %rdi
callq 0x2160
movq %rax, %rdi
leaq 0x282a(%rip), %rsi      # 0x50d6
callq 0x21d0
movl 0xcc(%rsp,%r12,4), %esi
movq %rax, %rdi
callq 0x2160
movq %rax, %rdi
leaq 0x280b(%rip), %rsi      # 0x50d6
callq 0x21d0
movl 0xf0(%rsp,%r12,4), %esi
movq %rax, %rdi
callq 0x2160
movq %rax, %rdi
callq 0x2130
movq %rbx, %rdi
callq 0x2110
movq %rbx, %rax
movq %rbp, %r14
incl %r12d
jmp 0x27c6
leaq 0x1e8(%rsp), %rdi
callq 0x2260
movq 0x18(%rsp), %rbx
movq 0x10(%rsp), %r14
movq 0x20(%rsp), %rdi
callq 0x2240
movq %r14, %rdi
callq 0x2240
movq 0x56a2(%rip), %rdi      # 0x7fd0
leaq 0x2762(%rip), %rsi      # 0x5097
callq 0x21d0
movq 0x568f(%rip), %rdi      # 0x7fd0
leaq 0x2778(%rip), %rsi      # 0x50c0
callq 0x21d0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x21d0
xorl %ebx, %ebx
leaq 0x2777(%rip), %rsi      # 0x50d8
movq %rax, %rdi
callq 0x21d0
leaq 0x1e8(%rsp), %rdi
callq 0x2280
jmp 0x24c1
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
jmp 0x29d5
jmp 0x29dc
movq %rax, %rbx
leaq 0x68(%rsp), %rdi
jmp 0x29d5
jmp 0x29dc
jmp 0x29dc
jmp 0x29dc
jmp 0x29dc
jmp 0x29b5
jmp 0x29b5
jmp 0x29dc
movq %rax, %rbx
leaq 0x1a8(%rsp), %rdi
callq 0x2110
jmp 0x29bf
jmp 0x29bc
jmp 0x29dc
movq %rax, %rbx
jmp 0x29ec
jmp 0x29dc
movq %rax, %rbx
leaq 0x1c8(%rsp), %rdi
jmp 0x29d5
jmp 0x29dc
jmp 0x29dc
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x2110
jmp 0x29df
movq %rax, %rbx
leaq 0x1e8(%rsp), %rdi
callq 0x2280
leaq 0x88(%rsp), %rdi
callq 0x2ae6
movq %rbx, %rdi
callq 0x22d0
nop