// File: /workspace/github_cpp_makefile_star2_O2/dramninjasUMD[P]BOBSim/BOBWrapper.cpp
// Function: BOBSim::BOBWrapper::Update()
void BOBWrapper::Update()
{
	maxReadsPerCycle = max<uint64_t>(maxReadsPerCycle, readsPerCycle);
	maxWritesPerCycle = max<uint64_t>(maxWritesPerCycle, writesPerCycle);
	readsPerCycle = writesPerCycle = 0;

	bob->Update();

	//BOOK-KEEPING
	for(unsigned i=0; i<NUM_PORTS; i++)
	{
		//STATS
		if(inFlightResponse[i]==NULL)
		{
			responsePortEmptyCount[i]++;
		}

		if(inFlightRequest[i]==NULL)
		{
			requestPortEmptyCount[i]++;
		}

		//
		//Requests
		//
		if(inFlightRequestHeaderCounter[i]>0)
		{
			inFlightRequestHeaderCounter[i]--;
			//done
			if(inFlightRequestHeaderCounter[i]==0)
			{
				if(inFlightRequest[i]!=NULL)
				{
					if(DEBUG_PORTS)DEBUG("== Header done - Adding "<<*inFlightRequest[i]<<" to port "<<i);
					bob->ports[i].inputBuffer.push_back(inFlightRequest[i]);
				}
				else
				{
					ERROR("== Error - inFlightResponse null when not supposed to be");
					exit(0);
				}
			}
		}

		if(inFlightRequestCounter[i]>0)
		{
			inFlightRequestCounter[i]--;
			if(inFlightRequestCounter[i]==0)
			{
				inFlightRequest[i]=NULL;
			}
		}

		//
		//Responses
		//
		if(inFlightResponseHeaderCounter[i]>0)
		{
			//does nothing
			inFlightResponseHeaderCounter[i]--;
		}

		if(inFlightResponseCounter[i]>0)
		{
			inFlightResponseCounter[i]--;
			if(inFlightResponseCounter[i]==0)
			{
				if(inFlightResponse[i]->transactionType==RETURN_DATA)
				{
					if (readDoneCallback)
					{
						(*readDoneCallback)(i, inFlightResponse[i]->address);
					}

					UpdateLatencyStats(inFlightResponse[i]);

					returnsPerPort[i]++;
				}
				else if(inFlightResponse[i]->transactionType==LOGIC_RESPONSE)
				{
					if(logicDoneCallback)
					{
						(*logicDoneCallback)(inFlightResponse[i]->mappedChannel, (void*)inFlightResponse[i]->address);
					}

					UpdateLatencyStats(inFlightResponse[i]);

					totalLogicResponses++;
				}
				else
				{
					ERROR("== ERROR - unknown packet type coming down : "<<*inFlightResponse[i]);
					exit(0);
				}

				bob->ports[i].outputBuffer.erase(bob->ports[i].outputBuffer.begin());
				delete inFlightResponse[i];
				inFlightResponse[i]=NULL;
			}
		}
	}

	//NEW STUFF
	for(unsigned i=0; i<NUM_PORTS; i++)
	{
		//look for new stuff to return from bob controller
		if(bob->ports[i].outputBuffer.size()>0 &&
		        inFlightResponseCounter[i]==0)
		{
			inFlightResponse[i] = bob->ports[i].outputBuffer[0];
			inFlightResponseHeaderCounter[i] = 1;

			if(inFlightResponse[i]->transactionType==RETURN_DATA)
			{
				inFlightResponseCounter[i] = TRANSACTION_SIZE / PORT_WIDTH;
			}
			else if(inFlightResponse[i]->transactionType==LOGIC_RESPONSE)
			{
				inFlightResponseCounter[i] = 1;
			}
			else
			{
				ERROR("== Error - wrong type of transaction out of");
				ERROR("== "<<*inFlightResponse[i]);
				exit(0);
			}
		}
	}

	if(currentClockCycle%EPOCH_LENGTH==0 && currentClockCycle>0)
	{
		PrintStats(false);
	}
	currentClockCycle++;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movdqu 0xa8(%rdi), %xmm0
movdqu 0xb8(%rdi), %xmm1
movdqa 0x7e2c(%rip), %xmm2     # 0xf890
movdqa %xmm1, %xmm3
pxor %xmm2, %xmm3
pxor %xmm0, %xmm2
movdqa %xmm2, %xmm4
pcmpgtd %xmm3, %xmm4
pshufd $0xa0, %xmm4, %xmm5     # xmm5 = xmm4[0,0,2,2]
pcmpeqd %xmm3, %xmm2
pshufd $0xf5, %xmm2, %xmm2     # xmm2 = xmm2[1,1,3,3]
pand %xmm5, %xmm2
pshufd $0xf5, %xmm4, %xmm3     # xmm3 = xmm4[1,1,3,3]
por %xmm2, %xmm3
pand %xmm3, %xmm0
pandn %xmm1, %xmm3
por %xmm0, %xmm3
movdqu %xmm3, 0xa8(%rdi)
pxor %xmm0, %xmm0
movdqu %xmm0, 0xb8(%rdi)
movq 0x10(%rdi), %rdi
movq (%rdi), %rax
callq *(%rax)
pushq $0x28
popq %r12
xorl %r13d, %r13d
leaq 0xe6e6(%rip), %r15      # 0x161b0
xorl %r14d, %r14d
movl (%r15), %esi
cmpq %rsi, %r14
jae 0x7c48
movq 0x60(%rbx), %rax
cmpq $0x0, (%rax,%r14,8)
jne 0x7aef
movq 0xe0(%rbx), %rax
incl (%rax,%r14,4)
movq 0x18(%rbx), %rsi
movq (%rsi,%r14,8), %rax
testq %rax, %rax
jne 0x7b07
movq 0xc8(%rbx), %rcx
incl (%rcx,%r14,4)
movq 0x48(%rbx), %rcx
movl (%rcx,%r14,4), %edx
testl %edx, %edx
je 0x7b3c
decl %edx
movl %edx, (%rcx,%r14,4)
jne 0x7b3c
testq %rax, %rax
je 0x7d02
addq %r13, %rsi
movq 0x10(%rbx), %rax
movq 0x10(%rax), %rax
leaq (%rax,%r12), %rdi
addq $-0x18, %rdi
callq 0x53ac
movq 0x30(%rbx), %rax
movl (%rax,%r14,4), %ecx
testl %ecx, %ecx
je 0x7b59
decl %ecx
movl %ecx, (%rax,%r14,4)
jne 0x7b59
movq 0x18(%rbx), %rax
andq $0x0, (%rax,%r14,8)
movq 0x90(%rbx), %rax
movl (%rax,%r14,4), %ecx
testl %ecx, %ecx
je 0x7b6e
decl %ecx
movl %ecx, (%rax,%r14,4)
movq 0x78(%rbx), %rax
movl (%rax,%r14,4), %ecx
testl %ecx, %ecx
je 0x7c38
decl %ecx
movl %ecx, (%rax,%r14,4)
jne 0x7c38
movq 0x60(%rbx), %rax
movq (%rax,%r14,8), %rsi
movl (%rsi), %eax
cmpl $0x4, %eax
je 0x7bd8
cmpl $0x2, %eax
jne 0x7d63
movq 0x158(%rbx), %rdi
testq %rdi, %rdi
je 0x7bc3
movq 0x8(%rsi), %rdx
movq (%rdi), %rax
movl %r14d, %esi
callq *0x10(%rax)
movq 0x60(%rbx), %rax
movq (%rax,%r14,8), %rsi
movq %rbx, %rdi
callq 0x7e98
movq 0x140(%rbx), %rax
incl (%rax,%r14,4)
jmp 0x7c09
movq 0x168(%rbx), %rdi
testq %rdi, %rdi
je 0x7bfb
movl 0x10(%rsi), %eax
movq 0x8(%rsi), %rdx
movq (%rdi), %rcx
movl %eax, %esi
callq *0x10(%rcx)
movq 0x60(%rbx), %rax
movq (%rax,%r14,8), %rsi
movq %rbx, %rdi
callq 0x7e98
incl 0x2a8(%rbx)
movq 0x10(%rbx), %rax
movq 0x10(%rax), %rdi
movq (%rdi,%r12), %rsi
addq %r12, %rdi
callq 0x53ca
movq 0x60(%rbx), %rax
movq (%rax,%r14,8), %rdi
movl $0x90, %esi
callq 0x21b0
movq 0x60(%rbx), %rax
andq $0x0, (%rax,%r14,8)
incq %r14
addq $0x8, %r13
addq $0x40, %r12
jmp 0x7acd
pushq $0xc
popq %rax
xorl %r14d, %r14d
pushq $0x4
popq %rcx
pushq $0x1
popq %rdx
movl %esi, %esi
cmpq %rsi, %r14
jae 0x7cc3
movq 0x10(%rbx), %rsi
movq 0x10(%rsi), %rdi
movq -0x8(%rdi,%rax,4), %rsi
cmpq %rsi, (%rdi,%rax,4)
je 0x7cb7
movq 0x78(%rbx), %rdi
cmpl $0x0, (%rdi,%r14,4)
jne 0x7cb7
movq (%rsi), %rsi
movq 0x60(%rbx), %rdi
movq %rsi, (%rdi,%r14,8)
movq 0x90(%rbx), %rsi
movl $0x1, (%rsi,%r14,4)
movq 0x60(%rbx), %rsi
movq (%rsi,%r14,8), %rsi
movl (%rsi), %edi
movl %ecx, %esi
cmpl $0x2, %edi
je 0x7caf
cmpl $0x4, %edi
jne 0x7dbc
movl %edx, %esi
movq 0x78(%rbx), %rdi
movl %esi, (%rdi,%r14,4)
incq %r14
movl (%r15), %esi
addq $0x10, %rax
jmp 0x7c54
movq 0x8(%rbx), %rcx
movl $0xf4240, %esi          # imm = 0xF4240
movq %rcx, %rax
xorl %edx, %edx
divq %rsi
testq %rcx, %rcx
je 0x7cec
testq %rdx, %rdx
jne 0x7cec
movq %rbx, %rdi
xorl %esi, %esi
callq 0x810a
movq 0x8(%rbx), %rcx
incq %rcx
movq %rcx, 0x8(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0xe2e7(%rip), %rdi      # 0x15ff0
leaq 0x7470(%rip), %rsi      # 0xf180
callq 0x2180
leaq 0x7e91(%rip), %rsi      # 0xfbad
movq %rax, %rdi
callq 0x2180
leaq 0x73fe(%rip), %rsi      # 0xf129
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
movl $0x185, %esi            # imm = 0x185
callq 0x22e0
leaq 0x744a(%rip), %rsi      # 0xf191
movq %rax, %rdi
callq 0x2180
leaq 0x7eb9(%rip), %rsi      # 0xfc0f
movq %rax, %rdi
callq 0x2180
jmp 0x7e88
movq 0xe286(%rip), %rdi      # 0x15ff0
leaq 0x740f(%rip), %rsi      # 0xf180
callq 0x2180
leaq 0x7e30(%rip), %rsi      # 0xfbad
movq %rax, %rdi
callq 0x2180
leaq 0x739d(%rip), %rsi      # 0xf129
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
movl $0x1ba, %esi            # imm = 0x1BA
callq 0x22e0
leaq 0x73e9(%rip), %rsi      # 0xf191
movq %rax, %rdi
callq 0x2180
leaq 0x7e91(%rip), %rsi      # 0xfc48
jmp 0x7e70
movq 0xe22d(%rip), %rdi      # 0x15ff0
leaq 0x73b6(%rip), %r15      # 0xf180
movq %r15, %rsi
callq 0x2180
leaq 0x7dd4(%rip), %r12      # 0xfbad
movq %rax, %rdi
movq %r12, %rsi
callq 0x2180
leaq 0x733e(%rip), %r13      # 0xf129
movq %rax, %rdi
movq %r13, %rsi
callq 0x2180
movq %rax, %rdi
movl $0x1d9, %esi            # imm = 0x1D9
callq 0x22e0
leaq 0x7387(%rip), %rbp      # 0xf191
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
leaq 0x7e5a(%rip), %rsi      # 0xfc76
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
movq 0xe1bd(%rip), %rdi      # 0x15ff0
movq %r15, %rsi
callq 0x2180
movq %rax, %rdi
movq %r12, %rsi
callq 0x2180
movq %rax, %rdi
movq %r13, %rsi
callq 0x2180
movq %rax, %rdi
movl $0x1da, %esi            # imm = 0x1DA
callq 0x22e0
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
leaq 0x7690(%rip), %rsi      # 0xf500
movq %rax, %rdi
callq 0x2180
movq 0x60(%rbx), %rcx
movq (%rcx,%r14,8), %rsi
movq %rax, %rdi
callq 0xe728
movq %rax, %rdi
callq 0x20b0
xorl %edi, %edi
callq 0x21d0
nop