// File: /workspace/github_cpp_makefile_star2_O3/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 $0x28, %rsp
movq 0x60(%rdi), %rax
testq %rax, %rax
je 0x2171f
movq %rdi, %r14
movq 0x68(%rdi), %rdi
testq %rdi, %rdi
je 0x2173e
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
leaq (,%r13,2), %rcx
addq %r13, %rcx
movslq %ebp, %rdx
movq (%rax,%rcx,8), %rax
movq (%rax,%rdx,8), %r13
cmpb $0x1, (%r13)
jne 0x216ff
movq %r15, 0x20(%rsp)
movl %ebx, 0xc(%rsp)
leaq 0x24a6a(%rip), %rax     # 0x45f50
cmpb $0x1, 0x1cc(%rax)
jne 0x215f8
movsd 0x130(%r13), %xmm0
leaq 0x24a4d(%rip), %rax     # 0x45f50
cvtsi2sdl 0x1e8(%rax), %xmm1
ucomisd %xmm1, %xmm0
seta %al
xorb %r12b, %al
jne 0x21584
movsd %xmm1, 0x10(%rsp)
movsd %xmm0, 0x18(%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 0x21561
movq 0x288(%r14), %rax
movq 0x8(%r13), %rdi
movq 0x10(%r13), %rsi
callq *0x8(%rax)
cltq
jmp 0x21563
xorl %eax, %eax
movslq %r12d, %rcx
movq 0x418(%r14), %rdx
leaq (%rcx,%rcx,2), %rcx
movq (%rdx,%rcx,8), %rcx
incl (%rcx,%rax,4)
movsd 0x18(%rsp), %xmm0
movsd 0x10(%rsp), %xmm1
movq 0x278(%r14), %rax
cmpq 0x270(%r14), %rax
je 0x215f8
xorl %r12d, %r12d
ucomisd %xmm1, %xmm0
seta %r12b
movl $0x1, %ebx
xorl %r15d, %r15d
movq 0x288(%r14), %rax
movq 0x8(%r13), %rdi
movq 0x10(%r13), %rsi
callq *(%rax,%r15,8)
movq 0xd0(%r13), %rcx
cmpl %r12d, 0x4(%rcx,%r15,8)
jne 0x215dc
movq 0x400(%r14), %rcx
leaq (%r15,%r15,2), %rdx
cltq
movq (%rcx,%rdx,8), %rcx
incl (%rcx,%rax,4)
movq 0x278(%r14), %rax
subq 0x270(%r14), %rax
movl %ebx, %r15d
sarq $0x3, %rax
incl %ebx
cmpq %r15, %rax
ja 0x215a7
cmpb $0x1, 0x148(%r13)
jne 0x216d7
movsd 0x130(%r13), %xmm0
leaq 0x2493a(%rip), %rax     # 0x45f50
xorps %xmm1, %xmm1
cvtsi2sdl 0x1e8(%rax), %xmm1
ucomisd %xmm1, %xmm0
movq 0x270(%r14), %rax
movq 0x278(%r14), %rcx
jbe 0x21689
cmpq %rax, %rcx
je 0x216d7
movl $0x1, %ebx
xorl %r15d, %r15d
movq 0x288(%r14), %rax
movq 0x8(%r13), %rdi
movq 0x10(%r13), %rsi
callq *(%rax,%r15,8)
movq 0x270(%r14), %rcx
movq (%rcx,%r15,8), %rdi
movl %eax, %esi
callq 0x14864
movq 0x278(%r14), %rax
subq 0x270(%r14), %rax
movl %ebx, %r15d
sarq $0x3, %rax
incl %ebx
cmpq %r15, %rax
ja 0x21646
jmp 0x216d7
cmpq %rax, %rcx
je 0x216d7
movl $0x1, %ebx
xorl %r15d, %r15d
movq 0x288(%r14), %rax
movq 0x8(%r13), %rdi
movq 0x10(%r13), %rsi
callq *(%rax,%r15,8)
movq 0x270(%r14), %rcx
movq (%rcx,%r15,8), %rdi
movl %eax, %esi
callq 0x148a8
movq 0x278(%r14), %rax
subq 0x270(%r14), %rax
movl %ebx, %r15d
sarq $0x3, %rax
incl %ebx
cmpq %r15, %rax
ja 0x21696
cmpl $0x0, 0x11c(%r13)
movl 0xc(%rsp), %ebx
movq 0x20(%rsp), %r15
jne 0x216ff
cmpl $0x0, 0x120(%r13)
jne 0x216ff
movq 0x340(%r14), %rax
incq -0x8(%rax)
movq %r14, %rdi
movl %ebx, %esi
movl %ebp, %edx
movl %r15d, %ecx
callq 0x264ec
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x12a4f(%rip), %rdi     # 0x34175
leaq 0x14a46(%rip), %rsi     # 0x36173
leaq 0x14a6c(%rip), %rcx     # 0x361a0
movl $0x129, %edx            # imm = 0x129
callq 0x51d0
leaq 0x12a89(%rip), %rdi     # 0x341ce
leaq 0x14a27(%rip), %rsi     # 0x36173
leaq 0x14a4d(%rip), %rcx     # 0x361a0
movl $0x12a, %edx            # imm = 0x12A
callq 0x51d0
nop