// File: /workspace/github_cpp_makefile_star2_O3/gvaumour[P]cache-simulator/src/DBAMBPredictor.cc
// Function: DBAMBPredictor::determineStatus(DHPEntry*)
void 
DBAMBPredictor::determineStatus(DHPEntry* entry)
{
	if(entry->des == BYPASS_CACHE)
	{
		//All the info gathered here are from learning cache line
		//If we see any any reuse we learn again
		/*if(entry->rw_history.size() != 0)
		{
			entry->des = ALLOCATE_PREEMPTIVELY;
			entry->state_rd = RD_NOT_ACCURATE;
			entry->state_rw = RW_NOT_ACCURATE;
			entry->dead_counter = 0;
		}*/
		return;		
	}


	/* Count the number of read and write during window */
	vector<int> cpts_rw = vector<int>(2,0);
	for(auto isWrite : entry->rw_history)
	{
		if(isWrite)
			cpts_rw[INDEX_WRITE]++;
		else
			cpts_rw[INDEX_READ]++;
	}

	if(cpts_rw[INDEX_READ] == 0 && cpts_rw[INDEX_WRITE] > 0)
		entry->state_rw = WO;
	else if(cpts_rw[INDEX_READ] > 0 && cpts_rw[INDEX_WRITE] == 0)
		entry->state_rw = RO;
	else if(cpts_rw[INDEX_READ] > 0 && cpts_rw[INDEX_WRITE] > 0)
		entry->state_rw = RW;
	else
		entry->state_rw = DEAD;
		
	if(entry->state_rw == DEAD)
	{
		entry->state_rd = RD_NOT_ACCURATE;
		return;	
	}

	
	/* Determination of the rd type */
//	int window_rd = entry->rd_history.size();
//	vector<int> cpts_rd = vector<int>(NUM_RD_TYPE,0);
//	
//	for(auto rd : entry->rd_history)
//		cpts_rd[rd]++;
//		
//	int max = 0, index_max = -1;
//	for(unsigned i = 0 ; i < cpts_rd.size() ; i++)
//	{
//		if(cpts_rd[i] > max)
//		{
//			max = cpts_rd[i];
//			index_max = i;
//		}
//	}

	double costSRAM = 0;
	double costNVM =0;
	for(unsigned i = 0 ; i < entry->rd_history.size() ; i++)
	{
		bool isWrite = entry->rw_history[i];
		if(entry->rd_history[i] == RD_NOT_ACCURATE)
		{			
				costSRAM += m_costParameters.costDRAM[isWrite] + m_costParameters.costSRAM[isWrite]; 
				costNVM += m_costParameters.costDRAM[isWrite] + m_costParameters.costNVM[isWrite];		
		}
		else if(entry->rd_history[i] == RD_SHORT)
		{
			costSRAM += m_costParameters.costSRAM[isWrite]; 
			costNVM += m_costParameters.costNVM[isWrite];
		}
		else
		{
			costSRAM += m_costParameters.costDRAM[isWrite]; 
			costNVM += m_costParameters.costNVM[isWrite];	
		}
	}

	if(costSRAM > costNVM)
		entry->state_rd = (RD_TYPE) RD_MEDIUM;
	else
		entry->state_rd = (RD_TYPE) RD_SHORT;
			
	
//	if( ((double)max / (double)window_rd) > RAP_INACURACY_TH)
//		entry->state_rd = (RD_TYPE) index_max;
//	else
//		entry->state_rd = RD_NOT_ACCURATE;

	

			
//	/** Debugging purpose */	
//	if(entry->state_rd == RD_NOT_ACCURATE && entry->state_rw == DEAD)
//	{
//		cout <<"RD history\t";
//		for(auto p : entry->rd_history)
//			cout <<p << "\t";
//		cout <<endl;
//		cout <<"RW history\tNBWrite=" << cpts_rw[INDEX_WRITE] << "\tNBRead=" << cpts_rw[INDEX_READ] << endl;
//		cout <<"New state is " << str_RD_status[entry->state_rd] << "\t" << str_RW_status[entry->state_rw] << endl;	
//	}


	/*
	if( ((double)max / (double) RAP_WINDOW_SIZE) > RAP_INACURACY_TH)
		entry->state_rw = (RW_TYPE)index_max;
	else
		entry->state_rw = RW_NOT_ACCURATE;
	*/
}

// Assembly:
cmpl $0x2, 0x28(%rsi)
jne 0x104b9
retq
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
movl $0x8, %edi
callq 0x52f0
movq $0x0, (%rax)
movq 0x58(%rbx), %rcx
movq 0x68(%rbx), %rdx
movl 0x70(%rbx), %esi
cmpq %rdx, %rcx
setne %dil
testl %esi, %esi
setne %r8b
orb %dil, %r8b
cmpb $0x1, %r8b
jne 0x10565
xorl %r9d, %r9d
xorl %r8d, %r8d
xorl %edi, %edi
xorl %r11d, %r11d
movq %rcx, %r10
movq (%r10), %r15
btq %r11, %r15
jae 0x10516
incl %edi
movl %edi, 0x4(%rax)
jmp 0x1051c
incl %r8d
movl %r8d, (%rax)
xorl %r15d, %r15d
cmpl $0x3f, %r11d
leal 0x1(%r11), %r11d
sete %r15b
leaq (%r10,%r15,8), %r10
cmovel %r9d, %r11d
cmpq %rdx, %r10
setne %bpl
cmpl %esi, %r11d
setne %r15b
orb %bpl, %r15b
jne 0x10506
testl %r8d, %r8d
je 0x1055b
jle 0x10565
testl %edi, %edi
je 0x10579
movl $0x3, %r8d
jg 0x1057f
jmp 0x10565
movl $0x1, %r8d
testl %edi, %edi
jg 0x1057f
movl $0x0, 0x98(%rbx)
movl $0x2, %ecx
jmp 0x10630
movl $0x2, %r8d
movq 0x40(%rbx), %rdx
movq 0x48(%rbx), %rsi
movl %r8d, 0x98(%rbx)
subq %rdx, %rsi
je 0x1062e
sarq $0x2, %rsi
movq 0x2a0(%r14), %rdi
movq 0x2b8(%r14), %r8
movq 0x2d0(%r14), %r9
xorpd %xmm0, %xmm0
xorl %r10d, %r10d
xorpd %xmm1, %xmm1
movl %r10d, %r11d
shrl $0x6, %r11d
movq (%rcx,%r11,8), %r14
movl (%rdx,%r10,4), %ebp
xorl %r11d, %r11d
btq %r10, %r14
setb %r11b
shll $0x2, %r11d
testl %ebp, %ebp
je 0x105f3
cmpl $0x2, %ebp
jne 0x105f9
movl (%r9,%r11), %r14d
movl (%r8,%r11), %ebp
addl %r14d, %ebp
addl (%rdi,%r11), %r14d
jmp 0x10601
movl (%r8,%r11), %ebp
jmp 0x105fd
movl (%r9,%r11), %ebp
movl (%rdi,%r11), %r14d
xorps %xmm2, %xmm2
cvtsi2sd %r14d, %xmm2
addsd %xmm2, %xmm0
xorps %xmm2, %xmm2
cvtsi2sd %ebp, %xmm2
addsd %xmm2, %xmm1
incq %r10
movl %r10d, %r11d
cmpq %r11, %rsi
ja 0x105bb
movl $0x1, %ecx
ucomisd %xmm0, %xmm1
ja 0x10630
xorl %ecx, %ecx
movl %ecx, 0x9c(%rbx)
movq %rax, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x52b0