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

	CacheEntry* entry = NULL;
	if(inNVM)
	{	
		assoc_victim = m_replacementPolicyNVM_ptr->evictPolicy(set);
		entry = m_tableNVM[set][assoc_victim];
	}
	else
	{
		assoc_victim = m_replacementPolicySRAM_ptr->evictPolicy(set);
		entry = m_tableSRAM[set][assoc_victim];		
	}

	if(entry->isValid )
	{
		/*
		string alloc = inNVM ? "NVM" : "SRAM";
		cout << "Eviction Block 0x" << std::hex << entry->address << std::dec << " from " << alloc << " Cost Value = " << entry->cost_value << endl;
		*/
		if(simu_parameters.perceptron_drawFeatureMaps)
		{
			bool global_error = false;
			allocDecision des = entry->cost_value > simu_parameters.PHC_cost_threshold ? ALLOCATE_IN_SRAM : ALLOCATE_IN_NVM;
			//cout << "\t Evaluated allocation = " << str_allocDecision[des] << " , cost Value = " << entry->cost_value << endl;
			if(( des == ALLOCATE_IN_SRAM && inNVM ) || \
				( des == ALLOCATE_IN_NVM && !inNVM ))
				global_error = true;
			if(global_error)
			{
				int hash1 = m_features_hash[0](entry->address , entry->m_pc);
				int hash2 = (m_features.size() > 1) ? m_features_hash[1](entry->address , entry->m_pc) : 0;
				stats_global_error[hash1][hash2]++;
				//cout << "\tGlobal Error Detected features[" << hash1 << "][" << hash2 << "]" << endl; 

			}
		
			for(unsigned i = 0; i < m_features.size() ; i++)
			{
				int hash = m_features_hash[i](entry->address , entry->m_pc);
				allocDecision alloc_pred = entry->PHC_allocation_pred[i].second;
				
				bool local_error = false;
				if( des == ALLOCATE_IN_NVM && alloc_pred == ALLOCATE_IN_SRAM)
					local_error = true;
				else if( des == ALLOCATE_IN_SRAM && alloc_pred == ALLOCATE_IN_NVM )
				 	local_error = true;
				 
						
				if(local_error)
				{
					stats_local_error[i][hash]++;
					/*cout << "\tLocal Error detected, " << m_criterias_names[i] << std::dec << \
						"[" << hash << "] = " << str_allocDecision[alloc_pred] << endl; */
				}	
			}

		}	
		if(entry->isLearning)
		{
			if(entry->cost_value > simu_parameters.PHC_cost_threshold)
			{
				//cout << "Decrease allocation counter" << endl; 
				for(unsigned i = 0; i < m_features.size() ; i++)
				{
					int hash = m_features_hash[i](entry->address , entry->m_pc);
					m_features[i]->decreaseAlloc(hash);
					/*cout << "\t - Feature " << m_criterias_names[i] << std::dec << ": Hash=" \
						<< hash  << ", Alloc=" << m_features[i]->getAllocationPrediction(hash, false) << endl; */

				}
			}			
			else
			{
				//cout << "Increase allocation counter" << endl; 
				for(unsigned i = 0; i < m_features.size() ; i++)
				{
					int hash = m_features_hash[i](entry->address , entry->m_pc);
					m_features[i]->increaseAlloc(hash);
					/*cout << "\t - Feature " << m_criterias_names[i] << std::dec << ": Hash=" \
						<< hash  << ", Alloc" << m_features[i]->getAllocationPrediction(hash, false) << endl; */
				}
			}
		}

		if(entry->nbWrite == 0 && entry->nbRead == 0)
			stats_nbDeadLine[stats_nbDeadLine.size()-1]++;
	}
	
	evictRecording(set , assoc_victim , inNVM);	
	return assoc_victim;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq 0x60(%rdi), %rax
