// File: /workspace/github_cpp_makefile_star2_O2/gvaumour[P]cache-simulator/src/SaturationPredictor.cc
// Function: SaturationCounter::updatePolicy(unsigned long, unsigned long, bool, Access, bool)
void SaturationCounter::updatePolicy(uint64_t set, uint64_t index, bool inNVM, Access element , bool isWBrequest = false)
{
	//DPRINTF("SaturationCounter::updatePolicy\n");
	
	if(inNVM){
		//Update NVM entry 
		CacheEntry* current = m_tableNVM[set][index];
		current->policyInfo = m_cpt;
		
		if(element.isWrite()){
			current->saturation_counter++;
			if(current->saturation_counter == simu_parameters.saturation_threshold)
			{
				//Trigger Migration
				//Select LRU candidate from SRAM cache
				//DPRINTF("SaturationCounter:: Migration Triggered from NVM\n");

				int id_assoc = evictPolicy(set, false);
				
				CacheEntry* replaced_entry = m_tableSRAM[set][id_assoc];
			
				current->saturation_counter = 0;
				replaced_entry->saturation_counter = 0;
			
				/** Migration incurs one read and one extra write */ 
				replaced_entry->nbWrite++;
				current->nbRead++;

				Predictor::migrationRecording();
				m_cache->triggerMigration(set, id_assoc , index , true);
				if(!m_isWarmup)
					stats_nbMigrationsFromNVM[inNVM]++;

				
			}
		}
		else{
			current->saturation_counter--;
			if(current->saturation_counter < 0)
				current->saturation_counter = 0;					
		}
			
	}
	else{// Update SRAM entry 
		CacheEntry* current = m_tableSRAM[set][index];
		current->policyInfo = m_cpt;
		
		if(element.isWrite())
		{
			current->saturation_counter--;
			if(current->saturation_counter < 0)
				current->saturation_counter = 0;
		}
		else{
			current->saturation_counter++;
			if(current->saturation_counter == simu_parameters.saturation_threshold)
			{
				//Trigger Migration
				//DPRINTF("SaturationCounter:: Migration Triggered from SRAM\n");
				int id_assoc = evictPolicy(set, true);//Select LRU candidate from NVM cache

				CacheEntry* replaced_entry = m_tableNVM[set][id_assoc];
				assert(replaced_entry != NULL);
							
				current->saturation_counter = 0;
				replaced_entry->saturation_counter = 0;
		
				Predictor::migrationRecording();
		
				/** Migration incurs one read and one extra write */ 
				replaced_entry->nbWrite++;
				current->nbRead++;

				m_cache->triggerMigration(set, index, id_assoc, false);
			
				if(!m_isWarmup)
					stats_nbMigrationsFromNVM[inNVM]++;

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

	m_cpt++;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movl %ecx, %r9d
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
leaq 0x80(%rsp), %rbp
movl 0x270(%rdi), %eax
testl %ecx, %ecx
je 0x21bc7
movq 0x10(%rbx), %rcx
movq (%rcx), %rcx
imulq $0x18, %r15, %r12
movq (%rcx,%r12), %rcx
movq (%rcx,%r14,8), %r13
movl %eax, 0x38(%r13)
movl 0x1c(%rbp), %eax
cmpl $0x6, %eax
je 0x21b1e
cmpl $0x3, %eax
jne 0x21beb
movl 0x128(%r13), %eax
incl %eax
movl %eax, 0x128(%r13)
leaq 0x1c41b(%rip), %rcx     # 0x3df50
cmpl 0xb8(%rcx), %eax
jne 0x21c03
movq (%rbx), %rax
movq %rbx, %rdi
movl %r15d, %esi
xorl %edx, %edx
movl %r8d, 0x40(%rsp)
movl %r9d, 0x3c(%rsp)
callq *0x28(%rax)
movq 0x8(%rbx), %rcx
movq (%rcx), %rcx
movslq %eax, %rdx
movq (%rcx,%r12), %rax
movq (%rax,%rdx,8), %rax
movq %rdx, %r12
andl $0x0, 0x128(%r13)
andl $0x0, 0x128(%rax)
incl 0x11c(%rax)
incl 0x120(%r13)
movq %rbx, %rdi
callq 0x1fe30
movq 0x70(%rbx), %rdi
pushq $0x1
popq %r8
movl %r15d, %esi
movl %r12d, %edx
movl %r14d, %ecx
callq 0x163be
movl 0x3c(%rsp), %r9d
movl 0x40(%rsp), %r8d
cmpb $0x0, 0x81(%rbx)
jne 0x21c03
movq 0x278(%rbx), %rax
incl 0x4(%rax)
jmp 0x21c03
movq 0x8(%rbx), %rcx
movq (%rcx), %rcx
imulq $0x18, %r15, %r12
movq (%rcx,%r12), %rcx
movq (%rcx,%r14,8), %r13
movl %eax, 0x38(%r13)
movl 0x1c(%rbp), %eax
cmpl $0x6, %eax
je 0x21beb
cmpl $0x3, %eax
jne 0x21c51
movl 0x128(%r13), %eax
leal -0x1(%rax), %ecx
xorl %edx, %edx
testl %eax, %eax
cmovgl %ecx, %edx
movl %edx, 0x128(%r13)
movq 0x30(%rbp), %rax
movq %rax, 0x30(%rsp)
movups (%rbp), %xmm0
movups 0x10(%rbp), %xmm1
movups 0x20(%rbp), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movzbl %r9b, %ecx
movzbl %r8b, %r8d
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x1fe44
incl 0x270(%rbx)
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl 0x128(%r13), %eax
incl %eax
movl %eax, 0x128(%r13)
leaq 0x1c2e8(%rip), %rcx     # 0x3df50
cmpl 0xb8(%rcx), %eax
jne 0x21c03
movl %r9d, 0x3c(%rsp)
movl %r8d, 0x40(%rsp)
movq (%rbx), %rax
pushq $0x1
popq %rdx
movq %rbx, %rdi
movl %r15d, %esi
callq *0x28(%rax)
movq 0x10(%rbx), %rcx
movq (%rcx), %rdx
movl %eax, 0x44(%rsp)
movslq %eax, %rcx
movq (%rdx,%r12), %rax
movq (%rax,%rcx,8), %r12
testq %r12, %r12
je 0x21d07
andl $0x0, 0x128(%r13)
andl $0x0, 0x128(%r12)
movq %rbx, %rdi
callq 0x1fe30
incl 0x11c(%r12)
incl 0x120(%r13)
movq 0x70(%rbx), %rdi
movl %r15d, %esi
movl %r14d, %edx
movl 0x44(%rsp), %ecx
xorl %r8d, %r8d
callq 0x163be
cmpb $0x0, 0x81(%rbx)
movl 0x40(%rsp), %r8d
movl 0x3c(%rsp), %r9d
jne 0x21c03
movq 0x278(%rbx), %rax
incl (%rax)
jmp 0x21c03
leaq 0x9e4d(%rip), %rdi      # 0x2bb5b
leaq 0x9e5d(%rip), %rsi      # 0x2bb72
leaq 0x9e71(%rip), %rcx      # 0x2bb8d
pushq $0x5e
popq %rdx
callq 0x51e0