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

	if(entry->isLearning)
	{
		if(m_enableBP)
		{
			stats_update_learning++;
			for(unsigned i = 0 ; i < m_BP_features.size() ; i++)
			{
				if( entry->perceptron_BPpred[i] > -simu_parameters.perceptron_bypass_learning || !entry->predictedReused[i])
					m_BP_features[i]->decreaseConfidence(entry->perceptron_BPHash[i]);
			}
			setBPPrediction(entry);
		}
		
		if(m_enableAllocation)
		{
			RD_TYPE rd_type = classifyRD(set , index , inNVM);
			
		
			if(rd_type == RD_SHORT && element.isWrite() && inNVM)
			{
				for(unsigned i = 0 ; i < m_Allocation_features.size() ; i++)
				{
					if( entry->perceptron_Allocpred[i] > - simu_parameters.perceptron_bypass_learning)
						m_Allocation_features[i]->decreaseConfidence(entry->perceptron_AllocHash[i]);
				}		
			}
			setAllocPrediction(entry);

		}
	}
	
	if(m_enableAllocation)
	{
		RD_TYPE rd_type = classifyRD(set , index , inNVM);
	
		for(unsigned i = 0 ; i < m_Allocation_features.size() ; i++)
		{
			int hash = m_Allocation_features_hash[i](entry->address , entry->m_pc);
			m_Allocation_features[i]->recordAccess( hash  , element.isWrite() , rd_type);
		}
	}

	
	stats_nbHits++;
	miss_counter--;
	if(miss_counter < 0)
		miss_counter = 0;


	Predictor::updatePolicy(set , index , inNVM , element , isWBrequest);
}

