// File: /workspace/github_cpp_makefile_star2_O1/estwings57[P]CasHMC/sources/CasHMCWrapper.cpp
// Function: CasHMC::CasHMCWrapper::Update()
void CasHMCWrapper::Update()
{
	if(BANDWIDTH_PLOT && currentClockCycle > 0 && currentClockCycle%PLOT_SAMPLING == 0) {
		MakePlotData();
	}
	
#ifdef DEBUG_LOG
	if(currentClockCycle > 0 && currentClockCycle%LOG_EPOCH == 0) {
		cout<<"\n   === Simulation ["<<currentClockCycle/LOG_EPOCH<<"] epoch starts  ( CPU clk:"<<currentClockCycle<<" ) ===   "<<endl;
		PrintEpochStatistic();
		if(DEBUG_SIM) {
			debugOut.flush();	debugOut.close();
		}
		if(STATE_SIM) {
			stateOut.flush();	stateOut.close();
		}
		if(DEBUG_SIM || STATE_SIM) {
			PrintEpochHeader();
		}
	}
#endif

	//
	//update all class (HMC controller, links, and HMC block)
	//Roughly synchronize CPU clock cycle, link speed, and HMC clock cycle
	//
	hmcCont->Update();
	//Link master and slave are separately updated to flow packet from master to slave regardless of downstream or upstream
	for(int l=0; l<NUM_LINKS; l++) {
		hmcCont->downLinkMasters[l]->Update();
	}
	
		//Downstream links update at CPU clock cycle (depending on ratio of CPU cycle to Link cycle)
		while(CPU_CLK_PERIOD*downLinkTuner > linkPeriod*(downLinkClock + 1)) {
			DownLinkUpdate(false);
		}
		if(CPU_CLK_PERIOD*downLinkTuner == linkPeriod*(downLinkClock + 1)) {
			DownLinkUpdate(false);
			downLinkTuner = 0;
			downLinkClock = 0;
		}
		DownLinkUpdate(true);
	
			//HMC update at CPU clock cycle
			if(CPU_CLK_PERIOD <= tCK) {
				if(CPU_CLK_PERIOD*dramTuner > tCK*hmc->clockTuner) {
					hmc->Update();
				}
				else if(CPU_CLK_PERIOD*dramTuner == tCK*hmc->clockTuner) {
					dramTuner = 0;
					hmc->clockTuner = 0;
					hmc->Update();
				}
			}
			else {
				while(CPU_CLK_PERIOD*dramTuner > tCK*(hmc->clockTuner + 1)) {
					hmc->Update();
				}
				if(CPU_CLK_PERIOD*dramTuner == tCK*(hmc->clockTuner + 1)) {
					hmc->Update();
					dramTuner = 0;
					hmc->clockTuner = 0;
				}
				hmc->Update();
			}
		
		//Upstream links update at CPU clock cycle (depending on ratio of CPU cycle to Link cycle)
		while(CPU_CLK_PERIOD*upLinkTuner > linkPeriod*(upLinkClock + 1)) {
			UpLinkUpdate(false);
		}
		if(CPU_CLK_PERIOD*upLinkTuner == linkPeriod*(upLinkClock + 1)) {
			UpLinkUpdate(false);
			upLinkTuner = 0;
			upLinkClock = 0;
		}
		UpLinkUpdate(true);
	
	//Link master and slave are separately updated to flow packet from master to slave regardless of downstream or upstream
	for(int l=0; l<NUM_LINKS; l++) {
		hmcCont->upLinkSlaves[l]->Update();
	}
	
#ifndef DEBUG_LOG
	cout<<endl;
#endif
	//Print respective class state
	hmcCont->PrintState();
	for(int l=0; l<NUM_LINKS; l++) {
		hmcCont->downLinkMasters[l]->PrintState();
	}
		for(int l=0; l<NUM_LINKS; l++) {
			downstreamLinks[l]->PrintState();
		}
			hmc->PrintState();
		for(int l=0; l<NUM_LINKS; l++) {
			upstreamLinks[l]->PrintState();
		}
	for(int l=0; l<NUM_LINKS; l++) {
		hmcCont->upLinkSlaves[l]->PrintState();
	}
	
	currentClockCycle++;
	downLinkTuner++;
	upLinkTuner++;
	dramTuner++;
	DE_ST("\n---------------------------------------[ CPU clk:"<<currentClockCycle<<" / HMC clk:"<<hmc->currentClockCycle<<" ]---------------------------------------");
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
leaq 0x2ad6a(%rip), %rax     # 0x3c490
cmpb $0x1, (%rax)
jne 0x11753
movq 0x370(%rbx), %rax
testq %rax, %rax
je 0x11753
leaq 0x2ad4e(%rip), %rcx     # 0x3c48c
movslq (%rcx), %rcx
xorl %edx, %edx
divq %rcx
testq %rdx, %rdx
jne 0x11753
movq %rbx, %rdi
callq 0x11c50
movq 0x330(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
leaq 0x2ad41(%rip), %r15     # 0x3c4a8
cmpl $0x0, (%r15)
jle 0x11793
xorl %r14d, %r14d
movq 0x330(%rbx), %rax
movq 0x208(%rax), %rax
movq (%rax,%r14,8), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
incq %r14
movslq (%r15), %rax
cmpq %rax, %r14
jl 0x11770
leaq 0x2acfe(%rip), %r14     # 0x3c498
movsd 0x380(%rbx), %xmm1
movsd 0x1f956(%rip), %xmm3    # 0x31100
unpcklps %xmm3, %xmm1            # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
movapd 0x1f93b(%rip), %xmm4    # 0x310f0
subpd %xmm4, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
mulsd (%r14), %xmm0
movq 0x388(%rbx), %rax
incq %rax
movq %rax, %xmm2
punpckldq %xmm3, %xmm2    # xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
subpd %xmm4, %xmm2
movapd %xmm2, %xmm1
unpckhpd %xmm2, %xmm1            # xmm1 = xmm1[1],xmm2[1]
addsd %xmm2, %xmm1
mulsd 0x3a0(%rbx), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x11822
movq %rbx, %rdi
xorl %esi, %esi
callq 0x12026
movapd 0x1f8e3(%rip), %xmm4    # 0x310f0
movsd 0x1f8eb(%rip), %xmm3    # 0x31100
movsd 0x380(%rbx), %xmm1
unpcklps %xmm3, %xmm1            # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
jmp 0x117b5
ucomisd %xmm1, %xmm0
jne 0x11845
jp 0x11845
leaq 0x380(%rbx), %r12
movq %rbx, %rdi
xorl %esi, %esi
callq 0x12026
xorpd %xmm0, %xmm0
movupd %xmm0, (%r12)
movq %rbx, %rdi
movl $0x1, %esi
callq 0x12026
movsd (%r14), %xmm0
leaq 0x2ad42(%rip), %r12     # 0x3c5a0
movsd (%r12), %xmm1
ucomisd %xmm0, %xmm1
jae 0x118d8
movsd 0x378(%rbx), %xmm1
movsd 0x1f886(%rip), %xmm3    # 0x31100
unpcklps %xmm3, %xmm1            # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
movapd 0x1f86b(%rip), %xmm4    # 0x310f0
subpd %xmm4, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
mulsd (%r14), %xmm0
movq 0x368(%rbx), %rdi
movq 0x1c8(%rdi), %rax
incq %rax
movq %rax, %xmm2
punpckldq %xmm3, %xmm2    # xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
subpd %xmm4, %xmm2
movapd %xmm2, %xmm1
unpckhpd %xmm2, %xmm1            # xmm1 = xmm1[1],xmm2[1]
addsd %xmm2, %xmm1
mulsd (%r12), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x11949
movq (%rdi), %rax
callq *0x10(%rax)
jmp 0x1186a
movsd 0x378(%rbx), %xmm2
movsd 0x1f818(%rip), %xmm4    # 0x31100
unpcklps %xmm4, %xmm2            # xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1]
movapd 0x1f7fd(%rip), %xmm5    # 0x310f0
subpd %xmm5, %xmm2
movapd %xmm2, %xmm3
unpckhpd %xmm2, %xmm3            # xmm3 = xmm3[1],xmm2[1]
addsd %xmm2, %xmm3
mulsd %xmm3, %xmm0
movq 0x368(%rbx), %rdi
movsd 0x1c8(%rdi), %xmm2
unpcklps %xmm4, %xmm2            # xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1]
subpd %xmm5, %xmm2
movapd %xmm2, %xmm3
unpckhpd %xmm2, %xmm3            # xmm3 = xmm3[1],xmm2[1]
addsd %xmm2, %xmm3
mulsd %xmm3, %xmm1
ucomisd %xmm1, %xmm0
ja 0x11975
jne 0x1198b
jp 0x1198b
xorl %eax, %eax
movq %rax, 0x378(%rbx)
movq %rax, 0x1c8(%rdi)
jmp 0x11975
ucomisd %xmm1, %xmm0
jne 0x1196e
jp 0x1196e
movq (%rdi), %rax
callq *0x10(%rax)
xorl %eax, %eax
movq %rax, 0x378(%rbx)
movq 0x368(%rbx), %rcx
movq %rax, 0x1c8(%rcx)
movq 0x368(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movsd 0x1f77d(%rip), %xmm4    # 0x31100
movapd 0x1f765(%rip), %xmm5    # 0x310f0
movsd 0x390(%rbx), %xmm1
unpcklps %xmm4, %xmm1            # xmm1 = xmm1[0],xmm4[0],xmm1[1],xmm4[1]
subpd %xmm5, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
mulsd (%r14), %xmm0
movq 0x398(%rbx), %rax
incq %rax
movq %rax, %xmm2
punpckldq %xmm4, %xmm2    # xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1]
subpd %xmm5, %xmm2
movapd %xmm2, %xmm1
unpckhpd %xmm2, %xmm1            # xmm1 = xmm1[1],xmm2[1]
addsd %xmm2, %xmm1
mulsd 0x3a0(%rbx), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x11a2f
movq %rbx, %rdi
xorl %esi, %esi
callq 0x12074
movapd 0x1f702(%rip), %xmm4    # 0x310f0
movsd 0x1f70a(%rip), %xmm3    # 0x31100
movsd 0x390(%rbx), %xmm1
unpcklps %xmm3, %xmm1            # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm4, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
mulsd (%r14), %xmm0
movq 0x398(%rbx), %rax
incq %rax
movq %rax, %xmm2
punpckldq %xmm3, %xmm2    # xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
subpd %xmm4, %xmm2
jmp 0x119c2
ucomisd %xmm1, %xmm0
jne 0x11a51
jp 0x11a51
leaq 0x390(%rbx), %r14
movq %rbx, %rdi
xorl %esi, %esi
callq 0x12074
xorpd %xmm0, %xmm0
movupd %xmm0, (%r14)
movq %rbx, %rdi
movl $0x1, %esi
callq 0x12074
cmpl $0x0, (%r15)
jle 0x11a8a
xorl %r14d, %r14d
movq 0x330(%rbx), %rax
movq 0x220(%rax), %rax
movq (%rax,%r14,8), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
incq %r14
movslq (%r15), %rax
cmpq %rax, %r14
jl 0x11a67
movq 0x2a53f(%rip), %r14     # 0x3bfd0
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 0x330(%rbx), %rdi
callq 0x21950
cmpl $0x0, (%r15)
jle 0x11aef
xorl %r14d, %r14d
movq 0x330(%rbx), %rax
movq 0x208(%rax), %rax
movq (%rax,%r14,8), %rdi
callq 0x25b4a
incq %r14
movslq (%r15), %rax
cmpq %rax, %r14
jl 0x11acd
cmpl $0x0, (%r15)
jle 0x11b13
xorl %r14d, %r14d
movq 0x338(%rbx), %rax
movq (%rax,%r14,8), %rdi
callq 0x22a9e
incq %r14
movslq (%r15), %rax
cmpq %rax, %r14
jl 0x11af8
movq 0x368(%rbx), %rdi
callq 0x1da54
cmpl $0x0, (%r15)
jle 0x11b43
xorl %r14d, %r14d
movq 0x350(%rbx), %rax
movq (%rax,%r14,8), %rdi
callq 0x22a9e
incq %r14
movslq (%r15), %rax
cmpq %rax, %r14
jl 0x11b28
cmpl $0x0, (%r15)
jle 0x11b6e
xorl %r14d, %r14d
movq 0x330(%rbx), %rax
movq 0x220(%rax), %rax
movq (%rax,%r14,8), %rdi
callq 0x2803c
incq %r14
movslq (%r15), %rax
cmpq %rax, %r14
jl 0x11b4c
incq 0x370(%rbx)
incq 0x380(%rbx)
incq 0x390(%rbx)
incq 0x378(%rbx)
leaq 0x2a8f7(%rip), %rax     # 0x3c488
cmpb $0x0, (%rax)
jne 0x11ba6
leaq 0x2a8ed(%rip), %rax     # 0x3c48a
cmpb $0x1, (%rax)
jne 0x11c43
movq 0x2a423(%rip), %r14     # 0x3bfd0
leaq 0x1fd1c(%rip), %rsi     # 0x318d0
movl $0x32, %edx
movq %r14, %rdi
callq 0x4340
movq 0x370(%rbx), %rsi
movq %r14, %rdi
callq 0x41e0
movq %rax, %r14
leaq 0x1fd29(%rip), %rsi     # 0x31903
movl $0xb, %edx
movq %rax, %rdi
callq 0x4340
movq 0x368(%rbx), %rax
movq 0x8(%rax), %rsi
movq %r14, %rdi
callq 0x41e0
movq %rax, %rbx
leaq 0x1fd0b(%rip), %rsi     # 0x3190f
movl $0x29, %edx
movq %rax, %rdi
callq 0x4340
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x42d0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4040
movq %rax, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x41f0
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
nop