// File: /workspace/github_cpp_makefile_star2_O3/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 0x29ff4(%rip), %rax     # 0x3b490
cmpb $0x1, (%rax)
jne 0x114c9
movq 0x370(%rbx), %rax
testq %rax, %rax
je 0x114c9
leaq 0x29fd8(%rip), %rcx     # 0x3b48c
movslq (%rcx), %rcx
xorl %edx, %edx
divq %rcx
testq %rdx, %rdx
jne 0x114c9
movq %rbx, %rdi
callq 0x11a2a
movq 0x330(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
leaq 0x29fcb(%rip), %r15     # 0x3b4a8
cmpl $0x0, (%r15)
jle 0x11509
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 0x114e6
leaq 0x29f88(%rip), %r14     # 0x3b498
movsd 0x380(%rbx), %xmm1
movsd 0x1ec00(%rip), %xmm3    # 0x30120
unpcklps %xmm3, %xmm1            # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
movapd 0x1ebe5(%rip), %xmm4    # 0x30110
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 0x11598
movq %rbx, %rdi
xorl %esi, %esi
callq 0x11dec
movapd 0x1eb8d(%rip), %xmm4    # 0x30110
movsd 0x1eb95(%rip), %xmm3    # 0x30120
movsd 0x380(%rbx), %xmm1
unpcklps %xmm3, %xmm1            # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
jmp 0x1152b
ucomisd %xmm1, %xmm0
jne 0x115bb
jp 0x115bb
leaq 0x380(%rbx), %r12
movq %rbx, %rdi
xorl %esi, %esi
callq 0x11dec
xorpd %xmm0, %xmm0
movupd %xmm0, (%r12)
movq %rbx, %rdi
movl $0x1, %esi
callq 0x11dec
movsd (%r14), %xmm0
leaq 0x29fcc(%rip), %r12     # 0x3b5a0
movsd (%r12), %xmm1
ucomisd %xmm0, %xmm1
jae 0x116b3
movsd 0x378(%rbx), %xmm2
movsd 0x1eb2c(%rip), %xmm4    # 0x30120
unpcklps %xmm4, %xmm2            # xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1]
movapd 0x1eb11(%rip), %xmm5    # 0x30110
subpd %xmm5, %xmm2
movapd %xmm2, %xmm3
unpckhpd %xmm2, %xmm3            # xmm3 = xmm3[1],xmm2[1]
addsd %xmm2, %xmm3
mulsd %xmm3, %xmm0
movq 0x368(%rbx), %rdi
movq 0x1c8(%rdi), %rax
incq %rax
movq %rax, %xmm2
punpckldq %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
jbe 0x1171f
movq (%rdi), %rax
callq *0x10(%rax)
movapd 0x1eab7(%rip), %xmm4    # 0x30110
movsd 0x1eabf(%rip), %xmm3    # 0x30120
movsd 0x378(%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 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
jmp 0x11641
movsd 0x378(%rbx), %xmm2
movsd 0x1ea5d(%rip), %xmm4    # 0x30120
unpcklps %xmm4, %xmm2            # xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1]
movapd 0x1ea42(%rip), %xmm5    # 0x30110
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 0x1174a
jne 0x11760
jp 0x11760
movq $0x0, 0x378(%rbx)
jmp 0x1173f
ucomisd %xmm1, %xmm0
jne 0x1174a
jp 0x1174a
movq (%rdi), %rax
callq *0x10(%rax)
movq $0x0, 0x378(%rbx)
movq 0x368(%rbx), %rdi
movq $0x0, 0x1c8(%rdi)
movq (%rdi), %rax
callq *0x10(%rax)
movsd 0x1e9c8(%rip), %xmm4    # 0x30120
movapd 0x1e9b0(%rip), %xmm5    # 0x30110
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 0x11804
movq %rbx, %rdi
xorl %esi, %esi
callq 0x11e3a
movapd 0x1e94d(%rip), %xmm4    # 0x30110
movsd 0x1e955(%rip), %xmm3    # 0x30120
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 0x11797
ucomisd %xmm1, %xmm0
jne 0x11826
jp 0x11826
leaq 0x390(%rbx), %r14
movq %rbx, %rdi
xorl %esi, %esi
callq 0x11e3a
xorpd %xmm0, %xmm0
movupd %xmm0, (%r14)
movq %rbx, %rdi
movl $0x1, %esi
callq 0x11e3a
cmpl $0x0, (%r15)
jle 0x1185f
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 0x1183c
movq 0x2976a(%rip), %r14     # 0x3afd0
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 0x2126e
cmpl $0x0, (%r15)
jle 0x118e6
xorl %r14d, %r14d
movq 0x330(%rbx), %rax
movq 0x208(%rax), %rax
movq (%rax,%r14,8), %rdi
callq 0x2534a
incq %r14
movslq (%r15), %rax
cmpq %rax, %r14
jl 0x118a2
testl %eax, %eax
jle 0x118e6
xorl %r14d, %r14d
movq 0x338(%rbx), %rax
movq (%rax,%r14,8), %rdi
callq 0x22360
incq %r14
movslq (%r15), %rax
cmpq %rax, %r14
jl 0x118cb
movq 0x368(%rbx), %rdi
callq 0x1d2c6
cmpl $0x0, (%r15)
jle 0x1193f
xorl %r14d, %r14d
movq 0x350(%rbx), %rax
movq (%rax,%r14,8), %rdi
callq 0x22360
incq %r14
movslq (%r15), %rax
cmpq %rax, %r14
jl 0x118fb
testl %eax, %eax
jle 0x1193f
xorl %r14d, %r14d
movq 0x330(%rbx), %rax
movq 0x220(%rax), %rax
movq (%rax,%r14,8), %rdi
callq 0x277c8
incq %r14
movslq (%r15), %rax
cmpq %rax, %r14
jl 0x1191d
incq 0x380(%rbx)
incq 0x390(%rbx)
movdqu 0x370(%rbx), %xmm0
pcmpeqd %xmm1, %xmm1
psubq %xmm1, %xmm0
movdqu %xmm0, 0x370(%rbx)
leaq 0x29b1c(%rip), %rax     # 0x3b488
cmpb $0x0, (%rax)
jne 0x11981
leaq 0x29b12(%rip), %rax     # 0x3b48a
cmpb $0x1, (%rax)
jne 0x11a1e
movq 0x29648(%rip), %r14     # 0x3afd0
leaq 0x1efa1(%rip), %rsi     # 0x30930
movl $0x32, %edx
movq %r14, %rdi
callq 0x4340
movq 0x370(%rbx), %rsi
movq %r14, %rdi
callq 0x41e0
movq %rax, %r14
leaq 0x1efae(%rip), %rsi     # 0x30963
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 0x1ef90(%rip), %rsi     # 0x3096f
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