// File: CMU-SAFARI[P]ramulator/src/Refresh.cpp
// Function: ramulator::Refresh<ramulator::DSARP>::wrp()
void Refresh<DSARP>::wrp() {
  for (int ref_rid = 0; ref_rid < max_rank_count; ref_rid++)
  {
    // Pending refresh in the rank?
    bool pending_ref = false;
    for (Request req : ctrl->otherq.q) {
      if (req.type == Request::Type::REFRESH && req.addr_vec[level_rank] == ref_rid) {
        pending_ref = true;
        break;
      }
    }
    if (pending_ref)
      continue;

    // Find the bank with the lowest number of writes+reads
    vector<wrq_idx> sorted_bank_demand;
    for (int b = 0; b < max_bank_count; b++)
      sorted_bank_demand.push_back(wrq_idx(0,b));
    // Filter out all the writes to this rank
    int total_wr = 0;
    for (auto req : ctrl->writeq.q) {
      if (req.addr_vec[level_rank] == ref_rid) {
        sorted_bank_demand[req.addr_vec[level_bank]].first++;
        total_wr++;
      }
    }
    // If there's no write, just skip.
    if (total_wr == 0)
      continue;

    // Add read
    for (auto req : ctrl->readq.q)
      if (req.addr_vec[level_rank] == ref_rid)
        sorted_bank_demand[req.addr_vec[level_bank]].first++;

    // Sort based on the entries
    std::sort(sorted_bank_demand.begin(), sorted_bank_demand.end(), wrq_comp);

    // Randomly select an idle bank to refresh
    int top_idle_idx = 0;
    for (int i = 0; i < max_bank_count; i++) {
      if (sorted_bank_demand[i].second != 0) {
        top_idle_idx = i;
        break;
      }
    }

    // Select a bank to ref
    int ref_bid_idx = (top_idle_idx == 0) ? 0 : rand() % top_idle_idx;
    int ref_bid = sorted_bank_demand[ref_bid_idx].second;

    // Make sure we don't exceed the credit
    if ((*(bank_refresh_backlog[ref_rid]))[ref_bid] < backlog_max
        && ctrl->otherq.q.size() < ctrl->otherq.max) {
      refresh_target(ctrl, ref_rid, ref_bid, subarray_ref_counters[ref_rid][ref_bid]);
      // Get 1 ref credit
      (*(bank_refresh_backlog[ref_rid]))[ref_bid]++;
      subarray_ref_counters[ref_rid][ref_bid] = (subarray_ref_counters[ref_rid][ref_bid]+1) % max_sa_count;
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x210, %rsp            # imm = 0x210
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x1e0(%rbp)
movl $0x0, -0xc(%rbp)
movq -0x1e0(%rbp), %rcx
movl -0xc(%rbp), %eax
cmpl 0x38(%rcx), %eax
jge 0x200347
movq -0x1e0(%rbp), %rax
movb $0x0, -0xd(%rbp)
movq 0x8(%rax), %rax
addq $0x1120, %rax           # imm = 0x1120
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
callq 0x42b70
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
callq 0x417c0
movq %rax, -0x28(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x41790
testb $0x1, %al
jne 0x1ffd9d
jmp 0x1ffe21
leaq -0x20(%rbp), %rdi
callq 0x41cf0
movq %rax, %rsi
leaq -0x88(%rbp), %rdi
callq 0x42ba0
cmpl $0x2, -0x5c(%rbp)
jne 0x1ffded
movq -0x1e0(%rbp), %rax
leaq -0x88(%rbp), %rdi
addq $0x10, %rdi
movslq 0x44(%rax), %rsi
callq 0x384f0
movl (%rax), %eax
cmpl -0xc(%rbp), %eax
jne 0x1ffded
movb $0x1, -0xd(%rbp)
movl $0x5, -0x8c(%rbp)
jmp 0x1ffdf7
movl $0x0, -0x8c(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x36780
movl -0x8c(%rbp), %eax
testl %eax, %eax
je 0x1ffe11
jmp 0x1ffe0f
jmp 0x1ffe21
jmp 0x1ffe13
leaq -0x20(%rbp), %rdi
callq 0x42f20
jmp 0x1ffd87
testb $0x1, -0xd(%rbp)
je 0x1ffe2c
jmp 0x200339
leaq -0xa8(%rbp), %rdi
callq 0x2006d0
movl $0x0, -0xac(%rbp)
movq -0x1e0(%rbp), %rcx
movl -0xac(%rbp), %eax
cmpl 0x3c(%rcx), %eax
jge 0x1ffec5
movl $0x0, -0xb8(%rbp)
leaq -0xb4(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
leaq -0xac(%rbp), %rdx
callq 0x200720
jmp 0x1ffe7a
leaq -0xa8(%rbp), %rdi
leaq -0xb4(%rbp), %rsi
callq 0x2006f0
jmp 0x1ffe8f
jmp 0x1ffe91
movl -0xac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xac(%rbp)
jmp 0x1ffe42
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x200820
jmp 0x200350
movq -0x1e0(%rbp), %rax
movl $0x0, -0xc8(%rbp)
movq 0x8(%rax), %rax
addq $0x10e0, %rax           # imm = 0x10E0
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x42b70
movq %rax, -0xd8(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x417c0
movq %rax, -0xe0(%rbp)
leaq -0xd8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x41790
testb $0x1, %al
jne 0x1fff29
jmp 0x1fffc5
leaq -0xd8(%rbp), %rdi
callq 0x41cf0
movq %rax, %rsi
leaq -0x140(%rbp), %rdi
callq 0x42ba0
jmp 0x1fff46
movq -0x1e0(%rbp), %rax
leaq -0x140(%rbp), %rdi
addq $0x10, %rdi
movslq 0x44(%rax), %rsi
callq 0x384f0
movl (%rax), %eax
cmpl -0xc(%rbp), %eax
jne 0x1fffa8
movq -0x1e0(%rbp), %rax
leaq -0x140(%rbp), %rdi
addq $0x10, %rdi
movslq 0x48(%rax), %rsi
callq 0x384f0
movslq (%rax), %rsi
leaq -0xa8(%rbp), %rdi
callq 0x200750
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movl -0xc8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc8(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x36780
leaq -0xd8(%rbp), %rdi
callq 0x42f20
jmp 0x1fff0d
cmpl $0x0, -0xc8(%rbp)
jne 0x1fffdd
movl $0x4, -0x8c(%rbp)
jmp 0x20031d
movq -0x1e0(%rbp), %rax
movq 0x8(%rax), %rax
addq $0x10c0, %rax           # imm = 0x10C0
movq %rax, -0x148(%rbp)
movq -0x148(%rbp), %rdi
callq 0x42b70
movq %rax, -0x150(%rbp)
movq -0x148(%rbp), %rdi
callq 0x417c0
movq %rax, -0x158(%rbp)
leaq -0x150(%rbp), %rdi
leaq -0x158(%rbp), %rsi
callq 0x41790
testb $0x1, %al
jne 0x200037
jmp 0x2000c4
leaq -0x150(%rbp), %rdi
callq 0x41cf0
movq %rax, %rsi
leaq -0x1b8(%rbp), %rdi
callq 0x42ba0
jmp 0x200054
movq -0x1e0(%rbp), %rax
leaq -0x1b8(%rbp), %rdi
addq $0x10, %rdi
movslq 0x44(%rax), %rsi
callq 0x384f0
movl (%rax), %eax
cmpl -0xc(%rbp), %eax
jne 0x2000a7
movq -0x1e0(%rbp), %rax
leaq -0x1b8(%rbp), %rdi
addq $0x10, %rdi
movslq 0x48(%rax), %rsi
callq 0x384f0
movslq (%rax), %rsi
leaq -0xa8(%rbp), %rdi
callq 0x200750
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
leaq -0x1b8(%rbp), %rdi
callq 0x36780
leaq -0x150(%rbp), %rdi
callq 0x42f20
jmp 0x20001b
leaq -0xa8(%rbp), %rdi
movq %rdi, -0x1e8(%rbp)
callq 0x2007c0
movq -0x1e8(%rbp), %rdi
movq %rax, -0x1c0(%rbp)
callq 0x2007f0
movq %rax, -0x1c8(%rbp)
movq -0x1c0(%rbp), %rdi
movq -0x1c8(%rbp), %rsi
leaq -0x406(%rip), %rdx      # 0x1ffd00
callq 0x200770
jmp 0x20010d
movl $0x0, -0x1cc(%rbp)
movl $0x0, -0x1d0(%rbp)
movq -0x1e0(%rbp), %rcx
movl -0x1d0(%rbp), %eax
cmpl 0x3c(%rcx), %eax
jge 0x20016d
movslq -0x1d0(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
callq 0x200750
cmpl $0x0, 0x4(%rax)
je 0x20015a
movl -0x1d0(%rbp), %eax
movl %eax, -0x1cc(%rbp)
jmp 0x20016d
jmp 0x20015c
movl -0x1d0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1d0(%rbp)
jmp 0x200121
cmpl $0x0, -0x1cc(%rbp)
jne 0x200180
xorl %edx, %edx
movl %edx, -0x1ec(%rbp)
jmp 0x200192
callq 0xc130
cltd
idivl -0x1cc(%rbp)
movl %edx, -0x1ec(%rbp)
movl -0x1ec(%rbp), %eax
movl %eax, -0x1d4(%rbp)
movslq -0x1d4(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
callq 0x200750
movq -0x1e0(%rbp), %rdi
movl 0x4(%rax), %eax
movl %eax, -0x1d8(%rbp)
addq $0x50, %rdi
movslq -0xc(%rbp), %rsi
callq 0x344d0
movq (%rax), %rdi
movslq -0x1d8(%rbp), %rsi
callq 0x384f0
movq -0x1e0(%rbp), %rcx
movl (%rax), %eax
cmpl 0x84(%rcx), %eax
jge 0x200313
movq -0x1e0(%rbp), %rax
movq 0x8(%rax), %rdi
addq $0x1120, %rdi           # imm = 0x1120
callq 0x409b0
movq -0x1e0(%rbp), %rcx
movq 0x8(%rcx), %rcx
movl 0x1138(%rcx), %ecx
cmpq %rcx, %rax
jae 0x200313
movq -0x1e0(%rbp), %rdi
movq 0x8(%rdi), %rax
movq %rax, -0x200(%rbp)
movl -0xc(%rbp), %eax
movl %eax, -0x1f4(%rbp)
movl -0x1d8(%rbp), %ecx
movl %ecx, -0x1f0(%rbp)
addq $0x68, %rdi
movslq %eax, %rsi
callq 0x2006b0
movq %rax, %rdi
movslq -0x1d8(%rbp), %rsi
callq 0x384f0
movq -0x1e0(%rbp), %rdi
movq -0x200(%rbp), %rsi
movl -0x1f4(%rbp), %edx
movl -0x1f0(%rbp), %ecx
movl (%rax), %r8d
callq 0x200490
jmp 0x200289
movq -0x1e0(%rbp), %rdi
addq $0x50, %rdi
movslq -0xc(%rbp), %rsi
callq 0x344d0
movq (%rax), %rdi
movslq -0x1d8(%rbp), %rsi
callq 0x384f0
movq -0x1e0(%rbp), %rdi
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
addq $0x68, %rdi
movslq -0xc(%rbp), %rsi
callq 0x2006b0
movq %rax, %rdi
movslq -0x1d8(%rbp), %rsi
callq 0x384f0
movq -0x1e0(%rbp), %rdi
movl (%rax), %eax
addl $0x1, %eax
cltd
idivl 0x80(%rdi)
movl %edx, -0x204(%rbp)
addq $0x68, %rdi
movslq -0xc(%rbp), %rsi
callq 0x2006b0
movq %rax, %rdi
movslq -0x1d8(%rbp), %rsi
callq 0x384f0
movl -0x204(%rbp), %edx
movl %edx, (%rax)
movl $0x0, -0x8c(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x200820
movl -0x8c(%rbp), %eax
testl %eax, %eax
je 0x200337
jmp 0x200335
jmp 0x200339
jmp 0x200339
movl -0xc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc(%rbp)
jmp 0x1ffd41
addq $0x210, %rsp            # imm = 0x210
popq %rbp
retq
movq -0xc0(%rbp), %rdi
callq 0xc5d0
nopl (%rax)