// File: /workspace/github_cpp_makefile_star2_O2/CMU-SAFARI[P]ramulator/src/Cache.cpp
// Function: ramulator::Cache::Cache(int, int, int, int, ramulator::Cache::Level, std::shared_ptr<ramulator::CacheSystem>)
Cache::Cache(int size, int assoc, int block_size,
    int mshr_entry_num, Level level,
    std::shared_ptr<CacheSystem> cachesys):
    level(level), cachesys(cachesys), higher_cache(0),
    lower_cache(nullptr), size(size), assoc(assoc),
    block_size(block_size), mshr_entry_num(mshr_entry_num) {

  debug("level %d size %d assoc %d block_size %d\n",
      int(level), size, assoc, block_size);

  if (level == Level::L1) {
    level_string = "L1";
  } else if (level == Level::L2) {
    level_string = "L2";
  } else if (level == Level::L3) {
    level_string = "L3";
  }

  is_first_level = (level == cachesys->first_level);
  is_last_level = (level == cachesys->last_level);

  // Check size, block size and assoc are 2^N
  assert((size & (size - 1)) == 0);
  assert((block_size & (block_size - 1)) == 0);
  assert((assoc & (assoc - 1)) == 0);
  assert(size >= block_size);

  // Initialize cache configuration
  block_num = size / (block_size * assoc);
  index_mask = block_num - 1;
  index_offset = calc_log2(block_size);
  tag_offset = calc_log2(block_num) + index_offset;

  debug("index_offset %d", index_offset);
  debug("index_mask 0x%x", index_mask);
  debug("tag_offset %d", tag_offset);

  // regStats
  cache_read_miss.name(level_string + string("_cache_read_miss"))
                 .desc("cache read miss count")
                 .precision(0)
                 ;

  cache_write_miss.name(level_string + string("_cache_write_miss"))
                  .desc("cache write miss count")
                  .precision(0)
                  ;

  cache_total_miss.name(level_string + string("_cache_total_miss"))
                  .desc("cache total miss count")
                  .precision(0)
                  ;

  cache_eviction.name(level_string + string("_cache_eviction"))
                .desc("number of evict from this level to lower level")
                .precision(0)
                ;

  cache_read_access.name(level_string + string("_cache_read_access"))
                  .desc("cache read access count")
                  .precision(0)
                  ;

  cache_write_access.name(level_string + string("_cache_write_access"))
                    .desc("cache write access count")
                    .precision(0)
                    ;

  cache_total_access.name(level_string + string("_cache_total_access"))
                    .desc("cache total access count")
                    .precision(0)
                    ;

  cache_mshr_hit.name(level_string + string("_cache_mshr_hit"))
                .desc("cache mshr hit count")
                .precision(0)
                ;
  cache_mshr_unavailable.name(level_string + string("_cache_mshr_unavailable"))
                         .desc("cache mshr not available count")
                         .precision(0)
                         ;
  cache_set_unavailable.name(level_string + string("_cache_set_unavailable"))
                         .desc("cache set not available")
                         .precision(0)
                         ;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x308, %rsp            # imm = 0x308
movl %r9d, %r14d
movl %r8d, %ebp
movl %ecx, %r15d
movl %edx, %r12d
movl %esi, %r13d
movq %rdi, %rbx
callq 0x186fa
leaq 0x98(%rbx), %rdi
movq %rdi, 0x70(%rsp)
callq 0x186fa
leaq 0x130(%rbx), %rdi
movq %rdi, 0x68(%rsp)
callq 0x186fa
leaq 0x1c8(%rbx), %rdi
movq %rdi, 0x60(%rsp)
callq 0x186fa
leaq 0x260(%rbx), %rdi
movq %rdi, 0x58(%rsp)
callq 0x186fa
leaq 0x2f8(%rbx), %rdi
movq %rdi, 0x50(%rsp)
callq 0x186fa
leaq 0x390(%rbx), %rdi
movq %rdi, 0x48(%rsp)
callq 0x186fa
leaq 0x428(%rbx), %rdi
movq %rdi, 0x40(%rsp)
callq 0x186fa
leaq 0x4c0(%rbx), %rdi
movq %rdi, 0x38(%rsp)
callq 0x186fa
leaq 0x558(%rbx), %rdi
movq %rdi, 0x30(%rsp)
callq 0x186fa
movl %r14d, 0x5f0(%rbx)
leaq 0x608(%rbx), %rax
movq %rax, 0x5f8(%rbx)
andq $0x0, 0x600(%rbx)
movq 0x340(%rsp), %rsi
leaq 0x5f8(%rbx), %rax
movq %rax, 0x28(%rsp)
movb $0x0, 0x608(%rbx)
movaps 0x42114(%rip), %xmm0    # 0xdc3c0
movups %xmm0, 0x618(%rbx)
movabsq $0x1f0000000c, %rax     # imm = 0x1F0000000C
movq %rax, 0x628(%rbx)
leaq 0x630(%rbx), %rdi
callq 0x9ba06
leaq 0x640(%rbx), %rdi
leaq 0x8(%rsp), %rdx
movq %rdi, 0x80(%rsp)
xorl %esi, %esi
callq 0x9b834
andq $0x0, 0x658(%rbx)
movslq %r13d, %rax
movq %rax, 0x668(%rbx)
movl %r12d, 0x670(%rbx)
movl %r15d, 0x67c(%rbx)
movl %ebp, 0x688(%rbx)
andq $0x0, 0x6a0(%rbx)
xorps %xmm0, %xmm0
movups %xmm0, 0x690(%rbx)
leaq 0x6a8(%rbx), %rax
movq %rax, 0x6b0(%rbx)
movq %rax, 0x78(%rsp)
movq %rax, 0x6a8(%rbx)
andq $0x0, 0x6b8(%rbx)
andl $0x0, 0x6c8(%rbx)
andq $0x0, 0x6d0(%rbx)
leaq 0x6c8(%rbx), %rax
movq %rax, 0x6d8(%rbx)
movq %rax, 0x6e0(%rbx)
andq $0x0, 0x6e8(%rbx)
cmpl $0x3, %r14d
jae 0x9a392
movl %r14d, %eax
leaq 0x424db(%rip), %rcx     # 0xdc85c
movslq (%rcx,%rax,4), %rsi
addq %rcx, %rsi
movq 0x28(%rsp), %rdi
callq 0xb510
movq 0x340(%rsp), %rax
movq (%rax), %rax
cmpl %r14d, 0x58(%rax)
sete 0x660(%rbx)
cmpl %r14d, 0x5c(%rax)
sete 0x661(%rbx)
leal -0x1(%r13), %eax
testl %eax, %r13d
jne 0x9a9fb
leal -0x1(%r15), %eax
testl %eax, %r15d
jne 0x9aa14
leal -0x1(%r12), %eax
testl %eax, %r12d
jne 0x9aa2d
cmpl %r15d, %r13d
jl 0x9aa46
imull %r15d, %r12d
movl %r13d, %eax
cltd
idivl %r12d
movl %eax, 0x674(%rbx)
decl %eax
movl %eax, 0x678(%rbx)
movq %rbx, %rdi
movl %r15d, %esi
callq 0x9b886
movl %eax, 0x680(%rbx)
movl 0x674(%rbx), %esi
movq %rbx, %rdi
callq 0x9b886
addl 0x680(%rbx), %eax
movl %eax, 0x684(%rbx)
leaq 0x42072(%rip), %rsi     # 0xdc4a1
leaq 0x8(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x10eea
leaq 0x2e8(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movq 0x28(%rsp), %r15
movq %r15, %rsi
callq 0x1108b
leaq 0x2e8(%rsp), %rsi
movq %rbx, %rdi
callq 0x1a7c6
movq %rax, %r14
leaq 0x42040(%rip), %rsi     # 0xdc4b2
leaq 0x2c8(%rsp), %rdi
leaq 0x6(%rsp), %rdx
callq 0x10eea
leaq 0x28(%r14), %rdi
leaq 0x2c8(%rsp), %rsi
callq 0xb1c0
andl $0x0, 0x48(%r14)
leaq 0x2c8(%rsp), %rdi
callq 0xb568
leaq 0x2e8(%rsp), %rdi
callq 0xb568
leaq 0x8(%rsp), %rdi
callq 0xb568
leaq 0x42003(%rip), %rsi     # 0xdc4c8
leaq 0x8(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x10eea
leaq 0x2a8(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movq %r15, %rsi
callq 0x1108b
leaq 0x2a8(%rsp), %rsi
movq 0x70(%rsp), %rdi
callq 0x1a7c6
movq %rax, %r14
leaq 0x41fd5(%rip), %rsi     # 0xdc4da
leaq 0x288(%rsp), %rdi
leaq 0x6(%rsp), %rdx
callq 0x10eea
leaq 0x28(%r14), %rdi
leaq 0x288(%rsp), %rsi
callq 0xb1c0
andl $0x0, 0x48(%r14)
leaq 0x288(%rsp), %rdi
callq 0xb568
leaq 0x2a8(%rsp), %rdi
callq 0xb568
leaq 0x8(%rsp), %rdi
callq 0xb568
leaq 0x41f99(%rip), %rsi     # 0xdc4f1
leaq 0x8(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x10eea
leaq 0x268(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movq %r15, %rsi
callq 0x1108b
leaq 0x268(%rsp), %rsi
movq 0x68(%rsp), %rdi
callq 0x1a7c6
movq %rax, %r14
leaq 0x41f6b(%rip), %rsi     # 0xdc503
leaq 0x248(%rsp), %rdi
leaq 0x6(%rsp), %rdx
callq 0x10eea
leaq 0x28(%r14), %rdi
leaq 0x248(%rsp), %rsi
callq 0xb1c0
andl $0x0, 0x48(%r14)
leaq 0x248(%rsp), %rdi
callq 0xb568
leaq 0x268(%rsp), %rdi
callq 0xb568
leaq 0x8(%rsp), %rdi
callq 0xb568
leaq 0x41f2f(%rip), %rsi     # 0xdc51a
leaq 0x8(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x10eea
leaq 0x228(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movq %r15, %rsi
callq 0x1108b
leaq 0x228(%rsp), %rsi
movq 0x60(%rsp), %rdi
callq 0x1a7c6
movq %rax, %r14
leaq 0x41eff(%rip), %rsi     # 0xdc52a
leaq 0x208(%rsp), %rdi
leaq 0x6(%rsp), %rdx
callq 0x10eea
leaq 0x28(%r14), %rdi
leaq 0x208(%rsp), %rsi
callq 0xb1c0
andl $0x0, 0x48(%r14)
leaq 0x208(%rsp), %rdi
callq 0xb568
leaq 0x228(%rsp), %rdi
callq 0xb568
leaq 0x8(%rsp), %rdi
callq 0xb568
leaq 0x41edb(%rip), %rsi     # 0xdc559
leaq 0x8(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x10eea
leaq 0x1e8(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movq %r15, %rsi
callq 0x1108b
leaq 0x1e8(%rsp), %rsi
movq 0x58(%rsp), %rdi
callq 0x1a7c6
movq %rax, %r14
leaq 0x41eae(%rip), %rsi     # 0xdc56c
leaq 0x1c8(%rsp), %rdi
leaq 0x6(%rsp), %rdx
callq 0x10eea
leaq 0x28(%r14), %rdi
leaq 0x1c8(%rsp), %rsi
callq 0xb1c0
andl $0x0, 0x48(%r14)
leaq 0x1c8(%rsp), %rdi
callq 0xb568
leaq 0x1e8(%rsp), %rdi
callq 0xb568
leaq 0x8(%rsp), %rdi
callq 0xb568
leaq 0x41e73(%rip), %rsi     # 0xdc584
leaq 0x8(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x10eea
leaq 0x1a8(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movq %r15, %rsi
callq 0x1108b
leaq 0x1a8(%rsp), %rsi
movq 0x50(%rsp), %rdi
callq 0x1a7c6
movq %rax, %r14
leaq 0x41e47(%rip), %rsi     # 0xdc598
leaq 0x188(%rsp), %rdi
leaq 0x6(%rsp), %rdx
callq 0x10eea
leaq 0x28(%r14), %rdi
leaq 0x188(%rsp), %rsi
callq 0xb1c0
andl $0x0, 0x48(%r14)
leaq 0x188(%rsp), %rdi
callq 0xb568
leaq 0x1a8(%rsp), %rdi
callq 0xb568
leaq 0x8(%rsp), %rdi
callq 0xb568
leaq 0x41e0d(%rip), %rsi     # 0xdc5b1
leaq 0x8(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x10eea
leaq 0x168(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movq %r15, %rsi
callq 0x1108b
leaq 0x168(%rsp), %rsi
movq 0x48(%rsp), %rdi
callq 0x1a7c6
movq %rax, %r14
leaq 0x41de1(%rip), %rsi     # 0xdc5c5
leaq 0x148(%rsp), %rdi
leaq 0x6(%rsp), %rdx
callq 0x10eea
leaq 0x28(%r14), %rdi
leaq 0x148(%rsp), %rsi
callq 0xb1c0
andl $0x0, 0x48(%r14)
leaq 0x148(%rsp), %rdi
callq 0xb568
leaq 0x168(%rsp), %rdi
callq 0xb568
leaq 0x8(%rsp), %rdi
callq 0xb568
leaq 0x41da7(%rip), %rsi     # 0xdc5de
leaq 0x8(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x10eea
leaq 0x128(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movq %r15, %rsi
callq 0x1108b
leaq 0x128(%rsp), %rsi
movq 0x40(%rsp), %rdi
callq 0x1a7c6
movq %rax, %r14
leaq 0x41d77(%rip), %rsi     # 0xdc5ee
leaq 0x108(%rsp), %rdi
leaq 0x6(%rsp), %rdx
callq 0x10eea
leaq 0x28(%r14), %rdi
leaq 0x108(%rsp), %rsi
callq 0xb1c0
andl $0x0, 0x48(%r14)
leaq 0x108(%rsp), %rdi
callq 0xb568
leaq 0x128(%rsp), %rdi
callq 0xb568
leaq 0x8(%rsp), %rdi
callq 0xb568
leaq 0x41d39(%rip), %rsi     # 0xdc603
leaq 0x8(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x10eea
leaq 0xe8(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movq %r15, %rsi
callq 0x1108b
leaq 0xe8(%rsp), %rsi
movq 0x38(%rsp), %rdi
callq 0x1a7c6
movq %rax, %r14
leaq 0x41d11(%rip), %rsi     # 0xdc61b
leaq 0xc8(%rsp), %rdi
leaq 0x6(%rsp), %rdx
callq 0x10eea
leaq 0x28(%r14), %rdi
leaq 0xc8(%rsp), %rsi
callq 0xb1c0
andl $0x0, 0x48(%r14)
leaq 0xc8(%rsp), %rdi
callq 0xb568
leaq 0xe8(%rsp), %rdi
callq 0xb568
leaq 0x8(%rsp), %rdi
callq 0xb568
leaq 0x41cdd(%rip), %rsi     # 0xdc63a
leaq 0x8(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x10eea
leaq 0xa8(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movq %r15, %rsi
callq 0x1108b
leaq 0xa8(%rsp), %rsi
movq 0x30(%rsp), %rdi
callq 0x1a7c6
movq %rax, %r14
leaq 0x41cb4(%rip), %rsi     # 0xdc651
leaq 0x88(%rsp), %rdi
leaq 0x6(%rsp), %rdx
callq 0x10eea
leaq 0x28(%r14), %rdi
leaq 0x88(%rsp), %rsi
callq 0xb1c0
andl $0x0, 0x48(%r14)
leaq 0x88(%rsp), %rdi
callq 0xb568
leaq 0xa8(%rsp), %rdi
callq 0xb568
leaq 0x8(%rsp), %rdi
callq 0xb568
addq $0x308, %rsp            # imm = 0x308
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x419d4(%rip), %rdi     # 0xdc3d6
leaq 0x419e6(%rip), %rsi     # 0xdc3ef
leaq 0x419ed(%rip), %rcx     # 0xdc3fd
pushq $0x26
jmp 0x9aa5d
leaq 0x41a33(%rip), %rdi     # 0xdc44e
leaq 0x419cd(%rip), %rsi     # 0xdc3ef
leaq 0x419d4(%rip), %rcx     # 0xdc3fd
pushq $0x27
jmp 0x9aa5d
leaq 0x41a3f(%rip), %rdi     # 0xdc473
leaq 0x419b4(%rip), %rsi     # 0xdc3ef
leaq 0x419bb(%rip), %rcx     # 0xdc3fd
pushq $0x28
jmp 0x9aa5d
leaq 0x41a41(%rip), %rdi     # 0xdc48e
leaq 0x4199b(%rip), %rsi     # 0xdc3ef
leaq 0x419a2(%rip), %rcx     # 0xdc3fd
pushq $0x29
popq %rdx
callq 0xb210
jmp 0x9ac20
movq %rax, %r15
leaq 0x88(%rsp), %rdi
callq 0xb568
jmp 0x9aa7f
jmp 0x9aa7c
movq %rax, %r15
leaq 0xa8(%rsp), %rdi
jmp 0x9ac0a
jmp 0x9ac11
jmp 0x9ac20
movq %rax, %r15
leaq 0xc8(%rsp), %rdi
callq 0xb568
jmp 0x9aaad
jmp 0x9aaaa
movq %rax, %r15
leaq 0xe8(%rsp), %rdi
jmp 0x9ac0a
jmp 0x9ac11
jmp 0x9ac20
movq %rax, %r15
leaq 0x108(%rsp), %rdi
callq 0xb568
jmp 0x9aadb
jmp 0x9aad8
movq %rax, %r15
leaq 0x128(%rsp), %rdi
jmp 0x9ac0a
jmp 0x9ac11
jmp 0x9ac20
movq %rax, %r15
leaq 0x148(%rsp), %rdi
callq 0xb568
jmp 0x9ab09
jmp 0x9ab06
movq %rax, %r15
leaq 0x168(%rsp), %rdi
jmp 0x9ac0a
jmp 0x9ac11
jmp 0x9ac20
movq %rax, %r15
leaq 0x188(%rsp), %rdi
callq 0xb568
jmp 0x9ab37
jmp 0x9ab34
movq %rax, %r15
leaq 0x1a8(%rsp), %rdi
jmp 0x9ac0a
jmp 0x9ac11
jmp 0x9ac20
movq %rax, %r15
leaq 0x1c8(%rsp), %rdi
callq 0xb568
jmp 0x9ab65
jmp 0x9ab62
movq %rax, %r15
leaq 0x1e8(%rsp), %rdi
jmp 0x9ac0a
jmp 0x9ac11
jmp 0x9ac20
movq %rax, %r15
leaq 0x208(%rsp), %rdi
callq 0xb568
jmp 0x9ab93
jmp 0x9ab90
movq %rax, %r15
leaq 0x228(%rsp), %rdi
jmp 0x9ac0a
jmp 0x9ac11
jmp 0x9ac20
movq %rax, %r15
leaq 0x248(%rsp), %rdi
callq 0xb568
jmp 0x9abb8
jmp 0x9abb5
movq %rax, %r15
leaq 0x268(%rsp), %rdi
jmp 0x9ac0a
jmp 0x9ac11
jmp 0x9ac20
movq %rax, %r15
leaq 0x288(%rsp), %rdi
callq 0xb568
jmp 0x9abdd
jmp 0x9abda
movq %rax, %r15
leaq 0x2a8(%rsp), %rdi
jmp 0x9ac0a
jmp 0x9ac11
jmp 0x9ac20
movq %rax, %r15
leaq 0x2c8(%rsp), %rdi
callq 0xb568
jmp 0x9ac02
jmp 0x9abff
movq %rax, %r15
leaq 0x2e8(%rsp), %rdi
callq 0xb568
jmp 0x9ac14
movq %rax, %r15
leaq 0x8(%rsp), %rdi
callq 0xb568
jmp 0x9ac23
movq %rax, %r15
leaq 0x690(%rbx), %r14
leaq 0x6c0(%rbx), %rdi
callq 0x22396
movq 0x78(%rsp), %rdi
callq 0x1cc2e
movq %r14, %rdi
callq 0x22424
movq 0x80(%rsp), %rdi
callq 0x22458
leaq 0x638(%rbx), %rdi
callq 0x2248c
movq 0x28(%rsp), %rdi
callq 0xb568
movq 0x30(%rsp), %rdi
callq 0x186e4
movq 0x38(%rsp), %rdi
callq 0x186e4
movq 0x40(%rsp), %rdi
callq 0x186e4
movq 0x48(%rsp), %rdi
callq 0x186e4
movq 0x50(%rsp), %rdi
callq 0x186e4
movq 0x58(%rsp), %rdi
callq 0x186e4
movq 0x60(%rsp), %rdi
callq 0x186e4
movq 0x68(%rsp), %rdi
callq 0x186e4
movq 0x70(%rsp), %rdi
callq 0x186e4
movq %rbx, %rdi
callq 0x186e4
movq %r15, %rdi
callq 0xb4d0
movq %rax, %r15
jmp 0x9ac55
movq %rax, %r15
jmp 0x9ac75
movq %rax, %r15
jmp 0x9ac7f
movq %rax, %r15
jmp 0x9ac89
movq %rax, %r15
jmp 0x9ac93
movq %rax, %r15
jmp 0x9ac9d
movq %rax, %r15
jmp 0x9aca7
movq %rax, %r15
jmp 0x9acb1
movq %rax, %r15
jmp 0x9acbb
movq %rax, %r15
jmp 0x9acc5