// File: /workspace/github_cpp_makefile_star2_O2/gvaumour[P]cache-simulator/src/DBAMBPredictor.cc
// Function: DBAMBPredictor::evictPolicy(int, bool)
int
DBAMBPredictor::evictPolicy(int set, bool inNVM)
{	
	int assoc_victim = -1;
	assert(m_replacementPolicyNVM_ptr != NULL);
	assert(m_replacementPolicySRAM_ptr != NULL);

	CacheEntry* current = NULL;
	if(inNVM)
	{	
		assoc_victim = m_replacementPolicyNVM_ptr->evictPolicy(set);
		current = m_tableNVM[set][assoc_victim];
	}
	else
	{
		assoc_victim = m_replacementPolicySRAM_ptr->evictPolicy(set);
		current = m_tableSRAM[set][assoc_victim];		
	}
		
	//DPRINTF("DBAMBPredictor::evictPolicy set %d n assoc_victim %d \n" , set , assoc_victim);
	DHPEntry* rap_current = lookup(current->signature);
	//We didn't create an entry for this dataset, probably a good reason =) (instruction mainly) 
	if(rap_current != NULL)
	{
		if(rap_current->des != BYPASS_CACHE)
		{
			// A learning cache line on dead dataset goes here
			if( current->nbWrite == 0 && current->nbRead == 0)
				rap_current->dead_counter--;
			else
				rap_current->dead_counter++;
		
			if(rap_current->dead_counter > simu_parameters.deadSaturationCouter)
				rap_current->dead_counter = simu_parameters.deadSaturationCouter;
			else if(rap_current->dead_counter < -simu_parameters.deadSaturationCouter)
				rap_current->dead_counter = -simu_parameters.deadSaturationCouter;


			string a =  current->nbWrite == 0 && current->nbRead == 0 ? "DEAD" : "LIVELY";
			dataset_file << "Dataset n°" << rap_current->id << ": Eviction of a " << a << " CL, Address :" << \
				std::hex << current->address << std::dec << " DeadCounter=" << rap_current->dead_counter << endl;
				
			if(rap_current->dead_counter == -simu_parameters.deadSaturationCouter && simu_parameters.enableBP)
			{
				/* Switch the state of the dataset to dead */ 
				rap_current->des = BYPASS_CACHE;			
				dataset_file << "Dataset n°" << rap_current->id << ": Going into BYPASS mode " << endl;
				// Reset the window 
				RW_TYPE old_rw = rap_current->state_rw;
				RD_TYPE old_rd = rap_current->state_rd;

				rap_current->state_rd = RD_NOT_ACCURATE;
				rap_current->state_rw = DEAD;
				rap_current->rd_history.clear();
				rap_current->rw_history.clear();
				rap_current->cptWindow = 0;	
				rap_current->dead_counter = 0;

				// Monitor state switching 
				if(!m_isWarmup)
					stats_ClassErrors[old_rd + NUM_RD_TYPE*old_rw][rap_current->state_rd + NUM_RD_TYPE*rap_current->state_rw]++;
			}
		}
	}
	
	evictRecording(set , assoc_victim , inNVM);	
	return assoc_victim;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq 0x60(%rdi), %rax
testq %rax, %rax
je 0xd4a6
movq %rdi, %r14
movq 0x68(%rdi), %rdi
testq %rdi, %rdi
je 0xd4c5
movl %esi, %ebx
movslq %esi, %r12
testb %dl, %dl
cmovneq %rax, %rdi
movzbl %dl, %r15d
movq (%rdi), %rax
movl %r12d, %esi
callq *0x20(%rax)
movl %eax, %ebp
movq 0x8(%r14,%r15,8), %rax
movq (%rax), %rax
imulq $0x18, %r12, %rcx
movslq %ebp, %rdx
movq (%rax,%rcx), %rax
movq (%rax,%rdx,8), %r13
movq 0x18(%r13), %rsi
movq %r14, %rdi
callq 0xc1d8
testq %rax, %rax
je 0xd47f
movq %rax, %r12
cmpl $0x2, 0x28(%rax)
je 0xd47f
movl 0x11c(%r13), %eax
testl %eax, %eax
jne 0xd285
cmpl $0x0, 0x120(%r13)
je 0xd49f
pushq $0x1
popq %rcx
addl 0xb8(%r12), %ecx
movl %ecx, 0xb8(%r12)
leaq 0x30cb1(%rip), %rdx     # 0x3df50
movl 0x9c(%rdx), %edx
cmpl %edx, %ecx
jg 0xd2af
negl %edx
cmpl %edx, %ecx
jge 0xd2b7
movl %edx, 0xb8(%r12)
testl %eax, %eax
je 0xd2c4
leaq 0x1c7b8(%rip), %rsi     # 0x29a7a
jmp 0xd2de
cmpl $0x0, 0x120(%r13)
leaq 0x1c7a2(%rip), %rax     # 0x29a75
leaq 0x1c7a0(%rip), %rsi     # 0x29a7a
cmoveq %rax, %rsi
leaq 0x8(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x5140
leaq 0x30374(%rip), %rdi     # 0x3d668
leaq 0x1c7e7(%rip), %rsi     # 0x29ae2
callq 0x52c0
movl 0x18(%r12), %esi
movq %rax, %rdi
callq 0x5560
leaq 0x1c76d(%rip), %rsi     # 0x29a81
movq %rax, %rdi
callq 0x52c0
leaq 0x8(%rsp), %rsi
movq %rax, %rdi
callq 0x5290
leaq 0x1c762(%rip), %rsi     # 0x29a92
movq %rax, %rdi
callq 0x52c0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x8, %edx
movl %edx, 0x18(%rax,%rcx)
movq 0x8(%r13), %rsi
movq %rax, %rdi
callq 0x5200
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x2, %edx
movl %edx, 0x18(%rax,%rcx)
leaq 0x1c72c(%rip), %rsi     # 0x29aa1
movq %rax, %rdi
callq 0x52c0
movl 0xb8(%r12), %esi
movq %rax, %rdi
callq 0x5560
movq %rax, %rdi
callq 0x5190
movl 0xb8(%r12), %eax
leaq 0x30bac(%rip), %rcx     # 0x3df50
addl 0x9c(%rcx), %eax
jne 0xd475
cmpb $0x1, 0xa8(%rcx)
jne 0xd475
movl $0x2, 0x28(%r12)
leaq 0x3029b(%rip), %rdi     # 0x3d668
leaq 0x1c70e(%rip), %rsi     # 0x29ae2
callq 0x52c0
movl 0x18(%r12), %esi
movq %rax, %rdi
callq 0x5560
leaq 0x1c6c2(%rip), %rsi     # 0x29aaf
movq %rax, %rdi
callq 0x52c0
movq %rax, %rdi
callq 0x5190
movslq 0x98(%r12), %rcx
movslq 0x9c(%r12), %rax
movabsq $0x200000000, %rdx      # imm = 0x200000000
movq %rdx, 0x98(%r12)
movq 0x40(%r12), %rdx
cmpq %rdx, 0x48(%r12)
je 0xd430
movq %rdx, 0x48(%r12)
movq 0x58(%r12), %rdx
movq %rdx, 0x68(%r12)
andl $0x0, 0x70(%r12)
andl $0x0, 0x84(%r12)
andl $0x0, 0xb8(%r12)
cmpb $0x0, 0x81(%r14)
jne 0xd475
leaq (%rcx,%rcx,2), %rcx
addq %rcx, %rax
movq 0x3a0(%r14), %rcx
imulq $0x18, %rax, %rax
movq (%rcx,%rax), %rax
incl 0x8(%rax)
leaq 0x8(%rsp), %rdi
callq 0x5618
movq %r14, %rdi
movl %ebx, %esi
movl %ebp, %edx
movl %r15d, %ecx
callq 0x1f248
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $-0x1
jmp 0xd287
leaq 0x1bce4(%rip), %rdi     # 0x29191
leaq 0x1c578(%rip), %rsi     # 0x29a2c
leaq 0x1c587(%rip), %rcx     # 0x29a42
movl $0x13d, %edx            # imm = 0x13D
callq 0x51e0
leaq 0x1bd1e(%rip), %rdi     # 0x291ea
leaq 0x1c559(%rip), %rsi     # 0x29a2c
leaq 0x1c568(%rip), %rcx     # 0x29a42
movl $0x13e, %edx            # imm = 0x13E
callq 0x51e0
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x5618
movq %rbx, %rdi
callq 0x5570
nop