// File: CMU-SAFARI[P]ramulator/src/Refresh.cpp
// Function: ramulator::Refresh<ramulator::DSARP>::inject_refresh(bool)
void Refresh<DSARP>::inject_refresh(bool b_ref_rank) {
  // Rank-level refresh
  if (b_ref_rank)
    for (auto rank : ctrl->channel->children)
      refresh_target(ctrl, rank->id, -1, -1);
  // Bank-level refresh. Simultaneously issue to all ranks (better performance than staggered refreshes).
  else {
    for (auto rank : ctrl->channel->children) {
      int rid = rank->id;
      int bid = bank_ref_counters[rid];

      // Behind refresh schedule by 1 ref
      (*(bank_refresh_backlog[rid]))[bid]--;

      // Next time, refresh the next bank in the same bank
      bank_ref_counters[rid] = (bank_ref_counters[rid] + 1) % max_bank_count;

      // Check to see if we can skip a refresh
      if (ctrl->channel->spec->type == DSARP::Type::DARP ||
        ctrl->channel->spec->type == DSARP::Type::DSARP) {

        bool ref_now = false;
        // 1. Any pending refrehes?
        bool pending_ref = false;
        for (Request req : ctrl->otherq.q) {
          if (req.type == Request::Type::REFRESH) {
            pending_ref = true;
            break;
          }
        }

        // 2. Track readq
        if (!pending_ref && ctrl->readq.size() == 0)
          ref_now = true;

        // 3. Track log status. If we are too behind the schedule, then we need to refresh now.
        if ((*(bank_refresh_backlog[rid]))[bid] <= backlog_min)
          ref_now = true;

        // Otherwise skip refresh
        if (!ref_now)
          continue;
      }

      refresh_target(ctrl, rid, bid, subarray_ref_counters[rid][bid]);
      // Get 1 ref credit
      (*(bank_refresh_backlog[rid]))[bid]++;
      // Next time, refresh the next sa in the same bank
      subarray_ref_counters[rid][bid] = (subarray_ref_counters[rid][bid]+1) % max_sa_count;
    }
  }
  refreshed = clk;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movb %sil, %al
movq %rdi, -0x8(%rbp)
andb $0x1, %al
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xe8(%rbp)
testb $0x1, -0x9(%rbp)
je 0x1ff9b8
movq -0xe8(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x1098(%rax), %rax
addq $0x3b0, %rax            # imm = 0x3B0
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
callq 0x137cb0
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
callq 0x137b40
movq %rax, -0x28(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x138530
testb $0x1, %al
jne 0x1ff975
jmp 0x1ff9b3
leaq -0x20(%rbp), %rdi
callq 0x138570
movq -0xe8(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movq 0x8(%rdi), %rsi
movq -0x30(%rbp), %rax
movl 0x39c(%rax), %edx
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
movl %r8d, %ecx
callq 0x200490
leaq -0x20(%rbp), %rdi
callq 0x138590
jmp 0x1ff962
jmp 0x1ffce7
movq -0xe8(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x1098(%rax), %rax
addq $0x3b0, %rax            # imm = 0x3B0
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
callq 0x137cb0
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rdi
callq 0x137b40
movq %rax, -0x48(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x138530
testb $0x1, %al
jne 0x1ffa04
jmp 0x1ffce5
leaq -0x40(%rbp), %rdi
callq 0x138570
movq -0xe8(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movl 0x39c(%rax), %eax
movl %eax, -0x54(%rbp)
addq $0x20, %rdi
movslq -0x54(%rbp), %rsi
callq 0x384f0
movq -0xe8(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x58(%rbp)
addq $0x50, %rdi
movslq -0x54(%rbp), %rsi
callq 0x344d0
movq (%rax), %rdi
movslq -0x58(%rbp), %rsi
callq 0x384f0
movq -0xe8(%rbp), %rdi
movl (%rax), %ecx
addl $-0x1, %ecx
movl %ecx, (%rax)
addq $0x20, %rdi
movslq -0x54(%rbp), %rsi
callq 0x384f0
movq -0xe8(%rbp), %rdi
movl (%rax), %eax
addl $0x1, %eax
cltd
idivl 0x3c(%rdi)
movl %edx, -0xec(%rbp)
addq $0x20, %rdi
movslq -0x54(%rbp), %rsi
callq 0x384f0
movl -0xec(%rbp), %edx
movq %rax, %rcx
movq -0xe8(%rbp), %rax
movl %edx, (%rcx)
movq 0x8(%rax), %rax
movq 0x1098(%rax), %rax
movq 0x390(%rax), %rax
cmpl $0x2, (%rax)
je 0x1ffae3
movq -0xe8(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x1098(%rax), %rax
movq 0x390(%rax), %rax
cmpl $0x4, (%rax)
jne 0x1ffbf7
movq -0xe8(%rbp), %rax
movb $0x0, -0x59(%rbp)
movb $0x0, -0x5a(%rbp)
movq 0x8(%rax), %rax
addq $0x1120, %rax           # imm = 0x1120
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rdi
callq 0x42b70
movq %rax, -0x70(%rbp)
movq -0x68(%rbp), %rdi
callq 0x417c0
movq %rax, -0x78(%rbp)
leaq -0x70(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x41790
testb $0x1, %al
jne 0x1ffb2d
jmp 0x1ffb8f
leaq -0x70(%rbp), %rdi
callq 0x41cf0
movq %rax, %rsi
leaq -0xd8(%rbp), %rdi
callq 0x42ba0
cmpl $0x2, -0xac(%rbp)
jne 0x1ffb5e
movb $0x1, -0x5a(%rbp)
movl $0x6, -0xdc(%rbp)
jmp 0x1ffb68
movl $0x0, -0xdc(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x36780
movl -0xdc(%rbp), %eax
testl %eax, %eax
je 0x1ffb82
jmp 0x1ffb80
jmp 0x1ffb8f
jmp 0x1ffb84
leaq -0x70(%rbp), %rdi
callq 0x42f20
jmp 0x1ffb1a
testb $0x1, -0x5a(%rbp)
jne 0x1ffbb5
movq -0xe8(%rbp), %rax
movq 0x8(%rax), %rdi
addq $0x10c0, %rdi           # imm = 0x10C0
callq 0x13fb00
cmpl $0x0, %eax
jne 0x1ffbb5
movb $0x1, -0x59(%rbp)
movq -0xe8(%rbp), %rdi
addq $0x50, %rdi
movslq -0x54(%rbp), %rsi
callq 0x344d0
movq (%rax), %rdi
movslq -0x58(%rbp), %rsi
callq 0x384f0
movq -0xe8(%rbp), %rcx
movl (%rax), %eax
cmpl 0x88(%rcx), %eax
jg 0x1ffbea
movb $0x1, -0x59(%rbp)
testb $0x1, -0x59(%rbp)
jne 0x1ffbf5
jmp 0x1ffcd7
jmp 0x1ffbf7
movq -0xe8(%rbp), %rdi
movq 0x8(%rdi), %rax
movq %rax, -0x100(%rbp)
movl -0x54(%rbp), %eax
movl %eax, -0xf8(%rbp)
movl -0x58(%rbp), %eax
movl %eax, -0xf4(%rbp)
addq $0x68, %rdi
movslq -0x54(%rbp), %rsi
callq 0x2006b0
movq %rax, %rdi
movslq -0x58(%rbp), %rsi
callq 0x384f0
movq -0x100(%rbp), %rsi
movl -0xf8(%rbp), %edx
movl -0xf4(%rbp), %ecx
movq -0xe8(%rbp), %rdi
movl (%rax), %r8d
callq 0x200490
movq -0xe8(%rbp), %rdi
addq $0x50, %rdi
movslq -0x54(%rbp), %rsi
callq 0x344d0
movq (%rax), %rdi
movslq -0x58(%rbp), %rsi
callq 0x384f0
movq -0xe8(%rbp), %rdi
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
addq $0x68, %rdi
movslq -0x54(%rbp), %rsi
callq 0x2006b0
movq %rax, %rdi
movslq -0x58(%rbp), %rsi
callq 0x384f0
movq -0xe8(%rbp), %rdi
movl (%rax), %eax
addl $0x1, %eax
cltd
idivl 0x80(%rdi)
movl %edx, -0xf0(%rbp)
addq $0x68, %rdi
movslq -0x54(%rbp), %rsi
callq 0x2006b0
movq %rax, %rdi
movslq -0x58(%rbp), %rsi
callq 0x384f0
movl -0xf0(%rbp), %edx
movl %edx, (%rax)
leaq -0x40(%rbp), %rdi
callq 0x138590
jmp 0x1ff9ee
jmp 0x1ffce7
movq -0xe8(%rbp), %rax
movq 0x10(%rax), %rcx
movq %rcx, 0x18(%rax)
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nop