// File: gvaumour[P]cache-simulator/src/Cerebron.cc
// Function: CerebronPredictor::recordAccess(CacheEntry*, unsigned long, unsigned long, int, bool, bool, int, RD_TYPE, bool)
void
CerebronPredictor::recordAccess(CacheEntry* entry,uint64_t block_addr, uint64_t missPC, int set,\
			bool isWrite , bool inNVM, int index, RD_TYPE rd , bool isUpdate)
{
	if(simu_parameters.Cerebron_RDmodel)
	{
		bool hitSRAM = false, hitNVM = false;
		hitNVM = getHitPerDataArray( block_addr , set , true);
		hitSRAM = getHitPerDataArray( block_addr , set , false);
		/*
		if( !inNVM && isUpdate)
			hitSRAM = true;
		else
			hitSRAM = getHitPerDataArray( block_addr , set , false);
				
	
		if( inNVM && isUpdate)
			hitNVM = true;
		else 
			hitNVM = getHitPerDataArray( block_addr , set , true);
		*/
		/*
		string hitSRAM_str = hitSRAM ? "TRUE" : "FALSE";
		string hitNVM_str = hitNVM ? "TRUE" : "FALSE";		
		//debug_file << "hitSRAM = " << hitSRAM_str << " , hitNVM = " << hitNVM_str << endl;
		//debug_file << "BEFORE : entry->e_sram = " << entry->e_sram << endl;
		*/
		entry->e_sram += m_costParameters.costSRAM[isWrite];
		entry->e_sram +=  !hitSRAM ? m_costParameters.costDRAM[isWrite] : 0;

		entry->e_nvm += m_costParameters.costNVM[isWrite];
		entry->e_nvm += !hitNVM ? m_costParameters.costDRAM[isWrite] : 0;
		//debug_file << "END: entry->e_sram = " << entry->e_sram << endl;
	
		if(entry->isLearning_policy)
		{
			for(unsigned i = 0 ; i < m_features.size() ; i++)
			{
				int hash = hashing_function1( m_features_hash[i] , block_addr , missPC);
				m_features[i]->recordAccess(hash, isWrite , hitSRAM , hitNVM);
			}		
		}
	}
	else
	{
		if(entry->isLearning_policy)
		{
			for(unsigned i = 0 ; i < m_features.size() ; i++)
			{
				int hash = hashing_function1( m_features_hash[i] , block_addr , missPC);
				m_features[i]->recordAccess(hash, isWrite , rd);	
			}
		}
	}	
}

