// File: dsesami[P]superscalar-processor-model/fetch.cc
// Function: fetch()
u_int fetch() {
    static u_int stall = 0;
    string line;                    // Current line
    string raw_address;             // PC (hexadecimal string)
    u_ll address;                   // PC (unsigned long long)
    int   op_type,                  // Latency: 0=1 cycle, 1=2 cycles, 2=5 cycles
          dest,                     // Destination register: -1=none
          src_1,                    // Source register 1: -1=none
          src_2;                    // Source register 2: -1=none
    for(u_int i=0; i<WIDTH; i++) {
        // If we are assuming a perfect cache...
        if(!CACHE_SIZE) {
            // Stall if the decode register is full.
            if(DE_register.size() == WIDTH) {
                stall++;
                return CONTINUE;
            }
            // Grab an instruction. If there are no more instructions, then quit.
            getline(infile, line);
            istringstream iss(line);
            if(!(iss >> raw_address >> op_type >> dest >> src_1 >> src_2))
                return QUIT;
        }

        // Otherwise process information and send it to the DE_register.
        // sscanf can read hex of format 0xaaaa, so we go ahead and create this...
        raw_address = "0x" + raw_address;
        sscanf(raw_address.c_str(), "%016lx", &address);

        // Add this instruction to the decode register.
        bundle instruction;
        instruction.address = address;
        instruction.op_type = op_type;
        instruction.dest    = dest;
        instruction.rn_dest = -1;
        instruction.src_1   = src_1;
        instruction.rn_src_1 = -1;
        instruction.src_2   = src_2;
        instruction.rn_src_2 = -1;
        instruction.valid = false;
        instruction.fetch_first = cycles;
        instruction.fetch_time = cycles - instruction.fetch_first+1;
        instruction.decode_first = -1;
        instruction.rename_first = -1;
        instruction.regRead_first = -1;
        instruction.dispatch_first = -1;
        instruction.issue_first = -1;
        instruction.execute_first = -1;
        instruction.writeback_first = -1;
        instruction.retire_first = -1;
        instruction.dyn = dyn_instr_count;
        dyn_instr_count++;
        DE_register.push_back(instruction);
    }
    stall=0;
    return CONTINUE;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2d0, %rsp            # imm = 0x2D0
leaq -0x28(%rbp), %rdi
callq 0x2220
leaq -0x48(%rbp), %rdi
callq 0x2220
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
leaq 0xacb6(%rip), %rcx      # 0x111c4
cmpl (%rcx), %eax
jae 0x67f5
leaq 0xacab(%rip), %rax      # 0x111c8
cmpl $0x0, (%rax)
jne 0x6692
leaq 0xaf23(%rip), %rdi      # 0x11450
callq 0x3700
leaq 0xac8b(%rip), %rcx      # 0x111c4
movl (%rcx), %ecx
cmpq %rcx, %rax
jne 0x6562
movl 0xb09e(%rip), %eax      # 0x115e4
addl $0x1, %eax
movl %eax, 0xb095(%rip)      # 0x115e4
movl $0x1, -0x4(%rbp)
movl $0x1, -0x68(%rbp)
jmp 0x680d
leaq 0xac77(%rip), %rdi      # 0x111e0
leaq -0x28(%rbp), %rsi
callq 0x2040
jmp 0x6574
leaq -0x1f8(%rbp), %rdi
leaq -0x28(%rbp), %rsi
movl $0x8, %edx
callq 0x22b0
jmp 0x658b
leaq -0x1f8(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x2200
movq %rax, -0x298(%rbp)
jmp 0x65a4
movq -0x298(%rbp), %rdi
leaq -0x54(%rbp), %rsi
callq 0x2110
movq %rax, -0x2a0(%rbp)
jmp 0x65bd
movq -0x2a0(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x2110
movq %rax, -0x2a8(%rbp)
jmp 0x65d6
movq -0x2a8(%rbp), %rdi
leaq -0x5c(%rbp), %rsi
callq 0x2110
movq %rax, -0x2b0(%rbp)
jmp 0x65ef
movq -0x2b0(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x2110
movq %rax, -0x2b8(%rbp)
jmp 0x6608
movq -0x2b8(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x20d0
movb %al, -0x2b9(%rbp)
jmp 0x6626
movb -0x2b9(%rbp), %al
testb $0x1, %al
jne 0x6632
jmp 0x6670
movl $0x0, -0x4(%rbp)
movl $0x1, -0x68(%rbp)
jmp 0x6677
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x682b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x20e0
jmp 0x682b
movl $0x0, -0x68(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x20e0
movl -0x68(%rbp), %eax
testl %eax, %eax
jne 0x680d
jmp 0x6690
jmp 0x6692
leaq 0x4c8b(%rip), %rsi      # 0xb324
leaq -0x218(%rbp), %rdi
leaq -0x48(%rbp), %rdx
callq 0x6850
jmp 0x66ab
leaq -0x48(%rbp), %rdi
movq %rdi, -0x2c8(%rbp)
leaq -0x218(%rbp), %rsi
movq %rsi, -0x2d0(%rbp)
callq 0x21f0
movq -0x2d0(%rbp), %rdi
callq 0x2120
movq -0x2c8(%rbp), %rdi
callq 0x20b0
movq %rax, %rdi
leaq 0x4c3c(%rip), %rsi      # 0xb327
xorl %eax, %eax
leaq -0x50(%rbp), %rdx
callq 0x2180
movq -0x50(%rbp), %rax
movq %rax, -0x290(%rbp)
movl -0x54(%rbp), %eax
movl %eax, -0x288(%rbp)
movl -0x58(%rbp), %eax
movl %eax, -0x284(%rbp)
movl $0xffffffff, -0x280(%rbp) # imm = 0xFFFFFFFF
movl -0x5c(%rbp), %eax
movl %eax, -0x27c(%rbp)
movl $0xffffffff, -0x278(%rbp) # imm = 0xFFFFFFFF
movl -0x60(%rbp), %eax
movl %eax, -0x274(%rbp)
movl $0xffffffff, -0x270(%rbp) # imm = 0xFFFFFFFF
movb $0x0, -0x224(%rbp)
leaq 0xaa83(%rip), %rax      # 0x111d4
movl (%rax), %ecx
movl %ecx, -0x26c(%rbp)
movl (%rax), %eax
movl -0x26c(%rbp), %ecx
subl %ecx, %eax
incl %eax
movl %eax, -0x268(%rbp)
movl $0xffffffff, -0x264(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x25c(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x254(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x24c(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x244(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x23c(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x234(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x22c(%rbp) # imm = 0xFFFFFFFF
leaq 0xaa0e(%rip), %rax      # 0x111d0
movl (%rax), %ecx
movl %ecx, -0x220(%rbp)
movl (%rax), %ecx
incl %ecx
movl %ecx, (%rax)
leaq 0xac79(%rip), %rdi      # 0x11450
leaq -0x290(%rbp), %rsi
callq 0x6960
jmp 0x67e5
jmp 0x67e7
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x6504
movl $0x0, 0xade5(%rip)      # 0x115e4
movl $0x1, -0x4(%rbp)
movl $0x1, -0x68(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x2120
leaq -0x28(%rbp), %rdi
callq 0x2120
movl -0x4(%rbp), %eax
addq $0x2d0, %rsp            # imm = 0x2D0
popq %rbp
retq
leaq -0x48(%rbp), %rdi
callq 0x2120
leaq -0x28(%rbp), %rdi
callq 0x2120
movq -0x70(%rbp), %rdi
callq 0x22e0
nopw %cs:(%rax,%rax)