// File: /workspace/github_cpp_makefile_star2_O3/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 $0xb8, %rsp
movq 0x8(%rdi), %rax
cmpb $0x0, 0x1190(%rax)
jne 0x12fd09
movq %rdi, %rbx
movslq 0x38(%rdi), %rax
movslq 0x3c(%rdi), %rsi
imulq %rax, %rsi
leaq 0x30(%rsp), %rdx
movb $0x0, (%rdx)
leaq 0x90(%rsp), %rdi
leaq 0xf(%rsp), %rcx
callq 0x12eec4
movq 0x8(%rbx), %r12
movq 0x10c0(%r12), %r13
addq $0x10c0, %r12           # imm = 0x10C0
cmpq %r12, %r13
je 0x12faa0
leaq 0x40(%rsp), %r14
leaq 0x70(%rsp), %r15
movabsq $-0x8000000000000000, %rax # imm = 0x8000000000000000
leaq 0x3f(%rax), %rbp
movups 0x10(%r13), %xmm0
movaps %xmm0, 0x30(%rsp)
leaq 0x20(%r13), %rsi
movq %r14, %rdi
callq 0x24b42
movq 0x48(%r13), %rax
movq %rax, 0x28(%r14)
movups 0x38(%r13), %xmm0
movups %xmm0, 0x18(%r14)
leaq 0x50(%r13), %rsi
movq %r15, %rdi
callq 0x29968
movslq 0x40(%rbx), %rax
movq 0x40(%rsp), %rdi
movl (%rdi,%rax,4), %eax
movq 0x8(%rbx), %rcx
movq 0x1098(%rcx), %rcx
cmpl 0x39c(%rcx), %eax
jne 0x12fd1b
movslq 0x44(%rbx), %rax
movslq (%rdi,%rax,4), %rax
movslq 0x3c(%rbx), %rdx
imulq %rax, %rdx
movslq 0x48(%rbx), %rax
movslq (%rdi,%rax,4), %rcx
addq %rdx, %rcx
leal 0x3f(%rcx), %eax
testl %ecx, %ecx
cmovnsl %ecx, %eax
sarl $0x6, %eax
cltq
shlq $0x3, %rax
addq 0x90(%rsp), %rax
movq %rcx, %rdx
andq %rbp, %rdx
xorl %esi, %esi
movabsq $-0x8000000000000000, %r8 # imm = 0x8000000000000000
cmpq %r8, %rdx
setbe %sil
movl $0x1, %edx
shlq %cl, %rdx
orq %rdx, -0x8(%rax,%rsi,8)
movq 0x80(%rsp), %rax
testq %rax, %rax
je 0x12fa86
movq %r15, %rdi
movq %r15, %rsi
movl $0x3, %edx
callq *%rax
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x12fa93
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0xb2f0
movq (%r13), %r13
cmpq %r12, %r13
jne 0x12f9b1
cmpl $0x0, 0x38(%rbx)
movabsq $-0x8000000000000000, %rax # imm = 0x8000000000000000
jle 0x12fcec
leaq 0x40(%rsp), %r14
leaq 0x70(%rsp), %r15
xorl %r12d, %r12d
addq $0x3f, %rax
movq %rax, 0x20(%rsp)
callq 0xb0e0
movabsq $-0x8000000000000000, %rdi # imm = 0x8000000000000000
movl 0x3c(%rbx), %ecx
cltd
idivl %ecx
movq %rdx, 0x28(%rsp)
testl %ecx, %ecx
jle 0x12fcdc
xorl %r13d, %r13d
movq %r12, 0x10(%rsp)
movq 0x28(%rsp), %rax
addl %r13d, %eax
cltd
idivl %ecx
imull %r12d, %ecx
leal (%rdx,%rcx), %eax
cltq
movq %rdx, 0x18(%rsp)
addl %edx, %ecx
addl $0x3f, %ecx
testl %eax, %eax
cmovnsl %eax, %ecx
sarl $0x6, %ecx
movslq %ecx, %rcx
shlq $0x3, %rcx
addq 0x90(%rsp), %rcx
movq %rax, %rdx
andq 0x20(%rsp), %rdx
xorl %esi, %esi
cmpq %rdi, %rdx
setbe %sil
movq -0x8(%rcx,%rsi,8), %rcx
btq %rax, %rcx
jae 0x12fb5a
incl %r13d
movl 0x3c(%rbx), %ecx
cmpl %ecx, %r13d
movq 0x10(%rsp), %r12
jl 0x12faf4
jmp 0x12fcdc
movq 0x8(%rbx), %r12
movq 0x1120(%r12), %rbp
addq $0x1120, %r12           # imm = 0x1120
cmpq %r12, %rbp
je 0x12fc50
movl $0x0, 0x8(%rsp)
movups 0x10(%rbp), %xmm0
movaps %xmm0, 0x30(%rsp)
leaq 0x20(%rbp), %rsi
movq %r14, %rdi
callq 0x24b42
movq 0x48(%rbp), %rax
movq %rax, 0x28(%r14)
movups 0x38(%rbp), %xmm0
movups %xmm0, 0x18(%r14)
leaq 0x50(%rbp), %rsi
movq %r15, %rdi
callq 0x29968
cmpl $0x2, 0x5c(%rsp)
jne 0x12fbfd
movslq 0x40(%rbx), %rcx
movq 0x40(%rsp), %rax
movl (%rax,%rcx,4), %ecx
movq 0x8(%rbx), %rdx
movq 0x1098(%rdx), %rdx
cmpl 0x39c(%rdx), %ecx
jne 0x12fbfd
movslq 0x44(%rbx), %rcx
movl (%rax,%rcx,4), %ecx
cmpq %rcx, 0x10(%rsp)
jne 0x12fbfd
movslq 0x48(%rbx), %rcx
movq 0x18(%rsp), %rdx
cmpl %edx, (%rax,%rcx,4)
sete %al
movl 0x8(%rsp), %ecx
orb %al, %cl
movl %ecx, 0x8(%rsp)
movq 0x80(%rsp), %rax
testq %rax, %rax
je 0x12fc17
movq %r15, %rdi
movq %r15, %rsi
movl $0x3, %edx
callq *%rax
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x12fc2e
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0xb2f0
movq (%rbp), %rbp
cmpq %r12, %rbp
jne 0x12fb7e
testb $0x1, 0x8(%rsp)
movabsq $-0x8000000000000000, %rdi # imm = 0x8000000000000000
jne 0x12fb45
movq 0x50(%rbx), %rax
movq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movslq 0x18(%rsp), %rbp
movq (%rax), %rax
movl (%rax,%rbp,4), %eax
cmpl 0x8c(%rbx), %eax
jge 0x12fb45
movq 0x8(%rbx), %rsi
movl 0x1138(%rsi), %eax
cmpq %rax, 0x1130(%rsi)
jae 0x12fb45
movq 0x68(%rbx), %rax
movq 0x10(%rsp), %r13
leaq (,%r13,2), %r12
addq %r13, %r12
movq (%rax,%r12,8), %rax
movl (%rax,%rbp,4), %r8d
movq %rbx, %rdi
movl %r13d, %edx
movl %ebp, %ecx
callq 0x1304c2
movq 0x50(%rbx), %rax
movq (%rax,%r13,8), %rax
movq (%rax), %rax
incl (%rax,%rbp,4)
movq 0x68(%rbx), %rax
movq (%rax,%r12,8), %rcx
movl (%rcx,%rbp,4), %eax
incl %eax
cltd
idivl 0x80(%rbx)
movl %edx, (%rcx,%rbp,4)
movq %r13, %r12
incq %r12
movslq 0x38(%rbx), %rax
cmpq %rax, %r12
jl 0x12faca
movq 0x90(%rsp), %rdi
testq %rdi, %rdi
je 0x12fd09
movq 0xb0(%rsp), %rsi
subq %rdi, %rsi
callq 0xb2f0
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2b5ae(%rip), %rdi     # 0x15b2d0
leaq 0x2b5d5(%rip), %rsi     # 0x15b2fe
leaq 0x2b5de(%rip), %rcx     # 0x15b30e
movl $0x39, %edx
callq 0xb200
jmp 0x12fd4a
jmp 0x12fd42
jmp 0x12fd4a
jmp 0x12fd4f
movq %rax, %rdi
callq 0x171a3
movq %rax, %rbx
jmp 0x12fd69
movq %rax, %rbx
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x12fd69
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0xb2f0
movq 0x90(%rsp), %rdi
testq %rdi, %rdi
je 0x12fd86
movq 0xb0(%rsp), %rsi
subq %rdi, %rsi
callq 0xb2f0
movq %rbx, %rdi
callq 0xb510