// File: /workspace/github_cpp_makefile_star2_O2/estwings57[P]CasHMC/sources/HMCController.cpp
// Function: CasHMC::HMCController::LinkPowerStateManager()
void HMCController::LinkPowerStateManager()
{
	switch(LINK_POWER) {
		case NO_MANAGEMENT:
		case QUIESCE_SLEEP:{
			break;
		}
		case MSHR:{
			linkEpochCycle--;
			//control the number of active link in every one epoch
			if(linkEpochCycle == 0) {
				//The average allocated MSHR size
				double aveMSHR = accuMSHR/((double)LINK_EPOCH*1000000/CPU_CLK_PERIOD);
				aveMSHR *= MSHR_SCALING;
				
				if(aveMSHR >= 4) {
					sleepLink = 0;
				}
				else if(aveMSHR >= 3) {
					sleepLink = 1;
				}
				else if(aveMSHR >= 2) {
					sleepLink = 2;
				}
				else {
					sleepLink = 3;
				}
				DEBUG(ALI(33)<<header<<"Down) epoch average MSHR size : "<<aveMSHR);
				
				//link epoch cycle reset
				accuMSHR = 0;
				linkEpochCycle = ceil((double)LINK_EPOCH*1000000/CPU_CLK_PERIOD);
			}
			break;
		}
		case LINK_MONITOR:{
			linkEpochCycle--;
			//control the number of active link in every one epoch
			if(linkEpochCycle == 0) {
				//( ( total FLIT length * 16 bytes) / one epoch time ) * 1000 ms / 1000000000 B = [GB/s]
				double epochDownBandwidth = LINK_SCALING*((requestAccLNG*16)/LINK_EPOCH)/1000000;
				double epochUpBandwidth = LINK_SCALING*((responseAccLNG*16)/LINK_EPOCH)/1000000;
				if(epochDownBandwidth >= maxLinkBand*3 || epochUpBandwidth >= maxLinkBand*3) {
					sleepLink = 0;
				}
				else if(epochDownBandwidth >= maxLinkBand*2 || epochUpBandwidth >= maxLinkBand*2) {
					sleepLink = 1;
				}
				else if(epochDownBandwidth >= maxLinkBand || epochUpBandwidth >= maxLinkBand) {
					sleepLink = 2;
				}
				else {
					sleepLink = 3;
				}

				DEBUG(ALI(33)<<header<<"Down) epoch link BANDWIDTH downstream : "<<epochDownBandwidth<<" GB/s | upstream : "<<epochUpBandwidth<<" GB/s (sleepLink : "<<sleepLink<<")");
				
				//packet accumulated length and link epoch cycle reset
				requestAccLNG = 0;
				responseAccLNG = 0;
				linkEpochCycle = ceil((double)LINK_EPOCH*1000000/CPU_CLK_PERIOD);
			}
			break;
		}
		case AUTONOMOUS:{
			linkEpochCycle--;
			//control the number of active link in every one epoch
			if(linkEpochCycle == 0) {
				//The average MSHR size
				double aveMSHR = accuMSHR/((double)LINK_EPOCH*1000000/CPU_CLK_PERIOD);
				aveMSHR *= MSHR_SCALING;
				//( ( total FLIT length * 16 bytes) / one epoch time ) * 1000 ms / 1000000000 B = [GB/s]
				double epochDownBandwidth = LINK_SCALING*((requestAccLNG*16)/LINK_EPOCH)/1000000;
				double epochUpBandwidth = LINK_SCALING*((responseAccLNG*16)/LINK_EPOCH)/1000000;
				if(aveMSHR >= 4 || epochDownBandwidth >= maxLinkBand*3 || epochUpBandwidth >= maxLinkBand*3) {
					sleepLink = 0;
				}
				else if(aveMSHR >= 3 || epochDownBandwidth >= maxLinkBand*2 || epochUpBandwidth >= maxLinkBand*2) {
					sleepLink = 1;
				}
				else if(aveMSHR >= 2 || epochDownBandwidth >= maxLinkBand || epochUpBandwidth >= maxLinkBand) {
					sleepLink = 2;
				}
				else {
					sleepLink = 3;
				}
				
				DEBUG(ALI(33)<<header<<"Down) epoch average MSHR size : "<<aveMSHR);
				DEBUG(ALI(33)<<header<<"Down) epoch link BANDWIDTH downstream : "<<epochDownBandwidth<<" GB/s | upstream : "<<epochUpBandwidth<<" GB/s (sleepLink : "<<sleepLink<<")");

				//packet accumulated length and link epoch cycle reset
				accuMSHR = 0;
				requestAccLNG = 0;
				responseAccLNG = 0;
				linkEpochCycle = ceil((double)LINK_EPOCH*1000000/CPU_CLK_PERIOD);
			}
			break;
		}
		default:{
			ERROR(header<<"   == Error - WRONG LINK_POWER parameter  (LINK_POWER : "<<LINK_POWER<<")");
			exit(0);
			break;
		}
	}
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdi, %rbx
leaq 0x195b5(%rip), %r14     # 0x314e8
movl (%r14), %eax
cmpq $0x4, %rax
ja 0x1857c
leaq 0xe429(%rip), %rcx      # 0x26370
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
decl 0x240(%rbx)
jne 0x18570
movsd 0x260(%rbx), %xmm1
unpcklps 0xc1c5(%rip), %xmm1     # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0xc1cd(%rip), %xmm1     # 0x24140
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
leaq 0x1956e(%rip), %r14     # 0x314f0
movsd (%r14), %xmm0
mulsd 0xe2a1(%rip), %xmm0     # 0x26230
addsd %xmm1, %xmm2
leaq 0x194fe(%rip), %r15     # 0x31498
divsd (%r15), %xmm0
divsd %xmm0, %xmm2
leaq 0x1954e(%rip), %rax     # 0x314f8
mulsd (%rax), %xmm2
ucomisd 0xe28a(%rip), %xmm2     # 0x26240
jae 0x1821a
ucomisd 0xe284(%rip), %xmm2     # 0x26248
jae 0x1822f
ucomisd 0xe27e(%rip), %xmm2     # 0x26250
jae 0x1824a
movl $0x3, 0x258(%rbx)
jmp 0x18254
decl 0x240(%rbx)
jne 0x18570
movsd 0x260(%rbx), %xmm0
unpcklps 0xc12e(%rip), %xmm0     # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0xc136(%rip), %xmm0     # 0x24140
movapd %xmm0, %xmm3
unpckhpd %xmm0, %xmm3            # xmm3 = xmm3[1],xmm0[1]
addsd %xmm0, %xmm3
leaq 0x194d3(%rip), %r14     # 0x314f0
movsd (%r14), %xmm0
movsd 0xe206(%rip), %xmm1     # 0x26230
mulsd %xmm0, %xmm1
leaq 0x19463(%rip), %r15     # 0x31498
divsd (%r15), %xmm1
divsd %xmm1, %xmm3
leaq 0x194b3(%rip), %rax     # 0x314f8
mulsd (%rax), %xmm3
movdqu 0x248(%rbx), %xmm1
psllq $0x4, %xmm1
movdqa 0xc092(%rip), %xmm2     # 0x240f0
pand %xmm1, %xmm2
por 0xc096(%rip), %xmm2     # 0x24100
leaq 0x1948f(%rip), %rax     # 0x31500
psrlq $0x20, %xmm1
por 0xc092(%rip), %xmm1     # 0x24110
subpd 0xc09a(%rip), %xmm1     # 0x24120
addpd %xmm2, %xmm1
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
divpd %xmm0, %xmm1
movsd (%rax), %xmm2
unpcklpd %xmm2, %xmm2            # xmm2 = xmm2[0,0]
mulpd %xmm1, %xmm2
xorl %eax, %eax
ucomisd 0xe198(%rip), %xmm3     # 0x26240
divpd 0xe1c0(%rip), %xmm2     # 0x26270
movapd %xmm2, %xmm1
unpckhpd %xmm2, %xmm1            # xmm1 = xmm1[1],xmm2[1]
jae 0x183e7
movl 0x23c(%rbx), %ecx
leal (%rcx,%rcx,2), %edx
cvtsi2sd %rdx, %xmm0
ucomisd %xmm0, %xmm2
jae 0x183e7
ucomisd %xmm0, %xmm1
jae 0x183e7
pushq $0x1
popq %rax
ucomisd 0xe15d(%rip), %xmm3     # 0x26248
jae 0x183e7
leal (%rcx,%rcx), %edx
cvtsi2sd %rdx, %xmm0
ucomisd %xmm0, %xmm2
jae 0x183e7
ucomisd %xmm0, %xmm1
jae 0x183e7
ucomisd 0xe13b(%rip), %xmm3     # 0x26250
jae 0x183e4
movl %ecx, %eax
cvtsi2sd %rax, %xmm0
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
cmpnlepd %xmm2, %xmm0
movmskpd %xmm0, %ecx
xorl %eax, %eax
cmpl $0x3, %ecx
sete %al
orl $0x2, %eax
jmp 0x183e7
decl 0x240(%rbx)
jne 0x18570
leaq 0x193ae(%rip), %rax     # 0x31500
movdqu 0x248(%rbx), %xmm1
psllq $0x4, %xmm1
movdqa 0xbf89(%rip), %xmm2     # 0x240f0
pand %xmm1, %xmm2
por 0xbf8d(%rip), %xmm2     # 0x24100
leaq 0x19376(%rip), %r14     # 0x314f0
psrlq $0x20, %xmm1
por 0xbf89(%rip), %xmm1     # 0x24110
movsd (%r14), %xmm0
subpd 0xbf8c(%rip), %xmm1     # 0x24120
addpd %xmm2, %xmm1
movapd %xmm0, %xmm2
unpcklpd %xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0]
divpd %xmm2, %xmm1
movsd (%rax), %xmm2
unpcklpd %xmm2, %xmm2            # xmm2 = xmm2[0,0]
mulpd %xmm1, %xmm2
divpd 0xe0b8(%rip), %xmm2     # 0x26270
movl 0x23c(%rbx), %eax
leal (%rax,%rax,2), %ecx
cvtsi2sd %rcx, %xmm1
ucomisd %xmm1, %xmm2
movapd %xmm2, %xmm3
unpckhpd %xmm2, %xmm3            # xmm3 = xmm3[1],xmm2[1]
jae 0x18223
ucomisd %xmm1, %xmm3
jae 0x18223
leal (%rax,%rax), %ecx
cvtsi2sd %rcx, %xmm1
ucomisd %xmm1, %xmm2
jae 0x1823b
ucomisd %xmm1, %xmm3
jae 0x1823b
movl %eax, %eax
cvtsi2sd %rax, %xmm1
unpcklpd %xmm1, %xmm1            # xmm1 = xmm1[0,0]
cmpnlepd %xmm2, %xmm1
movmskpd %xmm1, %eax
cmpl $0x3, %eax
jne 0x182e5
movl $0x3, 0x258(%rbx)
jmp 0x182ef
andl $0x0, 0x258(%rbx)
jmp 0x18254
andl $0x0, 0x258(%rbx)
jmp 0x182ef
movl $0x1, 0x258(%rbx)
jmp 0x18254
movl $0x1, 0x258(%rbx)
jmp 0x182ef
movl $0x2, 0x258(%rbx)
leaq 0x1922d(%rip), %rax     # 0x31488
cmpb $0x1, (%rax)
jne 0x182d1
leaq 0x19222(%rip), %rax     # 0x31489
cmpb $0x0, (%rax)
jne 0x182d1
movq 0x18d5d(%rip), %rdi     # 0x30fd0
movq (%rdi), %rax
movq -0x18(%rax), %rax
movq $0x21, 0x10(%rdi,%rax)
pushq $0x20
popq %rsi
movapd %xmm2, (%rsp)
callq 0x4440
leaq 0x20(%rbx), %rsi
movq %rax, %rdi
callq 0x42b0
leaq 0xe39a(%rip), %rsi      # 0x2663d
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movaps (%rsp), %xmm0
callq 0x4470
movq %rax, %rdi
callq 0x4180
movsd (%r14), %xmm0
mulsd 0xdf64(%rip), %xmm0     # 0x26230
divsd (%r15), %xmm0
andq $0x0, 0x260(%rbx)
addq $0x240, %rbx            # imm = 0x240
jmp 0x18564
movl $0x2, 0x258(%rbx)
leaq 0x248(%rbx), %r15
leaq 0x1918b(%rip), %rax     # 0x31488
cmpb $0x1, (%rax)
jne 0x183bc
leaq 0x1917c(%rip), %rax     # 0x31489
cmpb $0x0, (%rax)
jne 0x183bc
movq 0x18cb3(%rip), %rdi     # 0x30fd0
movq (%rdi), %rax
movq -0x18(%rax), %rax
movq $0x21, 0x10(%rdi,%rax)
pushq $0x20
popq %rsi
movapd %xmm2, 0x10(%rsp)
movapd %xmm3, (%rsp)
callq 0x4440
leaq 0x20(%rbx), %rsi
movq %rax, %rdi
callq 0x42b0
leaq 0xe30b(%rip), %rsi      # 0x2665e
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movaps 0x10(%rsp), %xmm0
callq 0x4470
leaq 0xe318(%rip), %rsi      # 0x26687
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movaps (%rsp), %xmm0
callq 0x4470
leaq 0xe311(%rip), %rsi      # 0x2669b
movq %rax, %rdi
callq 0x4300
movl 0x258(%rbx), %esi
movq %rax, %rdi
callq 0x4210
leaq 0xf12a(%rip), %rsi      # 0x274d1
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
movsd (%r14), %xmm0
addq $0x240, %rbx            # imm = 0x240
mulsd 0xde65(%rip), %xmm0     # 0x26230
xorpd %xmm1, %xmm1
movupd %xmm1, (%r15)
leaq 0x190bd(%rip), %rax     # 0x31498
divsd (%rax), %xmm0
jmp 0x18564
pushq $0x2
popq %rax
movl %eax, 0x258(%rbx)
leaq 0x19094(%rip), %r12     # 0x31488
movb (%r12), %al
cmpb $0x1, %al
jne 0x18478
leaq 0x19086(%rip), %rcx     # 0x31489
cmpb $0x0, (%rcx)
jne 0x18478
movq 0x18bc1(%rip), %rdi     # 0x30fd0
movq (%rdi), %rax
movq -0x18(%rax), %rax
movq $0x21, 0x10(%rdi,%rax)
pushq $0x20
popq %rsi
movapd %xmm1, (%rsp)
movapd %xmm2, 0x10(%rsp)
movapd %xmm3, 0x20(%rsp)
callq 0x4440
leaq 0x20(%rbx), %rsi
movq %rax, %rdi
callq 0x42b0
leaq 0xe1f2(%rip), %rsi      # 0x2663d
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movapd 0x20(%rsp), %xmm0
callq 0x4470
movq %rax, %rdi
callq 0x4180
movapd 0x10(%rsp), %xmm2
movapd (%rsp), %xmm1
movb (%r12), %al
leaq 0x248(%rbx), %r12
testb $0x1, %al
je 0x18539
leaq 0x18ffb(%rip), %rax     # 0x31489
cmpb $0x0, (%rax)
jne 0x18539
movq 0x18b32(%rip), %rdi     # 0x30fd0
movq (%rdi), %rax
movq -0x18(%rax), %rax
movq $0x21, 0x10(%rdi,%rax)
pushq $0x20
popq %rsi
movapd %xmm1, (%rsp)
movapd %xmm2, 0x10(%rsp)
callq 0x4440
leaq 0x20(%rbx), %rsi
movq %rax, %rdi
callq 0x42b0
leaq 0xe18a(%rip), %rsi      # 0x2665e
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movaps 0x10(%rsp), %xmm0
callq 0x4470
leaq 0xe197(%rip), %rsi      # 0x26687
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movapd (%rsp), %xmm0
callq 0x4470
leaq 0xe18f(%rip), %rsi      # 0x2669b
movq %rax, %rdi
callq 0x4300
movl 0x258(%rbx), %esi
movq %rax, %rdi
callq 0x4210
leaq 0xefa8(%rip), %rsi      # 0x274d1
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
andq $0x0, 0x260(%rbx)
addq $0x240, %rbx            # imm = 0x240
xorpd %xmm0, %xmm0
movupd %xmm0, (%r12)
movsd (%r14), %xmm0
mulsd 0xdcd1(%rip), %xmm0     # 0x26230
divsd (%r15), %xmm0
callq 0x4080
cvttsd2si %xmm0, %rax
movl %eax, (%rbx)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq 0x18a6d(%rip), %rdi     # 0x30ff0
leaq 0xba98(%rip), %rsi      # 0x24022
callq 0x4300
leaq 0xde81(%rip), %rsi      # 0x26417
movq %rax, %rdi
callq 0x4300
leaq 0xc2d2(%rip), %rsi      # 0x24877
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movl $0x254, %esi            # imm = 0x254
callq 0x44f0
leaq 0xba80(%rip), %rsi      # 0x24041
movq %rax, %rdi
callq 0x4300
addq $0x20, %rbx
movq %rax, %rdi
movq %rbx, %rsi
callq 0x42b0
leaq 0xe025(%rip), %rsi      # 0x26604
movq %rax, %rdi
callq 0x4300
movl (%r14), %esi
movq %rax, %rdi
callq 0x44f0
leaq 0xeed8(%rip), %rsi      # 0x274d1
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
xorl %edi, %edi
callq 0x4370