// File: /workspace/github_cpp_makefile_star2_O3/dramninjasUMD[P]BOBSim/Rank.cpp
// Function: BOBSim::Rank::ReceiveFromBus(BOBSim::BusPacket*)
void Rank::ReceiveFromBus(BusPacket *busPacket)
{
	if(DEBUG_CHANNEL) DEBUG("     == Rank "<<id<<" received : " << *busPacket);

	if(VERIFICATION_OUTPUT && busPacket->channel==0)
	{
		busPacket->PrintVerification(currentClockCycle);
	}

	switch(busPacket->busPacketType)
	{
	case REFRESH:
		for(unsigned i=0; i<NUM_BANKS; i++)
		{
			if(bankStates[i].currentBankState != IDLE ||
			        bankStates[i].nextActivate > currentClockCycle)
			{
				ERROR("== Error - Refresh when not allowed in bank "<<i);
				ERROR("           NextAct : "<<bankStates[i].nextActivate);
				ERROR("           State : "<<bankStates[i].currentBankState);
				exit(0);
			}

			bankStates[i].lastCommand = REFRESH;
			bankStates[i].currentBankState = REFRESHING;
			bankStates[i].stateChangeCountdown = tRFC;
			bankStates[i].nextActivate = currentClockCycle + tRFC;
		}
		delete busPacket;
		break;
	case READ_P:
		if(bankStates[busPacket->bank].currentBankState != ROW_ACTIVE ||
		        bankStates[busPacket->bank].openRowAddress != busPacket->row ||
		        currentClockCycle < bankStates[busPacket->bank].nextRead)
		{
			ERROR("== Error - Rank receiving READ_P when not allowed");
			ERROR("           Current Clock Cycle : "<<currentClockCycle);
			ERROR(bankStates[busPacket->bank]);
			exit(0);
		}

		//
		//update bankstates
		//
		busPacket->busPacketType = READ_DATA;
		readReturnQueue.push_back(busPacket);
		readReturnCountdown.push_back(tCL);

		for(unsigned i=0; i<NUM_BANKS; i++)
		{
			bankStates[i].nextRead = max(bankStates[i].nextRead, currentClockCycle + tCCD);
			bankStates[i].nextWrite = max(bankStates[i].nextWrite, currentClockCycle + tCCD);
		}

		bankStates[busPacket->bank].lastCommand = READ_P;
		bankStates[busPacket->bank].stateChangeCountdown = tRTP;
		bankStates[busPacket->bank].nextActivate = currentClockCycle + tRTP + tRP;
		bankStates[busPacket->bank].nextRead = bankStates[busPacket->bank].nextActivate;
		bankStates[busPacket->bank].nextWrite = bankStates[busPacket->bank].nextActivate;
		break;
	case WRITE_P:
		if(bankStates[busPacket->bank].currentBankState != ROW_ACTIVE ||
		        bankStates[busPacket->bank].openRowAddress != busPacket->row ||
		        currentClockCycle < bankStates[busPacket->bank].nextWrite)
		{
			ERROR("== Error - Rank "<<id<<" receiving WRITE_P when not allowed");
			ERROR(bankStates[busPacket->bank]);
			ERROR("           currentClockCycle : "<<currentClockCycle);
			exit(0);
		}

		//
		//update bank states
		//

		for(unsigned i=0; i<NUM_BANKS; i++)
		{
			bankStates[i].nextRead = max(bankStates[i].nextRead, currentClockCycle + tCCD);
			bankStates[i].nextWrite = max(bankStates[i].nextWrite, currentClockCycle + tCCD);
		}
		bankStates[busPacket->bank].lastCommand = WRITE_P;
		bankStates[busPacket->bank].stateChangeCountdown = tCWL + TRANSACTION_SIZE/DRAM_BUS_WIDTH + tWR;
		bankStates[busPacket->bank].nextActivate = currentClockCycle + tCWL + busPacket->burstLength + tWR + tRP;
		bankStates[busPacket->bank].nextRead = bankStates[busPacket->bank].nextActivate;
		bankStates[busPacket->bank].nextWrite = bankStates[busPacket->bank].nextActivate;

		delete busPacket;
		break;
	case ACTIVATE:
		if(bankStates[busPacket->bank].currentBankState != IDLE ||
		        currentClockCycle < bankStates[busPacket->bank].nextActivate)
		{
			ERROR("== Error - Rank receiving ACT when not allowed");
			exit(0);
		}

		//
		//update bank states
		//
		bankStates[busPacket->bank].currentBankState = ROW_ACTIVE;
		bankStates[busPacket->bank].openRowAddress = busPacket->row;
		bankStates[busPacket->bank].nextRead = currentClockCycle + tRCD;
		bankStates[busPacket->bank].nextWrite = currentClockCycle + tRCD;
		bankStates[busPacket->bank].nextActivate = currentClockCycle + tRC;

		for(unsigned i=0; i<NUM_BANKS; i++)
		{
			if(i!=busPacket->bank)
			{
				bankStates[i].nextActivate = max(bankStates[i].nextActivate, currentClockCycle + tRRD);
			}
		}

		delete busPacket;
		break;
	case WRITE_DATA:
		if(bankStates[busPacket->bank].currentBankState != ROW_ACTIVE ||
		        bankStates[busPacket->bank].openRowAddress != busPacket->row)
		{
			ERROR("== Error - Clock Cycle : "<<currentClockCycle);
			ERROR("== Error - Rank receiving WRITE_DATA when not allowed: " << *busPacket <<endl << bankStates[busPacket->bank]);
			exit(0);
		}

		bankStates[busPacket->bank].stateChangeCountdown = tWR;
		bankStates[busPacket->bank].nextActivate = currentClockCycle + tWR + tRP;

		delete busPacket;
		break;
	default:
		ERROR("== Error - Rank receiving incorrect type of bus packet");
		break;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, (%rsp)
movl 0x4(%rsi), %eax
decl %eax
cmpl $0x7, %eax
ja 0xfb06
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x4d8e(%rip), %rcx      # 0x14834
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x50(%rbx), %rax
movl 0x10(%r14), %ecx
shlq $0x6, %rcx
cmpl $0x1, (%rax,%rcx)
jne 0xff71
addq %rcx, %rax
movl 0x4(%rax), %ecx
cmpl 0xc(%r14), %ecx
jne 0xff71
movq 0x8(%rbx), %rcx
cmpq 0x10(%rax), %rcx
jb 0xff71
movl $0x7, 0x4(%r14)
movq 0x38(%rbx), %rsi
cmpq 0x40(%rbx), %rsi
je 0xfd71
movq %r14, (%rsi)
addq $0x8, 0x38(%rbx)
jmp 0xfd7d
movq 0x94e3(%rip), %rbx      # 0x18ff0
leaq 0x36b4(%rip), %rsi      # 0x131c8
movl $0x8, %edx
movq %rbx, %rdi
callq 0x3200
leaq 0x4d3b(%rip), %rsi      # 0x14863
movl $0x8, %edx
movq %rbx, %rdi
callq 0x3200
leaq 0x3635(%rip), %rsi      # 0x13171
movl $0x1, %edx
movq %rbx, %rdi
callq 0x3200
movq %rbx, %rdi
movl $0xce, %esi
callq 0x3330
movq %rax, %rbx
leaq 0x3679(%rip), %rsi      # 0x131d9
movl $0x4, %edx
movq %rax, %rdi
callq 0x3200
leaq 0x4e79(%rip), %rsi      # 0x149ed
movl $0x36, %edx
movq %rbx, %rdi
callq 0x3200
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x3030
movq %rax, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3130
movq 0x50(%rbx), %rax
movl 0x10(%r14), %ecx
shlq $0x6, %rcx
cmpl $0x0, (%rax,%rcx)
jne 0x101c3
leaq (%rax,%rcx), %rsi
movq 0x8(%rbx), %rdx
cmpq 0x8(%rsi), %rdx
jb 0x101c3
movl $0x1, (%rsi)
movl 0xc(%r14), %esi
movl %esi, 0x4(%rax,%rcx)
leaq 0x9(%rdx), %rsi
movq %rsi, 0x10(%rax,%rcx)
movq %rsi, 0x18(%rax,%rcx)
leaq 0x21(%rdx), %rsi
movq %rsi, 0x8(%rax,%rcx)
addq $0x4, %rdx
xorl %esi, %esi
cmpq %rsi, %rcx
je 0xfc1f
movq 0x8(%rax,%rsi), %rdi
cmpq %rdx, %rdi
cmovbeq %rdx, %rdi
movq %rdi, 0x8(%rax,%rsi)
addq $0x40, %rsi
cmpq $0x200, %rsi            # imm = 0x200
jne 0xfc09
jmp 0xfd56
movq 0x50(%rbx), %rax
movl 0x10(%r14), %ecx
shlq $0x6, %rcx
cmpl $0x1, (%rax,%rcx)
jne 0x10083
leaq (%rax,%rcx), %rdx
movl 0x4(%rdx), %esi
cmpl 0xc(%r14), %esi
jne 0x10083
movq 0x8(%rbx), %rsi
cmpq 0x18(%rdx), %rsi
jb 0x10083
leaq 0x4(%rsi), %rdi
xorl %r8d, %r8d
movq 0x10(%rax,%r8), %r9
movq 0x18(%rax,%r8), %r10
cmpq %rdi, %r9
cmovbeq %rdi, %r9
cmpq %rdi, %r10
cmovbeq %rdi, %r10
movq %r9, 0x10(%rax,%r8)
movq %r10, 0x18(%rax,%r8)
addq $0x40, %r8
cmpq $0x200, %r8             # imm = 0x200
jne 0xfc6d
movabsq $0x1500000003, %rdi     # imm = 0x1500000003
movq %rdi, 0x38(%rax,%rcx)
movl 0x24(%r14), %edi
addq %rdi, %rsi
addq $0x1a, %rsi
movq %rsi, 0x8(%rax,%rcx)
movq %rsi, 0x10(%rdx)
movq %rsi, 0x18(%rdx)
jmp 0xfd56
movq 0x8(%rbx), %rax
movq 0x50(%rbx), %rcx
leaq 0x6b(%rax), %rdx
xorl %r12d, %r12d
movabsq $0x6b00000005, %rsi     # imm = 0x6B00000005
xorl %r15d, %r15d
cmpl $0x0, (%rcx,%r12)
jne 0xfe22
cmpq %rax, 0x8(%rcx,%r12)
ja 0xfe22
movq %rsi, 0x38(%rcx,%r12)
movl $0x3, (%rcx,%r12)
movq %rdx, 0x8(%rcx,%r12)
incq %r15
addq $0x40, %r12
cmpq $0x8, %r15
jne 0xfce4
jmp 0xfd56
movq 0x50(%rbx), %rax
movl 0x10(%r14), %ecx
shlq $0x6, %rcx
cmpl $0x1, (%rax,%rcx)
jne 0x10224
leaq (%rax,%rcx), %rdx
movl 0x4(%rdx), %esi
cmpl 0xc(%r14), %esi
jne 0x10224
movl $0xa, 0x3c(%rdx)
movq 0x8(%rbx), %rdx
addq $0x13, %rdx
movq %rdx, 0x8(%rax,%rcx)
movl $0x38, %esi
movq %r14, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x31f0
leaq 0x30(%rbx), %rdi
movq %rsp, %rdx
callq 0x1031e
movq 0x20(%rbx), %rsi
cmpq 0x28(%rbx), %rsi
je 0xfd99
movl 0x94f3(%rip), %eax      # 0x19280
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x20(%rbx)
jmp 0xfda9
leaq 0x18(%rbx), %rdi
leaq 0x94dc(%rip), %rdx      # 0x19280
callq 0xc292
movq 0x8(%rbx), %rax
movq 0x50(%rbx), %rcx
leaq 0x4(%rax), %rdx
xorl %esi, %esi
movq 0x10(%rcx,%rsi), %rdi
movq 0x18(%rcx,%rsi), %r8
cmpq %rdx, %rdi
cmovbeq %rdx, %rdi
cmpq %rdx, %r8
cmovbeq %rdx, %r8
movq %rdi, 0x10(%rcx,%rsi)
movq %r8, 0x18(%rcx,%rsi)
addq $0x40, %rsi
cmpq $0x200, %rsi            # imm = 0x200
jne 0xfdb7
movq (%rsp), %rdx
movl 0x10(%rdx), %edx
shlq $0x6, %rdx
movabsq $0x500000001, %rsi      # imm = 0x500000001
movq %rsi, 0x38(%rcx,%rdx)
addq $0xe, %rax
movq %rax, 0x8(%rcx,%rdx)
movq %rax, 0x10(%rcx,%rdx)
movq %rax, 0x18(%rcx,%rdx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x91c7(%rip), %rdi      # 0x18ff0
leaq 0x3398(%rip), %rsi      # 0x131c8
callq 0x31c0
leaq 0x4a27(%rip), %r13      # 0x14863
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
leaq 0x3323(%rip), %rbp      # 0x13171
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x5d, %esi
callq 0x3330
leaq 0x336c(%rip), %r14      # 0x131d9
movq %rax, %rdi
movq %r14, %rsi
callq 0x31c0
leaq 0x49ed(%rip), %rsi      # 0x1486c
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
movl %r15d, %esi
callq 0x3260
movq %rax, %rdi
callq 0x30d0
movq 0x914f(%rip), %r15      # 0x18ff0
movq %r15, %rdi
leaq 0x331d(%rip), %rsi      # 0x131c8
callq 0x31c0
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x5e, %esi
callq 0x3330
movq %rax, %rdi
movq %r14, %rsi
callq 0x31c0
leaq 0x49b4(%rip), %rsi      # 0x14899
movq %rax, %rdi
callq 0x31c0
movq 0x50(%rbx), %rcx
movq 0x8(%rcx,%r12), %rsi
movq %rax, %rdi
callq 0x3060
movq %rax, %rdi
callq 0x30d0
movq %r15, %rdi
leaq 0x32b8(%rip), %rsi      # 0x131c8
callq 0x31c0
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x5f, %esi
callq 0x3330
movq %rax, %rdi
movq %r14, %rsi
callq 0x31c0
leaq 0x4965(%rip), %rsi      # 0x148af
movq %rax, %rdi
callq 0x31c0
movq 0x50(%rbx), %rcx
movl (%rcx,%r12), %esi
movq %rax, %rdi
callq 0x3330
movq %rax, %rdi
callq 0x30d0
xorl %edi, %edi
callq 0x3220
movq 0x9078(%rip), %r12      # 0x18ff0
leaq 0x3249(%rip), %rsi      # 0x131c8
movq %r12, %rdi
callq 0x31c0
leaq 0x48d5(%rip), %r13      # 0x14863
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
leaq 0x31d1(%rip), %rbp      # 0x13171
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x6f, %esi
callq 0x3330
leaq 0x321a(%rip), %r15      # 0x131d9
movq %rax, %rdi
movq %r15, %rsi
callq 0x31c0
leaq 0x48f2(%rip), %rsi      # 0x148c3
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
callq 0x30d0
movq %r12, %rdi
leaq 0x31dd(%rip), %rsi      # 0x131c8
callq 0x31c0
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x70, %esi
callq 0x3330
movq %rax, %rdi
movq %r15, %rsi
callq 0x31c0
leaq 0x48d0(%rip), %rsi      # 0x148f5
movq %rax, %rdi
callq 0x31c0
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x3060
movq %rax, %rdi
callq 0x30d0
movq %r12, %rdi
leaq 0x317d(%rip), %rsi      # 0x131c8
callq 0x31c0
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x71, %esi
callq 0x3330
movq %rax, %rdi
movq %r15, %rsi
callq 0x31c0
jmp 0x102ff
movq 0x8f66(%rip), %rdi      # 0x18ff0
leaq 0x3137(%rip), %r13      # 0x131c8
movq %r13, %rsi
callq 0x31c0
leaq 0x47c3(%rip), %rbp      # 0x14863
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
leaq 0x30bf(%rip), %r15      # 0x13171
movq %rax, %rdi
movq %r15, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x8d, %esi
callq 0x3330
leaq 0x3108(%rip), %r12      # 0x131d9
movq %rax, %rdi
movq %r12, %rsi
callq 0x31c0
leaq 0x4834(%rip), %rsi      # 0x14917
movq %rax, %rdi
callq 0x31c0
movl 0x10(%rbx), %esi
movq %rax, %rdi
callq 0x3260
leaq 0x482b(%rip), %rsi      # 0x14928
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
callq 0x30d0
movq 0x8edc(%rip), %rdi      # 0x18ff0
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
movq %rax, %rdi
movq %r15, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x8e, %esi
callq 0x3330
movq %rax, %rdi
movq %r12, %rsi
callq 0x31c0
movl 0x10(%r14), %esi
shlq $0x6, %rsi
addq 0x50(%rbx), %rsi
movq %rax, %rdi
callq 0xc44e
movq %rax, %rdi
callq 0x30d0
movq 0x8e83(%rip), %rdi      # 0x18ff0
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
movq %rax, %rdi
movq %r15, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x8f, %esi
callq 0x3330
movq %rax, %rdi
movq %r12, %rsi
callq 0x31c0
leaq 0x47a2(%rip), %rsi      # 0x1494c
movq %rax, %rdi
callq 0x31c0
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x3060
jmp 0xff62
movq 0x8e26(%rip), %rdi      # 0x18ff0
leaq 0x2ff7(%rip), %rsi      # 0x131c8
callq 0x31c0
leaq 0x4686(%rip), %rsi      # 0x14863
movq %rax, %rdi
callq 0x31c0
leaq 0x2f85(%rip), %rsi      # 0x13171
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
movl $0xa8, %esi
callq 0x3330
leaq 0x2fd1(%rip), %rsi      # 0x131d9
movq %rax, %rdi
callq 0x31c0
leaq 0x4755(%rip), %rsi      # 0x1496c
movq %rax, %rdi
callq 0x31c0
jmp 0xff62
movq 0x8dc5(%rip), %rdi      # 0x18ff0
leaq 0x2f96(%rip), %r12      # 0x131c8
movq %r12, %rsi
callq 0x31c0
leaq 0x4622(%rip), %r13      # 0x14863
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
leaq 0x2f1e(%rip), %rbp      # 0x13171
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0xc3, %esi
callq 0x3330
leaq 0x2f67(%rip), %r15      # 0x131d9
movq %rax, %rdi
movq %r15, %rsi
callq 0x31c0
leaq 0x4717(%rip), %rsi      # 0x1499b
movq %rax, %rdi
callq 0x31c0
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x3060
movq %rax, %rdi
callq 0x30d0
movq 0x8d49(%rip), %rdi      # 0x18ff0
movq %r12, %rsi
callq 0x31c0
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0xc4, %esi
callq 0x3330
movq %rax, %rdi
movq %r15, %rsi
callq 0x31c0
leaq 0x46d1(%rip), %rsi      # 0x149b5
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
movq %r14, %rsi
callq 0xc7bb
movq %rax, %rdi
callq 0x30d0
movl 0x10(%r14), %esi
shlq $0x6, %rsi
addq 0x50(%rbx), %rsi
movq %rax, %rdi
callq 0xc44e
jmp 0xff62