// File: 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:
subq $0x118, %rsp            # imm = 0x118
movq %rdi, 0x110(%rsp)
movq %rsi, 0x108(%rsp)
movq 0x110(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x108(%rsp), %rax
cmpl $0x2, 0x28(%rax)
jne 0x1dda7
jmp 0x1e327
movl $0x0, 0xec(%rsp)
leaq 0xeb(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0xed30
movq 0x40(%rsp), %rcx
leaq 0xf0(%rsp), %rdi
movl $0x2, %esi
leaq 0xec(%rsp), %rdx
callq 0xed40
jmp 0x1dde5
leaq 0xeb(%rsp), %rdi
callq 0xef60
movq 0x108(%rsp), %rax
addq $0x58, %rax
movq %rax, 0xd0(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x174b0
movl %edx, 0xb8(%rsp)
movq %rax, 0xb0(%rsp)
movl 0xb8(%rsp), %eax
movl %eax, 0xc8(%rsp)
movq 0xb0(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x20df0
movl %edx, 0x98(%rsp)
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rax
movq %rax, 0xa0(%rsp)
movl 0x98(%rsp), %eax
movl %eax, 0xa8(%rsp)
leaq 0xc0(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x20e10
movb %al, 0x3f(%rsp)
jmp 0x1de95
movb 0x3f(%rsp), %al
testb $0x1, %al
jne 0x1dea2
jmp 0x1df7d
leaq 0xc0(%rsp), %rdi
callq 0x175f0
movq %rdx, 0x28(%rsp)
movq %rax, 0x30(%rsp)
jmp 0x1debb
movq 0x28(%rsp), %rax
movq 0x30(%rsp), %rcx
movq %rcx, 0x80(%rsp)
movq %rax, 0x88(%rsp)
leaq 0x80(%rsp), %rdi
callq 0xfaf0
testb $0x1, %al
jne 0x1dee8
jmp 0x1df4f
leaq 0xf0(%rsp), %rdi
movl $0x1, %esi
callq 0xef90
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x1df67
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xe0(%rsp)
movl %eax, 0xdc(%rsp)
leaq 0xeb(%rsp), %rdi
callq 0xef60
jmp 0x1e32f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xe0(%rsp)
movl %eax, 0xdc(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0xef00
jmp 0x1e32f
leaq 0xf0(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xef90
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x1df69
leaq 0xc0(%rsp), %rdi
callq 0x20e40
jmp 0x1df78
jmp 0x1de7a
leaq 0xf0(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xef90
cmpl $0x0, (%rax)
jne 0x1dfc1
leaq 0xf0(%rsp), %rdi
movl $0x1, %esi
callq 0xef90
cmpl $0x0, (%rax)
jle 0x1dfc1
movq 0x108(%rsp), %rax
movl $0x1, 0x98(%rax)
jmp 0x1e059
leaq 0xf0(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xef90
cmpl $0x0, (%rax)
jle 0x1e002
leaq 0xf0(%rsp), %rdi
movl $0x1, %esi
callq 0xef90
cmpl $0x0, (%rax)
jne 0x1e002
movq 0x108(%rsp), %rax
movl $0x2, 0x98(%rax)
jmp 0x1e057
leaq 0xf0(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xef90
cmpl $0x0, (%rax)
jle 0x1e043
leaq 0xf0(%rsp), %rdi
movl $0x1, %esi
callq 0xef90
cmpl $0x0, (%rax)
jle 0x1e043
movq 0x108(%rsp), %rax
movl $0x3, 0x98(%rax)
jmp 0x1e055
movq 0x108(%rsp), %rax
movl $0x0, 0x98(%rax)
jmp 0x1e057
jmp 0x1e059
movq 0x108(%rsp), %rax
cmpl $0x0, 0x98(%rax)
jne 0x1e089
movq 0x108(%rsp), %rax
movl $0x2, 0x9c(%rax)
movl $0x1, 0x7c(%rsp)
jmp 0x1e31a
xorps %xmm0, %xmm0
movsd %xmm0, 0x70(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x68(%rsp)
movl $0x0, 0x64(%rsp)
movl 0x64(%rsp), %eax
movq %rax, 0x20(%rsp)
movq 0x108(%rsp), %rdi
addq $0x40, %rdi
callq 0x20e70
movq %rax, %rcx
movq 0x20(%rsp), %rax
cmpq %rcx, %rax
jae 0x1e2de
movq 0x108(%rsp), %rdi
addq $0x58, %rdi
movl 0x64(%rsp), %eax
movl %eax, %esi
callq 0xfa90
movq %rdx, 0x10(%rsp)
movq %rax, 0x18(%rsp)
jmp 0x1e0f1
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rcx
movq %rcx, 0x50(%rsp)
movq %rax, 0x58(%rsp)
leaq 0x50(%rsp), %rdi
callq 0xfaf0
andb $0x1, %al
movb %al, 0x63(%rsp)
movq 0x108(%rsp), %rdi
addq $0x40, %rdi
movl 0x64(%rsp), %eax
movl %eax, %esi
callq 0x20e90
cmpl $0x2, (%rax)
jne 0x1e1f4
movq 0x48(%rsp), %rdi
addq $0x2a0, %rdi            # imm = 0x2A0
addq $0x30, %rdi
movb 0x63(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, %esi
callq 0xef90
movq 0x48(%rsp), %rdi
movl (%rax), %eax
movl %eax, 0x8(%rsp)
addq $0x2a0, %rdi            # imm = 0x2A0
addq $0x18, %rdi
movb 0x63(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, %esi
callq 0xef90
movq 0x48(%rsp), %rdi
movq %rax, %rcx
movl 0x8(%rsp), %eax
addl (%rcx), %eax
cvtsi2sd %eax, %xmm0
addsd 0x70(%rsp), %xmm0
movsd %xmm0, 0x70(%rsp)
addq $0x2a0, %rdi            # imm = 0x2A0
addq $0x30, %rdi
movb 0x63(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, %esi
callq 0xef90
movq 0x48(%rsp), %rdi
movl (%rax), %eax
movl %eax, 0xc(%rsp)
addq $0x2a0, %rdi            # imm = 0x2A0
movb 0x63(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, %esi
callq 0xef90
movq %rax, %rcx
movl 0xc(%rsp), %eax
addl (%rcx), %eax
cvtsi2sd %eax, %xmm0
addsd 0x68(%rsp), %xmm0
movsd %xmm0, 0x68(%rsp)
jmp 0x1e2cc
movq 0x108(%rsp), %rdi
addq $0x40, %rdi
movl 0x64(%rsp), %eax
movl %eax, %esi
callq 0x20e90
cmpl $0x0, (%rax)
jne 0x1e26e
movq 0x48(%rsp), %rdi
addq $0x2a0, %rdi            # imm = 0x2A0
addq $0x18, %rdi
movb 0x63(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, %esi
callq 0xef90
movq 0x48(%rsp), %rdi
cvtsi2sdl (%rax), %xmm0
addsd 0x70(%rsp), %xmm0
movsd %xmm0, 0x70(%rsp)
addq $0x2a0, %rdi            # imm = 0x2A0
movb 0x63(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, %esi
callq 0xef90
cvtsi2sdl (%rax), %xmm0
addsd 0x68(%rsp), %xmm0
movsd %xmm0, 0x68(%rsp)
jmp 0x1e2ca
movq 0x48(%rsp), %rdi
addq $0x2a0, %rdi            # imm = 0x2A0
addq $0x30, %rdi
movb 0x63(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, %esi
callq 0xef90
movq 0x48(%rsp), %rdi
cvtsi2sdl (%rax), %xmm0
addsd 0x70(%rsp), %xmm0
movsd %xmm0, 0x70(%rsp)
addq $0x2a0, %rdi            # imm = 0x2A0
movb 0x63(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, %esi
callq 0xef90
cvtsi2sdl (%rax), %xmm0
addsd 0x68(%rsp), %xmm0
movsd %xmm0, 0x68(%rsp)
jmp 0x1e2cc
jmp 0x1e2ce
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x1e0a3
movsd 0x70(%rsp), %xmm0
ucomisd 0x68(%rsp), %xmm0
jbe 0x1e300
movq 0x108(%rsp), %rax
movl $0x1, 0x9c(%rax)
jmp 0x1e312
movq 0x108(%rsp), %rax
movl $0x0, 0x9c(%rax)
movl $0x0, 0x7c(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0xef00
addq $0x118, %rsp            # imm = 0x118
retq
movq 0xe0(%rsp), %rdi
callq 0x5690
nopl (%rax)