// File: /workspace/github_cpp_makefile_star2_O2/saeefahmad[P]MIPS-pipeline-simulator/pipeline.cpp
// Function: main
int main(int argc, char* args[]) {
  int choice;
  if (argc !=2) {
    cout << "ERROR: Wrong number of argument!!!" << endl;
    cout << "USAGE: " << string(args[0]) << " program_num" << endl; 
    exit(-1);
  } else
    choice = atoi(args[1]);
  initialize(choice);
  
  int i = 0;
  AbstractStage* stages[TOTAL_STAGE_TYPE];
  AbstractStage* prevStage = NULL;
  
  for (i = 0; i < TOTAL_STAGE_TYPE; i++) {
	  stages[i] = AbstractStage::createStage((StageType)i, prevStage);
	  prevStage = stages[i];
  }

  // Simulates one cycle at a time until end
  while (continueSimulation && (clockCycle <= TOTALCYCLE)) {
    // - Call the process function of each stage.
    // - You need to determine whether you should call the process
    //   function starting from the WB stage or FETCH stage.

	  stages[4]->process();
	  stages[3]->process();
	  stages[2]->process();
	  stages[1]->process();
	  stages[0]->process();

	  clockCycle++;
  }
  cout << "Name: Saeef Ahmad, ID: gij817" << endl;
  cout << "Fetched ins " << fetchedIns << endl;
  cout << "Finished ins " << finishedIns << endl;
  cout << "Total cycles " << (clockCycle - 1) << endl;
  cout << "Stall cycles " << stallCycle << endl;
  for (i = 1; i < TOTAL_REGISTER_TYPE; i++)
	cout << registerNames[i] << " " << getReg((RegisterType)i) << endl;

  for (i = 0; i < TOTAL_STAGE_TYPE; i++)
    delete stages[i];
  finalize();
  return 0;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x40, %rsp
movq %rsi, %rbx
cmpl $0x2, %edi
jne 0x26d3
movq 0x8(%rbx), %rdi
callq 0x2120
movl %eax, %edi
callq 0x2761
xorl %ebx, %ebx
xorl %eax, %eax
cmpq $0x5, %rbx
je 0x2533
movl %ebx, %edi
movq %rax, %rsi
callq 0x3d6e
movq %rax, 0x10(%rsp,%rbx,8)
incq %rbx
jmp 0x2519
movq 0x30(%rsp), %rbx
movq 0x28(%rsp), %r14
movq 0x20(%rsp), %r15
movq 0x10(%rsp), %r12
movq 0x18(%rsp), %r13
movl 0x6fd2(%rip), %eax      # 0x9524
cmpb $0x1, 0x6fc7(%rip)      # 0x9520
jne 0x259a
cmpl $0x64, %eax
jg 0x259a
movq (%rbx), %rax
movq %rbx, %rdi
callq *(%rax)
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
movq (%r15), %rax
movq %r15, %rdi
callq *(%rax)
movq (%r13), %rax
movq %r13, %rdi
callq *(%rax)
movq (%r12), %rax
movq %r12, %rdi
callq *(%rax)
movl 0x6f94(%rip), %eax      # 0x9524
incl %eax
movl %eax, 0x6f8c(%rip)      # 0x9524
jmp 0x2552
movq 0x6a37(%rip), %rbx      # 0x8fd8
leaq 0x2ac4(%rip), %rsi      # 0x506c
movq %rbx, %rdi
callq 0x20c0
movq %rax, %rdi
callq 0x2060
leaq 0x2acb(%rip), %rsi      # 0x508a
movq %rbx, %rdi
callq 0x20c0
movl 0x6f5f(%rip), %esi      # 0x952c
movq %rax, %rdi
callq 0x2130
movq %rax, %rdi
callq 0x2060
leaq 0x2ab3(%rip), %rsi      # 0x5097
movq %rbx, %rdi
callq 0x20c0
movl 0x6f3e(%rip), %esi      # 0x9530
movq %rax, %rdi
callq 0x2130
movq %rax, %rdi
callq 0x2060
leaq 0x2a9c(%rip), %rsi      # 0x50a5
movq %rbx, %rdi
callq 0x20c0
movl 0x6f0d(%rip), %esi      # 0x9524
decl %esi
movq %rax, %rdi
callq 0x2130
movq %rax, %rdi
callq 0x2060
leaq 0x2a83(%rip), %rsi      # 0x50b3
movq %rbx, %rdi
callq 0x20c0
movl 0x6eea(%rip), %esi      # 0x9528
movq %rax, %rdi
callq 0x2130
movq %rax, %rdi
callq 0x2060
pushq $0x1
popq %r12
leaq 0x6f07(%rip), %r14      # 0x9560
leaq 0x29fd(%rip), %r15      # 0x505d
leaq 0x6a89(%rip), %r13      # 0x90f0
cmpq $0x8, %r12
je 0x26a1
movq %rbx, %rdi
movq %r14, %rsi
callq 0x20b0
movq %rax, %rdi
movq %r15, %rsi
callq 0x20c0
movl (%r13,%r12,4), %esi
movq %rax, %rdi
callq 0x2130
movq %rax, %rdi
callq 0x2060
incq %r12
addq $0x20, %r14
jmp 0x2667
xorl %ebx, %ebx
cmpq $0x5, %rbx
je 0x26be
movq 0x10(%rsp,%rbx,8), %rdi
testq %rdi, %rdi
je 0x26b9
movq (%rdi), %rax
callq *0x10(%rax)
incq %rbx
jmp 0x26a3
callq 0x3a4d
xorl %eax, %eax
addq $0x40, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
movq 0x68fe(%rip), %r14      # 0x8fd8
leaq 0x2953(%rip), %rsi      # 0x5034
movq %r14, %rdi
callq 0x20c0
movq %rax, %rdi
callq 0x2060
leaq 0x295f(%rip), %rsi      # 0x5057
movq %r14, %rdi
callq 0x20c0
movq %rax, %r14
movq (%rbx), %rsi
leaq 0x10(%rsp), %rbx
leaq 0xf(%rsp), %rdx
movq %rbx, %rdi
callq 0x3c5e
movq %r14, %rdi
movq %rbx, %rsi
callq 0x20b0
leaq 0x2935(%rip), %rsi      # 0x505f
movq %rax, %rdi
callq 0x20c0
movq %rax, %rdi
callq 0x2060
leaq 0x10(%rsp), %rdi
callq 0x2050
pushq $-0x1
popq %rdi
callq 0x20f0
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x2050
movq %rbx, %rdi
callq 0x2140