testq %rax, %rax
je 0x1b6e3
movq %rdi, %r14
movq 0x68(%rdi), %rdi
testq %rdi, %rdi
je 0x1b702
movl %edx, %r12d
movl %esi, %ebx
movslq %esi, %r13
testb %r12b, %r12b
cmovneq %rax, %rdi
movzbl %r12b, %r15d
movq (%rdi), %rax
movl %r13d, %esi
callq *0x20(%rax)
movl %eax, %ebp
movq 0x8(%r14,%r15,8), %rax
movq (%rax), %rax
imulq $0x18, %r13, %rcx
movslq %ebp, %rdx
movq (%rax,%rcx), %rax
movq (%rax,%rdx,8), %r13
cmpb $0x1, (%r13)
jne 0x1b6c3
movl %ebx, 0x4(%rsp)
leaq 0x22a5e(%rip), %rax     # 0x3df50
cmpb $0x1, 0x1cc(%rax)
jne 0x1b5ee
movsd 0x130(%r13), %xmm0
leaq 0x22a41(%rip), %rax     # 0x3df50
cvtsi2sdl 0x1e8(%rax), %xmm1
ucomisd %xmm1, %xmm0
seta %al
xorb %r12b, %al
jne 0x1b590
movsd %xmm1, 0x8(%rsp)
movsd %xmm0, 0x10(%rsp)
movq 0x288(%r14), %rax
movq 0x8(%r13), %rdi
movq 0x10(%r13), %rsi
callq *(%rax)
movl %eax, %r12d
movq 0x278(%r14), %rax
subq 0x270(%r14), %rax
cmpq $0x9, %rax
jb 0x1b56d
movq 0x288(%r14), %rax
movq 0x8(%r13), %rdi
movq 0x10(%r13), %rsi
callq *0x8(%rax)
cltq
jmp 0x1b56f
xorl %eax, %eax
movslq %r12d, %rcx
movq 0x418(%r14), %rdx
imulq $0x18, %rcx, %rcx
movq (%rdx,%rcx), %rcx
incl (%rcx,%rax,4)
movsd 0x10(%rsp), %xmm0
movsd 0x8(%rsp), %xmm1
xorl %r12d, %r12d
ucomisd %xmm1, %xmm0
seta %r12b
xorl %ebx, %ebx
movl %ebx, %ebx
movq 0x278(%r14), %rax
subq 0x270(%r14), %rax
sarq $0x3, %rax
cmpq %rbx, %rax
jbe 0x1b5ee
movq 0x288(%r14), %rax
movq 0x8(%r13), %rdi
movq 0x10(%r13), %rsi
callq *(%rax,%rbx,8)
movq 0xd0(%r13), %rcx
cmpl %r12d, 0x4(%rcx,%rbx,8)
jne 0x1b5ea
movq 0x400(%r14), %rcx
imulq $0x18, %rbx, %rdx
cltq
movq (%rcx,%rdx), %rcx
incl (%rcx,%rax,4)
incl %ebx
jmp 0x1b59d
cmpb $0x1, 0x148(%r13)
jne 0x1b6a0
movsd 0x130(%r13), %xmm0
leaq 0x22944(%rip), %rax     # 0x3df50
cvtsi2sdl 0x1e8(%rax), %xmm1
xorl %eax, %eax
ucomisd %xmm1, %xmm0
jbe 0x1b65e
movl %eax, %ebx
movq 0x278(%r14), %rax
subq 0x270(%r14), %rax
sarq $0x3, %rax
cmpq %rbx, %rax
jbe 0x1b6a0
movq 0x288(%r14), %rax
movq 0x8(%r13), %rdi
movq 0x10(%r13), %rsi
callq *(%rax,%rbx,8)
movq 0x270(%r14), %rcx
movq (%rcx,%rbx,8), %rdi
movl %eax, %esi
callq 0x110ec
leal 0x1(%rbx), %eax
jmp 0x1b61c
movl %eax, %ebx
movq 0x278(%r14), %rax
subq 0x270(%r14), %rax
sarq $0x3, %rax
cmpq %rbx, %rax
jbe 0x1b6a0
movq 0x288(%r14), %rax
movq 0x8(%r13), %rdi
movq 0x10(%r13), %rsi
callq *(%rax,%rbx,8)
movq 0x270(%r14), %rcx
movq (%rcx,%rbx,8), %rdi
movl %eax, %esi
callq 0x1110a
leal 0x1(%rbx), %eax
jmp 0x1b65e
cmpl $0x0, 0x11c(%r13)
movl 0x4(%rsp), %ebx
jne 0x1b6c3
cmpl $0x0, 0x120(%r13)
jne 0x1b6c3
movq 0x340(%r14), %rax
incq -0x8(%rax)
movq %r14, %rdi
movl %ebx, %esi
movl %ebp, %edx
movl %r15d, %ecx
callq 0x1f248
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xdaa7(%rip), %rdi      # 0x29191
leaq 0xfa32(%rip), %rsi      # 0x2b123
leaq 0xfa58(%rip), %rcx      # 0x2b150
movl $0x129, %edx            # imm = 0x129
callq 0x51e0
leaq 0xdae1(%rip), %rdi      # 0x291ea
leaq 0xfa13(%rip), %rsi      # 0x2b123
leaq 0xfa39(%rip), %rcx      # 0x2b150
movl $0x12a, %edx            # imm = 0x12A
callq 0x51e0
nop