// File: gvaumour[P]cache-simulator/src/Predictor.cc
// Function: Predictor::updateBypassTag(CacheEntry*, int, bool)
void
Predictor::updateBypassTag(CacheEntry* entry, int set, bool inNVM)
{
	uint64_t block_addr = entry->address;
	//DPRINTF(DebugCache, "Predictor::recordAllocationDecision Set %d, block_addr = 0x%lx\n ", set, block_addr);

	//Look if the entry already exists, if yes => BP Error, if No insert it
	for(unsigned i = 0 ; i < BP_missing_tags[set].size() ; i++)
	{	
		if(BP_missing_tags[set][i]->addr == block_addr)
		{
			BP_missing_tags[set][i]->last_time_touched = m_cpt_bypassTag++;
			return;		
		}
	}
	//DPRINTF(DebugCache, "Predictor::recordAllocationDecision Didn't find the entry in the BP Missing Tags\n");
	int index_oldest =0;
	uint64_t oldest = BP_missing_tags[set][0]->last_time_touched;
	for(unsigned i = 0 ; i < BP_missing_tags[set].size() ; i++)
	{
		if(!BP_missing_tags[set][i]->isValid)		
		{
			index_oldest= i;
			break;
		}
	
		if(BP_missing_tags[set][i]->last_time_touched < oldest)
		{
			index_oldest = i;
			oldest = BP_missing_tags[set][i]->last_time_touched;
		}
	}
	//DPRINTF(DebugCache, "Predictor::Insertion of the new entry at assoc %d\n", index_oldest);
	
	BP_missing_tags[set][index_oldest]->last_time_touched = m_cpt_bypassTag++;
	BP_missing_tags[set][index_oldest]->addr = block_addr;
	BP_missing_tags[set][index_oldest]->isValid = true;		
	BP_missing_tags[set][index_oldest]->allocSite = inNVM;
	BP_missing_tags[set][index_oldest]->missPC = entry->missPC;
	
	
	/*
	if(m_policy == "Cerebron")
	{
		for(int i = 0 ; i < simu_parameters.PHC_features.size() ; i++)
		{		
			BP_missing_tags[set][index_oldest]->features_hash[i] = entry->PHC_allocation_pred[i].first;
			
		}
	}*/
		
}

