// File: /workspace/github_cpp_makefile_star2_O1/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), %ecx
decl %ecx
cmpl $0x7, %ecx
ja 0xfc71
movq %rsi, %rax
movq %rdi, %rbx
leaq 0x4b80(%rip), %rdx      # 0x14794
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movq 0x50(%rbx), %rcx
movl 0x10(%rax), %edx
shlq $0x6, %rdx
cmpl $0x1, (%rcx,%rdx)
jne 0x100eb
addq %rdx, %rcx
movl 0x4(%rcx), %edx
cmpl 0xc(%rax), %edx
jne 0x100eb
movq 0x8(%rbx), %rdx
cmpq 0x10(%rcx), %rdx
jb 0x100eb
movl $0x7, 0x4(%rax)
movq 0x38(%rbx), %rsi
cmpq 0x40(%rbx), %rsi
je 0xfee3
movq %rax, (%rsi)
addq $0x8, 0x38(%rbx)
jmp 0xfeef
movq 0x9378(%rip), %rbx      # 0x18ff0
leaq 0x34f9(%rip), %rsi      # 0x13178
movl $0x8, %edx
movq %rbx, %rdi
callq 0x3200
leaq 0x4b30(%rip), %rsi      # 0x147c3
movl $0x8, %edx
movq %rbx, %rdi
callq 0x3200
leaq 0x347a(%rip), %rsi      # 0x13121
movl $0x1, %edx
movq %rbx, %rdi
callq 0x3200
movq %rbx, %rdi
movl $0xce, %esi
callq 0x3330
movq %rax, %rbx
leaq 0x34be(%rip), %rsi      # 0x13189
movl $0x4, %edx
movq %rax, %rdi
callq 0x3200
leaq 0x4c6e(%rip), %rsi      # 0x1494d
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), %rcx
movl 0x10(%rax), %edx
shlq $0x6, %rdx
cmpl $0x0, (%rcx,%rdx)
jne 0x10336
leaq (%rcx,%rdx), %rdi
movq 0x8(%rbx), %rsi
cmpq 0x8(%rdi), %rsi
jb 0x10336
movl $0x1, (%rdi)
movl 0xc(%rax), %edi
movl %edi, 0x4(%rcx,%rdx)
leaq 0x9(%rsi), %rdi
movq %rdi, 0x10(%rcx,%rdx)
movq %rdi, 0x18(%rcx,%rdx)
leaq 0x21(%rsi), %rdi
movq %rdi, 0x8(%rcx,%rdx)
addq $0x4, %rsi
xorl %edi, %edi
cmpq %rdi, %rdx
je 0xfd88
movq 0x8(%rcx,%rdi), %r8
cmpq %rsi, %r8
cmovbeq %rsi, %r8
movq %r8, 0x8(%rcx,%rdi)
addq $0x40, %rdi
cmpq $0x200, %rdi            # imm = 0x200
jne 0xfd72
jmp 0xfebf
movq 0x50(%rbx), %rcx
movl 0x10(%rax), %edx
shlq $0x6, %rdx
cmpl $0x1, (%rcx,%rdx)
jne 0x101f8
leaq (%rcx,%rdx), %rsi
movl 0x4(%rsi), %edi
cmpl 0xc(%rax), %edi
jne 0x101f8
movq 0x8(%rbx), %rdi
cmpq 0x18(%rsi), %rdi
jb 0x101f8
leaq 0x4(%rdi), %r8
xorl %r9d, %r9d
movq 0x10(%rcx,%r9), %r10
movq 0x18(%rcx,%r9), %r11
cmpq %r8, %r10
cmovbeq %r8, %r10
cmpq %r8, %r11
cmovbeq %r8, %r11
movq %r10, 0x10(%rcx,%r9)
movq %r11, 0x18(%rcx,%r9)
addq $0x40, %r9
cmpq $0x200, %r9             # imm = 0x200
jne 0xfdd4
movabsq $0x1500000003, %r8      # imm = 0x1500000003
movq %r8, 0x38(%rcx,%rdx)
movl 0x24(%rax), %r8d
addq %r8, %rdi
addq $0x1a, %rdi
movq %rdi, 0x8(%rcx,%rdx)
movq 0x8(%rsi), %rcx
movq %rcx, 0x10(%rsi)
movq %rcx, 0x18(%rsi)
jmp 0xfebf
movq 0x8(%rbx), %rcx
movq 0x50(%rbx), %rdx
leaq 0x6b(%rcx), %rsi
xorl %r15d, %r15d
movabsq $0x6b00000005, %rdi     # imm = 0x6B00000005
xorl %r14d, %r14d
cmpl $0x0, (%rdx,%r15)
jne 0xff9c
cmpq %rcx, 0x8(%rdx,%r15)
ja 0xff9c
movq %rdi, 0x38(%rdx,%r15)
movl $0x3, (%rdx,%r15)
movq %rsi, 0x8(%rdx,%r15)
incq %r14
addq $0x40, %r15
cmpq $0x8, %r14
jne 0xfe4f
jmp 0xfebf
movq 0x50(%rbx), %rcx
movl 0x10(%rax), %edx
shlq $0x6, %rdx
cmpl $0x1, (%rcx,%rdx)
jne 0x10397
leaq (%rcx,%rdx), %rsi
movl 0x4(%rsi), %edi
cmpl 0xc(%rax), %edi
jne 0x10397
movl $0xa, 0x3c(%rsi)
movq 0x8(%rbx), %rsi
addq $0x13, %rsi
movq %rsi, 0x8(%rcx,%rdx)
testq %rax, %rax
je 0xff8d
movl $0x38, %esi
movq %rax, %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 0x10494
movq 0x20(%rbx), %rsi
cmpq 0x28(%rbx), %rsi
je 0xff0b
movl 0x9381(%rip), %eax      # 0x19280
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x20(%rbx)
jmp 0xff1b
leaq 0x18(%rbx), %rdi
leaq 0x936a(%rip), %rdx      # 0x19280
callq 0xc480
movq 0x8(%rbx), %rax
movq 0x50(%rbx), %rcx
addq $0x4, %rax
xorl %edx, %edx
movq 0x10(%rcx,%rdx), %rsi
movq 0x18(%rcx,%rdx), %rdi
cmpq %rax, %rsi
cmovbeq %rax, %rsi
cmpq %rax, %rdi
cmovbeq %rax, %rdi
movq %rsi, 0x10(%rcx,%rdx)
movq %rdi, 0x18(%rcx,%rdx)
addq $0x40, %rdx
cmpq $0x200, %rdx            # imm = 0x200
jne 0xff29
movq 0x50(%rbx), %rax
movq (%rsp), %rcx
movl 0x10(%rcx), %ecx
shlq $0x6, %rcx
movabsq $0x500000001, %rdx      # imm = 0x500000001
movq %rdx, 0x38(%rax,%rcx)
movq 0x8(%rbx), %rdx
addq $0xe, %rdx
movq %rdx, 0x8(%rax,%rcx)
movq %rdx, 0x10(%rax,%rcx)
movq %rdx, 0x18(%rax,%rcx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x904d(%rip), %rdi      # 0x18ff0
leaq 0x31ce(%rip), %rsi      # 0x13178
callq 0x31c0
leaq 0x480d(%rip), %r13      # 0x147c3
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
leaq 0x3159(%rip), %rbp      # 0x13121
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x5d, %esi
callq 0x3330
leaq 0x31a2(%rip), %r12      # 0x13189
movq %rax, %rdi
movq %r12, %rsi
callq 0x31c0
leaq 0x47d3(%rip), %rsi      # 0x147cc
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
movl %r14d, %esi
callq 0x3260
movq %rax, %rdi
callq 0x30d0
movq 0x8fd5(%rip), %r14      # 0x18ff0
movq %r14, %rdi
leaq 0x3153(%rip), %rsi      # 0x13178
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 %r12, %rsi
callq 0x31c0
leaq 0x479a(%rip), %rsi      # 0x147f9
movq %rax, %rdi
callq 0x31c0
movq 0x50(%rbx), %rcx
movq 0x8(%rcx,%r15), %rsi
movq %rax, %rdi
callq 0x3060
movq %rax, %rdi
callq 0x30d0
movq %r14, %rdi
leaq 0x30ee(%rip), %rsi      # 0x13178
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 %r12, %rsi
callq 0x31c0
leaq 0x474b(%rip), %rsi      # 0x1480f
movq %rax, %rdi
callq 0x31c0
movq 0x50(%rbx), %rcx
movl (%rcx,%r15), %esi
movq %rax, %rdi
callq 0x3330
movq %rax, %rdi
callq 0x30d0
xorl %edi, %edi
callq 0x3220
movq 0x8efe(%rip), %r14      # 0x18ff0
leaq 0x307f(%rip), %r15      # 0x13178
movq %r14, %rdi
movq %r15, %rsi
callq 0x31c0
leaq 0x46b8(%rip), %r12      # 0x147c3
movq %rax, %rdi
movq %r12, %rsi
callq 0x31c0
leaq 0x3004(%rip), %r13      # 0x13121
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x6f, %esi
callq 0x3330
leaq 0x304d(%rip), %rbp      # 0x13189
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
leaq 0x46d5(%rip), %rsi      # 0x14823
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
callq 0x30d0
movq %r14, %rdi
movq %r15, %rsi
callq 0x31c0
movq %rax, %rdi
movq %r12, %rsi
callq 0x31c0
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x70, %esi
callq 0x3330
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
leaq 0x46b7(%rip), %rsi      # 0x14855
movq %rax, %rdi
callq 0x31c0
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x3060
movq %rax, %rdi
callq 0x30d0
movq %r14, %rdi
movq %r15, %rsi
callq 0x31c0
movq %rax, %rdi
movq %r12, %rsi
callq 0x31c0
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x71, %esi
callq 0x3330
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
jmp 0x10472
movq 0x8df1(%rip), %r14      # 0x18ff0
leaq 0x2f72(%rip), %r15      # 0x13178
movq %r14, %rdi
movq %r15, %rsi
callq 0x31c0
leaq 0x45ab(%rip), %r12      # 0x147c3
movq %rax, %rdi
movq %r12, %rsi
callq 0x31c0
leaq 0x2ef7(%rip), %r13      # 0x13121
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x8d, %esi
callq 0x3330
leaq 0x2f40(%rip), %rbp      # 0x13189
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
leaq 0x461c(%rip), %rsi      # 0x14877
movq %rax, %rdi
callq 0x31c0
movl 0x10(%rbx), %esi
movq %rax, %rdi
callq 0x3260
leaq 0x4613(%rip), %rsi      # 0x14888
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
callq 0x30d0
movq %r14, %rdi
movq %r15, %rsi
callq 0x31c0
movq %rax, %rdi
movq %r12, %rsi
callq 0x31c0
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x8e, %esi
callq 0x3330
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
movq (%rsp), %rcx
movl 0x10(%rcx), %esi
shlq $0x6, %rsi
addq 0x50(%rbx), %rsi
movq %rax, %rdi
callq 0xc63a
movq %rax, %rdi
callq 0x30d0
movq %r14, %rdi
movq %r15, %rsi
callq 0x31c0
movq %rax, %rdi
movq %r12, %rsi
callq 0x31c0
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0x8f, %esi
callq 0x3330
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
leaq 0x458f(%rip), %rsi      # 0x148ac
movq %rax, %rdi
callq 0x31c0
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x3060
jmp 0x100dc
movq 0x8cb3(%rip), %rdi      # 0x18ff0
leaq 0x2e34(%rip), %rsi      # 0x13178
callq 0x31c0
leaq 0x4473(%rip), %rsi      # 0x147c3
movq %rax, %rdi
callq 0x31c0
leaq 0x2dc2(%rip), %rsi      # 0x13121
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
movl $0xa8, %esi
callq 0x3330
leaq 0x2e0e(%rip), %rsi      # 0x13189
movq %rax, %rdi
callq 0x31c0
leaq 0x4542(%rip), %rsi      # 0x148cc
movq %rax, %rdi
callq 0x31c0
jmp 0x100dc
movq 0x8c52(%rip), %r14      # 0x18ff0
leaq 0x2dd3(%rip), %r15      # 0x13178
movq %r14, %rdi
movq %r15, %rsi
callq 0x31c0
leaq 0x440c(%rip), %r12      # 0x147c3
movq %rax, %rdi
movq %r12, %rsi
callq 0x31c0
leaq 0x2d58(%rip), %r13      # 0x13121
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0xc3, %esi
callq 0x3330
leaq 0x2da1(%rip), %rbp      # 0x13189
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
leaq 0x4501(%rip), %rsi      # 0x148fb
movq %rax, %rdi
callq 0x31c0
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x3060
movq %rax, %rdi
callq 0x30d0
movq %r14, %rdi
movq %r15, %rsi
callq 0x31c0
movq %rax, %rdi
movq %r12, %rsi
callq 0x31c0
movq %rax, %rdi
movq %r13, %rsi
callq 0x31c0
movq %rax, %rdi
movl $0xc4, %esi
callq 0x3330
movq %rax, %rdi
movq %rbp, %rsi
callq 0x31c0
leaq 0x44bf(%rip), %rsi      # 0x14915
movq %rax, %rdi
callq 0x31c0
movq (%rsp), %rsi
movq %rax, %rdi
callq 0xc9a7
movq %rax, %rdi
callq 0x30d0
movq (%rsp), %rcx
movl 0x10(%rcx), %esi
shlq $0x6, %rsi
addq 0x50(%rbx), %rsi
movq %rax, %rdi
callq 0xc63a
jmp 0x100dc