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

	stats_allocate++;

	/** Training learning cache lines */ 
	if(current->isLearning)
	{
		if(m_enableBP)
		{
			stats_allocate_learning++;
			setBPPrediction(current);		
		}
		
		if(m_enableAllocation)
		{
			if(element.isSRAMerror && !inNVM)
			{
				for(unsigned i = 0 ; i < m_Allocation_features.size() ; i++)
				{
					if( current->perceptron_Allocpred[i] < simu_parameters.perceptron_bypass_learning)
						m_Allocation_features[i]->increaseConfidence(current->perceptron_AllocHash[i]);
				}
			}
		}
	}
	
	if(m_enableAllocation)
	{
		RD_TYPE rd_type = classifyRD(set , index , inNVM);
		if( element.isSRAMerror )
			rd_type = RD_MEDIUM;
		
		for(unsigned i = 0 ; i < m_Allocation_features.size() ; i++)
		{
			int hash = m_Allocation_features_hash[i](current->address , current->m_pc);
			m_Allocation_features[i]->recordAccess( hash  , element.isWrite() , rd_type);
		}
	}
			
	Predictor::insertionPolicy(set , index , inNVM , element);
}

// Assembly:
subq $0xf8, %rsp
movb %cl, %al
leaq 0x100(%rsp), %rcx
movq %rcx, 0x78(%rsp)
movq %rdi, 0xf0(%rsp)
movq %rsi, 0xe8(%rsp)
movq %rdx, 0xe0(%rsp)
andb $0x1, %al
movb %al, 0xdf(%rsp)
movq 0xf0(%rsp), %rdi
movq %rdi, 0x80(%rsp)
movq 0xe8(%rsp), %rsi
movq 0xe0(%rsp), %rdx
movb 0xdf(%rsp), %al
andb $0x1, %al
movzbl %al, %ecx
callq 0x51d00
movq %rax, %rcx
movq 0x80(%rsp), %rax
movq %rcx, 0xd0(%rsp)
movq 0x308(%rax), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, 0x308(%rax)
movl %ecx, %edx
movq 0xd0(%rsp), %rcx
movl %edx, 0x38(%rcx)
movq 0x3e8(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x3e8(%rax)
movq 0xd0(%rsp), %rax
testb $0x1, 0x148(%rax)
je 0x52441
movq 0x80(%rsp), %rax
testb $0x1, 0x348(%rax)
je 0x5233c
movq 0x80(%rsp), %rdi
movq 0x3f0(%rdi), %rax
addq $0x1, %rax
movq %rax, 0x3f0(%rdi)
movq 0xd0(%rsp), %rsi
callq 0x51d90
movq 0x80(%rsp), %rax
testb $0x1, 0x349(%rax)
je 0x5243f
movq 0x78(%rsp), %rax
testb $0x1, 0x28(%rax)
je 0x5243d
testb $0x1, 0xdf(%rsp)
jne 0x5243d
movl $0x0, 0xcc(%rsp)
movq 0x80(%rsp), %rdi
movl 0xcc(%rsp), %eax
movq %rax, 0x70(%rsp)
addq $0x270, %rdi            # imm = 0x270
callq 0xf840
movq %rax, %rcx
movq 0x70(%rsp), %rax
cmpq %rcx, %rax
jae 0x5243b
movq 0xd0(%rsp), %rdi
addq $0x60, %rdi
movl 0xcc(%rsp), %eax
movl %eax, %esi
callq 0xef90
movl (%rax), %eax
leaq 0x41c23(%rip), %rcx     # 0x93ff0
cmpl 0x1bc(%rcx), %eax
jge 0x52423
movq 0x80(%rsp), %rdi
addq $0x270, %rdi            # imm = 0x270
movl 0xcc(%rsp), %eax
movl %eax, %esi
callq 0xf8c0
movq (%rax), %rax
movq %rax, 0x68(%rsp)
movq 0xd0(%rsp), %rdi
addq $0x90, %rdi
movl 0xcc(%rsp), %eax
movl %eax, %esi
callq 0xef90
movq 0x68(%rsp), %rdi
movl (%rax), %esi
callq 0x2d600
jmp 0x52425
movl 0xcc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xcc(%rsp)
jmp 0x52379
jmp 0x5243d
jmp 0x5243f
jmp 0x52441
movq 0x80(%rsp), %rax
testb $0x1, 0x349(%rax)
je 0x5258c
movq 0x80(%rsp), %rdi
movq 0xe8(%rsp), %rax
movl %eax, %esi
movq 0xe0(%rsp), %rax
movl %eax, %edx
movb 0xdf(%rsp), %al
andb $0x1, %al
movzbl %al, %ecx
callq 0x51f10
movl %eax, %ecx
movq 0x78(%rsp), %rax
movl %ecx, 0xc8(%rsp)
testb $0x1, 0x28(%rax)
je 0x524a2
movl $0x1, 0xc8(%rsp)
movl $0x0, 0xc4(%rsp)
movq 0x80(%rsp), %rdi
movl 0xc4(%rsp), %eax
movq %rax, 0x60(%rsp)
addq $0x270, %rdi            # imm = 0x270
callq 0xf840
movq %rax, %rcx
movq 0x60(%rsp), %rax
cmpq %rcx, %rax
jae 0x5258a
movq 0x80(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
movl 0xc4(%rsp), %eax
movl %eax, %esi
callq 0x4d780
movq (%rax), %rax
movq 0xd0(%rsp), %rcx
movq 0x8(%rcx), %rdi
movq 0xd0(%rsp), %rcx
movq 0x10(%rcx), %rsi
callq *%rax
movq 0x80(%rsp), %rdi
movl %eax, 0xc0(%rsp)
addq $0x270, %rdi            # imm = 0x270
movl 0xc4(%rsp), %eax
movl %eax, %esi
callq 0xf8c0
movq 0x78(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0x50(%rsp)
movl 0xc0(%rsp), %eax
movl %eax, 0x5c(%rsp)
callq 0xf7c0
movq 0x50(%rsp), %rdi
movl 0x5c(%rsp), %esi
movl 0xc8(%rsp), %ecx
movzbl %al, %edx
andl $0x1, %edx
callq 0x2cfc0
movl 0xc4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc4(%rsp)
jmp 0x524ad
jmp 0x5258c
movq 0x78(%rsp), %rsi
movq 0xe8(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0xe0(%rsp), %rax
movq %rax, 0x48(%rsp)
movb 0xdf(%rsp), %al
movb %al, 0x3f(%rsp)
leaq 0x88(%rsp), %rdi
movl $0x38, %edx
callq 0x52f0
movb 0x3f(%rsp), %al
movq 0x80(%rsp), %rdi
movq 0x40(%rsp), %rsi
movq 0x48(%rsp), %rdx
movq 0xb8(%rsp), %r8
movq %rsp, %rcx
movq %r8, 0x30(%rcx)
movups 0x88(%rsp), %xmm0
movups 0x98(%rsp), %xmm1
movups 0xa8(%rsp), %xmm2
movups %xmm2, 0x20(%rcx)
movups %xmm1, 0x10(%rcx)
movups %xmm0, (%rcx)
movzbl %al, %ecx
andl $0x1, %ecx
callq 0x55140
addq $0xf8, %rsp
retq
nopw %cs:(%rax,%rax)