// File: /workspace/github_cpp_makefile_star2_O2/CMU-SAFARI[P]ramulator/src/Refresh.cpp
// Function: ramulator::Refresh<ramulator::DSARP>::early_inject_refresh()
void Refresh<DSARP>::early_inject_refresh() {
  // Only enabled during reads
  if (ctrl->write_mode)
    return;

  // OoO bank-level refresh
  vector<bool> is_bank_occupied(max_rank_count * max_bank_count, false);
  Controller<DSARP>::Queue& rdq = ctrl->readq;

  // Figure out which banks are idle in order to refresh one of them
  for (auto req: rdq.q)
  {
    assert(req.addr_vec[level_chan] == ctrl->channel->id);
    int ridx = req.addr_vec[level_rank] * max_bank_count;
    int bidx = req.addr_vec[level_bank];
    is_bank_occupied[ridx+bidx] = true;
  }

  // Try to pick an idle bank to refresh per rank
  for (int r = 0; r < max_rank_count; r++) {
    // Randomly pick a bank to examine
    int bidx_start = rand() % max_bank_count;

    for (int b = 0; b < max_bank_count; b++)
    {
      int bidx = (bidx_start + b) % max_bank_count;
      // Idle cycle only
      if (is_bank_occupied[(r * max_bank_count) + bidx])
        continue;

      // Pending refresh
      bool pending_ref = false;
      for (Request req : ctrl->otherq.q)
        if (req.type == Request::Type::REFRESH
            && req.addr_vec[level_chan] == ctrl->channel->id
            && req.addr_vec[level_rank] == r && req.addr_vec[level_bank] == bidx)
          pending_ref = true;
      if (pending_ref)
        continue;

      // Only pull in refreshes when we are almost running out of credits
      if ((*(bank_refresh_backlog[r]))[bidx] >= backlog_early_pull_threshold ||
          ctrl->otherq.q.size() >= ctrl->otherq.max)
        continue;

      // Refresh now
      refresh_target(ctrl, r, bidx, subarray_ref_counters[r][bidx]);
      // One credit for delaying a future ref
      (*(bank_refresh_backlog[r]))[bidx]++;
      subarray_ref_counters[r][bidx] = (subarray_ref_counters[r][bidx]+1) % max_sa_count;
      break;
    }
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq 0x8(%rdi), %rax
cmpb $0x0, 0x1190(%rax)
jne 0xbcaf1
movq %rdi, %rbx
movslq 0x38(%rdi), %rax
movslq 0x3c(%rdi), %rsi
imulq %rax, %rsi
leaq 0x48(%rsp), %r14
movb $0x0, (%r14)
leaq 0x20(%rsp), %r15
leaq 0xf(%rsp), %rcx
movq %r15, %rdi
movq %r14, %rdx
callq 0xbbc12
movl $0x10c0, %r12d          # imm = 0x10C0
addq 0x8(%rbx), %r12
movq %r12, %r13
movq (%r13), %r13
cmpq %r12, %r13
je 0xbc96c
leaq 0x10(%r13), %rsi
movq %r14, %rdi
callq 0x2000a
movslq 0x40(%rbx), %rcx
movq 0x58(%rsp), %rax
movl (%rax,%rcx,4), %ecx
movq 0x8(%rbx), %rdx
movq 0x1098(%rdx), %rdx
cmpl 0x39c(%rdx), %ecx
jne 0xbcb03
movslq 0x44(%rbx), %rcx
movslq (%rax,%rcx,4), %rcx
movslq 0x3c(%rbx), %rdx
imulq %rcx, %rdx
movslq 0x48(%rbx), %rcx
movslq (%rax,%rcx,4), %rsi
addq %rdx, %rsi
movq %r15, %rdi
callq 0xbc682
orq %rdx, (%rax)
movq %r14, %rdi
callq 0x1cc14
jmp 0xbc904
xorl %r13d, %r13d
leaq 0x20(%rsp), %rbp
leaq 0x48(%rsp), %r12
movslq 0x38(%rbx), %rax
cmpq %rax, %r13
jge 0xbcae7
callq 0xb0f0
movl 0x3c(%rbx), %ecx
cltd
idivl %ecx
movl %edx, %r15d
xorl %r14d, %r14d
movq %r15, 0x10(%rsp)
cmpl %ecx, %r14d
jge 0xbcadf
leal (%r14,%r15), %eax
cltd
idivl %ecx
imull %r13d, %ecx
movl %edx, 0x8(%rsp)
addl %edx, %ecx
movslq %ecx, %rsi
movq %rbp, %rdi
callq 0xbc682
movq %r14, 0x18(%rsp)
testq %rdx, (%rax)
jne 0xbca88
movq %r13, %rbp
movq 0x8(%rbx), %r15
movl $0x1120, %eax           # imm = 0x1120
addq %rax, %r15
xorl %r14d, %r14d
movq %r15, %r13
movq (%r13), %r13
cmpq %r15, %r13
je 0xbca46
leaq 0x10(%r13), %rsi
movq %r12, %rdi
callq 0x2000a
cmpl $0x2, 0x74(%rsp)
jne 0xbca3c
movslq 0x40(%rbx), %rcx
movq 0x58(%rsp), %rax
movl (%rax,%rcx,4), %ecx
movq 0x8(%rbx), %rdx
movq 0x1098(%rdx), %rdx
cmpl 0x39c(%rdx), %ecx
jne 0xbca3c
movslq 0x44(%rbx), %rcx
movl (%rax,%rcx,4), %ecx
cmpq %rcx, %rbp
jne 0xbca3c
movslq 0x48(%rbx), %rcx
movl 0x8(%rsp), %edx
cmpl %edx, (%rax,%rcx,4)
sete %al
orb %al, %r14b
movq %r12, %rdi
callq 0x1cc14
jmp 0xbc9e4
testb $0x1, %r14b
movq %rbp, %r13
leaq 0x20(%rsp), %rbp
movq 0x10(%rsp), %r15
jne 0xbca88
movq 0x50(%rbx), %rax
movq (%rax,%r13,8), %rax
movslq 0x8(%rsp), %r14
movq (%rax), %rax
movl (%rax,%r14,4), %eax
cmpl 0x8c(%rbx), %eax
jge 0xbca88
movq 0x8(%rbx), %rsi
movl 0x1138(%rsi), %eax
cmpq %rax, 0x1130(%rsi)
jb 0xbca98
movq 0x18(%rsp), %r14
incl %r14d
movl 0x3c(%rbx), %ecx
jmp 0xbc99c
movq 0x68(%rbx), %rax
imulq $0x18, %r13, %r15
movq (%rax,%r15), %rax
movl (%rax,%r14,4), %r8d
movq %rbx, %rdi
movl %r13d, %edx
movl 0x8(%rsp), %ecx
callq 0xbd00c
movq 0x50(%rbx), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %rax
incl (%rax,%r14,4)
movq 0x68(%rbx), %rax
movq (%rax,%r15), %rcx
movl (%rcx,%r14,4), %eax
incl %eax
cltd
idivl 0x80(%rbx)
movl %edx, (%rcx,%r14,4)
incq %r13
jmp 0xbc979
leaq 0x20(%rsp), %rdi
callq 0x2264e
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x25786(%rip), %rdi     # 0xe2290
leaq 0x257ad(%rip), %rsi     # 0xe22be
leaq 0x257b6(%rip), %rcx     # 0xe22ce
pushq $0x39
popq %rdx
callq 0xb210
jmp 0xbcb35
jmp 0xbcb35
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
callq 0x1cc14
jmp 0xbcb38
jmp 0xbcb35
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x2264e
movq %rbx, %rdi
callq 0xb4d0