// File: 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:
subq $0xa8, %rsp
movl %r8d, %eax
movq %rcx, 0x10(%rsp)
movq %rdx, %rcx
movq 0x10(%rsp), %rdx
movq %rcx, 0x18(%rsp)
movq %rsi, %rcx
movq 0x18(%rsp), %rsi
movq %rcx, 0x20(%rsp)
movq %rdi, %r8
movq 0x20(%rsp), %rdi
movb %al, %cl
movb 0xb0(%rsp), %al
movq %r8, 0xa0(%rsp)
movq %rdi, 0x98(%rsp)
movq %rsi, 0x90(%rsp)
movq %rdx, 0x88(%rsp)
andb $0x1, %cl
movb %cl, 0x87(%rsp)
movq %r9, 0x78(%rsp)
andb $0x1, %al
movb %al, 0x77(%rsp)
movq 0xa0(%rsp), %rax
movq %rax, 0x28(%rsp)
movb 0x87(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x1d2a4
movq 0x98(%rsp), %rax
cmpl $0x1, 0x28(%rax)
jne 0x1d2a4
xorl %eax, %eax
leaq 0x76ee4(%rip), %rcx     # 0x93ff0
testb $0x1, 0x158(%rcx)
movb %al, 0xf(%rsp)
je 0x1d14a
movq 0x28(%rsp), %rdi
addq $0x110, %rdi            # imm = 0x110
movq 0x88(%rsp), %rsi
callq 0xfa90
movq %rax, 0x60(%rsp)
movq %rdx, 0x68(%rsp)
leaq 0x60(%rsp), %rdi
callq 0xfaf0
movb %al, 0xf(%rsp)
movb 0xf(%rsp), %al
testb $0x1, %al
jne 0x1d154
jmp 0x1d19d
movq 0x28(%rsp), %rdi
movq 0x98(%rsp), %rsi
movq 0x90(%rsp), %rax
movq 0x8(%rax), %rdx
movb 0x87(%rsp), %al
xorl %ecx, %ecx
andb $0x1, %al
movzbl %al, %r8d
callq 0x1b250
movq 0x28(%rsp), %rax
movq 0x380(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x380(%rax)
jmp 0x1d29f
movq 0x28(%rsp), %rdi
movq 0x88(%rsp), %rax
movl %eax, %esi
movq (%rdi), %rax
movl $0x1, %edx
callq *0x28(%rax)
movl %eax, %ecx
movq 0x28(%rsp), %rax
movl %ecx, 0x5c(%rsp)
movq 0x10(%rax), %rdi
movq 0x88(%rsp), %rsi
callq 0xf9a0
movq %rax, %rdi
movslq 0x5c(%rsp), %rsi
callq 0xf9c0
movq 0x28(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rax
movl 0x11c(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x11c(%rax)
movq 0x90(%rsp), %rax
movl 0x120(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x120(%rax)
callq 0x56e70
movq 0x28(%rsp), %rdi
movq 0x98(%rsp), %rsi
movq 0x90(%rsp), %rdx
xorl %ecx, %ecx
callq 0x1dad0
movq 0x28(%rsp), %rax
movq 0x70(%rax), %rdi
movq 0x88(%rsp), %rax
movl %eax, %esi
movq 0x78(%rsp), %rax
movl %eax, %edx
movl 0x5c(%rsp), %ecx
xorl %r8d, %r8d
callq 0x3ac00
movq 0x28(%rsp), %rax
testb $0x1, 0x81(%rax)
jne 0x1d292
movq 0x28(%rsp), %rdi
addq $0x3b8, %rdi            # imm = 0x3B8
callq 0x20d10
movq %rax, %rdi
movl $0x1, %esi
callq 0xef90
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq 0x50(%rsp), %rax
movq %rax, 0x90(%rsp)
jmp 0x1d463
movq 0x98(%rsp), %rax
cmpl $0x0, 0x28(%rax)
jne 0x1d461
movb 0x87(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x1d461
xorl %eax, %eax
leaq 0x76d1c(%rip), %rcx     # 0x93ff0
testb $0x1, 0x158(%rcx)
movb %al, 0xe(%rsp)
je 0x1d312
movq 0x28(%rsp), %rdi
addq $0xe8, %rdi
movq 0x88(%rsp), %rsi
callq 0xfa90
movq %rax, 0x40(%rsp)
movq %rdx, 0x48(%rsp)
leaq 0x40(%rsp), %rdi
callq 0xfaf0
movb %al, 0xe(%rsp)
movb 0xe(%rsp), %al
testb $0x1, %al
jne 0x1d31c
jmp 0x1d365
movq 0x28(%rsp), %rdi
movq 0x98(%rsp), %rsi
movq 0x90(%rsp), %rax
movq 0x8(%rax), %rdx
movb 0x87(%rsp), %al
xorl %ecx, %ecx
andb $0x1, %al
movzbl %al, %r8d
callq 0x1b250
movq 0x28(%rsp), %rax
movq 0x380(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x380(%rax)
jmp 0x1d45f
movq 0x28(%rsp), %rdi
movq 0x88(%rsp), %rax
movl %eax, %esi
movq (%rdi), %rax
xorl %edx, %edx
callq *0x28(%rax)
movl %eax, %ecx
movq 0x28(%rsp), %rax
movl %ecx, 0x3c(%rsp)
movq 0x8(%rax), %rdi
movq 0x88(%rsp), %rsi
callq 0xf9a0
movq %rax, %rdi
movslq 0x3c(%rsp), %rsi
callq 0xf9c0
movq 0x28(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rax
movl 0x11c(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x11c(%rax)
movq 0x90(%rsp), %rax
movl 0x120(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x120(%rax)
movq 0x98(%rsp), %rsi
movq 0x90(%rsp), %rdx
movl $0x1, %ecx
callq 0x1dad0
movq 0x28(%rsp), %rax
movq 0x70(%rax), %rdi
movq 0x88(%rsp), %rax
movl %eax, %esi
movl 0x3c(%rsp), %edx
movq 0x78(%rsp), %rax
movl %eax, %ecx
movl $0x1, %r8d
callq 0x3ac00
movq 0x28(%rsp), %rax
testb $0x1, 0x81(%rax)
jne 0x1d452
movq 0x28(%rsp), %rdi
addq $0x3b8, %rdi            # imm = 0x3B8
callq 0x20d10
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xef90
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq 0x30(%rsp), %rax
movq %rax, 0x90(%rsp)
jmp 0x1d461
jmp 0x1d463
movq 0x90(%rsp), %rax
addq $0xa8, %rsp
retq
nopw %cs:(%rax,%rax)