// File: gvaumour[P]cache-simulator/src/Cerebron.cc
// Function: CerebronPredictor::doLearning(CacheEntry*, bool)
void 
CerebronPredictor::doLearning(CacheEntry* entry, bool inNVM)
{
	allocDecision des = getDecision(entry);
	if( simu_parameters.Cerebron_independantLearning)
	{
		for(unsigned i = 0; i < m_features.size() ; i++)
		{
			if( (des == ALLOCATE_IN_NVM && entry->PHC_allocation_pred[i].second == ALLOCATE_IN_SRAM ) || \
			( des == ALLOCATE_IN_SRAM && entry->PHC_allocation_pred[i].second == ALLOCATE_IN_NVM) )
				m_features[i]->decreaseConfidence(entry->PHC_allocation_pred[i].first);
			else 
				m_features[i]->increaseConfidence(entry->PHC_allocation_pred[i].first);
		}
		
		for(unsigned i = 0 ; i < m_features.size() ; i++)
		{
			pair<int , allocDecision> dummy;
			dummy.first = hashing_function1(m_features_hash[i] , entry->address , entry->missPC);
			dummy.second = m_features[i]->getAllocDecision(dummy.first, false);
			entry->PHC_allocation_pred[i] = dummy;
		}
		if(simu_parameters.Cerebron_resetEnergyValues)
		{
			entry->e_sram = 0;
			entry->e_nvm = 0;
		}
	
	}
	else
	{	
		if( ( des == ALLOCATE_IN_NVM && !inNVM) || \
			(des == ALLOCATE_IN_SRAM && inNVM) )
		{
			for(unsigned i = 0; i < m_features.size() ; i++)
			{
				int hash = hashing_function1( m_features_hash[i] , entry->address , entry->missPC);
				m_features[i]->decreaseConfidence(hash);
			}
		}			
		else
		{
			for(unsigned i = 0; i < m_features.size() ; i++)
			{
				int hash = hashing_function1 ( m_features_hash[i] , entry->address , entry->missPC);
				m_features[i]->increaseConfidence(hash);
			}
		}
	}
}

