// File: /workspace/github_cpp_makefile_star2_O3/CMU-SAFARI[P]ramulator/src/Controller.h
// Function: ramulator::Controller<ramulator::DDR3>::cmd_issue_autoprecharge(ramulator::DDR3::Command&, std::vector<int, std::allocator<int>> const&)
void cmd_issue_autoprecharge(typename T::Command& cmd,
                                            const vector<int>& addr_vec) {

        // currently, autoprecharge is only used with closed row policy
        if(channel->spec->is_accessing(cmd) && rowpolicy->type == RowPolicy<T>::Type::ClosedAP) {
            // check if it is the last request to the opened row
            Queue* queue = write_mode ? &writeq : &readq;

            auto begin = addr_vec.begin();
            vector<int> rowgroup(begin, begin + int(T::Level::Row) + 1);

			int num_row_hits = 0;

            for (auto itr = queue->q.begin(); itr != queue->q.end(); ++itr) {
                if (is_row_hit(itr)) { 
                    auto begin2 = itr->addr_vec.begin();
                    vector<int> rowgroup2(begin2, begin2 + int(T::Level::Row) + 1);
                    if(rowgroup == rowgroup2)
                        num_row_hits++;
                }
            }

            if(num_row_hits == 0) {
                Queue* queue = &actq;
                for (auto itr = queue->q.begin(); itr != queue->q.end(); ++itr) {
                    if (is_row_hit(itr)) {
                        auto begin2 = itr->addr_vec.begin();
                        vector<int> rowgroup2(begin2, begin2 + int(T::Level::Row) + 1);
                        if(rowgroup == rowgroup2)
                            num_row_hits++;
                    }
                }
            }

            assert(num_row_hits > 0); // The current request should be a hit, 
                                      // so there should be at least one request 
                                      // that hits in the current open row
            if(num_row_hits == 1) {
                if(cmd == T::Command::RD)
                    cmd = T::Command::RDA;
                else if (cmd == T::Command::WR)
                    cmd = T::Command::WRA;
                else
                    assert(false && "Unimplemented command type.");
            }
        }

    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movl (%rsi), %eax
addl $-0x3, %eax
cmpl $0x3, %eax
ja 0x2a1a5
movq %rdi, %r14
movq 0x10a8(%rdi), %rax
cmpl $0x1, 0x8(%rax)
jne 0x2a1a5
movq %rsi, 0x40(%rsp)
movzbl 0x1190(%r14), %eax
shll $0x5, %eax
leaq (%r14,%rax), %rbx
addq $0x10c0, %rbx           # imm = 0x10C0
movq (%rdx), %rsi
leaq 0x10(%rsi), %rdx
leaq 0x28(%rsp), %rdi
leaq 0x10(%rsp), %rcx
callq 0x24766
movq (%rbx), %r15
cmpq %rbx, %r15
je 0x2a0b5
xorl %ebp, %ebp
leaq 0xf(%rsp), %r12
movq 0x1098(%r14), %rdi
movq 0x390(%rdi), %rax
movslq 0x3c(%r15), %rcx
movl 0x1c4(%rax,%rcx,4), %esi
movq 0x20(%r15), %rdx
callq 0x249f6
testb %al, %al
je 0x2a0a1
movq 0x20(%r15), %rsi
leaq 0x10(%rsi), %rdx
leaq 0x10(%rsp), %rdi
movq %r12, %rcx
callq 0x29cd2
movq 0x28(%rsp), %rdi
movq 0x30(%rsp), %rax
movq %rax, %rdx
subq %rdi, %rdx
movq 0x10(%rsp), %r13
movq 0x18(%rsp), %rcx
subq %r13, %rcx
cmpq %rcx, %rdx
jne 0x2a08c
cmpq %rdi, %rax
je 0x2a08a
movq %r13, %rsi
callq 0xb300
cmpl $0x1, %eax
adcl $0x0, %ebp
jmp 0x2a08c
incl %ebp
testq %r13, %r13
je 0x2a0a1
movq 0x20(%rsp), %rsi
subq %r13, %rsi
movq %r13, %rdi
callq 0xb2f0
movq (%r15), %r15
cmpq %rbx, %r15
jne 0x2a018
testl %ebp, %ebp
jne 0x2a168
leaq 0x1100(%r14), %rbx
movq 0x1100(%r14), %r15
cmpq %rbx, %r15
je 0x2a1b4
xorl %ebp, %ebp
leaq 0xf(%rsp), %r12
movq 0x1098(%r14), %rdi
movq 0x390(%rdi), %rax
movslq 0x3c(%r15), %rcx
movl 0x1c4(%rax,%rcx,4), %esi
movq 0x20(%r15), %rdx
callq 0x249f6
testb %al, %al
je 0x2a15c
movq 0x20(%r15), %rsi
leaq 0x10(%rsi), %rdx
leaq 0x10(%rsp), %rdi
movq %r12, %rcx
callq 0x29cd2
movq 0x28(%rsp), %rdi
movq 0x30(%rsp), %rax
movq %rax, %rdx
subq %rdi, %rdx
movq 0x10(%rsp), %r13
movq 0x18(%rsp), %rcx
subq %r13, %rcx
cmpq %rcx, %rdx
jne 0x2a147
cmpq %rdi, %rax
je 0x2a145
movq %r13, %rsi
callq 0xb300
cmpl $0x1, %eax
adcl $0x0, %ebp
jmp 0x2a147
incl %ebp
testq %r13, %r13
je 0x2a15c
movq 0x20(%rsp), %rsi
subq %r13, %rsi
movq %r13, %rdi
callq 0xb2f0
movq (%r15), %r15
cmpq %rbx, %r15
jne 0x2a0d3
testl %ebp, %ebp
jle 0x2a1b4
cmpl $0x1, %ebp
jne 0x2a18e
movq 0x40(%rsp), %rdx
movl (%rdx), %ecx
movl $0x5, %eax
cmpl $0x3, %ecx
je 0x2a18c
cmpl $0x4, %ecx
jne 0x2a1d3
movl $0x6, %eax
movl %eax, (%rdx)
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
je 0x2a1a5
movq 0x38(%rsp), %rsi
subq %rdi, %rsi
callq 0xb2f0
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1219ad(%rip), %rdi    # 0x14bb68
leaq 0x121909(%rip), %rsi    # 0x14bacb
leaq 0x1219b0(%rip), %rcx    # 0x14bb79
movl $0x247, %edx            # imm = 0x247
callq 0xb200
leaq 0x121a26(%rip), %rdi    # 0x14bc00
leaq 0x1218ea(%rip), %rsi    # 0x14bacb
leaq 0x121991(%rip), %rcx    # 0x14bb79
movl $0x250, %edx            # imm = 0x250
callq 0xb200
jmp 0x2a1f8
jmp 0x2a1f8
jmp 0x2a1f8
movq %rax, %rbx
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
je 0x2a212
movq 0x38(%rsp), %rsi
subq %rdi, %rsi
callq 0xb2f0
movq %rbx, %rdi
callq 0xb510