// File: gvaumour[P]cache-simulator/src/Hierarchy.cc
// Function: Hierarchy::signalWB(Access, bool, int)
void
Hierarchy::signalWB(Access wb_request, bool isKept, int idcore)
{

	if(idcore == -1)
	{
		// It is a WB from the LLC to the Main Mem
		if(wb_request.m_type == MemCmd::DIRTY_WRITEBACK)
			stats_dirtyWB_MainMem++;		
		else if(wb_request.m_type == MemCmd::CLEAN_WRITEBACK)
			stats_cleanWB_MainMem++;
		else
			assert(false && "Error on the type of the write back request");

		string state = directory_state_str[m_directory->getState(wb_request.m_address)];
		//cout << "WB Request address = " << std::hex << wb_request.m_address << ", DirectoryState = " << state  << endl;

		uint64_t addr =  wb_request.m_address;
		DirectoryState dir_state = m_directory->getEntry(addr)->coherence_state;
		
		if( dir_state == CLEAN_LLC || dir_state == DIRTY_LLC )
			m_directory->setCoherenceState(addr , NOT_PRESENT);
		else if( dir_state == SHARED_L1)
			m_directory->setCoherenceState(addr , SHARED_L1_NOT_LLC);
		else if( dir_state == EXCLUSIVE_L1)
			m_directory->setCoherenceState(addr , EXCLUSIVE_L1_NOT_LLC);
		else if( dir_state == MODIFIED_L1)
			m_directory->setCoherenceState(addr , MODIFIED_L1_NOT_LLC);
		else{
			cout << "Error dir_state = " << directory_state_str[dir_state] << endl;
			assert(false);
		}
	
		state = directory_state_str[m_directory->getState(wb_request.m_address)];
		//cout << "WB Request address = " << std::hex << wb_request.m_address << ", DirectoryState = " << state  << endl;
			
//		m_directory->removeEntry(wb_request.m_address);
	}			
	else{
	
		string dir_state = string( directory_state_str[m_directory->getState(wb_request.m_address)]);
		DPRINTF( DebugHierarchy , "Write Back Block %#lx , Id Core = %d , Dir State = %s \n" , wb_request.m_address , idcore , dir_state.c_str()); 
		//Remove the idcore from the tracker list and update the state
		if(!isKept)
			m_directory->removeTracker(wb_request.m_address , idcore);
		
		if( m_LLC->handleAccess(wb_request) == BYPASS_CACHE)
		{
			if(m_directory->getTrackers(wb_request.m_address).size() == 0)
				m_directory->setCoherenceState(wb_request.m_address , NOT_PRESENT);
		
			if(wb_request.m_type == MemCmd::DIRTY_WRITEBACK)
				stats_dirtyWB_MainMem++;		
			else if(wb_request.m_type == MemCmd::CLEAN_WRITEBACK)
				stats_cleanWB_MainMem++;
			else
				assert(false && "Error on the type of the write back request");
		}
		else
		{
			
			if(m_directory->getTrackers(wb_request.m_address).size() == 0)
				m_directory->setCoherenceState(wb_request.m_address , CLEAN_LLC);
			else
				m_directory->setCoherenceState(wb_request.m_address , SHARED_L1);
		}
		dir_state = directory_state_str[m_directory->getState(wb_request.m_address)];
		DPRINTF( DebugHierarchy , "End Write Back Block %#lx Dir State is now %s \n" , wb_request.m_address , dir_state.c_str()); 
		//m_directory->updateEntry(wb_request.m_address);
	}
}

