// File: /workspace/github_cpp_makefile_star2_O2/estwings57[P]CasHMC/sources/RunSim.cpp
// Function: main
int main(int argc, char **argv)
{
	//
	//parse command-line options setting
	//
	numSimCycles = 100000;
	memUtil = 0.1;
	rwRatio = 80;
	traceType = "";
	traceFileName = "";
	
	int opt;
	string pwdString = "";
	ifstream traceFile;
	string line;
	bool pendingTran = false;
	while(1) {
		static struct option long_options[] = {
			{"pwd", required_argument, 0, 'p'},
			{"cycle",  required_argument, 0, 'c'},
			{"trace",  required_argument, 0, 't'},
			{"util",  required_argument, 0, 'u'},
			{"rwratio",  required_argument, 0, 'r'},
			{"file",  required_argument, 0, 'f'},
			{"help", no_argument, 0, 'h'},
			{0, 0, 0, 0}
		};
		int option_index=0;
		opt = getopt_long (argc, argv, "p:c:t:u:r:f:h", long_options, &option_index);
		if(opt == -1) {
			break;
		}
		switch(opt) {
			case 0:
				if (long_options[option_index].flag != 0) {
					cout<<"setting flag"<<endl;
					break;
				}
				cout<<"option "<<long_options[option_index].name<<endl;
				if (optarg) {
					cout<<" with arg"<<optarg<<endl;
				}
				cout<<""<<endl;
				break;
			case 'p':
				pwdString = string(optarg);
				break;
			case 'c':
				numSimCycles = atol(optarg);
				break;
			case 't':
				traceType = string(optarg);
				if(traceType != "random" && traceType != "file") {
					cout<<endl<<" == -t (--trace) ERROR ==";
					cout<<endl<<"  This option must be selected by one of 'random' and 'file'"<<endl<<endl;
					exit(0);
				}
				break;
			case 'u':
				memUtil = atof(optarg);
				if(memUtil < 0 || memUtil > 1) {
					cout<<endl<<" == -u (--util) ERROR ==";
					cout<<endl<<"  This value must be in the between '0' and '1'"<<endl<<endl;
					exit(0);
				}
				break;
			case 'r':
				rwRatio = atof(optarg);
				if(rwRatio < 0 || rwRatio > 100) {
					cout<<endl<<" == -r (--rwratio) ERROR ==";
					cout<<endl<<"  This value is the percentage of reads in request stream"<<endl<<endl;
					exit(0);
				}
				break;
			case 'f':
				traceFileName = string(optarg);
				if(access(traceFileName.c_str(), 0) == -1) {
					cout<<endl<<" == -f (--file) ERROR ==";
					cout<<endl<<"  There is no trace file ["<<traceFileName<<"]"<<endl<<endl;
					exit(0);
				}
				break;
			case 'h':
			case '?':
				Help();
				exit(0);
				break;
		}
	}
	
	srand((unsigned)time(NULL));
	casHMCWrapper = new CasHMCWrapper("ConfigSim.ini", "ConfigDRAM.ini");
	
#ifdef CALLBACKTRANS
	//Register callback function (ReadComplete, WriteComplete)
	CallbackTrans callbackTrans;
	TransCompCB* read_cb = new Callback<CallbackTrans, void, uint64_t, uint64_t>(&callbackTrans, &CallbackTrans::ReadComplete);
    TransCompCB* write_cb = new Callback<CallbackTrans, void, uint64_t, uint64_t>(&callbackTrans, &CallbackTrans::WriteComplete);
	casHMCWrapper->RegisterCallbacks(read_cb, write_cb);
#endif
	
	if(traceType == "random") {
		for(uint64_t cpuCycle=0; cpuCycle<numSimCycles; cpuCycle++) {
			MakeRandomTransaction();
			if(!transactionBuffers.empty()) {
				if(casHMCWrapper->ReceiveTran(transactionBuffers[0])) {
					transactionBuffers.erase(transactionBuffers.begin());
				}
			}
			casHMCWrapper->Update();
		}
	}
	else if(traceType == "file") {
		uint64_t issueClock = 0;
		traceFile.open(traceFileName.c_str());
		if(!traceFile.is_open()) {
			ERROR(" == Error - Could not open trace file ["<<traceFileName<<"]");
			exit(0);
		}
		for(uint64_t cpuCycle=0; cpuCycle<numSimCycles; cpuCycle++) {
			if(!pendingTran) {
				if(!traceFile.eof()) {
					getline(traceFile, line);
					if(line.size() > 0) {
						uint64_t addr;
						TransactionType tranType;
						unsigned dataSize;
						ParseTraceFileLine(line, issueClock, addr, tranType, dataSize);
						Transaction *newTran = new Transaction(tranType, addr, dataSize, casHMCWrapper);
						
						if(cpuCycle >= issueClock) {
							if(!casHMCWrapper->ReceiveTran(newTran)) {
								pendingTran = true;
								transactionBuffers.push_back(newTran);
							}
						}
						else {
							pendingTran = true;
							transactionBuffers.push_back(newTran);
						}
					}
					else {
						cout<<" ## WARNING ## Skipping line ("<<lineNumber<<") in tracefile  (CurrentClock : "<<cpuCycle<<")"<<endl;
					}
					lineNumber++;
				}
			}
			else {
				if(cpuCycle >= issueClock) {
					if(casHMCWrapper->ReceiveTran(transactionBuffers[0])) {
						pendingTran = false;
						transactionBuffers.erase(transactionBuffers.begin());
					}
				}					
			}
			casHMCWrapper->Update();
		}
	}

	transactionBuffers.clear();
	delete casHMCWrapper;
	casHMCWrapper = NULL;

	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2d8, %rsp            # imm = 0x2D8
movq %rsi, 0x28(%rsp)
movl %edi, %ebp
leaq 0x112b2(%rip), %rax     # 0x31410
movq $0x186a0, (%rax)        # imm = 0x186A0
leaq 0x112ac(%rip), %rcx     # 0x31418
movabsq $0x3fb999999999999a, %rax # imm = 0x3FB999999999999A
movq %rax, (%rcx)
leaq 0x112a0(%rip), %rcx     # 0x31420
movabsq $0x4054000000000000, %rax # imm = 0x4054000000000000
movq %rax, (%rcx)
leaq 0x11294(%rip), %rdi     # 0x31428
leaq 0x58ba(%rip), %rbx      # 0x25a55
movq %rbx, %rsi
callq 0x4560
leaq 0x1129e(%rip), %rdi     # 0x31448
movq %rbx, %rsi
callq 0x4560
leaq 0xb0(%rsp), %rdi
leaq 0xd0(%rsp), %rdx
movq %rbx, %rsi
callq 0xcfd4
leaq 0xd0(%rsp), %rdi
callq 0x4350
leaq 0x60(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x74e3(%rip), %r15      # 0x276d2
leaq 0x1110a(%rip), %r13     # 0x31300
leaq 0x8(%rsp), %rbx
movl %ebp, 0x1c(%rsp)
andl $0x0, 0x8(%rsp)
movl %ebp, %edi
movq 0x28(%rsp), %rsi
movq %r15, %rdx
movq %r13, %rcx
movq %rbx, %r8
callq 0x44a0
leal -0x70(%rax), %ecx
cmpl $0x5, %ecx
ja 0x20267
leaq 0x7228(%rip), %rdx      # 0x27450
movslq (%rdx,%rcx,4), %rax
addq %rdx, %rax
jmpq *%rax
movq 0x10d88(%rip), %rax     # 0x30fc0
movq (%rax), %rsi
leaq 0x30(%rsp), %r14
movq %r14, %rdi
leaq 0x10(%rsp), %rdx
callq 0xcfd4
leaq 0xb0(%rsp), %rdi
movq %r14, %rsi
callq 0x4380
movq %r14, %rdi
callq 0x4598
jmp 0x201ff
testl %eax, %eax
je 0x203e8
cmpl $0x63, %eax
je 0x20491
cmpl $0x66, %eax
je 0x20384
cmpl $-0x1, %eax
je 0x204af
cmpl $0x3f, %eax
je 0x207e8
cmpl $0x68, %eax
jne 0x201ff
jmp 0x207e8
movq 0x10d18(%rip), %rax     # 0x30fc0
movq (%rax), %rsi
leaq 0x30(%rsp), %r14
movq %r14, %rdi
leaq 0x10(%rsp), %rdx
callq 0xcfd4
leaq 0x11164(%rip), %r12     # 0x31428
movq %r12, %rdi
movq %r14, %rsi
callq 0x4380
movq %r14, %rdi
callq 0x4598
movq %r12, %rdi
leaq 0x4780(%rip), %rsi      # 0x24a61
callq 0x20a51
testb %al, %al
je 0x201ff
leaq 0x11133(%rip), %rdi     # 0x31428
leaq 0x5aad(%rip), %rsi      # 0x25da9
callq 0x20a51
testb %al, %al
je 0x201ff
jmp 0x208f0
movq 0x10cab(%rip), %rax     # 0x30fc0
movq (%rax), %rdi
callq 0x4390
leaq 0x110f4(%rip), %rax     # 0x31418
movsd %xmm0, (%rax)
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
ja 0x2083c
ucomisd 0x3d72(%rip), %xmm0     # 0x240b0
jbe 0x201ff
jmp 0x2083c
movq 0x10c70(%rip), %rax     # 0x30fc0
movq (%rax), %rdi
callq 0x4390
leaq 0x110c1(%rip), %rax     # 0x31420
movsd %xmm0, (%rax)
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
ja 0x207f4
ucomisd 0x3d4f(%rip), %xmm0     # 0x240c8
jbe 0x201ff
jmp 0x207f4
movq %r13, %r14
movq 0x10c32(%rip), %rax     # 0x30fc0
movq %rbx, %r13
movq %r15, %rbx
movq (%rax), %rsi
leaq 0x30(%rsp), %r12
movq %r12, %rdi
leaq 0x10(%rsp), %rdx
callq 0xcfd4
leaq 0x11098(%rip), %r15     # 0x31448
movq %r15, %rdi
movq %r12, %rsi
callq 0x4380
movq %r12, %rdi
callq 0x4598
movq (%r15), %rdi
xorl %esi, %esi
callq 0x44b0
cmpl $-0x1, %eax
movq %rbx, %r15
movq %r13, %rbx
movq %r14, %r13
movl 0x1c(%rsp), %ebp
jne 0x201ff
jmp 0x20887
movslq 0x8(%rsp), %rax
shlq $0x5, %rax
cmpq $0x0, 0x10(%rax,%r13)
leaq 0x72e2(%rip), %rsi      # 0x276e0
jne 0x20478
movq 0x10bc9(%rip), %rdi     # 0x30fd0
leaq 0x72df(%rip), %rsi      # 0x276ed
callq 0x4300
movslq 0x8(%rsp), %rcx
shlq $0x5, %rcx
movq (%rcx,%r13), %rsi
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
movq 0x10b89(%rip), %rax     # 0x30fc0
cmpq $0x0, (%rax)
leaq 0x5613(%rip), %rsi      # 0x25a55
je 0x20478
movq 0x10b85(%rip), %rdi     # 0x30fd0
leaq 0x72a3(%rip), %rsi      # 0x276f5
callq 0x4300
movq 0x10b62(%rip), %rcx     # 0x30fc0
movq (%rcx), %rsi
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
leaq 0x55dd(%rip), %rsi      # 0x25a55
movq 0x10b51(%rip), %rdi     # 0x30fd0
callq 0x4300
movq %rax, %rdi
callq 0x4180
jmp 0x201ff
movq 0x10b28(%rip), %rax     # 0x30fc0
movq (%rax), %rdi
callq 0x4360
leaq 0x10f69(%rip), %rcx     # 0x31410
movq %rax, (%rcx)
jmp 0x201ff
xorl %edi, %edi
callq 0x42c0
movl %eax, %edi
callq 0x42f0
movl $0x1018, %edi           # imm = 0x1018
callq 0x4310
movq %rax, %r14
leaq 0x7358(%rip), %rsi      # 0x27829
leaq 0x90(%rsp), %rdi
leaq 0x30(%rsp), %rdx
callq 0xcfd4
leaq 0x734d(%rip), %rsi      # 0x27837
leaq 0x70(%rsp), %rdi
leaq 0x8(%rsp), %rdx
callq 0xcfd4
leaq 0x90(%rsp), %rsi
leaq 0x70(%rsp), %rdx
movq %r14, %rdi
callq 0x5c60
movq %r14, 0x11ebb(%rip)     # 0x323d0
leaq 0x70(%rsp), %rdi
callq 0x4598
leaq 0x90(%rsp), %rdi
callq 0x4598
leaq 0x10ef5(%rip), %rdi     # 0x31428
leaq 0x4527(%rip), %rsi      # 0x24a61
callq 0xde4e
testb %al, %al
je 0x205a5
xorl %r14d, %r14d
leaq 0x11e6b(%rip), %rbx     # 0x323b8
leaq 0x10ebc(%rip), %rax     # 0x31410
cmpq (%rax), %r14
jae 0x2077f
callq 0x1f867
movq 0x11e4f(%rip), %rax     # 0x323b8
cmpq 0x11e50(%rip), %rax     # 0x323c0
je 0x20594
movq 0x11e57(%rip), %rdi     # 0x323d0
movq (%rax), %rsi
callq 0xc5c6
testb %al, %al
je 0x20594
movq 0x11e2c(%rip), %rsi     # 0x323b8
movq %rbx, %rdi
callq 0x19444
movq 0x11e35(%rip), %rdi     # 0x323d0
callq 0xc676
incq %r14
jmp 0x2054d
leaq 0x10e7c(%rip), %rdi     # 0x31428
leaq 0x57f6(%rip), %rsi      # 0x25da9
callq 0xde4e
testb %al, %al
je 0x2077f
andq $0x0, 0x30(%rsp)
leaq 0x10e7b(%rip), %rax     # 0x31448
movq (%rax), %rsi
leaq 0xd0(%rsp), %rdi
pushq $0x8
popq %rdx
callq 0x41f0
leaq 0x148(%rsp), %rdi
callq 0x40c0
testb %al, %al
je 0x2093b
xorl %r13d, %r13d
leaq 0x11db9(%rip), %rbx     # 0x323b8
leaq 0xd0(%rsp), %r14
leaq 0x50(%rsp), %r15
pushq $0x30
popq %rbp
xorl %r12d, %r12d
leaq 0x10df7(%rip), %rax     # 0x31410
cmpq (%rax), %r12
jae 0x2077f
testb $0x1, %r13b
je 0x20668
movb $0x1, %r13b
cmpq 0x30(%rsp), %r12
jb 0x2076b
movq 0x11d93(%rip), %rdi     # 0x323d0
movq 0x11d74(%rip), %rax     # 0x323b8
movq (%rax), %rsi
callq 0xc5c6
testb %al, %al
je 0x2076b
movq 0x11d5d(%rip), %rsi     # 0x323b8
movq %rbx, %rdi
callq 0x19444
jmp 0x20709
movq 0xd0(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x2, 0xf0(%rsp,%rax)
jne 0x20709
movq %r14, %rdi
movq %r15, %rsi
callq 0x4090
cmpq $0x0, 0x58(%rsp)
je 0x2070e
movq %r15, %rdi
leaq 0x30(%rsp), %rsi
leaq 0x8(%rsp), %rdx
leaq 0x24(%rsp), %rcx
leaq 0x20(%rsp), %r8
callq 0x1f940
movq %rbp, %rdi
callq 0x4310
movq %rax, %r13
movl 0x24(%rsp), %esi
movq 0x8(%rsp), %rdx
movl 0x20(%rsp), %ecx
movq 0x11d00(%rip), %r8      # 0x323d0
movq %rax, %rdi
callq 0x20a5c
movq %r13, 0x10(%rsp)
cmpq 0x30(%rsp), %r12
jb 0x206f7
movq 0x11ce5(%rip), %rdi     # 0x323d0
movq %r13, %rsi
callq 0xc5c6
testb %al, %al
jne 0x20761
movb $0x1, %r13b
movq %rbx, %rdi
leaq 0x10(%rsp), %rsi
callq 0xe99e
jmp 0x20764
xorl %r13d, %r13d
jmp 0x2076b
movq 0x108bb(%rip), %rdi     # 0x30fd0
leaq 0x7152(%rip), %rsi      # 0x2786e
callq 0x4300
movq 0x10bc8(%rip), %rsi     # 0x312f0
movq %rax, %rdi
callq 0x4210
movq %rax, %rdi
leaq 0x7153(%rip), %rsi      # 0x2788d
callq 0x4300
movq %rax, %rdi
movq %r12, %rsi
callq 0x4210
movq %rax, %rdi
leaq 0x6d7d(%rip), %rsi      # 0x274d1
callq 0x4300
movq %rax, %rdi
callq 0x4180
xorl %r13d, %r13d
incq 0x10b85(%rip)           # 0x312f0
movq 0x11c5e(%rip), %rdi     # 0x323d0
callq 0xc676
incq %r12
jmp 0x20612
movq 0x11c32(%rip), %rax     # 0x323b8
cmpq %rax, 0x11c33(%rip)     # 0x323c0
je 0x20796
movq %rax, 0x11c2a(%rip)     # 0x323c0
movq 0x11c33(%rip), %rdi     # 0x323d0
testq %rdi, %rdi
je 0x207a8
movq (%rdi), %rax
callq *0x8(%rax)
andq $0x0, 0x11c20(%rip)     # 0x323d0
leaq 0x50(%rsp), %rdi
callq 0x4598
leaq 0xd0(%rsp), %rdi
callq 0x40f0
leaq 0xb0(%rsp), %rdi
callq 0x4598
xorl %eax, %eax
addq $0x2d8, %rsp            # imm = 0x2D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x1f7c4
xorl %edi, %edi
callq 0x4370
movq 0x107d5(%rip), %rdi     # 0x30fd0
callq 0x4180
leaq 0x6f98(%rip), %rsi      # 0x2779f
movq %rax, %rdi
callq 0x4300
movq 0x107ba(%rip), %rdi     # 0x30fd0
callq 0x4180
leaq 0x6f99(%rip), %rsi      # 0x277bb
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
movq %rax, %rdi
callq 0x4180
jmp 0x207ed
movq 0x1078d(%rip), %rdi     # 0x30fd0
callq 0x4180
leaq 0x6f07(%rip), %rsi      # 0x27756
movq %rax, %rdi
callq 0x4300
movq 0x10772(%rip), %rdi     # 0x30fd0
callq 0x4180
leaq 0x6f05(%rip), %rsi      # 0x2776f
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
movq %rax, %rdi
callq 0x4180
jmp 0x207ed
movq 0x10742(%rip), %rdi     # 0x30fd0
callq 0x4180
leaq 0x6f5b(%rip), %rsi      # 0x277f5
movq %rax, %rdi
callq 0x4300
movq 0x10727(%rip), %rdi     # 0x30fd0
callq 0x4180
leaq 0x6f59(%rip), %rsi      # 0x2780e
movq %rax, %rdi
callq 0x4300
leaq 0x10b84(%rip), %rsi     # 0x31448
movq %rax, %rdi
callq 0x42b0
leaq 0x5187(%rip), %rsi      # 0x25a5a
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
movq %rax, %rdi
callq 0x4180
jmp 0x207ed
movq 0x106d9(%rip), %rdi     # 0x30fd0
callq 0x4180
leaq 0x6dfc(%rip), %rsi      # 0x276ff
movq %rax, %rdi
callq 0x4300
movq 0x106be(%rip), %rdi     # 0x30fd0
callq 0x4180
leaq 0x6dfb(%rip), %rsi      # 0x27719
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
movq %rax, %rdi
callq 0x4180
jmp 0x207ed
movq 0x106ae(%rip), %rdi     # 0x30ff0
leaq 0x36d9(%rip), %rsi      # 0x24022
callq 0x4300
leaq 0x6c70(%rip), %rsi      # 0x275c5
movq %rax, %rdi
callq 0x4300
leaq 0x3f13(%rip), %rsi      # 0x24877
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movl $0x105, %esi            # imm = 0x105
callq 0x44f0
leaq 0x36c1(%rip), %rsi      # 0x24041
movq %rax, %rdi
callq 0x4300
leaq 0x6eb7(%rip), %rsi      # 0x27846
movq %rax, %rdi
callq 0x4300
leaq 0x10aaa(%rip), %rsi     # 0x31448
movq %rax, %rdi
callq 0x42b0
leaq 0x50ad(%rip), %rsi      # 0x25a5a
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
jmp 0x207ed
jmp 0x20a1d
jmp 0x20a1d
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
callq 0x4598
jmp 0x209d8
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x4598
jmp 0x209ea
movq %rax, %rbx
movl $0x1018, %esi           # imm = 0x1018
movq %r14, %rdi
jmp 0x20a04
jmp 0x20a1d
movq %rax, %rbx
jmp 0x20a37
movq %rax, %rbx
pushq $0x30
popq %rsi
movq %r13, %rdi
callq 0x4320
jmp 0x20a20
jmp 0x20a1d
jmp 0x20a1d
jmp 0x20a1d
jmp 0x20a1d
jmp 0x20a1d
jmp 0x20a1d
jmp 0x20a1d
jmp 0x20a1d
jmp 0x20a1d
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x4598
leaq 0xd0(%rsp), %rdi
callq 0x40f0
leaq 0xb0(%rsp), %rdi
callq 0x4598
movq %rbx, %rdi
callq 0x4520