// File: /workspace/github_cpp_makefile_star2_O1/gvaumour[P]cache-simulator/src/DBAMBPredictor.cc
// Function: DBAMBPredictor::checkLazyMigration(DHPEntry*, CacheEntry*, unsigned long, bool, unsigned long, bool)
CacheEntry*
DBAMBPredictor::checkLazyMigration(DHPEntry* rap_current , CacheEntry* current ,uint64_t set,bool inNVM, uint64_t index, bool isWrite)
{
	if( inNVM == false && rap_current->des == ALLOCATE_IN_NVM)
	{
		//cl is SRAM , check whether we should migrate to NVM 
		if(simu_parameters.enableDatasetSpilling && m_isNVMbusy[set])
		{
			reportSpilling(rap_current, current->address, false ,  inNVM);
			stats_busyness_migrate_change++; //If NVM tab is busy , don't migrate
		}
		else
		{
			//Trigger Migration
			int id_assoc = evictPolicy(set, true);//Select LRU candidate from NVM cache
			//DPRINTF("DBAMBPredictor:: Migration Triggered from SRAM, index %ld, id_assoc %d \n" , index, id_assoc);

			CacheEntry* replaced_entry = m_tableNVM[set][id_assoc];
					
			/** Migration incurs one read and one extra write */ 
			replaced_entry->nbWrite++;
			current->nbRead++;
		
			/* Record the write error migration */ 
			Predictor::migrationRecording();
		
			reportMigration(rap_current, current, false);
		
			m_cache->triggerMigration(set, index , id_assoc , false);
			if(!m_isWarmup)
				stats_nbMigrationsFromNVM.back()[FROMSRAM]++;


			current = replaced_entry;
		}

	}
	else if( rap_current->des == ALLOCATE_IN_SRAM && inNVM == true)
	{
		//cl is in NVM , check whether we should migrate to SRAM 
			
		//If SRAM tab is busy , don't migrate
		if(simu_parameters.enableDatasetSpilling && m_isSRAMbusy[set])
		{
			reportSpilling(rap_current, current->address, false ,  inNVM);
			stats_busyness_migrate_change++; //If NVM tab is busy , don't migrate
		}
		else 
		{		
			int id_assoc = evictPolicy(set, false);
		
			CacheEntry* replaced_entry = m_tableSRAM[set][id_assoc];

			/** Migration incurs one read and one extra write */ 
			replaced_entry->nbWrite++;
			current->nbRead++;
			reportMigration(rap_current, current, true);
	
			m_cache->triggerMigration(set, id_assoc , index , true);
		
			if(!m_isWarmup)
				stats_nbMigrationsFromNVM.back()[FROMNVM]++;

			current = replaced_entry;		
		}

	}
	return current;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rcx, %r12
movq %rdx, %r14
movq %rsi, %r13
movq %rdi, %rbx
testl %r8d, %r8d
jne 0xfd84
cmpl $0x1, 0x28(%r13)
jne 0xfd84
leaq 0x3622c(%rip), %rax     # 0x45f50
cmpb $0x1, 0x158(%rax)
jne 0xfe83
leaq 0x3f(%r12), %rax
testq %r12, %r12
cmovnsq %r12, %rax
sarq $0x6, %rax
shlq $0x3, %rax
addq 0x110(%rbx), %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
leaq 0x3f(%rcx), %rdx
andq %r12, %rdx
xorl %esi, %esi
cmpq %rcx, %rdx
setbe %sil
movq -0x8(%rax,%rsi,8), %rax
btq %r12, %rax
jae 0xfe83
movq 0x8(%r14), %rdx
movzbl %r8b, %r8d
movq %r13, %rsi
xorl %ecx, %ecx
jmp 0xfdf8
cmpl $0x0, 0x28(%r13)
setne %al
xorb $0x1, %r8b
orb %al, %r8b
jne 0xff00
leaq 0x361b0(%rip), %rax     # 0x45f50
cmpb $0x1, 0x158(%rax)
jne 0xfe09
leaq 0x3f(%r12), %rax
testq %r12, %r12
cmovnsq %r12, %rax
sarq $0x6, %rax
shlq $0x3, %rax
addq 0xe8(%rbx), %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
leaq 0x3f(%rcx), %rdx
andq %r12, %rdx
xorl %esi, %esi
cmpq %rcx, %rdx
setbe %sil
movq -0x8(%rax,%rsi,8), %rax
btq %r12, %rax
jae 0xfe09
movq 0x8(%r14), %rdx
movq %r13, %rsi
xorl %ecx, %ecx
movl $0x1, %r8d
callq 0xe90e
incq 0x380(%rbx)
jmp 0xff00
movq (%rbx), %rax
movq %rbx, %rdi
movl %r12d, %esi
xorl %edx, %edx
movq %r9, (%rsp)
callq *0x28(%rax)
movq 0x8(%rbx), %rcx
movq (%rcx), %rcx
leaq (%r12,%r12,2), %rdx
movslq %eax, %rbp
movq (%rcx,%rdx,8), %rax
movq (%rax,%rbp,8), %r15
incl 0x11c(%r15)
incl 0x120(%r14)
movq %r13, %rsi
movq %r14, %rdx
movl $0x1, %ecx
callq 0x102ec
movq 0x70(%rbx), %rdi
movl %r12d, %esi
movl %ebp, %edx
movq (%rsp), %rcx
movl $0x1, %r8d
callq 0x1b87a
cmpb $0x0, 0x81(%rbx)
jne 0xfefd
movq 0x3c0(%rbx), %rax
movq -0x18(%rax), %rax
incl (%rax)
jmp 0xfefd
movq (%rbx), %rax
movq %rbx, %rdi
movl %r12d, %esi
movl $0x1, %edx
movq %r9, (%rsp)
callq *0x28(%rax)
movq 0x10(%rbx), %rcx
movq (%rcx), %rcx
leaq (%r12,%r12,2), %rdx
movslq %eax, %rbp
movq (%rcx,%rdx,8), %rax
movq (%rax,%rbp,8), %r15
incl 0x11c(%r15)
incl 0x120(%r14)
movq %rbx, %rdi
callq 0x275aa
movq %r13, %rsi
movq %r14, %rdx
xorl %ecx, %ecx
callq 0x102ec
movq 0x70(%rbx), %rdi
movl %r12d, %esi
movq (%rsp), %rdx
movl %ebp, %ecx
xorl %r8d, %r8d
callq 0x1b87a
cmpb $0x0, 0x81(%rbx)
jne 0xfefd
movq 0x3c0(%rbx), %rax
movq -0x18(%rax), %rax
incl 0x4(%rax)
movq %r15, %r14
movq %r14, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq