// File: 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
movq %rsp, %rbp
subq $0x1e0, %rsp            # imm = 0x1E0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x188(%rbp)
movq 0x8(%rax), %rax
testb $0x1, 0x1190(%rax)
je 0x1ff30c
jmp 0x1ff8d7
movq -0x188(%rbp), %rcx
movl 0x38(%rcx), %eax
movl 0x3c(%rcx), %ecx
imull %ecx, %eax
cltq
movq %rax, -0x198(%rbp)
movb $0x0, -0x31(%rbp)
leaq -0x32(%rbp), %rdi
movq %rdi, -0x190(%rbp)
callq 0x1fb390
movq -0x198(%rbp), %rsi
movq -0x190(%rbp), %rcx
leaq -0x30(%rbp), %rdi
leaq -0x31(%rbp), %rdx
callq 0x1fb4a0
jmp 0x1ff356
leaq -0x32(%rbp), %rdi
callq 0x1fb3f0
movq -0x188(%rbp), %rax
movq 0x8(%rax), %rax
addq $0x10c0, %rax           # imm = 0x10C0
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdi
callq 0x42b70
movq %rax, -0x60(%rbp)
movq -0x58(%rbp), %rdi
callq 0x417c0
movq %rax, -0x68(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x41790
testb $0x1, %al
jne 0x1ff3ac
jmp 0x1ff525
leaq -0x60(%rbp), %rdi
callq 0x41cf0
movq %rax, %rsi
leaq -0xc8(%rbp), %rdi
callq 0x42ba0
jmp 0x1ff3c6
movq -0x188(%rbp), %rax
leaq -0xc8(%rbp), %rdi
addq $0x10, %rdi
movslq 0x40(%rax), %rsi
callq 0x384f0
movq -0x188(%rbp), %rcx
movl (%rax), %eax
movq 0x8(%rcx), %rcx
movq 0x1098(%rcx), %rcx
cmpl 0x39c(%rcx), %eax
jne 0x1ff3ff
jmp 0x1ff449
leaq 0x623a0(%rip), %rdi     # 0x2617a6
leaq 0x623c7(%rip), %rsi     # 0x2617d4
movl $0x39, %edx
leaq 0x623cb(%rip), %rcx     # 0x2617e4
callq 0xc280
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x32(%rbp), %rdi
callq 0x1fb3f0
jmp 0x1ff8e9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x1ff8e0
movq -0x188(%rbp), %rax
leaq -0xb8(%rbp), %rdi
movq %rdi, -0x1b0(%rbp)
movslq 0x44(%rax), %rsi
callq 0x384f0
movq -0x1b0(%rbp), %rdi
movq %rax, %rcx
movq -0x188(%rbp), %rax
movl (%rcx), %ecx
movl 0x3c(%rax), %edx
imull %edx, %ecx
movl %ecx, -0xcc(%rbp)
movslq 0x48(%rax), %rsi
callq 0x384f0
movl (%rax), %eax
movl %eax, -0xd0(%rbp)
movl -0xcc(%rbp), %eax
movl -0xd0(%rbp), %ecx
addl %ecx, %eax
movslq %eax, %rsi
leaq -0x30(%rbp), %rdi
callq 0x1fec30
movq %rdx, -0x1a8(%rbp)
movq %rax, -0x1a0(%rbp)
jmp 0x1ff4c1
movq -0x1a8(%rbp), %rax
movq -0x1a0(%rbp), %rcx
movq %rcx, -0xe0(%rbp)
movq %rax, -0xd8(%rbp)
leaq -0xe0(%rbp), %rdi
movl $0x1, %esi
callq 0x1faf60
leaq -0xc8(%rbp), %rdi
callq 0x36780
leaq -0x60(%rbp), %rdi
callq 0x42f20
jmp 0x1ff396
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x36780
jmp 0x1ff8e0
movl $0x0, -0xe4(%rbp)
movq -0x188(%rbp), %rcx
movl -0xe4(%rbp), %eax
cmpl 0x38(%rcx), %eax
jge 0x1ff8ce
callq 0xc130
movq -0x188(%rbp), %rcx
cltd
idivl 0x3c(%rcx)
movl %edx, -0xe8(%rbp)
movl $0x0, -0xec(%rbp)
movq -0x188(%rbp), %rcx
movl -0xec(%rbp), %eax
cmpl 0x3c(%rcx), %eax
jge 0x1ff8b8
movq -0x188(%rbp), %rcx
movl -0xe8(%rbp), %eax
movl -0xec(%rbp), %edx
addl %edx, %eax
movl 0x3c(%rcx), %esi
cltd
idivl %esi
movl %edx, -0xf0(%rbp)
movl -0xe4(%rbp), %eax
movl 0x3c(%rcx), %ecx
imull %ecx, %eax
movl -0xf0(%rbp), %ecx
addl %ecx, %eax
movslq %eax, %rsi
leaq -0x30(%rbp), %rdi
callq 0x1fec30
movq %rdx, -0x1c0(%rbp)
movq %rax, -0x1b8(%rbp)
jmp 0x1ff5cc
movq -0x1c0(%rbp), %rax
movq -0x1b8(%rbp), %rcx
movq %rcx, -0x100(%rbp)
movq %rax, -0xf8(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x1faff0
testb $0x1, %al
jne 0x1ff5fa
jmp 0x1ff5ff
jmp 0x1ff8a4
movq -0x188(%rbp), %rax
movb $0x0, -0x101(%rbp)
movq 0x8(%rax), %rax
addq $0x1120, %rax           # imm = 0x1120
movq %rax, -0x110(%rbp)
movq -0x110(%rbp), %rdi
callq 0x42b70
movq %rax, -0x118(%rbp)
movq -0x110(%rbp), %rdi
callq 0x417c0
movq %rax, -0x120(%rbp)
leaq -0x118(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x41790
testb $0x1, %al
jne 0x1ff660
jmp 0x1ff72f
leaq -0x118(%rbp), %rdi
callq 0x41cf0
movq %rax, %rsi
leaq -0x180(%rbp), %rdi
callq 0x42ba0
jmp 0x1ff67d
cmpl $0x2, -0x154(%rbp)
jne 0x1ff712
movq -0x188(%rbp), %rax
leaq -0x180(%rbp), %rdi
addq $0x10, %rdi
movslq 0x40(%rax), %rsi
callq 0x384f0
movq -0x188(%rbp), %rcx
movl (%rax), %eax
movq 0x8(%rcx), %rcx
movq 0x1098(%rcx), %rcx
cmpl 0x39c(%rcx), %eax
jne 0x1ff712
movq -0x188(%rbp), %rax
leaq -0x180(%rbp), %rdi
addq $0x10, %rdi
movslq 0x44(%rax), %rsi
callq 0x384f0
movl (%rax), %eax
cmpl -0xe4(%rbp), %eax
jne 0x1ff712
movq -0x188(%rbp), %rax
leaq -0x180(%rbp), %rdi
addq $0x10, %rdi
movslq 0x48(%rax), %rsi
callq 0x384f0
movl (%rax), %eax
cmpl -0xf0(%rbp), %eax
jne 0x1ff712
movb $0x1, -0x101(%rbp)
leaq -0x180(%rbp), %rdi
callq 0x36780
leaq -0x118(%rbp), %rdi
callq 0x42f20
jmp 0x1ff644
testb $0x1, -0x101(%rbp)
je 0x1ff73d
jmp 0x1ff8a4
movq -0x188(%rbp), %rdi
addq $0x50, %rdi
movslq -0xe4(%rbp), %rsi
callq 0x344d0
movq (%rax), %rdi
movslq -0xf0(%rbp), %rsi
callq 0x384f0
movq -0x188(%rbp), %rcx
movl (%rax), %eax
cmpl 0x8c(%rcx), %eax
jge 0x1ff7a1
movq -0x188(%rbp), %rax
movq 0x8(%rax), %rdi
addq $0x1120, %rdi           # imm = 0x1120
callq 0x409b0
movq -0x188(%rbp), %rcx
movq 0x8(%rcx), %rcx
movl 0x1138(%rcx), %ecx
cmpq %rcx, %rax
jb 0x1ff7a6
jmp 0x1ff8a4
movq -0x188(%rbp), %rdi
movq 0x8(%rdi), %rax
movq %rax, -0x1d0(%rbp)
movl -0xe4(%rbp), %eax
movl %eax, -0x1c8(%rbp)
movl -0xf0(%rbp), %ecx
movl %ecx, -0x1c4(%rbp)
addq $0x68, %rdi
movslq %eax, %rsi
callq 0x2006b0
movq %rax, %rdi
movslq -0xf0(%rbp), %rsi
callq 0x384f0
movq -0x188(%rbp), %rdi
movq -0x1d0(%rbp), %rsi
movl -0x1c8(%rbp), %edx
movl -0x1c4(%rbp), %ecx
movl (%rax), %r8d
callq 0x200490
jmp 0x1ff80f
movq -0x188(%rbp), %rdi
addq $0x50, %rdi
movslq -0xe4(%rbp), %rsi
callq 0x344d0
movq (%rax), %rdi
movslq -0xf0(%rbp), %rsi
callq 0x384f0
movq -0x188(%rbp), %rdi
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
addq $0x68, %rdi
movslq -0xe4(%rbp), %rsi
callq 0x2006b0
movq %rax, %rdi
movslq -0xf0(%rbp), %rsi
callq 0x384f0
movq -0x188(%rbp), %rdi
movl (%rax), %eax
addl $0x1, %eax
cltd
idivl 0x80(%rdi)
movl %edx, -0x1d4(%rbp)
addq $0x68, %rdi
movslq -0xe4(%rbp), %rsi
callq 0x2006b0
movq %rax, %rdi
movslq -0xf0(%rbp), %rsi
callq 0x384f0
movl -0x1d4(%rbp), %edx
movl %edx, (%rax)
jmp 0x1ff8b8
movl -0xec(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xec(%rbp)
jmp 0x1ff565
jmp 0x1ff8ba
movl -0xe4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xe4(%rbp)
jmp 0x1ff52f
leaq -0x30(%rbp), %rdi
callq 0x4c300
addq $0x1e0, %rsp            # imm = 0x1E0
popq %rbp
retq
leaq -0x30(%rbp), %rdi
callq 0x4c300
movq -0x40(%rbp), %rdi
callq 0xc5d0
nopw %cs:(%rax,%rax)