// File: /workspace/github_cpp_makefile_star2_O3/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 $0xe8, %rsp
movq %rsi, 0x10(%rsp)
movq %rdi, %r15
movsd 0x238(%rdi), %xmm0
addsd 0x4526d(%rip), %xmm0    # 0x14a0b8
movsd %xmm0, 0x238(%rdi)
movq 0x10(%rdx), %r12
movq %rdx, 0x8(%rsp)
movb 0x21(%rdx), %bpl
movq 0x648(%rdi), %r13
movq 0x640(%rdi), %r14
cmpq %r14, %r13
je 0x104ecc
xorl %ebx, %ebx
movq (%r14), %rdi
movq %r12, %rsi
callq 0x104cf8
testb $0x1, %dl
je 0x104ea3
movslq 0x5f0(%r15), %rcx
movslq 0x624(%r15,%rcx,4), %rcx
addq %rcx, %rax
cmpq %rax, %rbx
cmovgq %rbx, %rax
movb $0x1, %bpl
jmp 0x104ebe
cmpq %rax, %rbx
cmovgq %rbx, %rax
orb %bpl, %dl
movb $0x1, %bpl
testb $0x1, %dl
jne 0x104ebe
movq 0x8(%rsp), %rcx
movb 0x21(%rcx), %bpl
addq $0x8, %r14
movq %rax, %rbx
cmpq %r13, %r14
jne 0x104e75
jmp 0x104ece
xorl %eax, %eax
cmpb $0x0, 0x661(%r15)
je 0x104fdb
testb %bpl, %bpl
je 0x104ff3
leaq 0x88(%rsp), %rdx
movb $0x1, (%rdx)
movq %r12, 0x8(%rdx)
xorpd %xmm0, %xmm0
movupd %xmm0, 0x10(%rdx)
movupd %xmm0, 0x1c(%rdx)
movl $0x1, 0x2c(%rdx)
pcmpeqd %xmm1, %xmm1
movdqu %xmm1, 0x30(%rdx)
movupd %xmm0, 0x40(%rdx)
leaq 0xcfa(%rip), %rcx       # 0x105c18
movq %rcx, 0x58(%rdx)
leaq 0xcf1(%rip), %rcx       # 0x105c1a
movq %rcx, 0x50(%rdx)
movq 0x630(%r15), %r12
addq 0x50(%r12), %rax
movslq 0x5f0(%r15), %rcx
movslq 0x618(%r15,%rcx,4), %rcx
addq %rax, %rcx
leaq 0x18(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x105aba
leaq 0x20(%rsp), %rdx
movq %r12, %rdi
movq %r12, %rsi
callq 0x105c4e
movq 0x78(%rsp), %rax
testq %rax, %rax
je 0x104f86
leaq 0x68(%rsp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x104f9d
movq 0x48(%rsp), %rsi
subq %rdi, %rsi
callq 0xb2f0
movq 0xd8(%rsp), %rax
testq %rax, %rax
je 0x104fbc
leaq 0xc8(%rsp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movq 0x98(%rsp), %rdi
testq %rdi, %rdi
je 0x104ff3
movq 0xa8(%rsp), %rsi
subq %rdi, %rsi
callq 0xb2f0
jmp 0x104ff3
movq 0x658(%r15), %rdi
testq %rdi, %rdi
je 0x105028
movzbl %bpl, %edx
movq %r12, %rsi
callq 0x104bd2
movq 0x10(%rsp), %rax
decq 0x10(%rax)
movq 0x8(%rsp), %rbx
movq %rbx, %rdi
callq 0xb490
movl $0x28, %esi
movq %rbx, %rdi
callq 0xb2f0
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x5077d(%rip), %rdi     # 0x1557ac
leaq 0x50419(%rip), %rsi     # 0x15544f
leaq 0x50786(%rip), %rcx     # 0x1557c3
movl $0x119, %edx            # imm = 0x119
callq 0xb200
jmp 0x105049
movq %rax, %rdi
callq 0x171a3
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x105654
jmp 0x105063
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x25c78
movq %rbx, %rdi
callq 0xb510