// Assembly:
subq $0x258, %rsp            # imm = 0x258
movb %sil, %al
leaq 0x260(%rsp), %rcx
movq %rcx, 0xd8(%rsp)
movq %rdi, 0x250(%rsp)
andb $0x1, %al
movb %al, 0x24f(%rsp)
movl %edx, 0x248(%rsp)
movq 0x250(%rsp), %rax
movq %rax, 0xe0(%rsp)
cmpl $-0x1, 0x248(%rsp)
jne 0x31e13
movq 0xd8(%rsp), %rax
cmpl $0x6, 0x1c(%rax)
jne 0x31b24
movq 0xe0(%rsp), %rax
movq 0x78(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x78(%rax)
jmp 0x31b69
movq 0xd8(%rsp), %rax
cmpl $0x5, 0x1c(%rax)
jne 0x31b48
movq 0xe0(%rsp), %rax
movq 0x70(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x70(%rax)
jmp 0x31b67
leaq 0x40948(%rip), %rdi     # 0x72497
leaq 0x40978(%rip), %rsi     # 0x724ce
movl $0xa4, %edx
leaq 0x4097d(%rip), %rcx     # 0x724df
callq 0x5260
jmp 0x31b69
movq 0xd8(%rsp), %rax
movq 0xe0(%rsp), %rcx
movq 0x20(%rcx), %rdi
movq (%rax), %rsi
callq 0x27e20
movl %eax, %eax
movl %eax, %ecx
leaq 0x618c0(%rip), %rax     # 0x93450
movq (%rax,%rcx,8), %rax
movq %rax, 0xc8(%rsp)
leaq 0x227(%rsp), %rdi
movq %rdi, 0xd0(%rsp)
callq 0x56a0
movq 0xc8(%rsp), %rsi
movq 0xd0(%rsp), %rdx
leaq 0x228(%rsp), %rdi
callq 0x5530
jmp 0x31bd0
leaq 0x227(%rsp), %rdi
callq 0x53e0
movq 0xd8(%rsp), %rcx
movq 0xe0(%rsp), %rax
movq (%rcx), %rcx
movq %rcx, 0x208(%rsp)
movq 0x20(%rax), %rdi
movq 0x208(%rsp), %rsi
callq 0x27b00
movq %rax, 0xc0(%rsp)
jmp 0x31c13
movq 0xc0(%rsp), %rax
movl 0x38(%rax), %eax
movl %eax, 0x204(%rsp)
cmpl $0x6, 0x204(%rsp)
je 0x31c39
cmpl $0x7, 0x204(%rsp)
jne 0x31caa
movq 0xe0(%rsp), %rax
movq 0x20(%rax), %rdi
movq 0x208(%rsp), %rsi
movl $0x8, %edx
callq 0x27f50
jmp 0x31c59
jmp 0x31db7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x218(%rsp)
movl %eax, 0x214(%rsp)
leaq 0x227(%rsp), %rdi
callq 0x53e0
jmp 0x32371
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x218(%rsp)
movl %eax, 0x214(%rsp)
leaq 0x228(%rsp), %rdi
callq 0x5768
jmp 0x32371
cmpl $0x0, 0x204(%rsp)
jne 0x31cd9
movq 0xe0(%rsp), %rax
movq 0x20(%rax), %rdi
movq 0x208(%rsp), %rsi
movl $0x3, %edx
callq 0x27f50
jmp 0x31cd4
jmp 0x31db5
cmpl $0x2, 0x204(%rsp)
jne 0x31d08
movq 0xe0(%rsp), %rax
movq 0x20(%rax), %rdi
movq 0x208(%rsp), %rsi
movl $0x5, %edx
callq 0x27f50
jmp 0x31d03
jmp 0x31db3
cmpl $0x1, 0x204(%rsp)
jne 0x31d34
movq 0xe0(%rsp), %rax
movq 0x20(%rax), %rdi
movq 0x208(%rsp), %rsi
movl $0x4, %edx
callq 0x27f50
jmp 0x31d32
jmp 0x31db1
movq 0x61295(%rip), %rdi     # 0x92fd0
leaq 0x407c9(%rip), %rsi     # 0x7250b
callq 0x5380
movq %rax, 0xb8(%rsp)
jmp 0x31d51
movq 0xb8(%rsp), %rdi
movl 0x204(%rsp), %eax
movl %eax, %ecx
leaq 0x616e7(%rip), %rax     # 0x93450
movq (%rax,%rcx,8), %rsi
callq 0x5380
movq %rax, 0xb0(%rsp)
jmp 0x31d7c
movq 0xb0(%rsp), %rdi
movq 0x6122d(%rip), %rsi     # 0x92fb8
callq 0x53d0
jmp 0x31d92
leaq 0x40785(%rip), %rdi     # 0x7251e
leaq 0x4072e(%rip), %rsi     # 0x724ce
movl $0xb6, %edx
leaq 0x40733(%rip), %rcx     # 0x724df
callq 0x5260
jmp 0x31db3
jmp 0x31db5
jmp 0x31db7
movq 0xd8(%rsp), %rax
movq 0xe0(%rsp), %rcx
movq 0x20(%rcx), %rdi
movq (%rax), %rsi
callq 0x27e20
movl %eax, 0xac(%rsp)
jmp 0x31ddc
movl 0xac(%rsp), %eax
movl %eax, %eax
movl %eax, %ecx
leaq 0x61662(%rip), %rax     # 0x93450
movq (%rax,%rcx,8), %rsi
leaq 0x228(%rsp), %rdi
callq 0x5520
jmp 0x31e01
leaq 0x228(%rsp), %rdi
callq 0x5768
jmp 0x32369
movq 0xd8(%rsp), %rax
movq 0xe0(%rsp), %rcx
movq 0x20(%rcx), %rdi
movq (%rax), %rsi
callq 0x27e20
movl %eax, %eax
movl %eax, %ecx
leaq 0x61616(%rip), %rax     # 0x93450
movq (%rax,%rcx,8), %rax
movq %rax, 0x98(%rsp)
leaq 0x1df(%rsp), %rdi
movq %rdi, 0xa0(%rsp)
callq 0x56a0
movq 0x98(%rsp), %rsi
movq 0xa0(%rsp), %rdx
leaq 0x1e0(%rsp), %rdi
callq 0x5530
jmp 0x31e7a
leaq 0x1df(%rsp), %rdi
callq 0x53e0
leaq 0x1b7(%rsp), %rdi
movq %rdi, 0x90(%rsp)
callq 0x56a0
movq 0x90(%rsp), %rdx
leaq 0x404ad(%rip), %rsi     # 0x72358
leaq 0x1b8(%rsp), %rdi
callq 0x5530
jmp 0x31eba
leaq 0x6212f(%rip), %rdi     # 0x93ff0
addq $0x8, %rdi
leaq 0x1b8(%rsp), %rsi
callq 0x33a00
movq %rax, 0x88(%rsp)
jmp 0x31edc
leaq 0x1b8(%rsp), %rdi
callq 0x5768
leaq 0x1b7(%rsp), %rdi
callq 0x53e0
movq 0x88(%rsp), %rax
cmpq $0x0, %rax
je 0x31fdf
movq 0xd8(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x78(%rsp)
movl 0x248(%rsp), %eax
movl %eax, 0x84(%rsp)
leaq 0x1e0(%rsp), %rdi
callq 0x51a0
movq 0x78(%rsp), %rsi
movl 0x84(%rsp), %edx
movq %rax, %rcx
leaq 0x405db(%rip), %rdi     # 0x72524
xorl %eax, %eax
callq 0x5060
jmp 0x31f52
jmp 0x31fdf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x218(%rsp)
movl %eax, 0x214(%rsp)
leaq 0x1df(%rsp), %rdi
callq 0x53e0
jmp 0x32371
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x218(%rsp)
movl %eax, 0x214(%rsp)
jmp 0x31fb4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x218(%rsp)
movl %eax, 0x214(%rsp)
leaq 0x1b8(%rsp), %rdi
callq 0x5768
leaq 0x1b7(%rsp), %rdi
callq 0x53e0
jmp 0x3235a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x218(%rsp)
movl %eax, 0x214(%rsp)
jmp 0x3235a
testb $0x1, 0x24f(%rsp)
jne 0x32010
movq 0xd8(%rsp), %rax
movq 0xe0(%rsp), %rcx
movq 0x20(%rcx), %rdi
movq (%rax), %rsi
movl 0x248(%rsp), %edx
callq 0x27e80
jmp 0x3200e
jmp 0x32010
movq 0xd8(%rsp), %rax
movq 0xe0(%rsp), %rcx
movq 0x18(%rcx), %rdi
movq 0x30(%rax), %rcx
movq %rcx, 0x1a0(%rsp)
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups 0x20(%rax), %xmm2
movaps %xmm2, 0x190(%rsp)
movaps %xmm1, 0x180(%rsp)
movaps %xmm0, 0x170(%rsp)
movq 0x1a0(%rsp), %rcx
movq %rsp, %rax
movq %rcx, 0x30(%rax)
movaps 0x170(%rsp), %xmm0
movaps 0x180(%rsp), %xmm1
movaps 0x190(%rsp), %xmm2
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0x46b30
movl %eax, 0x74(%rsp)
jmp 0x32090
movl 0x74(%rsp), %eax
cmpl $0x2, %eax
jne 0x32180
movq 0xd8(%rsp), %rax
movq 0xe0(%rsp), %rcx
movq 0x20(%rcx), %rsi
movq (%rax), %rdx
leaq 0x140(%rsp), %rdi
callq 0x27da0
jmp 0x320c3
leaq 0x140(%rsp), %rdi
callq 0x33ee0
movq %rax, 0x68(%rsp)
leaq 0x140(%rsp), %rdi
callq 0x28d00
movq 0x68(%rsp), %rax
cmpq $0x0, %rax
jne 0x32112
movq 0xd8(%rsp), %rax
movq 0xe0(%rsp), %rcx
movq 0x20(%rcx), %rdi
movq (%rax), %rsi
movl $0x8, %edx
callq 0x27f50
jmp 0x32110
jmp 0x32112
movq 0xd8(%rsp), %rax
cmpl $0x6, 0x1c(%rax)
jne 0x32136
movq 0xe0(%rsp), %rax
movq 0x78(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x78(%rax)
jmp 0x3217b
movq 0xd8(%rsp), %rax
cmpl $0x5, 0x1c(%rax)
jne 0x3215a
movq 0xe0(%rsp), %rax
movq 0x70(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x70(%rax)
jmp 0x32179
leaq 0x40336(%rip), %rdi     # 0x72497
leaq 0x40366(%rip), %rsi     # 0x724ce
movl $0xd0, %edx
leaq 0x4036b(%rip), %rcx     # 0x724df
callq 0x5260
jmp 0x3217b
jmp 0x32219
movq 0xd8(%rsp), %rax
movq 0xe0(%rsp), %rcx
movq 0x20(%rcx), %rsi
movq (%rax), %rdx
leaq 0x110(%rsp), %rdi
callq 0x27da0
jmp 0x321a6
leaq 0x110(%rsp), %rdi
callq 0x33ee0
movq %rax, 0x60(%rsp)
leaq 0x110(%rsp), %rdi
callq 0x28d00
movq 0x60(%rsp), %rax
cmpq $0x0, %rax
jne 0x321f5
movq 0xd8(%rsp), %rax
movq 0xe0(%rsp), %rcx
movq 0x20(%rcx), %rdi
movq (%rax), %rsi
movl $0x6, %edx
callq 0x27f50
jmp 0x321f3
jmp 0x32217
movq 0xd8(%rsp), %rax
movq 0xe0(%rsp), %rcx
movq 0x20(%rcx), %rdi
movq (%rax), %rsi
xorl %edx, %edx
callq 0x27f50
jmp 0x32215
jmp 0x32217
jmp 0x32219
movq 0xd8(%rsp), %rax
movq 0xe0(%rsp), %rcx
movq 0x20(%rcx), %rdi
movq (%rax), %rsi
callq 0x27e20
movl %eax, 0x5c(%rsp)
jmp 0x3223b
movl 0x5c(%rsp), %eax
movl %eax, %eax
movl %eax, %ecx
leaq 0x61206(%rip), %rax     # 0x93450
movq (%rax,%rcx,8), %rsi
leaq 0x1e0(%rsp), %rdi
callq 0x5520
jmp 0x3225d
leaq 0xef(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0x56a0
movq 0x50(%rsp), %rdx
leaq 0x400dd(%rip), %rsi     # 0x72358
leaq 0xf0(%rsp), %rdi
callq 0x5530
jmp 0x3228a
leaq 0x61d5f(%rip), %rdi     # 0x93ff0
addq $0x8, %rdi
leaq 0xf0(%rsp), %rsi
callq 0x33a00
movq %rax, 0x48(%rsp)
jmp 0x322a9
leaq 0xf0(%rsp), %rdi
callq 0x5768
leaq 0xef(%rsp), %rdi
callq 0x53e0
movq 0x48(%rsp), %rax
cmpq $0x0, %rax
je 0x3234b
movq 0xd8(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x40(%rsp)
leaq 0x1e0(%rsp), %rdi
callq 0x51a0
movq 0x40(%rsp), %rsi
movq %rax, %rdx
leaq 0x40262(%rip), %rdi     # 0x7255c
xorl %eax, %eax
callq 0x5060
jmp 0x32303
jmp 0x3234b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x218(%rsp)
movl %eax, 0x214(%rsp)
jmp 0x3233c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x218(%rsp)
movl %eax, 0x214(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0x5768
leaq 0xef(%rsp), %rdi
callq 0x53e0
jmp 0x3235a
leaq 0x1e0(%rsp), %rdi
callq 0x5768
jmp 0x32369
leaq 0x1e0(%rsp), %rdi
callq 0x5768
jmp 0x32371
addq $0x258, %rsp            # imm = 0x258
retq
movq 0x218(%rsp), %rdi
callq 0x5690
nop