// File: CMU-SAFARI[P]SMLA/src/Main.cpp
// Function: void run_cputrace<ramulator::WideIO>(ramulator::Config const&, ramulator::Memory<ramulator::WideIO, ramulator::Controller>&, std::vector<char const*, std::allocator<char const*>> const&)
void run_cputrace(const Config& configs, Memory<T, Controller>& memory, const std::vector<const char *>& files)
{
    int cpu_tick = configs.get_cpu_tick();
    int mem_tick = configs.get_mem_tick();
    auto send = bind(&Memory<T, Controller>::send, &memory, placeholders::_1);
    Processor proc(configs, files, send, memory);
    for (long i = 0; ; i++) {
        proc.tick();
        Stats::curTick++; // processor clock, global, for Statistics
        if (i % cpu_tick == (cpu_tick - 1))
            for (int j = 0; j < mem_tick; j++)
                memory.tick();
      if (configs.calc_weighted_speedup()) {
        if (proc.has_reached_limit()) {
          break;
        }
      } else {
        if (configs.is_early_exit()) {
          if (proc.finished())
              break;
        } else {
          if (proc.finished() && (memory.pending_requests() == 0))
              break;
        }
      }
    }
    // This a workaround for statistics set only initially lost in the end
    memory.finish();
    Stats::statlist.printall();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x8a0, %rsp            # imm = 0x8A0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rdi
callq 0x31850
movl %eax, -0x1c(%rbp)
movq -0x8(%rbp), %rdi
callq 0x31870
movl %eax, -0x20(%rbp)
movq $0x0, -0x40(%rbp)
movq $0x21, -0x48(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
movq 0xd082a(%rip), %rcx     # 0xe2fc8
leaq -0x38(%rbp), %rdi
movq %rdi, -0x880(%rbp)
leaq -0x48(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x31890
movq -0x8(%rbp), %rax
movq %rax, -0x888(%rbp)
movq -0x18(%rbp), %rsi
leaq -0x838(%rbp), %rdi
callq 0x318d0
movq -0x880(%rbp), %rsi
leaq -0x858(%rbp), %rdi
callq 0x319c0
jmp 0x127e6
movq -0x888(%rbp), %rsi
movq -0x10(%rbp), %r8
leaq -0x820(%rbp), %rdi
leaq -0x838(%rbp), %rdx
leaq -0x858(%rbp), %rcx
callq 0x6ba10
jmp 0x1280d
leaq -0x858(%rbp), %rdi
callq 0x31a60
leaq -0x838(%rbp), %rdi
callq 0x9a70
movq $0x0, -0x870(%rbp)
leaq -0x820(%rbp), %rdi
callq 0x6c5b0
jmp 0x1283e
leaq 0xd0e4b(%rip), %rax     # 0xe3690
movq (%rax), %rcx
addq $0x1, %rcx
leaq 0xd0e3d(%rip), %rax     # 0xe3690
movq %rcx, (%rax)
movq -0x870(%rbp), %rax
movslq -0x1c(%rbp), %rcx
cqto
idivq %rcx
movl -0x1c(%rbp), %eax
subl $0x1, %eax
cltq
cmpq %rax, %rdx
jne 0x1291a
movl $0x0, -0x874(%rbp)
movl -0x874(%rbp), %eax
cmpl -0x20(%rbp), %eax
jge 0x12918
movq -0x10(%rbp), %rdi
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
jmp 0x1289f
jmp 0x128a1
movl -0x874(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x874(%rbp)
jmp 0x12881
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x860(%rbp)
movl %eax, -0x864(%rbp)
jmp 0x128e4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x860(%rbp)
movl %eax, -0x864(%rbp)
leaq -0x858(%rbp), %rdi
callq 0x31a60
leaq -0x838(%rbp), %rdi
callq 0x9a70
jmp 0x12a33
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x860(%rbp)
movl %eax, -0x864(%rbp)
leaq -0x820(%rbp), %rdi
callq 0x31d80
jmp 0x12a33
jmp 0x1291a
movq -0x8(%rbp), %rdi
callq 0x31a80
movb %al, -0x889(%rbp)
jmp 0x1292b
movb -0x889(%rbp), %al
testb $0x1, %al
jne 0x12937
jmp 0x12961
leaq -0x820(%rbp), %rdi
callq 0x6d160
movb %al, -0x88a(%rbp)
jmp 0x1294b
movb -0x88a(%rbp), %al
testb $0x1, %al
jne 0x12957
jmp 0x1295c
jmp 0x12a01
jmp 0x129e8
movq -0x8(%rbp), %rdi
callq 0x31aa0
movb %al, -0x88b(%rbp)
jmp 0x12972
movb -0x88b(%rbp), %al
testb $0x1, %al
jne 0x1297e
jmp 0x129a2
leaq -0x820(%rbp), %rdi
callq 0x6cef0
movb %al, -0x88c(%rbp)
jmp 0x12992
movb -0x88c(%rbp), %al
testb $0x1, %al
jne 0x1299e
jmp 0x129a0
jmp 0x12a01
jmp 0x129e6
leaq -0x820(%rbp), %rdi
callq 0x6cef0
movb %al, -0x88d(%rbp)
jmp 0x129b6
movb -0x88d(%rbp), %al
testb $0x1, %al
jne 0x129c2
jmp 0x129e4
movq -0x10(%rbp), %rdi
movq (%rdi), %rax
movq 0x28(%rax), %rax
callq *%rax
movl %eax, -0x894(%rbp)
jmp 0x129d7
movl -0x894(%rbp), %eax
cmpl $0x0, %eax
jne 0x129e4
jmp 0x12a01
jmp 0x129e6
jmp 0x129e8
jmp 0x129ea
movq -0x870(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x870(%rbp)
jmp 0x12830
movq -0x10(%rbp), %rdi
movq (%rdi), %rax
movq 0x30(%rax), %rax
callq *%rax
jmp 0x12a10
leaq 0xd0a61(%rip), %rdi     # 0xe3478
callq 0x31c80
jmp 0x12a1e
leaq -0x820(%rbp), %rdi
callq 0x31d80
addq $0x8a0, %rsp            # imm = 0x8A0
popq %rbp
retq
movq -0x860(%rbp), %rdi
callq 0x65b0
nop