// File: /workspace/github_cpp_makefile_star2_O2/CMU-SAFARI[P]ramulator/src/Cache.cpp
// Function: ramulator::Cache::evict(std::__cxx11::list<ramulator::Cache::Line, std::allocator<ramulator::Cache::Line>>*, std::_List_iterator<ramulator::Cache::Line>)
void Cache::evict(std::list<Line>* lines,
    std::list<Line>::iterator victim) {
  debug("level %d miss evict victim %lx", int(level), victim->addr);
  cache_eviction++;

  long addr = victim->addr;
  long invalidate_time = 0;
  bool dirty = victim->dirty;

  // First invalidate the victim line in higher level.
  if (higher_cache.size()) {
    for (auto hc : higher_cache) {
      auto result = hc->invalidate(addr);
      invalidate_time = max(invalidate_time,
          result.first + (result.second ? latency_each[int(level)] : 0));
      dirty = dirty || result.second || victim->dirty;
    }
  }

  debug("invalidate delay: %ld, dirty: %s", invalidate_time,
      dirty ? "true" : "false");

  if (!is_last_level) {
    // not LLC eviction
    assert(lower_cache != nullptr);
    lower_cache->evictline(addr, dirty);
  } else {
    // LLC eviction
    if (dirty) {
      Request write_req(addr, Request::Type::WRITE);
      cachesys->wait_list.push_back(make_pair(
          cachesys->clk + invalidate_time + latency[int(level)],
          write_req));

      debug("inject one write request to memory system "
          "addr %lx, invalidate time %ld, issue time %ld",
          write_req.addr, invalidate_time,
          cachesys->clk + invalidate_time + latency[int(level)]);
    }
  }

  lines->erase(victim);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movq %rsi, 0x8(%rsp)
movq %rdi, %r15
movsd 0x238(%rdi), %xmm0
addsd 0x35ced(%rip), %xmm0    # 0xd1078
movsd %xmm0, 0x238(%rdi)
movq 0x10(%rdx), %r12
movq %rdx, (%rsp)
movb 0x21(%rdx), %bpl
movq 0x648(%rdi), %r14
movq 0x640(%rdi), %rbx
xorl %r13d, %r13d
cmpq %rbx, %r14
je 0x9b400
cmpq %r14, %rbx
je 0x9b400
movq (%rbx), %rdi
movq %r12, %rsi
callq 0x9b258
testb $0x1, %dl
je 0x9b3db
movslq 0x5f0(%r15), %rcx
movslq 0x624(%r15,%rcx,4), %rcx
jmp 0x9b3dd
xorl %ecx, %ecx
addq %rax, %rcx
cmpq %rcx, %r13
cmovleq %rcx, %r13
orb %bpl, %dl
movb $0x1, %bpl
testb $0x1, %dl
jne 0x9b3fa
movq (%rsp), %rax
movb 0x21(%rax), %bpl
addq $0x8, %rbx
jmp 0x9b3b5
cmpb $0x0, 0x661(%r15)
je 0x9b4ad
testb $0x1, %bpl
je 0x9b4c8
leaq 0x10(%rsp), %rsi
movb $0x1, (%rsi)
movq %r12, 0x8(%rsi)
xorpd %xmm0, %xmm0
movupd %xmm0, 0x10(%rsi)
movupd %xmm0, 0x1c(%rsi)
movl $0x1, 0x2c(%rsi)
pcmpeqd %xmm1, %xmm1
movdqu %xmm1, 0x30(%rsi)
movupd %xmm0, 0x40(%rsi)
leaq 0xa66(%rip), %rax       # 0x9beb4
movq %rax, 0x58(%rsi)
leaq 0xa5d(%rip), %rax       # 0x9beb6
movq %rax, 0x50(%rsi)
movq 0x630(%r15), %r12
addq 0x50(%r12), %r13
movslq 0x5f0(%r15), %rax
movslq 0x618(%r15,%rax,4), %rax
addq %r13, %rax
leaq 0x78(%rsp), %r15
movq %rax, -0x8(%r15)
movq %r15, %rdi
callq 0x2000a
leaq 0x70(%rsp), %rsi
movq %r12, %rdi
callq 0x9b994
movq %r15, %rdi
callq 0x1cc14
leaq 0x10(%rsp), %rdi
callq 0x1cc14
jmp 0x9b4c8
movq 0x658(%r15), %rdi
testq %rdi, %rdi
je 0x9b4e8
movzbl %bpl, %edx
andl $0x1, %edx
movq %r12, %rsi
callq 0x9b178
movq 0x8(%rsp), %rdi
movq (%rsp), %rsi
callq 0x9b986
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x4125d(%rip), %rdi     # 0xdc74c
leaq 0x40ef9(%rip), %rsi     # 0xdc3ef
leaq 0x41266(%rip), %rcx     # 0xdc763
movl $0x119, %edx            # imm = 0x119
callq 0xb210
movq %rax, %rbx
movq %r15, %rdi
callq 0x1cc14
jmp 0x9b517
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x1cc14
movq %rbx, %rdi
callq 0xb4d0
nop