// Assembly:
subq $0xf8, %rsp
movl %r9d, %eax
movq %rcx, 0x40(%rsp)
movq %rdx, 0x48(%rsp)
movq %rsi, %r9
movq 0x40(%rsp), %rsi
movq %rdi, %r10
movq 0x48(%rsp), %rdi
movb %al, %dl
movb 0x118(%rsp), %al
movl 0x110(%rsp), %ecx
movl 0x108(%rsp), %ecx
movb 0x100(%rsp), %cl
movq %r10, 0xf0(%rsp)
movq %r9, 0xe8(%rsp)
movq %rdi, 0xe0(%rsp)
movq %rsi, 0xd8(%rsp)
movl %r8d, 0xd4(%rsp)
andb $0x1, %dl
movb %dl, 0xd3(%rsp)
andb $0x1, %cl
movb %cl, 0xd2(%rsp)
andb $0x1, %al
movb %al, 0xd1(%rsp)
movq 0xf0(%rsp), %rax
movq %rax, 0x50(%rsp)
leaq 0x8b235(%rip), %rax     # 0x93ff0
testb $0x1, 0x226(%rax)
je 0x9093
movq 0x50(%rsp), %rdi
movb $0x0, 0xd0(%rsp)
movb $0x0, 0xcf(%rsp)
movq 0xe0(%rsp), %rsi
movl 0xd4(%rsp), %edx
movl $0x1, %ecx
callq 0x57740
movq 0x50(%rsp), %rdi
andb $0x1, %al
movb %al, 0xcf(%rsp)
movq 0xe0(%rsp), %rsi
movl 0xd4(%rsp), %edx
xorl %ecx, %ecx
callq 0x57740
movq 0x50(%rsp), %rdi
andb $0x1, %al
movb %al, 0xd0(%rsp)
addq $0x340, %rdi            # imm = 0x340
addq $0x18, %rdi
movb 0xd3(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, %esi
callq 0xef90
movslq (%rax), %rcx
movq 0xe8(%rsp), %rax
addq 0x138(%rax), %rcx
movq %rcx, 0x138(%rax)
testb $0x1, 0xd0(%rsp)
jne 0x8e94
movq 0x50(%rsp), %rdi
addq $0x340, %rdi            # imm = 0x340
addq $0x30, %rdi
movb 0xd3(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, %esi
callq 0xef90
movl (%rax), %eax
movl %eax, 0x3c(%rsp)
jmp 0x8e9c
xorl %eax, %eax
movl %eax, 0x3c(%rsp)
jmp 0x8e9c
movq 0x50(%rsp), %rdi
movl 0x3c(%rsp), %eax
movslq %eax, %rcx
movq 0xe8(%rsp), %rax
addq 0x138(%rax), %rcx
movq %rcx, 0x138(%rax)
addq $0x340, %rdi            # imm = 0x340
movb 0xd3(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, %esi
callq 0xef90
movslq (%rax), %rcx
movq 0xe8(%rsp), %rax
addq 0x140(%rax), %rcx
movq %rcx, 0x140(%rax)
testb $0x1, 0xcf(%rsp)
jne 0x8f26
movq 0x50(%rsp), %rdi
addq $0x340, %rdi            # imm = 0x340
addq $0x30, %rdi
movb 0xd3(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, %esi
callq 0xef90
movl (%rax), %eax
movl %eax, 0x38(%rsp)
jmp 0x8f2e
xorl %eax, %eax
movl %eax, 0x38(%rsp)
jmp 0x8f2e
movl 0x38(%rsp), %eax
movslq %eax, %rcx
movq 0xe8(%rsp), %rax
addq 0x140(%rax), %rcx
movq %rcx, 0x140(%rax)
movq 0xe8(%rsp), %rax
testb $0x1, 0x149(%rax)
je 0x908e
movl $0x0, 0xc8(%rsp)
movq 0x50(%rsp), %rdi
movl 0xc8(%rsp), %eax
movq %rax, 0x30(%rsp)
addq $0x270, %rdi            # imm = 0x270
callq 0xf840
movq %rax, %rcx
movq 0x30(%rsp), %rax
cmpq %rcx, %rax
jae 0x908c
movq 0x50(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
movl 0xc8(%rsp), %eax
movl %eax, %esi
callq 0xf860
movq %rax, %rsi
leaq 0x98(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0xf880
movq 0x20(%rsp), %rdi
movq 0xe0(%rsp), %rsi
movq 0xd8(%rsp), %rdx
callq 0x2ff40
movl %eax, 0x2c(%rsp)
jmp 0x8fe8
leaq 0x98(%rsp), %rdi
callq 0xf7b0
movl 0x2c(%rsp), %eax
movq 0x50(%rsp), %rdi
movl %eax, 0xc4(%rsp)
addq $0x270, %rdi            # imm = 0x270
movl 0xc8(%rsp), %eax
movl %eax, %esi
callq 0xf8c0
movq (%rax), %rdi
movl 0xc4(%rsp), %esi
movb 0xd3(%rsp), %dl
movb 0xd0(%rsp), %cl
movb 0xcf(%rsp), %al
andb $0x1, %dl
andb $0x1, %cl
andb $0x1, %al
movzbl %dl, %edx
movzbl %cl, %ecx
movzbl %al, %r8d
callq 0x2d180
movl 0xc8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc8(%rsp)
jmp 0x8f6b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x90(%rsp)
movl %eax, 0x8c(%rsp)
leaq 0x98(%rsp), %rdi
callq 0xf7b0
jmp 0x91c0
jmp 0x908e
jmp 0x91b8
movq 0xe8(%rsp), %rax
testb $0x1, 0x149(%rax)
je 0x91b6
movl $0x0, 0x88(%rsp)
movq 0x50(%rsp), %rdi
movl 0x88(%rsp), %eax
movq %rax, 0x18(%rsp)
addq $0x270, %rdi            # imm = 0x270
callq 0xf840
movq %rax, %rcx
movq 0x18(%rsp), %rax
cmpq %rcx, %rax
jae 0x91b4
movq 0x50(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
movl 0x88(%rsp), %eax
movl %eax, %esi
callq 0xf860
movq %rax, %rsi
leaq 0x58(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0xf880
movq 0x8(%rsp), %rdi
movq 0xe0(%rsp), %rsi
movq 0xd8(%rsp), %rdx
callq 0x2ff40
movl %eax, 0x14(%rsp)
jmp 0x912d
leaq 0x58(%rsp), %rdi
callq 0xf7b0
movl 0x14(%rsp), %eax
movq 0x50(%rsp), %rdi
movl %eax, 0x84(%rsp)
addq $0x270, %rdi            # imm = 0x270
movl 0x88(%rsp), %eax
movl %eax, %esi
callq 0xf8c0
movq (%rax), %rdi
movl 0x84(%rsp), %esi
movb 0xd3(%rsp), %al
movl 0x110(%rsp), %ecx
andb $0x1, %al
movzbl %al, %edx
callq 0x2cfc0
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0x90b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x90(%rsp)
movl %eax, 0x8c(%rsp)
leaq 0x58(%rsp), %rdi
callq 0xf7b0
jmp 0x91c0
jmp 0x91b6
jmp 0x91b8
addq $0xf8, %rsp
retq
movq 0x90(%rsp), %rdi
callq 0x5690
nopl (%rax)