// File: /workspace/github_cpp_makefile_star2_O2/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
subq $0x28, %rsp
movq %rdi, %r15
callq 0x1739a
movl 0x25c(%r15), %eax
addq %rax, 0x260(%r15)
cmpl $0x0, 0x200(%r15)
movq %r15, 0x8(%rsp)
je 0x16e63
movq 0x1e8(%r15), %rax
cmpq %rax, 0x1f0(%r15)
je 0x16e35
movq (%rax), %rax
testq %rax, %rax
je 0x17308
leaq 0x1a78e(%rip), %rcx     # 0x31488
cmpb $0x1, (%rcx)
jne 0x16d79
movq 0x1a2ca(%rip), %rdi     # 0x30fd0
movq (%rdi), %rax
movq -0x18(%rax), %rax
movq $0x12, 0x10(%rdi,%rax)
pushq $0x20
popq %rbp
movl %ebp, %esi
callq 0x4440
leaq 0x20(%r15), %rsi
movq %rax, %rdi
callq 0x42b0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq $0xf, 0x10(%rax,%rcx)
movq %rax, %rdi
movl %ebp, %esi
callq 0x4440
movq 0x1e8(%r15), %rcx
movq (%rcx), %rsi
movq %rax, %rdi
callq 0x1e2c8
leaq 0xf755(%rip), %rsi      # 0x264b4
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
movq 0x1e8(%r15), %rax
movq (%rax), %rax
movq 0x8(%r15), %rdx
movq 0x8(%rax), %rsi
movl 0x8(%rsi), %ecx
movl %edx, %edi
subl %ecx, %edi
movl %edi, 0xc(%rsi)
movl 0x434(%rax), %ecx
cmpl $0x38, %ecx
jne 0x16dac
movl 0x430(%rax), %edi
shll $0x4, %edi
addl $-0x10, %edi
movq (%rsi), %rsi
addq %rdi, 0x128(%rsi)
decl 0x268(%r15)
cmpl $0x39, %ecx
jne 0x16fd3
movq 0x358(%r15), %rdi
testq %rdi, %rdi
je 0x16dd5
movq 0x450(%rax), %rsi
movq (%rdi), %rax
callq *0x10(%rax)
movq 0x1e8(%r15), %rax
movq (%rax), %rax
movslq 0x430(%rax), %r12
addq %r12, 0x250(%r15)
leaq 0x1e8(%r15), %r14
movq 0x8(%rax), %r15
testq %r15, %r15
je 0x16e05
movq %r15, %rdi
callq 0xdd6c
pushq $0x20
popq %rsi
movq %r15, %rdi
callq 0x4320
movq (%r14), %rsi
movq (%rsi), %rdi
testq %rdi, %rdi
je 0x16e24
movq (%rdi), %rax
callq *0x8(%rax)
movq (%r14), %rsi
leaq (%rsi,%r12,8), %rdx
movq %r14, %rdi
callq 0x132b4
movq 0x8(%rsp), %r15
movq %r15, %rdi
callq 0x17f1e
movq %r15, %rdi
callq 0x18610
movq %r15, %rdi
callq 0x190a2
movq %r15, %rdi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1947e
movq 0x1d8(%r15), %rax
cmpq 0x1d0(%r15), %rax
je 0x16cd3
leaq 0x1d0(%r15), %r14
leaq 0x208(%r15), %r13
leaq 0x20(%r15), %rax
movq %rax, 0x18(%rsp)
pushq $-0x1
popq %rax
movl %eax, 0x10(%rsp)
xorl %r12d, %r12d
leaq 0x1a609(%rip), %rbx     # 0x314a8
leaq 0x1a6e6(%rip), %r15     # 0x3158c
movslq (%rbx), %rax
cmpq %rax, %r12
jge 0x16ff5
movq (%r13), %rax
xorl %ebp, %ebp
movq (%rax,%r12,8), %rdx
movq 0x1d0(%rdx), %rcx
movq 0x1d8(%rdx), %rdx
subq %rcx, %rdx
sarq $0x3, %rdx
cmpq %rbp, %rdx
jbe 0x16fcb
cmpq $0x0, (%rcx,%rbp,8)
je 0x16f1a
movl (%r15), %edi
callq 0x13324
movl %eax, %ecx
movq (%r13), %rax
movq (%rax,%r12,8), %rdx
movq 0x1d0(%rdx), %rdx
movq (%rdx,%rbp,8), %rdx
movq 0x450(%rdx), %rdx
shrq %cl, %rdx
movq (%r14), %rsi
movq (%rsi), %rsi
movq 0x18(%rsi), %rsi
shrq %cl, %rsi
cmpq %rsi, %rdx
je 0x16f1f
incq %rbp
jmp 0x16eb8
leaq 0x1a562(%rip), %rax     # 0x31488
cmpb $0x1, (%rax)
jne 0x16fc6
leaq 0x1a553(%rip), %rax     # 0x31489
cmpb $0x0, (%rax)
jne 0x16fc6
movq 0x1a08a(%rip), %rdi     # 0x30fd0
movq (%rdi), %rax
movq -0x18(%rax), %rax
movq $0x12, 0x10(%rdi,%rax)
pushq $0x20
popq %rsi
callq 0x4440
movq %rax, %rdi
movq 0x18(%rsp), %rsi
callq 0x42b0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq $0xf, 0x10(%rax,%rcx)
movq %rax, %rdi
pushq $0x20
popq %rsi
callq 0x4440
movq (%r14), %rcx
movq (%rcx), %rsi
movq %rax, %rdi
callq 0x20aca
movq %rax, %rdi
leaq 0xf427(%rip), %rsi      # 0x263c5
callq 0x4300
movq (%r13), %rcx
movq (%rcx,%r12,8), %rcx
movq 0x1d0(%rcx), %rcx
movq (%rcx,%rbp,8), %rsi
movq %rax, %rdi
callq 0x1e2c8
movq %rax, %rdi
callq 0x4180
movl %r12d, 0x10(%rsp)
incq %r12
jmp 0x16ea6
cmpl $0x38, %ecx
setne %cl
movq 0x350(%r15), %rdi
testq %rdi, %rdi
sete %sil
orb %cl, %sil
je 0x16dc8
jmp 0x16dd5
movl 0x10(%rsp), %ebp
cmpl $-0x1, %ebp
je 0x1710a
movq 0x8(%rsp), %rbx
movq 0x1d0(%rbx), %rax
movq (%rax), %rsi
movq %rbx, %rdi
callq 0x17bbc
movq %rax, %r15
movslq %ebp, %rax
movq 0x208(%rbx), %rcx
movq (%rcx,%rax,8), %rdi
movq %r15, %rsi
callq 0x13460
testb %al, %al
je 0x171ad
leaq 0x1a447(%rip), %rax     # 0x31488
cmpb $0x1, (%rax)
jne 0x170e9
movq 0x19f7f(%rip), %rdi     # 0x30fd0
movq (%rdi), %rax
movq -0x18(%rax), %rax
movq $0x12, 0x10(%rdi,%rax)
pushq $0x20
popq %r12
movl %r12d, %esi
callq 0x4440
movq %rax, %rdi
movq 0x18(%rsp), %rsi
callq 0x42b0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq $0xf, 0x10(%rax,%rcx)
movq %rax, %rdi
movl %r12d, %esi
callq 0x4440
movq %rax, %rdi
movq %r15, %rsi
callq 0x1e2c8
leaq 0xf34c(%rip), %rsi      # 0x263f3
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movl %ebp, %esi
callq 0x44f0
leaq 0xf4fa(%rip), %rsi      # 0x265ba
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movl %ebp, %esi
callq 0x44f0
leaq 0x103f8(%rip), %rsi     # 0x274d1
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
movq (%r14), %rsi
movq (%rsi), %rdi
testq %rdi, %rdi
je 0x170fd
movq (%rdi), %rax
callq *0x8(%rax)
movq (%r14), %rsi
movq %r14, %rdi
callq 0x19444
jmp 0x171be
movq 0x8(%rsp), %r15
leaq 0x238(%r15), %rcx
movq %rcx, 0x10(%rsp)
xorl %r12d, %r12d
cmpl %eax, %r12d
jge 0x16cd3
movq %rbx, %rbp
movq 0x10(%rsp), %rdi
movq %r13, %rsi
callq 0x1c4f5
cmpl $-0x1, %eax
je 0x1719f
movslq %eax, %rbx
movq (%r13), %rcx
movq (%rcx,%rbx,8), %rcx
movl 0x200(%rcx), %ecx
cmpl $0xb, %ecx
je 0x17156
testl %ecx, %ecx
jne 0x1719f
movl %eax, 0x24(%rsp)
movq 0x1d0(%r15), %rax
movq (%rax), %rsi
movq %r15, %rdi
callq 0x17bbc
movq %r15, %rcx
movq %rax, %r15
movq 0x208(%rcx), %rax
movq (%rax,%rbx,8), %rdi
movq %r15, %rsi
callq 0x13460
testb %al, %al
jne 0x171c8
movq %r15, %rdi
callq 0x1e2be
movq (%r15), %rax
movq %r15, %rdi
callq *0x8(%rax)
movq 0x8(%rsp), %r15
incl %r12d
movq %rbp, %rbx
movl (%rbp), %eax
jmp 0x1711e
movq %r15, %rdi
callq 0x1e2be
movq (%r15), %rax
movq %r15, %rdi
callq *0x8(%rax)
movq 0x8(%rsp), %r15
jmp 0x16cd3
leaq 0x1a2b9(%rip), %rax     # 0x31488
cmpb $0x1, (%rax)
jne 0x1727b
movq 0x19df1(%rip), %rdi     # 0x30fd0
movq (%rdi), %rax
movq -0x18(%rax), %rax
movq $0x12, 0x10(%rdi,%rax)
pushq $0x20
popq %r12
movl %r12d, %esi
callq 0x4440
movq %rax, %rdi
movq 0x18(%rsp), %rsi
callq 0x42b0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq $0xf, 0x10(%rax,%rcx)
movq %rax, %rdi
movl %r12d, %esi
callq 0x4440
movq %rax, %rdi
movq %r15, %rsi
callq 0x1e2c8
leaq 0xf1be(%rip), %rsi      # 0x263f3
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movl 0x24(%rsp), %ebx
movl %ebx, %esi
callq 0x44f0
leaq 0xf368(%rip), %rsi      # 0x265ba
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movl %ebx, %esi
callq 0x44f0
leaq 0x10266(%rip), %rsi     # 0x274d1
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
movl 0x434(%r15), %eax
movl %eax, %ecx
andl $-0x8, %ecx
cmpl $0x18, %ecx
jne 0x172b0
movq 0x8(%rsp), %rbx
movq 0x358(%rbx), %rdi
testq %rdi, %rdi
je 0x172d2
movq 0x450(%r15), %rsi
movq 0x8(%rbx), %rdx
movq (%rdi), %rax
callq *0x10(%rax)
jmp 0x172d2
leal -0x21(%rax), %ecx
cmpl $0x3, %ecx
movq 0x8(%rsp), %rbx
jb 0x172d2
cmpl $0x54, %eax
je 0x172d2
cmpl $0x5f, %eax
je 0x1728c
movq 0x8(%rsp), %rbx
incl 0x268(%rbx)
movl 0x430(%r15), %eax
addq %rax, 0x248(%rbx)
movq 0x1d0(%rbx), %rsi
movq (%rsi), %rdi
testq %rdi, %rdi
movq %rbx, %r15
je 0x172fb
movq (%rdi), %rax
callq *0x8(%rax)
movq (%r14), %rsi
movq %r14, %rdi
callq 0x19444
jmp 0x16cd3
movq 0x19ce1(%rip), %rdi     # 0x30ff0
leaq 0xcd0c(%rip), %rsi      # 0x24022
callq 0x4300
leaq 0xf0f5(%rip), %rsi      # 0x26417
movq %rax, %rdi
callq 0x4300
leaq 0xd546(%rip), %rsi      # 0x24877
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movl $0xc9, %esi
callq 0x44f0
leaq 0xccf4(%rip), %rsi      # 0x24041
movq %rax, %rdi
callq 0x4300
leaq 0x20(%r15), %rsi
movq %rax, %rdi
callq 0x42b0
leaq 0xf0c9(%rip), %rsi      # 0x26431
movq %rax, %rdi
callq 0x4300
movq 0x8(%r15), %rsi
movq %rax, %rdi
callq 0x40d0
leaq 0x1014e(%rip), %rsi     # 0x274d1
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
xorl %edi, %edi
callq 0x4370