// File: /workspace/github_cpp_makefile_star2_O2/gvaumour[P]cache-simulator/src/PHC.cc
// Function: PHCPredictor::insertionPolicy(unsigned long, unsigned long, bool, Access)
void
PHCPredictor::insertionPolicy(uint64_t set, uint64_t index, bool inNVM, Access element)
{
	CacheEntry* entry = get_entry(set , index , inNVM);
	entry->policyInfo = m_cpt++;

	RD_TYPE rd = RD_NOT_ACCURATE;
	
	stats_allocate++;
	if( element.isSRAMerror)
	{
		rd = RD_MEDIUM;	
		stats_cptSRAMerror++;
	}
		
	stats_access_class[rd][element.isWrite()]++;
	
	/** Training learning cache lines */ 
	/*if(entry->isLearning)
	{
//		cout << "Insertion Learning Cache line 0x" << std::hex << element.block_addr << endl;
	*/
/*
	string alloc = inNVM ? "NVM" : "SRAM";
	cout << "Insertion Block addr = 0x" << std::hex << element.block_addr << std::dec << " in " << alloc << "; Prediction per feature:" << endl;
*/
	for(unsigned i = 0 ; i < m_features.size() ; i++)
	{
		int hash = m_features_hash[i](element.block_addr , element.m_pc);
		int pred = m_features[i]->getAllocationPrediction(hash, true);		
		allocDecision des = ALLOCATE_IN_SRAM;
		if( abs(pred) < simu_parameters.perceptron_allocation_threshold)
			des = element.isWrite() ? ALLOCATE_IN_SRAM : ALLOCATE_IN_NVM;
		if(pred > 0 )
			des = ALLOCATE_IN_NVM;
			
//		cout << "\t- " << m_criterias_names[i] << " : " << str_allocDecision[des]  << ", " << hash  << ", " << pred << endl; 
		entry->PHC_allocation_pred[i].second = des; 
		entry->PHC_allocation_pred[i].first = hash; 
		
	}
	if( element.isSRAMerror)
	{
		for(unsigned i = 0 ; i < m_features.size() ; i++)
		{
			int hash = m_features_hash[i](element.block_addr , element.m_pc);
			m_features[i]->increaseAlloc(hash);			
		}
		entry->cost_value = missingTagCostValue(element.block_addr , set) +  m_costAccess[element.isWrite()][RD_MEDIUM];
		stats_cptLearningSRAMerror++;		
	}
	else
		entry->cost_value = m_costAccess[element.isWrite()][RD_SHORT];

			
	Predictor::insertionPolicy(set , index , inNVM , element);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdi, %r15
movl %ecx, 0x1c(%rsp)
movl %ecx, %eax
movq 0x8(%rdi,%rax,8), %rax
movq (%rax), %rax
imulq $0x18, %rsi, %rcx
movq (%rax,%rcx), %rax
movq %rdx, 0x30(%rsp)
movq (%rax,%rdx,8), %rdx
movq 0x2d8(%rdi), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x2d8(%rdi)
movq %rdx, 0x10(%rsp)
movl %eax, 0x38(%rdx)
incq 0x3b8(%rdi)
leaq 0x70(%rsp), %rax
movb 0x28(%rax), %cl
movb %cl, 0xf(%rsp)
cmpb $0x1, %cl
movq %rsi, 0x28(%rsp)
jne 0x1b2da
incq 0x3d0(%r15)
pushq $0x1
jmp 0x1b2dc
pushq $0x2
popq %rcx
movq 0x430(%r15), %rdx
imulq $0x18, %rcx, %rcx
movl 0x1c(%rax), %esi
cmpl $0x3, %esi
sete %dil
cmpl $0x6, %esi
sete %sil
orb %dil, %sil
movzbl %sil, %esi
movq (%rdx,%rcx), %rcx
incl (%rcx,%rsi,4)
movq 0x10(%rax), %r13
movq 0x30(%rax), %r12
movq %rsi, 0x20(%rsp)
movl %esi, %r14d
xorb $0x1, %r14b
xorl %eax, %eax
movl %eax, %ebx
movq 0x270(%r15), %rcx
movq 0x278(%r15), %rax
movq %rax, %rdx
subq %rcx, %rdx
sarq $0x3, %rdx
cmpq %rbx, %rdx
jbe 0x1b3a5
movq 0x288(%r15), %rax
movq %r12, %rdi
movq %r13, %rsi
callq *(%rax,%rbx,8)
movl %eax, %ebp
movq 0x270(%r15), %rax
movq (%rax,%rbx,8), %rdi
movl %ebp, %esi
pushq $0x1
popq %rdx
callq 0x11126
movl %eax, %ecx
negl %ecx
cmovsl %eax, %ecx
leaq 0x22bdf(%rip), %rdx     # 0x3df50
cmpl 0x1c0(%rdx), %ecx
setl %cl
andb %r14b, %cl
testl %eax, %eax
setg %al
orb %cl, %al
movzbl %al, %eax
andl $0x1, %eax
movq 0x10(%rsp), %rcx
movq 0xd0(%rcx), %rcx
movl %eax, 0x4(%rcx,%rbx,8)
movl %ebp, (%rcx,%rbx,8)
leal 0x1(%rbx), %eax
jmp 0x1b31d
cmpb $0x0, 0xf(%rsp)
je 0x1b3f1
xorl %edx, %edx
subq %rcx, %rax
movl %edx, %ebx
sarq $0x3, %rax
cmpq %rbx, %rax
jbe 0x1b41a
movq 0x288(%r15), %rax
movq %r12, %rdi
movq %r13, %rsi
callq *(%rax,%rbx,8)
movq 0x270(%r15), %rcx
movq (%rcx,%rbx,8), %rdi
movl %eax, %esi
callq 0x1110a
leal 0x1(%rbx), %edx
movq 0x270(%r15), %rcx
movq 0x278(%r15), %rax
jmp 0x1b3ae
movq 0x2b8(%r15), %rax
imulq $0x18, 0x20(%rsp), %rcx
movq (%rax,%rcx), %rax
cvtsi2sdl (%rax), %xmm0
movq 0x10(%rsp), %rax
movsd %xmm0, 0x130(%rax)
movq 0x28(%rsp), %rbx
jmp 0x1b458
movq %r15, %rdi
movq %r12, %rsi
movq 0x28(%rsp), %rbx
movl %ebx, %edx
callq 0x1f9f4
movq 0x2b8(%r15), %rcx
imulq $0x18, 0x20(%rsp), %rdx
movq (%rcx,%rdx), %rcx
addl 0x4(%rcx), %eax
cvtsi2sd %eax, %xmm0
movq 0x10(%rsp), %rax
movsd %xmm0, 0x130(%rax)
incq 0x3c8(%r15)
movzbl 0x1c(%rsp), %ecx
movq %r15, %rdi
movq %rbx, %rsi
movq 0x30(%rsp), %rdx
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1f3a2
nop