// File: gvaumour[P]cache-simulator/src/HybridCache.cc
// Function: HybridCache::triggerMigration(int, int, int, bool)
void HybridCache::triggerMigration(int set, int id_assocSRAM, int id_assocNVM , bool fromNVM)
{
	entete_debug();
	DPRINTF(DebugCache , "TriggerMigration set %d , id_assocSRAM %d , id_assocNVM %d\n" , set , id_assocSRAM , id_assocNVM);
	
	CacheEntry* from_entry = fromNVM ? m_tableNVM[set][id_assocNVM] : m_tableSRAM[set][id_assocSRAM];
	CacheEntry* destination_entry = fromNVM ? m_tableSRAM[set][id_assocSRAM] : m_tableNVM[set][id_assocNVM];
	
	if(!m_isWarmup)
		stats_migration[fromNVM]++;
	
	assert(from_entry->isValid);
	
	if(destination_entry->isValid)
	{
		//WB this cache line to the lower levels 			
		Access wb_request;
		wb_request.m_address = destination_entry->address;
		wb_request.m_pc = destination_entry->m_pc;
		wb_request.m_size = 4;
		if(destination_entry->isDirty)
			wb_request.m_type = MemCmd::DIRTY_WRITEBACK;
		else
			wb_request.m_type = MemCmd::CLEAN_WRITEBACK;
		signalWB(wb_request, false);
		stats_evict++;	
	}
	
	deallocate(destination_entry);
	destination_entry->copyCL(from_entry);
	destination_entry->justMigrate = true;
	destination_entry->policyInfo = cpt_time;
	destination_entry->isValid = true;
	
	map<uint64_t,HybridLocation>::iterator p1 = m_tag_index.find(destination_entry->address);
	if(p1 != m_tag_index.end())
	{
 		p1->second.m_inNVM = !fromNVM;
		p1->second.m_way = fromNVM ? id_assocSRAM : id_assocNVM;
	}
	
	from_entry->isValid = false;
	
	
	if(fromNVM)
	{
		//One read NVM , one write SRAM 
		stats_hitsNVM[0]++;
		stats_hitsSRAM[1]++;
	}
	else
	{
		//One read SRAM , one write NVM  
		stats_hitsNVM[1]++;
		stats_hitsSRAM[0]++;
	}
}

