// File: NishadSaraf[P]Championship-Simulator/replacement/base_replacement.cc
// Function: CACHE::lru_victim(unsigned int, unsigned long, unsigned int, BLOCK const*, unsigned long, unsigned long, unsigned int)
uint32_t CACHE::lru_victim(uint32_t cpu, uint64_t instr_id, uint32_t set, const BLOCK *current_set, uint64_t ip, uint64_t full_addr, uint32_t type)
{
    uint32_t way = 0;

    // fill invalid line first
    for (way=0; way<NUM_WAY; way++) {
        if (block[set][way].valid == false) {

            DP ( if (warmup_complete[cpu]) {
            cout << "[" << NAME << "] " << __func__ << " instr_id: " << instr_id << " invalid set: " << set << " way: " << way;
            cout << hex << " address: " << (full_addr>>LOG2_BLOCK_SIZE) << " victim address: " << block[set][way].address << " data: " << block[set][way].data;
            cout << dec << " lru: " << block[set][way].lru << endl; });

            break;
        }
    }

    // LRU victim
    if (way == NUM_WAY) {
        for (way=0; way<NUM_WAY; way++) {
            if (block[set][way].lru == NUM_WAY-1) {

                DP ( if (warmup_complete[cpu]) {
                cout << "[" << NAME << "] " << __func__ << " instr_id: " << instr_id << " replace set: " << set << " way: " << way;
                cout << hex << " address: " << (full_addr>>LOG2_BLOCK_SIZE) << " victim address: " << block[set][way].address << " data: " << block[set][way].data;
                cout << dec << " lru: " << block[set][way].lru << endl; });

                break;
            }
        }
    }

    if (way == NUM_WAY) {
        cerr << "[" << NAME << "] " << __func__ << " no victim! set: " << set << endl;
        assert(0);
    }

    return way;
}

// Assembly:
subq $0x48, %rsp
movl 0x58(%rsp), %eax
movq 0x50(%rsp), %rax
movq %rdi, 0x40(%rsp)
movl %esi, 0x3c(%rsp)
movq %rdx, 0x30(%rsp)
movl %ecx, 0x2c(%rsp)
movq %r8, 0x20(%rsp)
movq %r9, 0x18(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x8(%rsp)
movl $0x0, 0x14(%rsp)
movl $0x0, 0x14(%rsp)
movq 0x8(%rsp), %rcx
movl 0x14(%rsp), %eax
cmpl 0x7374(%rcx), %eax
jae 0x223ec
movq 0x8(%rsp), %rax
movq 0x7390(%rax), %rax
movl 0x2c(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movl 0x14(%rsp), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
jne 0x223dd
jmp 0x223ec
jmp 0x223df
movl 0x14(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x14(%rsp)
jmp 0x223a3
movq 0x8(%rsp), %rcx
movl 0x14(%rsp), %eax
cmpl 0x7374(%rcx), %eax
jne 0x22458
movl $0x0, 0x14(%rsp)
movq 0x8(%rsp), %rcx
movl 0x14(%rsp), %eax
cmpl 0x7374(%rcx), %eax
jae 0x22456
movq 0x8(%rsp), %rcx
movq 0x7390(%rcx), %rax
movl 0x2c(%rsp), %edx
movq (%rax,%rdx,8), %rax
movl 0x14(%rsp), %edx
imulq $0x50, %rdx, %rdx
addq %rdx, %rax
movl 0x48(%rax), %eax
movl 0x7374(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x22447
jmp 0x22456
jmp 0x22449
movl 0x14(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x14(%rsp)
jmp 0x22405
jmp 0x22458
movq 0x8(%rsp), %rcx
movl 0x14(%rsp), %eax
cmpl 0x7374(%rcx), %eax
jne 0x224fb
movq 0x6b7c(%rip), %rdi      # 0x28ff0
leaq 0xbb2(%rip), %rsi       # 0x2302d
callq 0x3220
movq 0x8(%rsp), %rsi
movq %rax, %rdi
addq $0x7350, %rsi           # imm = 0x7350
callq 0x31c0
movq %rax, %rdi
leaq 0x1945(%rip), %rsi      # 0x23de3
callq 0x3220
movq %rax, %rdi
leaq 0x1c29(%rip), %rsi      # 0x240d6
callq 0x3220
movq %rax, %rdi
leaq 0x1c25(%rip), %rsi      # 0x240e1
callq 0x3220
movq %rax, %rdi
movl 0x2c(%rsp), %esi
callq 0x32c0
movq %rax, %rdi
movq 0x6ae1(%rip), %rsi      # 0x28fb8
callq 0x3250
leaq 0xb21(%rip), %rdi       # 0x23004
leaq 0x1c09(%rip), %rsi      # 0x240f3
movl $0x37, %edx
leaq 0x1c1d(%rip), %rcx      # 0x24113
callq 0x3160
movl 0x14(%rsp), %eax
addq $0x48, %rsp
retq
nopw %cs:(%rax,%rax)