// Assembly:
subq $0x128, %rsp            # imm = 0x128
movb %dl, %al
movq %rdi, 0x120(%rsp)
movq %rsi, 0x118(%rsp)
andb $0x1, %al
movb %al, 0x117(%rsp)
movq 0x120(%rsp), %rdi
movq %rdi, 0x60(%rsp)
movq 0x118(%rsp), %rsi
callq 0xc020
movl %eax, 0x110(%rsp)
leaq 0x89346(%rip), %rax     # 0x93ff0
testb $0x1, 0x220(%rax)
je 0xaf7d
movl $0x0, 0x10c(%rsp)
movq 0x60(%rsp), %rdi
movl 0x10c(%rsp), %eax
movq %rax, 0x58(%rsp)
addq $0x270, %rdi            # imm = 0x270
callq 0xf840
movq %rax, %rcx
movq 0x58(%rsp), %rax
cmpq %rcx, %rax
jae 0xadfa
cmpl $0x1, 0x110(%rsp)
jne 0xad1d
movq 0x118(%rsp), %rdi
addq $0xd0, %rdi
movl 0x10c(%rsp), %eax
movl %eax, %esi
callq 0xf900
cmpl $0x0, 0x4(%rax)
je 0xad4a
cmpl $0x0, 0x110(%rsp)
jne 0xad97
movq 0x118(%rsp), %rdi
addq $0xd0, %rdi
movl 0x10c(%rsp), %eax
movl %eax, %esi
callq 0xf900
cmpl $0x1, 0x4(%rax)
jne 0xad97
movq 0x60(%rsp), %rdi
addq $0x270, %rdi            # imm = 0x270
movl 0x10c(%rsp), %eax
movl %eax, %esi
callq 0xf8c0
movq (%rax), %rax
movq %rax, 0x50(%rsp)
movq 0x118(%rsp), %rdi
addq $0xd0, %rdi
movl 0x10c(%rsp), %eax
movl %eax, %esi
callq 0xf900
movq 0x50(%rsp), %rdi
movl (%rax), %esi
callq 0x2d5a0
jmp 0xade2
movq 0x60(%rsp), %rdi
addq $0x270, %rdi            # imm = 0x270
movl 0x10c(%rsp), %eax
movl %eax, %esi
callq 0xf8c0
movq (%rax), %rax
movq %rax, 0x48(%rsp)
movq 0x118(%rsp), %rdi
addq $0xd0, %rdi
movl 0x10c(%rsp), %eax
movl %eax, %esi
callq 0xf900
movq 0x48(%rsp), %rdi
movl (%rax), %esi
callq 0x2d600
jmp 0xade4
movl 0x10c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x10c(%rsp)
jmp 0xacc2
movl $0x0, 0x108(%rsp)
movq 0x60(%rsp), %rdi
movl 0x108(%rsp), %eax
movq %rax, 0x40(%rsp)
addq $0x270, %rdi            # imm = 0x270
callq 0xf840
movq %rax, %rcx
movq 0x40(%rsp), %rax
cmpq %rcx, %rax
jae 0xaf42
leaq 0x100(%rsp), %rdi
callq 0xf8e0
movq 0x60(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
movl 0x108(%rsp), %eax
movl %eax, %esi
callq 0xf860
movq %rax, %rsi
leaq 0xd8(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0xf880
movq 0x30(%rsp), %rdi
movq 0x118(%rsp), %rax
movq 0x8(%rax), %rsi
movq 0x20(%rax), %rdx
callq 0x2ff40
movl %eax, 0x3c(%rsp)
jmp 0xae8f
movl 0x3c(%rsp), %eax
movl %eax, 0x100(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0xf7b0
movq 0x60(%rsp), %rdi
addq $0x270, %rdi            # imm = 0x270
movl 0x108(%rsp), %eax
movl %eax, %esi
callq 0xf8c0
movq (%rax), %rdi
movl 0x100(%rsp), %esi
xorl %edx, %edx
callq 0x2d360
movl %eax, 0x104(%rsp)
movq 0x118(%rsp), %rdi
addq $0xd0, %rdi
movl 0x108(%rsp), %eax
movl %eax, %esi
callq 0xf900
movq %rax, %rdi
leaq 0x100(%rsp), %rsi
callq 0xf920
movl 0x108(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x108(%rsp)
jmp 0xae05
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0xf7b0
jmp 0xb1ba
leaq 0x890a7(%rip), %rax     # 0x93ff0
testb $0x1, 0x222(%rax)
je 0xaf78
movq 0x118(%rsp), %rax
movq $0x0, 0x138(%rax)
movq 0x118(%rsp), %rax
movq $0x0, 0x140(%rax)
jmp 0xb1b2
cmpl $0x1, 0x110(%rsp)
jne 0xaf91
testb $0x1, 0x117(%rsp)
je 0xafad
cmpl $0x0, 0x110(%rsp)
jne 0xb0b7
testb $0x1, 0x117(%rsp)
je 0xb0b7
movl $0x0, 0xc8(%rsp)
movq 0x60(%rsp), %rdi
movl 0xc8(%rsp), %eax
movq %rax, 0x28(%rsp)
addq $0x270, %rdi            # imm = 0x270
callq 0xf840
movq %rax, %rcx
movq 0x28(%rsp), %rax
cmpq %rcx, %rax
jae 0xb0b2
movq 0x60(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
movl 0xc8(%rsp), %eax
movl %eax, %esi
callq 0xf860
movq %rax, %rsi
leaq 0x98(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0xf880
movq 0x18(%rsp), %rdi
movq 0x118(%rsp), %rax
movq 0x8(%rax), %rsi
movq 0x20(%rax), %rdx
callq 0x2ff40
movl %eax, 0x24(%rsp)
jmp 0xb035
leaq 0x98(%rsp), %rdi
callq 0xf7b0
movl 0x24(%rsp), %eax
movq 0x60(%rsp), %rdi
movl %eax, 0xc4(%rsp)
addq $0x270, %rdi            # imm = 0x270
movl 0xc8(%rsp), %eax
movl %eax, %esi
callq 0xf8c0
movq (%rax), %rdi
movl 0xc4(%rsp), %esi
callq 0x2d5a0
movl 0xc8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc8(%rsp)
jmp 0xafb8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
leaq 0x98(%rsp), %rdi
callq 0xf7b0
jmp 0xb1ba
jmp 0xb1b0
movl $0x0, 0x94(%rsp)
movq 0x60(%rsp), %rdi
movl 0x94(%rsp), %eax
movq %rax, 0x10(%rsp)
addq $0x270, %rdi            # imm = 0x270
callq 0xf840
movq %rax, %rcx
movq 0x10(%rsp), %rax
cmpq %rcx, %rax
jae 0xb1ae
movq 0x60(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
movl 0x94(%rsp), %eax
movl %eax, %esi
callq 0xf860
movq %rax, %rsi
leaq 0x68(%rsp), %rdi
movq %rdi, (%rsp)
callq 0xf880
movq (%rsp), %rdi
movq 0x118(%rsp), %rax
movq 0x8(%rax), %rsi
movq 0x20(%rax), %rdx
callq 0x2ff40
movl %eax, 0xc(%rsp)
jmp 0xb13a
leaq 0x68(%rsp), %rdi
callq 0xf7b0
movl 0xc(%rsp), %eax
movq 0x60(%rsp), %rdi
movl %eax, 0x90(%rsp)
addq $0x270, %rdi            # imm = 0x270
movl 0x94(%rsp), %eax
movl %eax, %esi
callq 0xf8c0
movq (%rax), %rdi
movl 0x90(%rsp), %esi
callq 0x2d600
movl 0x94(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x94(%rsp)
jmp 0xb0c2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
leaq 0x68(%rsp), %rdi
callq 0xf7b0
jmp 0xb1ba
jmp 0xb1b0
jmp 0xb1b2
addq $0x128, %rsp            # imm = 0x128
retq
movq 0xd0(%rsp), %rdi
callq 0x5690
nopw (%rax,%rax)