// File: /workspace/github_cpp_makefile_star2_O2/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:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x38, %rsp
cmpl $0x2, 0x28(%rsi)
je 0xd811
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x1c(%rsp), %rdx
andl $0x0, (%rdx)
leaq 0x20(%rsp), %r12
pushq $0x2
popq %rsi
leaq 0x7(%rsp), %rcx
movq %r12, %rdi
callq 0x9c8a
leaq 0x58(%rbx), %r15
movq 0x58(%rbx), %rcx
movq 0x68(%rbx), %rdx
movl 0x70(%rbx), %esi
xorl %edi, %edi
movq (%r12), %rax
xorl %r8d, %r8d
cmpq %rdx, %rcx
jne 0xd6b2
cmpl %esi, %r8d
je 0xd6dd
movq (%rcx), %r9
xorl %r10d, %r10d
btq %r8, %r9
setb %r10b
incl (%rax,%r10,4)
xorl %r9d, %r9d
cmpl $0x3f, %r8d
leal 0x1(%r8), %r8d
sete %r9b
leaq (%rcx,%r9,8), %rcx
cmovel %edi, %r8d
jmp 0xd6a8
cmpl $0x0, (%rax)
je 0xd6f0
jle 0xd6fa
cmpl $0x0, 0x4(%rax)
je 0xd710
jle 0xd6fa
pushq $0x3
jmp 0xd712
cmpl $0x0, 0x4(%rax)
jle 0xd6fa
pushq $0x1
jmp 0xd712
movabsq $0x200000000, %rax      # imm = 0x200000000
movq %rax, 0x98(%rbx)
jmp 0xd807
pushq $0x2
popq %rax
movl %eax, 0x98(%rbx)
movq 0x40(%rbx), %rax
xorl %r12d, %r12d
xorps %xmm0, %xmm0
movsd %xmm0, 0x10(%rsp)
movsd %xmm0, 0x8(%rsp)
movl %r12d, %r12d
movq 0x48(%rbx), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
cmpq %r12, %rcx
jbe 0xd7e6
movq %r15, %rdi
movq %r12, %rsi
callq 0x9f66
xorl %ecx, %ecx
testq %rdx, (%rax)
setne %cl
movq 0x40(%rbx), %rax
movl (%rax,%r12,4), %edx
testl %edx, %edx
je 0xd78f
cmpl $0x2, %edx
jne 0xd79f
movq 0x2d0(%r14), %rdx
shll $0x2, %ecx
movl (%rdx,%rcx), %esi
movq 0x2a0(%r14), %rdi
movq 0x2b8(%r14), %rdx
movl (%rdx,%rcx), %edx
addl %esi, %edx
addl (%rdi,%rcx), %esi
jmp 0xd7b6
movq 0x2a0(%r14), %rsi
movq 0x2b8(%r14), %rdx
jmp 0xd7ad
movq 0x2a0(%r14), %rsi
movq 0x2d0(%r14), %rdx
shll $0x2, %ecx
movl (%rdx,%rcx), %edx
movl (%rsi,%rcx), %esi
cvtsi2sd %esi, %xmm0
movsd 0x8(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x8(%rsp)
cvtsi2sd %edx, %xmm0
movsd 0x10(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x10(%rsp)
incl %r12d
jmp 0xd72f
movsd 0x10(%rsp), %xmm0
ucomisd 0x8(%rsp), %xmm0
jbe 0xd800
movl $0x1, 0x9c(%rbx)
jmp 0xd807
andl $0x0, 0x9c(%rbx)
leaq 0x20(%rsp), %rdi
callq 0xa49a
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0xa49a
movq %rbx, %rdi
callq 0x5570