// File: estwings57[P]CasHMC/sources/LinkMaster.cpp
// Function: CasHMC::LinkMaster::Update()
void LinkMaster::Update()
{
	if(Buffers.size() > 0) {
		//Make sure that buffer[0] is not virtual tail packet.
		if(Buffers[0] == NULL) {
			ERROR(header<<"  == Error - Buffers[0] is NULL (It could be one of virtual tail packet  (CurrentClock : "<<currentClockCycle<<")");
			exit(0);
		}
		else if(Buffers[0]->bufPopDelay == 0) {
			//Token count register represents the available space in link slave input buffer
			if(linkRxTx.size() == 0 && !(Buffers[0]->packetType != FLOW && tokenCount < Buffers[0]->LNG)) {
				int tempWriteP = retBufWriteP + Buffers[0]->LNG;
				if(retBufWriteP	>= retBufReadP) {
					if(tempWriteP - (int)retBufReadP < MAX_RETRY_BUF) {
						CRCCountdown(tempWriteP, Buffers[0]);
					}
					else {
						//DEBUG(ALI(18)<<header<<ALI(15)<<*Buffers[0]<<(downstream ? "Down) " : "Up)   ")<<"Retry buffer is near-full condition");
					}
				}
				else {
					if((int)retBufReadP - tempWriteP > 0) {
						CRCCountdown(tempWriteP, Buffers[0]);
					}
					else {
						//DEBUG(ALI(18)<<header<<ALI(15)<<*Buffers[0]<<(downstream ? "Down) " : "Up)   ")<<"Retry buffer is near-full condition");
					}
				}
			}
			else {
				//DEBUG(ALI(18)<<header<<ALI(15)<<*Buffers[0]<<(downstream ? "Down) " : "Up)   ")<<"packet length ("<<Buffers[0]->LNG<<") is BIGGER than token count register ("<<tokenCount<<")");
			}
		}
	}

	//Finish LinkRetry state, and then backup packets return to buffers 
	if(currentState == LINK_RETRY && Buffers.empty() && linkRxTx.empty()) {
		//If StartRetry state is waiting, start StartRetry state
		if(readyStartRetry == true) {
			readyStartRetry = false;
			for(int i=0; i<NUM_OF_IRTRY; i++) {
				//packet, cmd, addr, cub, lng, *lat
				Packet *packetIRTRY = new Packet(FLOW, IRTRY, 0, 0, 1, NULL);
				packetIRTRY->TAG = retryStartPacket->TAG;
				packetIRTRY->RRP = lastestRRP;
				packetIRTRY->FRP = 1;		//StartRetry flag is set with FRP[0] = 1
				if(downstream)	packetIRTRY->bufPopDelay = 0;
				linkRxTx.push_back(packetIRTRY);
				currentState = START_RETRY;
				header.erase(header.find(")"));
				header += ") ST_RT";
			}
		}
		else {
			currentState = ACTIVE;
			header.erase(header.find(")"));
			header += ")";
		}
		//Restore backup packets to Buffers
		for(int i=0; i<backupBuffers.size(); i++) {
			Buffers.push_back(backupBuffers[i]);
		}
		backupBuffers.clear();
	}
	
	if(startRetryTimer)		retryTimer++;
	//Retry timer should be set to at least 3 times the retry buffer full period
	if(retryTimer > MAX_RETRY_BUF*4) {
		DEBUG(ALI(33)<<header<<(downstream ? "Down) " : "Up)   ")<<"Retry timer TIME-OUT  (retry attempt : "<<retryAttempts<<")");
		if(retryAttempts == RETRY_ATTEMPT_LIMIT) {
			FinishRetry();
		}
		else {
			retryAttempts++;
			StartRetry(retryStartPacket);
		}
	}
	
	//Requester/Responder issue continuous scrambled NULL packet and TS1 training sequence for link retraining
	if(currentState == RETRAIN1 && currentClockCycle >= retrainTransit && firstNull) {
		//Upon descrambler sync, the responder will begin to transmit scrambled NULL packet
		Packet *packetNULL = new Packet(FLOW, NULL_, 0, 0, 1, NULL);
		linkRxTx.push_back(packetNULL);
		DEBUG(ALI(33)<<header<<(downstream ? "Down) " : "Up)   ")<<"issue NULL packet for descrambler initializing");
		firstNull = false;
	}
	//Requester/Responder enters the TS1 state 
	// and issues the scrambled TS1 training sequence continuously to achieve FLIT synchrony
	else if(currentState == RETRAIN2 && currentClockCycle >= retrainTransit && firstNull) {
		//Because TS1 is 16-bit character, we just employ NULL packet instead of TS1
		Packet *packetTS1 = new Packet(FLOW, NULL_, 0, 0, 1, NULL);
		linkRxTx.push_back(packetTS1);
		DEBUG(ALI(33)<<header<<(downstream ? "Down) " : "Up)   ")<<"issue TS1 sequence to achieve FLIT synchrony");
		firstNull = false;
	}
	
	Step();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x58(%rbp)
addq $0x1d0, %rdi            # imm = 0x1D0
callq 0x22d60
cmpq $0x0, %rax
jbe 0x3e5d9
movq -0x58(%rbp), %rdi
addq $0x1d0, %rdi            # imm = 0x1D0
xorl %eax, %eax
movl %eax, %esi
callq 0x29940
cmpq $0x0, (%rax)
jne 0x3e47c
movq 0x27c0e(%rip), %rdi     # 0x65ff0
leaq 0x12c51(%rip), %rsi     # 0x5103a
callq 0x4380
movq %rax, %rdi
leaq 0x153b2(%rip), %rsi     # 0x537aa
callq 0x4380
movq %rax, %rdi
leaq 0x1342e(%rip), %rsi     # 0x51835
callq 0x4380
movq %rax, %rdi
movl $0x128, %esi            # imm = 0x128
callq 0x4610
movq %rax, %rdi
leaq 0x12c36(%rip), %rsi     # 0x51059
callq 0x4380
movq -0x58(%rbp), %rsi
movq %rax, %rdi
addq $0x20, %rsi
callq 0x4320
movq %rax, %rdi
leaq 0x15581(%rip), %rsi     # 0x539c3
callq 0x4380
movq %rax, %rdi
movq -0x58(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x40f0
movq %rax, %rdi
leaq 0x15f18(%rip), %rsi     # 0x54379
callq 0x4380
movq %rax, %rdi
movq 0x27b40(%rip), %rsi     # 0x65fb0
callq 0x43c0
xorl %edi, %edi
callq 0x4460
movq -0x58(%rbp), %rdi
addq $0x1d0, %rdi            # imm = 0x1D0
xorl %eax, %eax
movl %eax, %esi
callq 0x29940
movq (%rax), %rax
cmpl $0x0, 0x14(%rax)
jne 0x3e5d5
movq -0x58(%rbp), %rdi
addq $0x1e8, %rdi            # imm = 0x1E8
callq 0x22d60
cmpq $0x0, %rax
jne 0x3e5d1
movq -0x58(%rbp), %rdi
addq $0x1d0, %rdi            # imm = 0x1D0
xorl %eax, %eax
movl %eax, %esi
callq 0x29940
movq (%rax), %rax
cmpl $0x2, 0x10(%rax)
je 0x3e506
movq -0x58(%rbp), %rdi
movl 0x208(%rdi), %eax
movl %eax, -0x5c(%rbp)
addq $0x1d0, %rdi            # imm = 0x1D0
xorl %eax, %eax
movl %eax, %esi
callq 0x29940
movq %rax, %rcx
movl -0x5c(%rbp), %eax
movq (%rcx), %rcx
cmpl 0x430(%rcx), %eax
jb 0x3e5d1
movq -0x58(%rbp), %rdi
movl 0x260(%rdi), %eax
movl %eax, -0x60(%rbp)
addq $0x1d0, %rdi            # imm = 0x1D0
xorl %eax, %eax
movl %eax, %esi
callq 0x29940
movq -0x58(%rbp), %rcx
movq %rax, %rdx
movl -0x60(%rbp), %eax
movq (%rdx), %rdx
addl 0x430(%rdx), %eax
movl %eax, -0xc(%rbp)
movl 0x260(%rcx), %eax
cmpl 0x25c(%rcx), %eax
jb 0x3e58e
movq -0x58(%rbp), %rcx
movl -0xc(%rbp), %eax
subl 0x25c(%rcx), %eax
leaq 0x28001(%rip), %rcx     # 0x6655c
cmpl (%rcx), %eax
jge 0x3e58a
movq -0x58(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, -0x64(%rbp)
addq $0x1d0, %rdi            # imm = 0x1D0
xorl %eax, %eax
movl %eax, %esi
callq 0x29940
movq -0x58(%rbp), %rdi
movl -0x64(%rbp), %esi
movq (%rax), %rdx
callq 0x3ed30
jmp 0x3e58c
jmp 0x3e58c
jmp 0x3e5cf
movq -0x58(%rbp), %rax
movl 0x25c(%rax), %eax
subl -0xc(%rbp), %eax
cmpl $0x0, %eax
jle 0x3e5cb
movq -0x58(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, -0x68(%rbp)
addq $0x1d0, %rdi            # imm = 0x1D0
xorl %eax, %eax
movl %eax, %esi
callq 0x29940
movq -0x58(%rbp), %rdi
movl -0x68(%rbp), %esi
movq (%rax), %rdx
callq 0x3ed30
jmp 0x3e5cd
jmp 0x3e5cd
jmp 0x3e5cf
jmp 0x3e5d3
jmp 0x3e5d3
jmp 0x3e5d5
jmp 0x3e5d7
jmp 0x3e5d9
movq -0x58(%rbp), %rax
cmpl $0xb, 0x200(%rax)
jne 0x3e854
movq -0x58(%rbp), %rdi
addq $0x1d0, %rdi            # imm = 0x1D0
callq 0x405b0
testb $0x1, %al
jne 0x3e603
jmp 0x3e854
movq -0x58(%rbp), %rdi
addq $0x1e8, %rdi            # imm = 0x1E8
callq 0x405b0
testb $0x1, %al
jne 0x3e61c
jmp 0x3e854
movq -0x58(%rbp), %rax
movb 0x250(%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x3e781
movq -0x58(%rbp), %rax
movb $0x0, 0x250(%rax)
movl $0x0, -0x10(%rbp)
movl -0x10(%rbp), %eax
leaq 0x27f28(%rip), %rcx     # 0x66578
cmpl (%rcx), %eax
jge 0x3e77f
movl $0x468, %edi            # imm = 0x468
callq 0x4390
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x70(%rbp)
movq %rsp, %rax
movq $0x0, (%rax)
xorl %r8d, %r8d
movl %r8d, %ecx
movl $0x2, %esi
movl $0x3, %edx
movl $0x1, %r9d
callq 0x43a90
jmp 0x3e693
movq -0x58(%rbp), %rax
movq -0x70(%rbp), %rcx
movq %rcx, -0x18(%rbp)
movq 0x248(%rax), %rcx
movl 0x42c(%rcx), %edx
movq -0x18(%rbp), %rcx
movl %edx, 0x42c(%rcx)
movl 0x20c(%rax), %edx
movq -0x18(%rbp), %rcx
movl %edx, 0x44c(%rcx)
movq -0x18(%rbp), %rcx
movl $0x1, 0x448(%rcx)
testb $0x1, 0x1cc(%rax)
je 0x3e709
movq -0x18(%rbp), %rax
movl $0x0, 0x14(%rax)
jmp 0x3e709
movq -0x70(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x468, %esi            # imm = 0x468
callq 0x43a0
jmp 0x3ed18
movq -0x58(%rbp), %rdi
addq $0x1e8, %rdi            # imm = 0x1E8
leaq -0x18(%rbp), %rsi
callq 0x29ef0
movq -0x58(%rbp), %rdi
movl $0xa, 0x200(%rdi)
movq %rdi, %rax
addq $0x20, %rax
movq %rax, -0x78(%rbp)
addq $0x20, %rdi
leaq 0x15c38(%rip), %rsi     # 0x54379
xorl %eax, %eax
movl %eax, %edx
callq 0x46d0
movq -0x78(%rbp), %rdi
movq %rax, %rsi
movq $-0x1, %rdx
callq 0x40e0
movq -0x58(%rbp), %rdi
addq $0x20, %rdi
leaq 0x150ed(%rip), %rsi     # 0x53859
callq 0x4350
movl -0x10(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x10(%rbp)
jmp 0x3e646
jmp 0x3e7d5
movq -0x58(%rbp), %rdi
movl $0x0, 0x200(%rdi)
movq %rdi, %rax
addq $0x20, %rax
movq %rax, -0x80(%rbp)
addq $0x20, %rdi
leaq 0x15bd4(%rip), %rsi     # 0x54379
xorl %eax, %eax
movl %eax, %edx
callq 0x46d0
movq -0x80(%rbp), %rdi
movq %rax, %rsi
movq $-0x1, %rdx
callq 0x40e0
movq -0x58(%rbp), %rdi
addq $0x20, %rdi
leaq 0x15ba9(%rip), %rsi     # 0x54379
callq 0x4350
movl $0x0, -0x28(%rbp)
movq -0x58(%rbp), %rdi
movslq -0x28(%rbp), %rax
movq %rax, -0x88(%rbp)
addq $0x220, %rdi            # imm = 0x220
callq 0x22d60
movq %rax, %rcx
movq -0x88(%rbp), %rax
cmpq %rcx, %rax
jae 0x3e844
movq -0x58(%rbp), %rdi
movq %rdi, %rax
addq $0x1d0, %rax            # imm = 0x1D0
movq %rax, -0x90(%rbp)
addq $0x220, %rdi            # imm = 0x220
movslq -0x28(%rbp), %rsi
callq 0x29940
movq -0x90(%rbp), %rdi
movq %rax, %rsi
callq 0x29ef0
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x3e7dc
movq -0x58(%rbp), %rdi
addq $0x220, %rdi            # imm = 0x220
callq 0x29920
movq -0x58(%rbp), %rax
testb $0x1, 0x251(%rax)
je 0x3e874
movq -0x58(%rbp), %rax
movl 0x254(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x254(%rax)
movq -0x58(%rbp), %rax
movl 0x254(%rax), %eax
leaq 0x27cd7(%rip), %rcx     # 0x6655c
movl (%rcx), %ecx
shll $0x2, %ecx
cmpl %ecx, %eax
jbe 0x3e9cc
leaq 0x27c8f(%rip), %rax     # 0x66528
testb $0x1, (%rax)
je 0x3e98b
leaq 0x27c80(%rip), %rax     # 0x66529
testb $0x1, (%rax)
jne 0x3e98b
movl $0x21, %edi
callq 0x177b0
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %esi
movq 0x27707(%rip), %rdi     # 0x65fd0
callq 0x4440
movq %rax, -0xa0(%rbp)
movl $0x20, %edi
callq 0x177d0
movq -0xa0(%rbp), %rdi
movb %al, -0x2d(%rbp)
movzbl -0x2d(%rbp), %esi
callq 0x4550
movq -0x58(%rbp), %rsi
movq %rax, %rdi
addq $0x20, %rsi
callq 0x4320
movq %rax, %rcx
movq -0x58(%rbp), %rax
movq %rcx, -0x98(%rbp)
testb $0x1, 0x1cc(%rax)
je 0x3e929
leaq 0x14d28(%rip), %rax     # 0x53648
movq %rax, -0xa8(%rbp)
jmp 0x3e939
leaq 0x14d1f(%rip), %rax     # 0x5364f
movq %rax, -0xa8(%rbp)
jmp 0x3e939
movq -0x98(%rbp), %rdi
movq -0xa8(%rbp), %rsi
callq 0x4380
movq %rax, %rdi
leaq 0x150c7(%rip), %rsi     # 0x53a1d
callq 0x4380
movq %rax, %rdi
movq -0x58(%rbp), %rax
movl 0x258(%rax), %esi
callq 0x44c0
movq %rax, %rdi
leaq 0x15a02(%rip), %rsi     # 0x54379
callq 0x4380
movq %rax, %rdi
movq 0x2762a(%rip), %rsi     # 0x65fb0
callq 0x43c0
movq -0x58(%rbp), %rax
movl 0x258(%rax), %eax
leaq 0x27be0(%rip), %rcx     # 0x6657c
cmpl (%rcx), %eax
jne 0x3e9ab
movq -0x58(%rbp), %rdi
callq 0x3e170
jmp 0x3e9ca
movq -0x58(%rbp), %rdi
movl 0x258(%rdi), %eax
addl $0x1, %eax
movl %eax, 0x258(%rdi)
movq 0x248(%rdi), %rsi
callq 0x3d6e0
jmp 0x3e9cc
movq -0x58(%rbp), %rax
cmpl $0x3, 0x200(%rax)
jne 0x3eb6c
movq -0x58(%rbp), %rcx
movq 0x8(%rcx), %rax
movl 0x264(%rcx), %ecx
cmpq %rcx, %rax
jb 0x3eb6c
movq -0x58(%rbp), %rax
testb $0x1, 0x268(%rax)
je 0x3eb6c
movl $0x468, %edi            # imm = 0x468
callq 0x4390
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xb0(%rbp)
movq %rsp, %rax
movq $0x0, (%rax)
xorl %r8d, %r8d
movl %r8d, %ecx
movl $0x2, %esi
movl $0x1, %r9d
movl %r8d, %edx
callq 0x43a90
jmp 0x3ea41
movq -0x58(%rbp), %rdi
movq -0xb0(%rbp), %rax
movq %rax, -0x38(%rbp)
addq $0x1e8, %rdi            # imm = 0x1E8
leaq -0x38(%rbp), %rsi
callq 0x29ef0
leaq 0x27ac1(%rip), %rax     # 0x66528
testb $0x1, (%rax)
je 0x3eb5c
leaq 0x27ab2(%rip), %rax     # 0x66529
testb $0x1, (%rax)
jne 0x3eb5c
movl $0x21, %edi
callq 0x177b0
movl %eax, -0x3c(%rbp)
movl -0x3c(%rbp), %esi
movq 0x27539(%rip), %rdi     # 0x65fd0
callq 0x4440
movq %rax, -0xc0(%rbp)
movl $0x20, %edi
callq 0x177d0
movq -0xc0(%rbp), %rdi
movb %al, -0x3d(%rbp)
movzbl -0x3d(%rbp), %esi
callq 0x4550
movq -0x58(%rbp), %rsi
movq %rax, %rdi
addq $0x20, %rsi
callq 0x4320
movq %rax, %rcx
movq -0x58(%rbp), %rax
movq %rcx, -0xb8(%rbp)
testb $0x1, 0x1cc(%rax)
je 0x3eaf7
leaq 0x14b5a(%rip), %rax     # 0x53648
movq %rax, -0xc8(%rbp)
jmp 0x3eb07
leaq 0x14b51(%rip), %rax     # 0x5364f
movq %rax, -0xc8(%rbp)
jmp 0x3eb07
movq -0xb8(%rbp), %rdi
movq -0xc8(%rbp), %rsi
callq 0x4380
movq %rax, %rdi
leaq 0x14f21(%rip), %rsi     # 0x53a45
callq 0x4380
movq %rax, %rdi
movq 0x2747d(%rip), %rsi     # 0x65fb0
callq 0x43c0
jmp 0x3eb5c
movq -0xb0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x468, %esi            # imm = 0x468
callq 0x43a0
jmp 0x3ed18
movq -0x58(%rbp), %rax
movb $0x0, 0x268(%rax)
jmp 0x3ed06
movq -0x58(%rbp), %rax
cmpl $0x4, 0x200(%rax)
jne 0x3ed04
movq -0x58(%rbp), %rcx
movq 0x8(%rcx), %rax
movl 0x264(%rcx), %ecx
cmpq %rcx, %rax
jb 0x3ed04
movq -0x58(%rbp), %rax
testb $0x1, 0x268(%rax)
je 0x3ed04
movl $0x468, %edi            # imm = 0x468
callq 0x4390
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xd0(%rbp)
movq %rsp, %rax
movq $0x0, (%rax)
xorl %r8d, %r8d
movl %r8d, %ecx
movl $0x2, %esi
movl $0x1, %r9d
movl %r8d, %edx
callq 0x43a90
jmp 0x3ebe1
movq -0x58(%rbp), %rdi
movq -0xd0(%rbp), %rax
movq %rax, -0x48(%rbp)
addq $0x1e8, %rdi            # imm = 0x1E8
leaq -0x48(%rbp), %rsi
callq 0x29ef0
leaq 0x27921(%rip), %rax     # 0x66528
testb $0x1, (%rax)
je 0x3ecf9
leaq 0x27912(%rip), %rax     # 0x66529
testb $0x1, (%rax)
jne 0x3ecf9
movl $0x21, %edi
callq 0x177b0
movl %eax, -0x4c(%rbp)
movl -0x4c(%rbp), %esi
movq 0x27399(%rip), %rdi     # 0x65fd0
callq 0x4440
movq %rax, -0xe0(%rbp)
movl $0x20, %edi
callq 0x177d0
movq -0xe0(%rbp), %rdi
movb %al, -0x4d(%rbp)
movzbl -0x4d(%rbp), %esi
callq 0x4550
movq -0x58(%rbp), %rsi
movq %rax, %rdi
addq $0x20, %rsi
callq 0x4320
movq %rax, %rcx
movq -0x58(%rbp), %rax
movq %rcx, -0xd8(%rbp)
testb $0x1, 0x1cc(%rax)
je 0x3ec97
leaq 0x149ba(%rip), %rax     # 0x53648
movq %rax, -0xe8(%rbp)
jmp 0x3eca7
leaq 0x149b1(%rip), %rax     # 0x5364f
movq %rax, -0xe8(%rbp)
jmp 0x3eca7
movq -0xd8(%rbp), %rdi
movq -0xe8(%rbp), %rsi
callq 0x4380
movq %rax, %rdi
leaq 0x14db0(%rip), %rsi     # 0x53a74
callq 0x4380
movq %rax, %rdi
movq 0x272dd(%rip), %rsi     # 0x65fb0
callq 0x43c0
jmp 0x3ecf9
movq -0xd0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x468, %esi            # imm = 0x468
callq 0x43a0
jmp 0x3ed18
movq -0x58(%rbp), %rax
movb $0x0, 0x268(%rax)
jmp 0x3ed06
movq -0x58(%rbp), %rdi
callq 0x405f0
addq $0xf0, %rsp
popq %rbp
retq
movq -0x20(%rbp), %rdi
callq 0x4630
nopw %cs:(%rax,%rax)