// Assembly:
subq $0x78, %rsp
movb %cl, %al
movq %rdi, 0x70(%rsp)
movq %rsi, 0x68(%rsp)
movl %edx, 0x64(%rsp)
andb $0x1, %al
movb %al, 0x63(%rsp)
movq 0x70(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x68(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x58(%rsp)
movl $0x0, 0x54(%rsp)
movq 0x38(%rsp), %rdi
movl 0x54(%rsp), %eax
movq %rax, 0x30(%rsp)
addq $0x140, %rdi            # imm = 0x140
movslq 0x64(%rsp), %rsi
callq 0x58920
movq %rax, %rdi
callq 0x58940
movq %rax, %rcx
movq 0x30(%rsp), %rax
cmpq %rcx, %rax
jae 0x561bb
movq 0x38(%rsp), %rdi
addq $0x140, %rdi            # imm = 0x140
movslq 0x64(%rsp), %rsi
callq 0x58920
movq %rax, %rdi
movl 0x54(%rsp), %eax
movl %eax, %esi
callq 0x58860
movq (%rax), %rax
movq (%rax), %rax
cmpq 0x58(%rsp), %rax
jne 0x561a9
movq 0x38(%rsp), %rdi
movq 0x38(%rdi), %rax
movq %rax, 0x28(%rsp)
addq $0x1, %rax
movq %rax, 0x38(%rdi)
addq $0x140, %rdi            # imm = 0x140
movslq 0x64(%rsp), %rsi
callq 0x58920
movq %rax, %rdi
movl 0x54(%rsp), %eax
movl %eax, %esi
callq 0x58860
movq 0x28(%rsp), %rcx
movq (%rax), %rax
movq %rcx, 0x8(%rax)
jmp 0x563f9
jmp 0x561ab
movl 0x54(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54(%rsp)
jmp 0x560fa
movq 0x38(%rsp), %rdi
movl $0x0, 0x50(%rsp)
addq $0x140, %rdi            # imm = 0x140
movslq 0x64(%rsp), %rsi
callq 0x58920
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x58860
movq (%rax), %rax
movq 0x8(%rax), %rax
movq %rax, 0x48(%rsp)
movl $0x0, 0x44(%rsp)
movq 0x38(%rsp), %rdi
movl 0x44(%rsp), %eax
movq %rax, 0x20(%rsp)
addq $0x140, %rdi            # imm = 0x140
movslq 0x64(%rsp), %rsi
callq 0x58920
movq %rax, %rdi
callq 0x58940
movq %rax, %rcx
movq 0x20(%rsp), %rax
cmpq %rcx, %rax
jae 0x562e4
movq 0x38(%rsp), %rdi
addq $0x140, %rdi            # imm = 0x140
movslq 0x64(%rsp), %rsi
callq 0x58920
movq %rax, %rdi
movl 0x44(%rsp), %eax
movl %eax, %esi
callq 0x58860
movq (%rax), %rax
testb $0x1, 0x14(%rax)
jne 0x56268
movl 0x44(%rsp), %eax
movl %eax, 0x50(%rsp)
jmp 0x562e4
movq 0x38(%rsp), %rdi
addq $0x140, %rdi            # imm = 0x140
movslq 0x64(%rsp), %rsi
callq 0x58920
movq %rax, %rdi
movl 0x44(%rsp), %eax
movl %eax, %esi
callq 0x58860
movq (%rax), %rax
movq 0x8(%rax), %rax
cmpq 0x48(%rsp), %rax
jae 0x562d2
movq 0x38(%rsp), %rdi
movl 0x44(%rsp), %eax
movl %eax, 0x50(%rsp)
addq $0x140, %rdi            # imm = 0x140
movslq 0x64(%rsp), %rsi
callq 0x58920
movq %rax, %rdi
movl 0x44(%rsp), %eax
movl %eax, %esi
callq 0x58860
movq (%rax), %rax
movq 0x8(%rax), %rax
movq %rax, 0x48(%rsp)
jmp 0x562d4
movl 0x44(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44(%rsp)
jmp 0x561f9
movq 0x38(%rsp), %rdi
movq 0x38(%rdi), %rax
movq %rax, (%rsp)
addq $0x1, %rax
movq %rax, 0x38(%rdi)
addq $0x140, %rdi            # imm = 0x140
movslq 0x64(%rsp), %rsi
callq 0x58920
movq %rax, %rdi
movslq 0x50(%rsp), %rsi
callq 0x58860
movq (%rsp), %rcx
movq 0x38(%rsp), %rdi
movq (%rax), %rax
movq %rcx, 0x8(%rax)
movq 0x58(%rsp), %rax
movq %rax, 0x8(%rsp)
addq $0x140, %rdi            # imm = 0x140
movslq 0x64(%rsp), %rsi
callq 0x58920
movq %rax, %rdi
movslq 0x50(%rsp), %rsi
callq 0x58860
movq 0x8(%rsp), %rcx
movq 0x38(%rsp), %rdi
movq (%rax), %rax
movq %rcx, (%rax)
addq $0x140, %rdi            # imm = 0x140
movslq 0x64(%rsp), %rsi
callq 0x58920
movq %rax, %rdi
movslq 0x50(%rsp), %rsi
callq 0x58860
movq 0x38(%rsp), %rdi
movq (%rax), %rax
movb $0x1, 0x14(%rax)
movb 0x63(%rsp), %al
movb %al, 0x17(%rsp)
addq $0x140, %rdi            # imm = 0x140
movslq 0x64(%rsp), %rsi
callq 0x58920
movq %rax, %rdi
movslq 0x50(%rsp), %rsi
callq 0x58860
movb 0x17(%rsp), %cl
movq 0x38(%rsp), %rdi
movq (%rax), %rax
andb $0x1, %cl
movb %cl, 0x16(%rax)
movq 0x68(%rsp), %rax
movq 0x20(%rax), %rax
movq %rax, 0x18(%rsp)
addq $0x140, %rdi            # imm = 0x140
movslq 0x64(%rsp), %rsi
callq 0x58920
movq %rax, %rdi
movslq 0x50(%rsp), %rsi
callq 0x58860
movq 0x18(%rsp), %rcx
movq (%rax), %rax
movq %rcx, 0x18(%rax)
addq $0x78, %rsp
retq
nop