// File: /workspace/github_cpp_makefile_star2_O3/estwings57[P]CasHMC/sources/HMCController.cpp
// Function: CasHMC::HMCController::Update()
void HMCController::Update()
{
	//Link wakes up from low power mode
	LinkPowerExitManager();
	
	//accumulate the allocated MSHR size
	accuMSHR += alloMSHR;
	
	//Downstream buffer state
	if(bufPopDelay==0 && downBuffers.size() > 0) {
		//Check packet dependency
		int link = -1;
		for(int l=0; l<NUM_LINKS; l++) {
			for(int i=0; i<downLinkMasters[l]->Buffers.size(); i++) {
				if(downLinkMasters[l]->Buffers[i] != NULL) {
					unsigned maxBlockBit = _log2(ADDRESS_MAPPING);
					if((downLinkMasters[l]->Buffers[i]->ADRS >> maxBlockBit) == (downBuffers[0]->address >> maxBlockBit)) {
						link = l;
						DEBUG(ALI(18)<<header<<ALI(15)<<*downBuffers[0]<<"Down) This transaction has a DEPENDENCY with "<<*downLinkMasters[l]->Buffers[i]);
						break;
					}
				}
			}
		}
		
		if(link == -1) {
			for(int l=0; l<NUM_LINKS; l++) {
				link = FindAvailableLink(inServiceLink, downLinkMasters);
				if(link == -1) {
					//DEBUG(ALI(18)<<header<<ALI(15)<<*downBuffers[0]<<"Down) all link buffer FULL");
				}
				else if(downLinkMasters[link]->currentState != ACTIVE
				&& downLinkMasters[link]->currentState != LINK_RETRY) {
					continue;
					//DEBUG(ALI(18)<<header<<ALI(15)<<*downBuffers[0]<<"Down) link "<<l<<" is not ACTIVE mode ["<<downLinkMasters[link]->powerMode<<"]");
				}
				else {
					Packet *packet = ConvTranIntoPacket(downBuffers[0]);
					if(downLinkMasters[link]->Receive(packet)) {
						DE_CR(ALI(18)<<header<<ALI(15)<<*packet<<"Down) SENDING packet to link mater "<<link<<" (LM_D"<<link<<")");
						if(!((packet->CMD >= P_WR16 && packet->CMD <= P_WR128)
						|| packet->CMD == P_WR256 || packet->CMD == P_2ADD8
						|| packet->CMD == P_ADD16 || packet->CMD == P_INC8
						|| packet->CMD == P_BWR)) {
							returnTransCnt++;
						}
						//Call callback function if posted write packet is tranmitted
						if((packet->CMD >= P_WR16 && packet->CMD <= P_WR128) || packet->CMD == P_WR256) {
							if(writeDone != NULL) {
								(*writeDone)(packet->ADRS, currentClockCycle);
							}
						}
						requestAccLNG += packet->LNG;
						delete downBuffers[0];
						downBuffers.erase(downBuffers.begin());
						break;
					}
					else {
						packet->ReductGlobalTAG();
						delete packet;
						//DEBUG(ALI(18)<<header<<ALI(15)<<*packet<<"Down) Link "<<link<<" buffer FULL");	
					}
				}
			}
		}
		else {
			Packet *packet = ConvTranIntoPacket(downBuffers[0]);
			if(downLinkMasters[link]->Receive(packet)) {
				DE_CR(ALI(18)<<header<<ALI(15)<<*packet<<"Down) SENDING packet to link mater "<<link<<" (LM_D"<<link<<")");
				delete downBuffers[0];
				downBuffers.erase(downBuffers.begin());
			}
			else {
				packet->ReductGlobalTAG();
				delete packet;
				//DEBUG(ALI(18)<<header<<ALI(15)<<*packet<<"Down) Link "<<link<<" buffer FULL");	
			}
		}
	}
	
	//Upstream buffer state
	if(upBuffers.size() > 0) {
		//Make sure that buffer[0] is not virtual tail packet.
		if(upBuffers[0] == NULL) {
			ERROR(header<<"  == Error - HMC controller up buffer[0] is NULL (It could be one of virtual tail packet occupying packet length  (CurrentClock : "<<currentClockCycle<<")");
			exit(0);
		}
		else {
			DE_CR(ALI(18)<<header<<ALI(15)<<*upBuffers[0]<<"Up)   RETURNING transaction to system bus");
			upBuffers[0]->trace->tranFullLat = currentClockCycle - upBuffers[0]->trace->tranTransmitTime;
			if(upBuffers[0]->CMD == RD_RS) {
				upBuffers[0]->trace->statis->hmcTransmitSize += (upBuffers[0]->LNG - 1)*16;
			}
			returnTransCnt--;
			//Call callback function if it is registered
			if(upBuffers[0]->CMD == WR_RS) {
				if(writeDone != NULL) {
					(*writeDone)(upBuffers[0]->ADRS, currentClockCycle);
				}
			}
			else if(upBuffers[0]->CMD == RD_RS) {
				if(readDone != NULL) {
					(*readDone)(upBuffers[0]->ADRS, currentClockCycle);
				}
			}
			int packetLNG = upBuffers[0]->LNG;
			responseAccLNG += packetLNG;
			delete upBuffers[0]->trace;
			delete upBuffers[0];
			upBuffers.erase(upBuffers.begin(), upBuffers.begin()+packetLNG);
		}
	}
	
	//Link state manager
	LinkPowerStateManager();
	//Link goes to low power mode
	LinkPowerEntryManager();
	
	LinkStatistic();
	Step();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
callq 0x1ee18
movl 0x25c(%rbx), %eax
addq %rax, 0x260(%rbx)
cmpl $0x0, 0x200(%rbx)
je 0x1e6df
movq 0x1e8(%rbx), %rax
cmpq %rax, 0x1f0(%rbx)
je 0x1eaaf
movq (%rax), %rax
testq %rax, %rax
je 0x1ed86
leaq 0x1cf88(%rip), %rcx     # 0x3b488
cmpb $0x1, (%rcx)
jne 0x1e600
movq 0x1cac0(%rip), %rax     # 0x3afd0
movq (%rax), %rcx
movq -0x18(%rcx), %rdx
movq $0x12, 0x10(%rax,%rdx)
movq -0x18(%rcx), %rcx
leaq (%rax,%rcx), %r14
cmpb $0x0, 0xe1(%rax,%rcx)
jne 0x1e547
movq %r14, %rdi
movl $0x20, %esi
callq 0x42d0
movb $0x1, 0xe1(%r14)
movb $0x20, 0xe0(%r14)
movq 0x20(%rbx), %rsi
movq 0x28(%rbx), %rdx
movq 0x1ca72(%rip), %rdi     # 0x3afd0
callq 0x4340
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rcx
movq $0xf, 0x10(%r14,%rcx)
movq -0x18(%rax), %rax
leaq (%r14,%rax), %r15
cmpb $0x0, 0xe1(%r14,%rax)
jne 0x1e59e
movq %r15, %rdi
movl $0x20, %esi
callq 0x42d0
movb $0x1, 0xe1(%r15)
movb $0x20, 0xe0(%r15)
movq 0x1e8(%rbx), %rax
movq (%rax), %rsi
movq %r14, %rdi
callq 0x28270
movq %rax, %r14
leaq 0x13f02(%rip), %rsi     # 0x324c4
movl $0x29, %edx
movq %rax, %rdi
callq 0x4340
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x42d0
movsbl %al, %esi
movq %r14, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x41f0
movq 0x1e8(%rbx), %rax
movq (%rax), %rax
movq 0x8(%rbx), %rdx
movq 0x8(%rax), %rcx
movl 0x8(%rcx), %esi
movl %edx, %edi
subl %esi, %edi
movl %edi, 0xc(%rcx)
movl 0x434(%rax), %esi
cmpl $0x38, %esi
jne 0x1ea6f
movl 0x430(%rax), %esi
shll $0x4, %esi
addl $-0x10, %esi
movq (%rcx), %rcx
addq %rsi, 0x128(%rcx)
decl 0x268(%rbx)
movq 0x350(%rbx), %rdi
testq %rdi, %rdi
je 0x1e656
movq 0x450(%rax), %rsi
movq (%rdi), %rax
callq *0x10(%rax)
movq 0x1e8(%rbx), %rax
movq (%rax), %rax
movslq 0x430(%rax), %r15
addq %r15, 0x250(%rbx)
movq 0x8(%rax), %r14
testq %r14, %r14
je 0x1e67f
movq %r14, %rdi
callq 0x13542
movl $0x20, %esi
movq %r14, %rdi
callq 0x4300
movq 0x1e8(%rbx), %r14
movq (%r14), %rdi
testq %rdi, %rdi
je 0x1e6a8
movq (%rdi), %rax
callq *0x8(%rax)
movq 0x1e8(%rbx), %r14
testl %r15d, %r15d
je 0x1eaaf
leaq (%r14,%r15,8), %r15
movq 0x1f0(%rbx), %rdx
subq %r15, %rdx
je 0x1ea97
movq %r14, %rdi
movq %r15, %rsi
callq 0x4480
movq 0x1f0(%rbx), %rax
movq %rax, %rcx
jmp 0x1ea9d
movq 0x1d8(%rbx), %rax
cmpq 0x1d0(%rbx), %rax
je 0x1e4d9
leaq 0x1cdae(%rip), %rax     # 0x3b4a8
movl (%rax), %eax
testl %eax, %eax
jle 0x1e4d9
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
xorl %r10d, %r10d
leaq 0x1ce79(%rip), %r11     # 0x3b58c
leaq 0x1cd6e(%rip), %r12     # 0x3b488
movq 0x1c8af(%rip), %r13     # 0x3afd0
xorl %r15d, %r15d
movq 0x208(%rbx), %rcx
movq (%rcx,%r15,8), %rcx
movq 0x1d0(%rcx), %rdx
movq 0x1d8(%rcx), %rsi
subq %rdx, %rsi
je 0x1e8ed
sarq $0x3, %rsi
movl (%r11), %edi
bsrl %edi, %ecx
cmpl $0x2, %edi
cmovbl %r10d, %ecx
movl $0x1, %r8d
shll %cl, %r8d
cmpl %edi, %r8d
adcl $0x0, %ecx
movq 0x1d0(%rbx), %rdi
cmpq $0x1, %rsi
adcq $0x0, %rsi
xorl %r14d, %r14d
movq (%rdx,%r14,8), %r8
testq %r8, %r8
je 0x1e79a
movq 0x450(%r8), %r8
shrq %cl, %r8
movq (%rdi), %r9
movq 0x18(%r9), %r9
shrq %cl, %r9
cmpq %r9, %r8
je 0x1e7a7
incq %r14
cmpq %r14, %rsi
jne 0x1e778
jmp 0x1e8ed
cmpb $0x1, (%r12)
jne 0x1e7ba
leaq 0x1ccd4(%rip), %rcx     # 0x3b489
cmpb $0x0, (%rcx)
je 0x1e7c2
movl %r15d, %ebp
jmp 0x1e8ed
movq (%r13), %rax
movq -0x18(%rax), %rcx
movq $0x12, 0x10(%r13,%rcx)
movq -0x18(%rax), %rax
leaq (%rax,%r13), %r12
cmpb $0x0, 0xe1(%r13,%rax)
jne 0x1e7fc
movq %r12, %rdi
movl $0x20, %esi
callq 0x42d0
movb $0x1, 0xe1(%r12)
movb $0x20, 0xe0(%r12)
movq 0x20(%rbx), %rsi
movq 0x28(%rbx), %rdx
movq %r13, %rdi
callq 0x4340
movq %rax, %r12
movq (%rax), %rax
movq -0x18(%rax), %rcx
movq $0xf, 0x10(%r12,%rcx)
movq -0x18(%rax), %rax
leaq (%r12,%rax), %r13
cmpb $0x0, 0xe1(%r12,%rax)
jne 0x1e850
movq %r13, %rdi
movl $0x20, %esi
callq 0x42d0
movb $0x1, 0xe1(%r13)
movb $0x20, 0xe0(%r13)
movq 0x1d0(%rbx), %rax
movq (%rax), %rsi
movq %r12, %rdi
callq 0x2b744
movq %rax, %r12
movl $0x2d, %edx
movq %rax, %rdi
leaq 0x13b59(%rip), %rsi     # 0x323d5
callq 0x4340
movq 0x208(%rbx), %rax
movq (%rax,%r15,8), %rax
movq 0x1d0(%rax), %rax
movq (%rax,%r14,8), %rsi
movq %r12, %rdi
callq 0x28270
movq %rax, %r12
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x42d0
movsbl %al, %esi
movq %r12, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x41f0
leaq 0x1cbd8(%rip), %rax     # 0x3b4a8
movl (%rax), %eax
movl %r15d, %ebp
movq 0x1c6f4(%rip), %r13     # 0x3afd0
leaq 0x1cba5(%rip), %r12     # 0x3b488
xorl %r10d, %r10d
leaq 0x1cc9f(%rip), %r11     # 0x3b58c
incq %r15
movslq %eax, %rcx
cmpq %rcx, %r15
jl 0x1e724
cmpl $-0x1, %ebp
je 0x1eaf0
movq 0x1d0(%rbx), %rax
movq (%rax), %rsi
movq %rbx, %rdi
callq 0x1f810
movq %rax, %r15
movslq %ebp, %rax
movq 0x208(%rbx), %rcx
movq (%rcx,%rax,8), %rdi
movq %r15, %rsi
callq 0x1a222
testb %al, %al
je 0x1eb87
cmpb $0x1, (%r12)
jne 0x1ed38
movq (%r13), %rax
movq -0x18(%rax), %rcx
movq $0x12, 0x10(%r13,%rcx)
movq -0x18(%rax), %rax
leaq (%rax,%r13), %r12
cmpb $0x0, 0xe1(%r13,%rax)
jne 0x1e97d
movq %r12, %rdi
movl $0x20, %esi
callq 0x42d0
movb $0x1, 0xe1(%r12)
movb $0x20, 0xe0(%r12)
movq 0x20(%rbx), %rsi
movq 0x28(%rbx), %rdx
movq 0x1c63b(%rip), %rdi     # 0x3afd0
callq 0x4340
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rcx
movq $0xf, 0x10(%r14,%rcx)
movq -0x18(%rax), %rax
leaq (%r14,%rax), %r12
cmpb $0x0, 0xe1(%r14,%rax)
jne 0x1e9d6
movq %r12, %rdi
movl $0x20, %esi
callq 0x42d0
movb $0x1, 0xe1(%r12)
movb $0x20, 0xe0(%r12)
movq %r14, %rdi
movq %r15, %rsi
callq 0x28270
movq %rax, %r14
leaq 0x13a0f(%rip), %rsi     # 0x32403
movl $0x23, %edx
movq %rax, %rdi
callq 0x4340
movq %r14, %rdi
movl %ebp, %esi
callq 0x4500
movq %rax, %r14
leaq 0x13bb5(%rip), %rsi     # 0x325ca
movl $0x6, %edx
movq %rax, %rdi
callq 0x4340
movq %r14, %rdi
movl %ebp, %esi
callq 0x4500
movq %rax, %r14
leaq 0x14aab(%rip), %rsi     # 0x334e1
movl $0x1, %edx
movq %rax, %rdi
callq 0x4340
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x42d0
movsbl %al, %esi
movq %r14, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x41f0
jmp 0x1ed38
decl 0x268(%rbx)
cmpl $0x39, %esi
setne %cl
movq 0x358(%rbx), %rdi
testq %rdi, %rdi
sete %sil
orb %cl, %sil
je 0x1e649
jmp 0x1e656
movq %r15, %rax
movq %r15, %rcx
subq %r15, %rax
addq %rax, %r14
cmpq %r14, %rcx
je 0x1eaaf
movq %r14, 0x1f0(%rbx)
movq %rbx, %rdi
callq 0x1fc5a
movq %rbx, %rdi
callq 0x20464
movq %rbx, %rdi
callq 0x21216
incq 0x8(%rbx)
movl 0x200(%rbx), %eax
leal -0x1(%rax), %ecx
xorl %edx, %edx
testl %eax, %eax
cmovgl %ecx, %edx
movl %edx, 0x200(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testl %eax, %eax
jle 0x1e4d9
leaq 0x238(%rbx), %r15
leaq 0x208(%rbx), %r13
xorl %r14d, %r14d
movq %r15, %rdi
movq %r13, %rsi
callq 0x25b4e
cmpl $-0x1, %eax
je 0x1eb73
movl %eax, %ebp
movslq %eax, %r12
movq (%r13), %rax
movq (%rax,%r12,8), %rax
movl 0x200(%rax), %eax
cmpl $0xb, %eax
je 0x1eb35
testl %eax, %eax
jne 0x1eb73
movq 0x1d0(%rbx), %rax
movq (%rax), %rsi
movq %rbx, %rdi
callq 0x1f810
movq 0x208(%rbx), %rcx
movq (%rcx,%r12,8), %rdi
movq %rax, %r12
movq %rax, %rsi
callq 0x1a222
testb %al, %al
jne 0x1eb9d
movq %r12, %rdi
callq 0x28266
movq (%r12), %rax
movq %r12, %rdi
callq *0x8(%rax)
incl %r14d
leaq 0x1c92b(%rip), %rax     # 0x3b4a8
cmpl (%rax), %r14d
jl 0x1eb09
jmp 0x1e4d9
movq %r15, %rdi
callq 0x28266
movq (%r15), %rax
movq %r15, %rdi
callq *0x8(%rax)
jmp 0x1e4d9
leaq 0x1c8e4(%rip), %rax     # 0x3b488
cmpb $0x1, (%rax)
jne 0x1ecdf
movq %r12, %r15
movq 0x1c419(%rip), %rdx     # 0x3afd0
movq (%rdx), %rax
movq -0x18(%rax), %rcx
movq $0x12, 0x10(%rdx,%rcx)
movq -0x18(%rax), %rax
leaq (%rdx,%rax), %r12
cmpb $0x0, 0xe1(%rdx,%rax)
jne 0x1ebef
movq %r12, %rdi
movl $0x20, %esi
callq 0x42d0
movb $0x1, 0xe1(%r12)
movb $0x20, 0xe0(%r12)
movq 0x20(%rbx), %rsi
movq 0x28(%rbx), %rdx
movq 0x1c3c9(%rip), %rdi     # 0x3afd0
callq 0x4340
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rcx
movq $0xf, 0x10(%r14,%rcx)
movq -0x18(%rax), %rax
leaq (%r14,%rax), %r12
cmpb $0x0, 0xe1(%r14,%rax)
jne 0x1ec48
movq %r12, %rdi
movl $0x20, %esi
callq 0x42d0
movb $0x1, 0xe1(%r12)
movb $0x20, 0xe0(%r12)
movq %r14, %rdi
movq %r15, %r12
movq %r15, %rsi
callq 0x28270
movq %rax, %r14
leaq 0x1379a(%rip), %rsi     # 0x32403
movl $0x23, %edx
movq %rax, %rdi
callq 0x4340
movq %r14, %rdi
movl %ebp, %esi
callq 0x4500
movq %rax, %r14
leaq 0x13940(%rip), %rsi     # 0x325ca
movl $0x6, %edx
movq %rax, %rdi
callq 0x4340
movq %r14, %rdi
movl %ebp, %esi
callq 0x4500
movq %rax, %r14
leaq 0x14836(%rip), %rsi     # 0x334e1
movl $0x1, %edx
movq %rax, %rdi
callq 0x4340
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x42d0
movsbl %al, %esi
movq %r14, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x41f0
movl 0x434(%r12), %eax
movl %eax, %ecx
andl $-0x8, %ecx
cmpl $0x18, %ecx
jne 0x1ed11
movq 0x358(%rbx), %rdi
testq %rdi, %rdi
je 0x1ed29
movq 0x450(%r12), %rsi
movq 0x8(%rbx), %rdx
movq (%rdi), %rax
callq *0x10(%rax)
jmp 0x1ed29
leal -0x21(%rax), %ecx
cmpl $0x3, %ecx
jb 0x1ed29
cmpl $0x54, %eax
je 0x1ed29
cmpl $0x5f, %eax
je 0x1ecf1
incl 0x268(%rbx)
movl 0x430(%r12), %eax
addq %rax, 0x248(%rbx)
movq 0x1d0(%rbx), %rdi
movq (%rdi), %rax
testq %rax, %rax
je 0x1ed57
movq (%rax), %rcx
movq %rax, %rdi
callq *0x8(%rcx)
movq 0x1d0(%rbx), %rdi
leaq 0x8(%rdi), %rsi
movq 0x1d8(%rbx), %rdx
cmpq %rdx, %rsi
je 0x1ed76
subq %rsi, %rdx
callq 0x4480
movq 0x1d8(%rbx), %rdx
addq $-0x8, %rdx
movq %rdx, 0x1d8(%rbx)
jmp 0x1e4d9
movq 0x1c263(%rip), %rdi     # 0x3aff0
leaq 0x1128e(%rip), %rsi     # 0x30022
callq 0x42e0
leaq 0x13687(%rip), %rsi     # 0x32427
movq %rax, %rdi
callq 0x42e0
leaq 0x11ae8(%rip), %rsi     # 0x30897
movq %rax, %rdi
callq 0x42e0
movq %rax, %rdi
movl $0xc9, %esi
callq 0x4500
leaq 0x11276(%rip), %rsi     # 0x30041
movq %rax, %rdi
callq 0x42e0
leaq 0x20(%rbx), %rsi
movq %rax, %rdi
callq 0x4290
leaq 0x1365b(%rip), %rsi     # 0x32441
movq %rax, %rdi
callq 0x42e0
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x40c0
leaq 0x146e0(%rip), %rsi     # 0x334e1
movq %rax, %rdi
callq 0x42e0
movq %rax, %rdi
callq 0x4170
xorl %edi, %edi
callq 0x4360