// File: /workspace/github_cpp_makefile_star2_O2/estwings57[P]CasHMC/sources/HMCController.cpp
// Function: CasHMC::HMCController::LinkPowerExitManager()
void HMCController::LinkPowerExitManager()
{
	switch(LINK_POWER) {
		case NO_MANAGEMENT:{
			break;
		}
		case QUIESCE_SLEEP:{
			//Check the current link state (sleep or down)
			int link = 0;
			int linkState = 0;
			for(link=0; link<NUM_LINKS; link++) {
				if(downLinkMasters[link]->currentState == DOWN) {
					linkState = 1;
					break;
				}
				else if(downLinkMasters[link]->currentState == SLEEP) {
					linkState = 2;
					break;
				}
			}
			//Link is already waking up
			for(int l=0; l<NUM_LINKS; l++) {
				if(downLinkMasters[l]->currentState == TRANSITION_TO_RETRAIN
				|| downLinkMasters[l]->currentState == RETRAIN1
				|| downLinkMasters[l]->currentState == RETRAIN2) {
					linkState = 0;
					break;
				}
			}
			
			//If link is on down mode
			if(linkState == 1) {
				if(downBuffers.size() > 0 && currentClockCycle >= staySREF) {
					modeTransition[link] = currentClockCycle + ceil((double)(tPST+tTXD+tPSC)/CPU_CLK_PERIOD);
					downLinkMasters[link]->currentState = TRANSITION_TO_RETRAIN;
					DEBUG(ALI(33)<<header<<"Down) RETRAINING MODE transition after "<<modeTransition[link]<<" cycle (LM_D"<<link<<")");
				}
			}
			//If link is on sleep mode
			else if(linkState == 2) {
				if(downBuffers.size() >= AWAKE_REQ) {
					modeTransition[link] = currentClockCycle + ceil((double)(tPST+tTXD)/CPU_CLK_PERIOD);
					downLinkMasters[link]->currentState = TRANSITION_TO_RETRAIN;
					DEBUG(ALI(33)<<header<<"Down) RETRAINING MODE transition after "<<modeTransition[link]<<" cycle (LM_D"<<link<<")");
				}
			}
			
			//Retraining mode entry
			for(int l=0; l<NUM_LINKS; l++) {
				if(downLinkMasters[l]->currentState == TRANSITION_TO_RETRAIN) {
					if(currentClockCycle >= modeTransition[l]) {
						for(int k=0; k<NUM_LINKS; k++) {
							if(downLinkMasters[k]->currentState == DOWN) {
								downLinkMasters[k]->currentState = SLEEP;
							}
						}
						downLinkMasters[l]->firstNull = true;
						downLinkMasters[l]->currentState = RETRAIN1;
						stayActive[l] = currentClockCycle + ceil((double)tOP/CPU_CLK_PERIOD);
						DE_CR(ALI(33)<<header<<"Down) entering RETRAINING MODE (LM_D"<<l<<")");
					}
				}
			}
			break;
		}
		case MSHR:
		case LINK_MONITOR:
		case AUTONOMOUS:{
			//awake up links as many as sleepLink
			for(int l=0; l<NUM_LINKS-sleepLink; l++) {
				if(downLinkMasters[l]->currentState == SLEEP) {
					//Stagger transition between active mode and sleep modes in order to avoid supply voltage shifts
					if(currentClockCycle >= staggerActive) {
						uint64_t stag = 0;
						uint64_t tran = 0;
						if(staggeringActive[l]) {
							staggeringActive[l] = false;
							stag = ceil((double)tSS/CPU_CLK_PERIOD);
							tran = ceil((double)tTXD/CPU_CLK_PERIOD);
						}
						else {
							stag = ceil((double)(tPST+tSS)/CPU_CLK_PERIOD);
							tran = ceil((double)(tPST+tTXD)/CPU_CLK_PERIOD);
						}
						staggerActive = currentClockCycle + stag;
						modeTransition[l] = currentClockCycle + tran;
						downLinkMasters[l]->currentState = TRANSITION_TO_RETRAIN;
						DEBUG(ALI(33)<<header<<"Down) RETRAINING MODE transition after "<<modeTransition[l]<<" cycle (stagger : "<<staggerActive<<") (LM_D"<<l<<")");
					}
					else {
						staggeringActive[l] = true;
					}
				}
			}
			
			//Retraining mode entry
			for(int l=0; l<NUM_LINKS; l++) {
				if(downLinkMasters[l]->currentState == TRANSITION_TO_RETRAIN) {
					if(currentClockCycle >= modeTransition[l]) {
						for(int k=0; k<NUM_LINKS; k++) {
							if(downLinkMasters[k]->currentState == DOWN) {
								downLinkMasters[k]->currentState = SLEEP;
							}
						}
						downLinkMasters[l]->firstNull = true;
						downLinkMasters[l]->currentState = RETRAIN1;
						stayActive[l] = currentClockCycle + ceil((double)tOP/CPU_CLK_PERIOD);
						DE_CR(ALI(33)<<header<<"Down) entering RETRAINING MODE (LM_D"<<l<<")");
					}
				}
			}
			break;
		}
		default:{
			ERROR(header<<"   == Error - WRONG LINK_POWER parameter  (LINK_POWER : "<<LINK_POWER<<")");
			exit(0);
			break;
		}
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
leaq 0x1a136(%rip), %r14     # 0x314e8
movl (%r14), %eax
leal -0x2(%rax), %ecx
cmpl $0x3, %ecx
jae 0x17773
leaq 0x2f8(%rbx), %r12
leaq 0x20(%rbx), %rax
movq %rax, 0x18(%rsp)
xorl %r13d, %r13d
leaq 0x1a0cd(%rip), %rbp     # 0x314a8
movl (%rbp), %r14d
movl %r14d, %eax
subl 0x258(%rbx), %eax
cmpq %rax, %r13
jae 0x17613
movq 0x208(%rbx), %rax
movq (%rax,%r13,8), %rax
cmpl $0x1, 0x200(%rax)
jne 0x1760b
movq 0x8(%rbx), %r14
movq 0x278(%rbx), %r15
movq %r12, %rdi
movq %r13, %rsi
callq 0x11106
movq (%rax), %rcx
cmpq %r15, %r14
jae 0x17432
orq %rdx, %rcx
movq %rcx, (%rax)
jmp 0x1760b
testq %rcx, %rdx
je 0x1747f
movq %r12, %rdi
movq %r13, %rsi
callq 0x11106
notq %rdx
andq %rdx, (%rax)
leaq 0x1a0e1(%rip), %rax     # 0x31530
movsd (%rax), %xmm0
leaq 0x1a03e(%rip), %rax     # 0x31498
movsd (%rax), %xmm1
movsd %xmm1, 0x10(%rsp)
divsd %xmm1, %xmm0
callq 0x4080
movapd %xmm0, (%rsp)
leaq 0x1a0df(%rip), %rax     # 0x31558
movsd (%rax), %xmm0
jmp 0x174cf
leaq 0x1a09a(%rip), %rax     # 0x31520
movsd (%rax), %xmm1
movsd %xmm1, 0x20(%rsp)
leaq 0x1a099(%rip), %rax     # 0x31530
movsd (%rax), %xmm0
addsd %xmm1, %xmm0
leaq 0x19ff2(%rip), %rax     # 0x31498
movsd (%rax), %xmm1
movsd %xmm1, 0x10(%rsp)
divsd %xmm1, %xmm0
callq 0x4080
movapd %xmm0, (%rsp)
movsd 0x20(%rsp), %xmm0
leaq 0x1a08d(%rip), %rax     # 0x31558
addsd (%rax), %xmm0
divsd 0x10(%rsp), %xmm0
callq 0x4080
cvttsd2si %xmm0, %rax
movsd 0xed51(%rip), %xmm1     # 0x26238
subsd %xmm1, %xmm0
cvttsd2si %xmm0, %rcx
movq %rax, %rdx
sarq $0x3f, %rdx
movapd (%rsp), %xmm0
cvttsd2si %xmm0, %rsi
andq %rcx, %rdx
subsd %xmm1, %xmm0
cvttsd2si %xmm0, %rcx
orq %rax, %rdx
movq %rsi, %rax
sarq $0x3f, %rax
andq %rcx, %rax
orq %rsi, %rax
movq 0x8(%rbx), %rcx
addq %rcx, %rax
movq %rax, 0x278(%rbx)
addq %rcx, %rdx
movq 0x2b8(%rbx), %rax
movq %rdx, (%rax,%r13,8)
movq 0x208(%rbx), %rax
movq (%rax,%r13,8), %rax
movl $0x7, 0x200(%rax)
leaq 0x19f33(%rip), %rax     # 0x31488
cmpb $0x1, (%rax)
jne 0x1760b
leaq 0x19f24(%rip), %rax     # 0x31489
cmpb $0x0, (%rax)
jne 0x1760b
movq 0x19a5b(%rip), %rdi     # 0x30fd0
movq (%rdi), %rax
movq -0x18(%rax), %rax
movq $0x21, 0x10(%rdi,%rax)
pushq $0x20
popq %rsi
callq 0x4440
movq %rax, %rdi
movq 0x18(%rsp), %rsi
callq 0x42b0
movq %rax, %rdi
leaq 0xf10b(%rip), %rsi      # 0x266af
callq 0x4300
movq 0x2b8(%rbx), %rcx
movq (%rcx,%r13,8), %rsi
movq %rax, %rdi
callq 0x4210
movq %rax, %rdi
leaq 0xefe0(%rip), %rsi      # 0x265a6
callq 0x4300
movq 0x278(%rbx), %rsi
movq %rax, %rdi
callq 0x4210
movq %rax, %rdi
leaq 0xefd5(%rip), %rsi      # 0x265b9
callq 0x4300
movq %rax, %rdi
movl %r13d, %esi
callq 0x44f0
movq %rax, %rdi
leaq 0xfed3(%rip), %rsi      # 0x274d1
callq 0x4300
movq %rax, %rdi
callq 0x4180
incq %r13
jmp 0x173db
xorl %r12d, %r12d
leaq 0x19f2b(%rip), %r13     # 0x31548
pushq $0x20
popq %r15
movslq %r14d, %rax
cmpq %rax, %r12
jge 0x17b19
movq 0x208(%rbx), %rcx
movq (%rcx,%r12,8), %rax
cmpl $0x7, 0x200(%rax)
jne 0x1776b
movq 0x8(%rbx), %rdx
movq 0x2b8(%rbx), %rsi
cmpq (%rsi,%r12,8), %rdx
jb 0x1776b
movl %r14d, %esi
xorl %edi, %edi
cmpq %rdi, %rsi
je 0x17682
movq (%rcx,%rdi,8), %r8
cmpl $0x2, 0x200(%r8)
jne 0x1767d
movl $0x1, 0x200(%r8)
incq %rdi
jmp 0x1765f
movb $0x1, 0x268(%rax)
movl $0x3, 0x200(%rax)
movq %rdx, %xmm0
punpckldq 0xca90(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0xca98(%rip), %xmm0     # 0x24140
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd %xmm1, (%rsp)
movsd (%r13), %xmm0
leaq 0x19dd2(%rip), %rax     # 0x31498
divsd (%rax), %xmm0
callq 0x4080
addsd (%rsp), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0xeb50(%rip), %xmm0     # 0x26238
cvttsd2si %xmm0, %rdx
andq %rcx, %rdx
orq %rax, %rdx
movq 0x288(%rbx), %rax
movq %rdx, (%rax,%r12,8)
leaq 0x19d83(%rip), %rax     # 0x31488
cmpb $0x0, (%rax)
je 0x1776b
movq 0x198bf(%rip), %rdi     # 0x30fd0
movq (%rdi), %rax
movq -0x18(%rax), %rax
movq $0x21, 0x10(%rdi,%rax)
movl %r15d, %esi
callq 0x4440
movq %rax, %rdi
movq 0x18(%rsp), %rsi
callq 0x42b0
movq %rax, %rdi
leaq 0xefa4(%rip), %rsi      # 0x266e4
callq 0x4300
movq %rax, %rdi
movl %r12d, %esi
callq 0x44f0
movq %rax, %rdi
leaq 0xfd77(%rip), %rsi      # 0x274d1
callq 0x4300
movq %rax, %rdi
callq 0x4180
movl (%rbp), %r14d
incq %r12
jmp 0x17621
testl %eax, %eax
je 0x17b19
cmpl $0x1, %eax
jne 0x17b28
leaq 0x19d1d(%rip), %rax     # 0x314a8
movl (%rax), %eax
movq 0x208(%rbx), %r15
xorl %ecx, %ecx
testl %eax, %eax
cmovlel %ecx, %eax
xorl %r14d, %r14d
cmpq %r14, %rax
je 0x177bc
movq (%r15,%r14,8), %rdx
movl 0x200(%rdx), %edx
cmpl $0x1, %edx
je 0x177c5
cmpl $0x2, %edx
je 0x177c1
incq %r14
jmp 0x1779e
movl %eax, %r14d
jmp 0x177c8
pushq $0x1
jmp 0x177c7
pushq $0x2
popq %rcx
xorl %edx, %edx
movl $0x98, %esi
cmpq %rdx, %rax
je 0x177f1
movq (%r15,%rdx,8), %rdi
movl 0x200(%rdi), %edi
cmpl $0x7, %edi
ja 0x177ec
btl %edi, %esi
jb 0x179aa
incq %rdx
jmp 0x177cf
cmpl $0x2, %ecx
je 0x17860
cmpl $0x1, %ecx
jne 0x179aa
movq 0x1d8(%rbx), %rax
cmpq 0x1d0(%rbx), %rax
je 0x179aa
movq 0x8(%rbx), %rax
cmpq 0x280(%rbx), %rax
jb 0x179aa
movq %rax, %xmm1
punpckldq 0xc8ff(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0xc907(%rip), %xmm1     # 0x24140
movapd %xmm1, %xmm2
leaq 0x19cdc(%rip), %rax     # 0x31520
movsd (%rax), %xmm0
leaq 0x19d09(%rip), %rax     # 0x31558
addsd (%rax), %xmm0
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
leaq 0x19d12(%rip), %rax     # 0x31570
jmp 0x178b3
movq 0x1d8(%rbx), %rax
subq 0x1d0(%rbx), %rax
sarq $0x3, %rax
leaq 0x19c73(%rip), %rcx     # 0x314ec
movslq (%rcx), %rcx
cmpq %rcx, %rax
jb 0x179aa
movsd 0x8(%rbx), %xmm1
unpcklps 0xc89f(%rip), %xmm1     # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0xc8a7(%rip), %xmm1     # 0x24140
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
leaq 0x19c78(%rip), %rax     # 0x31520
movsd (%rax), %xmm0
leaq 0x19ca5(%rip), %rax     # 0x31558
addsd (%rax), %xmm0
addsd %xmm1, %xmm2
movapd %xmm2, (%rsp)
leaq 0x19bd1(%rip), %rax     # 0x31498
divsd (%rax), %xmm0
callq 0x4080
addsd (%rsp), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0xe94f(%rip), %xmm0     # 0x26238
cvttsd2si %xmm0, %rdx
andq %rcx, %rdx
orq %rax, %rdx
movl %r14d, %r12d
movq 0x2b8(%rbx), %rax
movq %rdx, (%rax,%r12,8)
movq (%r15,%r12,8), %rax
movl $0x7, 0x200(%rax)
leaq 0x19b71(%rip), %rax     # 0x31488
cmpb $0x1, (%rax)
jne 0x179aa
leaq 0x19b62(%rip), %rax     # 0x31489
cmpb $0x0, (%rax)
jne 0x179aa
movq 0x1969d(%rip), %rdi     # 0x30fd0
movq (%rdi), %rax
movq -0x18(%rax), %rax
movq $0x21, 0x10(%rdi,%rax)
pushq $0x20
popq %rsi
callq 0x4440
leaq 0x20(%rbx), %rsi
movq %rax, %rdi
callq 0x42b0
leaq 0xed51(%rip), %rsi      # 0x266af
movq %rax, %rdi
callq 0x4300
movq 0x2b8(%rbx), %rcx
movq (%rcx,%r12,8), %rsi
movq %rax, %rdi
callq 0x4210
leaq 0xed57(%rip), %rsi      # 0x266d7
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movl %r14d, %esi
callq 0x44f0
leaq 0xfb37(%rip), %rsi      # 0x274d1
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
leaq 0x20(%rbx), %r14
leaq 0x19af3(%rip), %rax     # 0x314a8
movl (%rax), %ebp
xorl %r15d, %r15d
leaq 0x19ac7(%rip), %r13     # 0x31488
movq 0x19608(%rip), %r12     # 0x30fd0
movslq %ebp, %rax
cmpq %rax, %r15
jge 0x17b19
movq 0x208(%rbx), %rcx
movq (%rcx,%r15,8), %rax
cmpl $0x7, 0x200(%rax)
jne 0x17b11
movq 0x8(%rbx), %rdx
movq 0x2b8(%rbx), %rsi
cmpq (%rsi,%r15,8), %rdx
jb 0x17b11
movl %ebp, %esi
xorl %edi, %edi
cmpq %rdi, %rsi
je 0x17a28
movq (%rcx,%rdi,8), %r8
cmpl $0x2, 0x200(%r8)
jne 0x17a23
movl $0x1, 0x200(%r8)
incq %rdi
jmp 0x17a05
movb $0x1, 0x268(%rax)
movl $0x3, 0x200(%rax)
movq %rdx, %xmm0
punpckldq 0xc6ea(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0xc6f2(%rip), %xmm0     # 0x24140
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd %xmm1, (%rsp)
leaq 0x19ae2(%rip), %rax     # 0x31548
movsd (%rax), %xmm0
leaq 0x19a27(%rip), %rax     # 0x31498
divsd (%rax), %xmm0
callq 0x4080
addsd (%rsp), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0xe7a5(%rip), %xmm0     # 0x26238
cvttsd2si %xmm0, %rdx
andq %rcx, %rdx
orq %rax, %rdx
movq 0x288(%rbx), %rax
movq %rdx, (%rax,%r15,8)
cmpb $0x0, (%r13)
je 0x17b11
movq (%r12), %rax
movq -0x18(%rax), %rax
movq $0x21, 0x10(%r12,%rax)
movq %r12, %rdi
pushq $0x20
popq %rsi
callq 0x4440
movq %rax, %rdi
movq %r14, %rsi
callq 0x42b0
movq %rax, %rdi
leaq 0xec03(%rip), %rsi      # 0x266e4
callq 0x4300
movq %rax, %rdi
movl %r15d, %esi
callq 0x44f0
movq %rax, %rdi
leaq 0xf9d6(%rip), %rsi      # 0x274d1
callq 0x4300
movq %rax, %rdi
callq 0x4180
leaq 0x19999(%rip), %rax     # 0x314a8
movl (%rax), %ebp
incq %r15
jmp 0x179c8
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x194c1(%rip), %rdi     # 0x30ff0
leaq 0xc4ec(%rip), %rsi      # 0x24022
callq 0x4300
leaq 0xe8d5(%rip), %rsi      # 0x26417
movq %rax, %rdi
callq 0x4300
leaq 0xcd26(%rip), %rsi      # 0x24877
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
movl $0x2d0, %esi            # imm = 0x2D0
callq 0x44f0
leaq 0xc4d4(%rip), %rsi      # 0x24041
movq %rax, %rdi
callq 0x4300
addq $0x20, %rbx
movq %rax, %rdi
movq %rbx, %rsi
callq 0x42b0
leaq 0xea79(%rip), %rsi      # 0x26604
movq %rax, %rdi
callq 0x4300
movl (%r14), %esi
movq %rax, %rdi
callq 0x44f0
leaq 0xf92c(%rip), %rsi      # 0x274d1
movq %rax, %rdi
callq 0x4300
movq %rax, %rdi
callq 0x4180
xorl %edi, %edi
callq 0x4370