// Assembly:
subq $0x158, %rsp            # imm = 0x158
movb %r8b, %al
movq %rdi, 0x150(%rsp)
movl %esi, 0x14c(%rsp)
movl %edx, 0x148(%rsp)
movl %ecx, 0x144(%rsp)
andb $0x1, %al
movb %al, 0x143(%rsp)
movq 0x150(%rsp), %rdi
movq %rdi, 0x68(%rsp)
callq 0x38560
leaq 0x11f(%rsp), %rdi
movq %rdi, 0x70(%rsp)
callq 0x56a0
movq 0x70(%rsp), %rdx
leaq 0x37c0e(%rip), %rsi     # 0x7286e
leaq 0x120(%rsp), %rdi
callq 0x5530
jmp 0x3ac6f
leaq 0x5937a(%rip), %rdi     # 0x93ff0
addq $0x8, %rdi
leaq 0x120(%rsp), %rsi
callq 0x33a00
movq %rax, 0x60(%rsp)
jmp 0x3ac8e
leaq 0x120(%rsp), %rdi
callq 0x5768
leaq 0x11f(%rsp), %rdi
callq 0x53e0
movq 0x60(%rsp), %rax
cmpq $0x0, %rax
je 0x3ad21
movl 0x14c(%rsp), %esi
movl 0x148(%rsp), %edx
movl 0x144(%rsp), %ecx
leaq 0x37df0(%rip), %rdi     # 0x72abf
movb $0x0, %al
callq 0x5060
jmp 0x3ad21
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x110(%rsp)
movl %eax, 0x10c(%rsp)
jmp 0x3ad0f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x110(%rsp)
movl %eax, 0x10c(%rsp)
leaq 0x120(%rsp), %rdi
callq 0x5768
leaq 0x11f(%rsp), %rdi
callq 0x53e0
jmp 0x3b0fc
testb $0x1, 0x143(%rsp)
je 0x3ad5b
movq 0x68(%rsp), %rdi
addq $0x8, %rdi
movslq 0x14c(%rsp), %rsi
callq 0xf9a0
movq %rax, %rdi
movslq 0x144(%rsp), %rsi
callq 0xf9c0
movq (%rax), %rax
movq %rax, 0x58(%rsp)
jmp 0x3ad89
movq 0x68(%rsp), %rdi
addq $0x20, %rdi
movslq 0x14c(%rsp), %rsi
callq 0xf9a0
movq %rax, %rdi
movslq 0x148(%rsp), %rsi
callq 0xf9c0
movq (%rax), %rax
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rax
movq %rax, 0x100(%rsp)
testb $0x1, 0x143(%rsp)
je 0x3add0
movq 0x68(%rsp), %rdi
addq $0x20, %rdi
movslq 0x14c(%rsp), %rsi
callq 0xf9a0
movq %rax, %rdi
movslq 0x148(%rsp), %rsi
callq 0xf9c0
movq (%rax), %rax
movq %rax, 0x50(%rsp)
jmp 0x3adfe
movq 0x68(%rsp), %rdi
addq $0x8, %rdi
movslq 0x14c(%rsp), %rsi
callq 0xf9a0
movq %rax, %rdi
movslq 0x144(%rsp), %rsi
callq 0xf9c0
movq (%rax), %rax
movq %rax, 0x50(%rsp)
movq 0x68(%rsp), %rax
movq 0x50(%rsp), %rcx
movq %rcx, 0xf8(%rsp)
testb $0x1, 0x91(%rax)
jne 0x3ae42
movq 0x68(%rsp), %rdi
addq $0x170, %rdi            # imm = 0x170
movb 0x143(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, %esi
callq 0xfa20
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq 0x100(%rsp), %rax
testb $0x1, (%rax)
je 0x3ae51
jmp 0x3ae70
leaq 0x37ca3(%rip), %rdi     # 0x72afb
leaq 0x378f3(%rip), %rsi     # 0x72752
movl $0x263, %edx            # imm = 0x263
leaq 0x37ca4(%rip), %rcx     # 0x72b0f
callq 0x5260
movq 0xf8(%rsp), %rax
testb $0x1, (%rax)
je 0x3af58
leaq 0xc0(%rsp), %rdi
callq 0x21120
movq 0xf8(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0xc0(%rsp)
movq 0xf8(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0xd0(%rsp)
movl $0x4, 0xc8(%rsp)
movq 0xf8(%rsp), %rax
testb $0x1, 0x1(%rax)
je 0x3aedc
movl $0x6, 0xdc(%rsp)
jmp 0x3aee7
movl $0x5, 0xdc(%rsp)
leaq 0x88(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
movl $0x38, %edx
callq 0x52f0
movq 0x68(%rsp), %rdi
xorl %eax, %eax
movq 0xb8(%rsp), %rcx
movq %rsp, %rax
movq %rcx, 0x30(%rax)
movups 0x88(%rsp), %xmm0
movups 0x98(%rsp), %xmm1
movups 0xa8(%rsp), %xmm2
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
xorl %esi, %esi
callq 0x3a180
movq 0x68(%rsp), %rax
movq 0x100(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x100(%rax)
movq 0x68(%rsp), %rdi
movq 0xf8(%rsp), %rsi
callq 0x3a330
movq 0xf8(%rsp), %rdi
movq 0x100(%rsp), %rsi
callq 0x3df10
movq 0x68(%rsp), %rdi
movq 0xf8(%rsp), %rax
movb $0x1, 0x14c(%rax)
leaq 0x5901e(%rip), %rax     # 0x93fb8
movq (%rax), %rax
movl %eax, %ecx
movq 0xf8(%rsp), %rax
movl %ecx, 0x38(%rax)
movq 0xf8(%rsp), %rax
movb $0x1, (%rax)
addq $0x38, %rdi
movq 0xf8(%rsp), %rsi
addq $0x8, %rsi
callq 0x3d9b0
movq 0x68(%rsp), %rdi
movq %rax, 0x80(%rsp)
addq $0x38, %rdi
callq 0x3db60
movq %rax, 0x78(%rsp)
leaq 0x80(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0x3db40
testb $0x1, %al
jne 0x3affd
jmp 0x3b05f
movb 0x143(%rsp), %al
xorb $-0x1, %al
movb %al, 0x4f(%rsp)
leaq 0x80(%rsp), %rdi
callq 0x3d9e0
movb 0x4f(%rsp), %cl
andb $0x1, %cl
movb %cl, 0xc(%rax)
testb $0x1, 0x143(%rsp)
je 0x3b038
movl 0x148(%rsp), %eax
movl %eax, 0x48(%rsp)
jmp 0x3b043
movl 0x144(%rsp), %eax
movl %eax, 0x48(%rsp)
movl 0x48(%rsp), %eax
movl %eax, 0x44(%rsp)
leaq 0x80(%rsp), %rdi
callq 0x3d9e0
movl 0x44(%rsp), %ecx
movl %ecx, 0x8(%rax)
movq 0x100(%rsp), %rax
movb $0x0, (%rax)
testb $0x1, 0x143(%rsp)
je 0x3b0b5
movq 0x68(%rsp), %rdi
addq $0x128, %rdi            # imm = 0x128
xorl %eax, %eax
movl %eax, %esi
callq 0xfa20
movq 0x68(%rsp), %rdi
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
addq $0xd8, %rdi
movl $0x1, %esi
callq 0xfa20
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
jmp 0x3b0f4
movq 0x68(%rsp), %rdi
addq $0x128, %rdi            # imm = 0x128
movl $0x1, %esi
callq 0xfa20
movq 0x68(%rsp), %rdi
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
addq $0xd8, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xfa20
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
addq $0x158, %rsp            # imm = 0x158
retq
movq 0x110(%rsp), %rdi
callq 0x5690
nopl (%rax)