// Assembly:
subq $0x148, %rsp            # imm = 0x148
movl %r8d, 0x94(%rsp)
movl %ecx, %eax
movl 0x94(%rsp), %ecx
movq %rdx, 0x98(%rsp)
movq %rsi, %rdx
movq 0x98(%rsp), %rsi
movq %rdx, 0xa0(%rsp)
movq %rdi, %r8
movq 0xa0(%rsp), %rdi
movb %al, %dl
leaq 0x150(%rsp), %rax
movq %rax, 0xa8(%rsp)
movq %r8, 0x140(%rsp)
movq %rdi, 0x138(%rsp)
movq %rsi, 0x130(%rsp)
andb $0x1, %dl
movb %dl, 0x12f(%rsp)
andb $0x1, %cl
movb %cl, 0x12e(%rsp)
movq 0x140(%rsp), %rdi
movq %rdi, 0xb0(%rsp)
movq 0x10(%rax), %rsi
callq 0x51630
movq 0xb0(%rsp), %rdi
movq 0x3d8(%rdi), %rax
addq $0x1, %rax
movq %rax, 0x3d8(%rdi)
movq 0x138(%rsp), %rsi
movq 0x130(%rsp), %rdx
movb 0x12f(%rsp), %al
andb $0x1, %al
movzbl %al, %ecx
callq 0x51d00
movq 0xb0(%rsp), %rcx
movq %rax, 0x120(%rsp)
movq 0x308(%rcx), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0x308(%rcx)
movl %eax, %ecx
movq 0x120(%rsp), %rax
movl %ecx, 0x38(%rax)
movq 0x120(%rsp), %rax
testb $0x1, 0x148(%rax)
je 0x51acd
movq 0xb0(%rsp), %rax
testb $0x1, 0x348(%rax)
je 0x51968
movq 0xb0(%rsp), %rax
movq 0x3e0(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x3e0(%rax)
movl $0x0, 0x11c(%rsp)
movq 0xb0(%rsp), %rdi
movl 0x11c(%rsp), %eax
movq %rax, 0x88(%rsp)
addq $0x2b8, %rdi            # imm = 0x2B8
callq 0xf840
movq %rax, %rcx
movq 0x88(%rsp), %rax
cmpq %rcx, %rax
jae 0x51953
movq 0x120(%rsp), %rdi
addq $0x48, %rdi
movl 0x11c(%rsp), %eax
movl %eax, %esi
callq 0xef90
movl (%rax), %ecx
xorl %edx, %edx
leaq 0x42763(%rip), %rax     # 0x93ff0
subl 0x1bc(%rax), %edx
movb $0x1, %al
cmpl %edx, %ecx
movb %al, 0x87(%rsp)
jg 0x518e3
movq 0x120(%rsp), %rdi
addq $0xa8, %rdi
movl 0x11c(%rsp), %eax
movl %eax, %esi
callq 0xfa90
movq %rax, 0x108(%rsp)
movq %rdx, 0x110(%rsp)
leaq 0x108(%rsp), %rdi
callq 0xfaf0
xorb $-0x1, %al
movb %al, 0x87(%rsp)
movb 0x87(%rsp), %al
testb $0x1, %al
jne 0x518f0
jmp 0x5193b
movq 0xb0(%rsp), %rdi
addq $0x2b8, %rdi            # imm = 0x2B8
movl 0x11c(%rsp), %eax
movl %eax, %esi
callq 0xf8c0
movq (%rax), %rax
movq %rax, 0x78(%rsp)
movq 0x120(%rsp), %rdi
addq $0x78, %rdi
movl 0x11c(%rsp), %eax
movl %eax, %esi
callq 0xef90
movq 0x78(%rsp), %rdi
movl (%rax), %esi
callq 0x2d5a0
jmp 0x5193d
movl 0x11c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x11c(%rsp)
jmp 0x51831
movq 0xb0(%rsp), %rdi
movq 0x120(%rsp), %rsi
callq 0x51d90
movq 0xb0(%rsp), %rax
testb $0x1, 0x349(%rax)
je 0x51acb
movq 0xb0(%rsp), %rdi
movq 0x138(%rsp), %rax
movl %eax, %esi
movq 0x130(%rsp), %rax
movl %eax, %edx
movb 0x12f(%rsp), %al
andb $0x1, %al
movzbl %al, %ecx
callq 0x51f10
movl %eax, 0x104(%rsp)
cmpl $0x0, 0x104(%rsp)
jne 0x51ab6
movq 0xa8(%rsp), %rdi
callq 0xf7c0
testb $0x1, %al
jne 0x519d5
jmp 0x51ab6
testb $0x1, 0x12f(%rsp)
je 0x51ab6
movl $0x0, 0x100(%rsp)
movq 0xb0(%rsp), %rdi
movl 0x100(%rsp), %eax
movq %rax, 0x70(%rsp)
addq $0x270, %rdi            # imm = 0x270
callq 0xf840
movq %rax, %rcx
movq 0x70(%rsp), %rax
cmpq %rcx, %rax
jae 0x51ab4
movq 0x120(%rsp), %rdi
addq $0x60, %rdi
movl 0x100(%rsp), %eax
movl %eax, %esi
callq 0xef90
movl (%rax), %eax
xorl %ecx, %ecx
leaq 0x425ac(%rip), %rdx     # 0x93ff0
subl 0x1bc(%rdx), %ecx
cmpl %ecx, %eax
jle 0x51a9c
movq 0xb0(%rsp), %rdi
addq $0x270, %rdi            # imm = 0x270
movl 0x100(%rsp), %eax
movl %eax, %esi
callq 0xf8c0
movq (%rax), %rax
movq %rax, 0x68(%rsp)
movq 0x120(%rsp), %rdi
addq $0x90, %rdi
movl 0x100(%rsp), %eax
movl %eax, %esi
callq 0xef90
movq 0x68(%rsp), %rdi
movl (%rax), %esi
callq 0x2d5a0
jmp 0x51a9e
movl 0x100(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x100(%rsp)
jmp 0x519ee
jmp 0x51ab6
movq 0xb0(%rsp), %rdi
movq 0x120(%rsp), %rsi
callq 0x52130
jmp 0x51acd
movq 0xb0(%rsp), %rax
testb $0x1, 0x349(%rax)
je 0x51c03
movq 0xb0(%rsp), %rdi
movq 0x138(%rsp), %rax
movl %eax, %esi
movq 0x130(%rsp), %rax
movl %eax, %edx
movb 0x12f(%rsp), %al
andb $0x1, %al
movzbl %al, %ecx
callq 0x51f10
movl %eax, 0xfc(%rsp)
movl $0x0, 0xf8(%rsp)
movq 0xb0(%rsp), %rdi
movl 0xf8(%rsp), %eax
movq %rax, 0x60(%rsp)
addq $0x270, %rdi            # imm = 0x270
callq 0xf840
movq %rax, %rcx
movq 0x60(%rsp), %rax
cmpq %rcx, %rax
jae 0x51c01
movq 0xb0(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
movl 0xf8(%rsp), %eax
movl %eax, %esi
callq 0x4d780
movq (%rax), %rax
movq 0x120(%rsp), %rcx
movq 0x8(%rcx), %rdi
movq 0x120(%rsp), %rcx
movq 0x10(%rcx), %rsi
callq *%rax
movq 0xb0(%rsp), %rdi
movl %eax, 0xf4(%rsp)
addq $0x270, %rdi            # imm = 0x270
movl 0xf8(%rsp), %eax
movl %eax, %esi
callq 0xf8c0
movq 0xa8(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0x50(%rsp)
movl 0xf4(%rsp), %eax
movl %eax, 0x5c(%rsp)
callq 0xf7c0
movq 0x50(%rsp), %rdi
movl 0x5c(%rsp), %esi
movl 0xfc(%rsp), %ecx
movzbl %al, %edx
andl $0x1, %edx
callq 0x2cfc0
movl 0xf8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xf8(%rsp)
jmp 0x51b21
jmp 0x51c03
movq 0xb0(%rsp), %rax
movq 0x3a0(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x3a0(%rax)
leaq 0x4261c(%rip), %rax     # 0x94240
movl (%rax), %ecx
addl $-0x1, %ecx
leaq 0x42610(%rip), %rax     # 0x94240
movl %ecx, (%rax)
leaq 0x42607(%rip), %rax     # 0x94240
cmpl $0x0, (%rax)
jge 0x51c4b
leaq 0x425fb(%rip), %rax     # 0x94240
movl $0x0, (%rax)
movq 0xa8(%rsp), %rsi
movq 0x138(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x130(%rsp), %rax
movq %rax, 0x48(%rsp)
movb 0x12f(%rsp), %al
movb %al, 0x3f(%rsp)
leaq 0xb8(%rsp), %rdi
movl $0x38, %edx
callq 0x52f0
movb 0x3f(%rsp), %cl
movq 0xb0(%rsp), %rdi
movq 0x40(%rsp), %rsi
movq 0x48(%rsp), %rdx
movb 0x12e(%rsp), %al
movq 0xe8(%rsp), %r9
movq %rsp, %r8
movq %r9, 0x30(%r8)
movups 0xb8(%rsp), %xmm0
movups 0xc8(%rsp), %xmm1
movups 0xd8(%rsp), %xmm2
movups %xmm2, 0x20(%r8)
movups %xmm1, 0x10(%r8)
movups %xmm0, (%r8)
movzbl %cl, %ecx
andl $0x1, %ecx
movzbl %al, %r8d
andl $0x1, %r8d
callq 0x56ed0
addq $0x148, %rsp            # imm = 0x148
retq
nopw (%rax,%rax)