// File: /workspace/github_cpp_makefile_star2_O3/dramninjasUMD[P]BOBSim/BOB.cpp
// Function: BOBSim::BOB::PrintStats(std::basic_ofstream<char, std::char_traits<char>>&, std::basic_ofstream<char, std::char_traits<char>>&, bool, unsigned int)
void BOB::PrintStats(ofstream &statsOut, ofstream &powerOut, bool finalPrint, unsigned elapsedCycles)
{
	unsigned long dramCyclesElapsed;
	//check if we are on an epoch boundary or if there are cycles left over
	//
	//NOTE : subtract one from currentClockCycle since BOB object Update() has already been called
	//       before this call to PrintStats()

	if((currentClockCycle-1)%EPOCH_LENGTH==0)
	{
		//OLD - doesn't work for non-even ratios
		//dramCyclesElapsed = EPOCH_LENGTH / DRAM_CPU_CLK_RATIO;

		//NEW
		dramCyclesElapsed = EPOCH_LENGTH / ((float)tCK/(float)CPU_CLK_PERIOD);
	}
	else
	{
		//same as above
		dramCyclesElapsed = ((currentClockCycle-1)%EPOCH_LENGTH)/((float)tCK/(float)CPU_CLK_PERIOD);
	}

	//dramCyclesElapsed = channels[0]->currentClockCycle;

#define MAX_TMP_STR 512
	char tmp_str[MAX_TMP_STR];

	PRINT(" === BOB Print === ");
	unsigned long totalRequestsAtChannels = 0L;
	PRINT(" == Ports");
	for(unsigned p=0; p<NUM_PORTS; p++)
	{
		PRINT("  -- Port "<<p<<" - inputBufferAvg : "<<(float)portInputBufferAvg[p]/elapsedCycles<<" ("<<ports[p].inputBuffer.size()<<")   outputBufferAvg : "<<(float)portOutputBufferAvg[p]/elapsedCycles<<" ("<<ports[p].outputBuffer.size()<<")");
		portInputBufferAvg[p]=0;
		portOutputBufferAvg[p]=0;
	}

	//calculate possible bandwidth of part
	float dataperiod = tCK/2;
	float bw = (1/dataperiod)*64/8;//64-bit bus, 8 bits/byte

	unsigned numDevices = 64 / DEVICE_WIDTH;
	unsigned long totalBytesPerDevice = (NUM_COLS * NUM_ROWS * NUM_BANKS * DEVICE_WIDTH) / 8L; //in bytes
	unsigned long gigabytesPerRank = (numDevices * totalBytesPerDevice)>>30;

	//calculate peak bandwidth for link bus
	float reqbwpeak = 0;
	float rspbwpeak = 0;
	if(LINK_BUS_USE_DDR)
	{
		reqbwpeak = ((REQUEST_LINK_BUS_WIDTH * 2) / LINK_BUS_CLK_PERIOD)/8; //in bytes
		rspbwpeak = ((RESPONSE_LINK_BUS_WIDTH * 2) / LINK_BUS_CLK_PERIOD)/8; //in bytes
	}
	else
	{
		reqbwpeak = (REQUEST_LINK_BUS_WIDTH / LINK_BUS_CLK_PERIOD) / 8; //in bytes
		rspbwpeak = (RESPONSE_LINK_BUS_WIDTH / LINK_BUS_CLK_PERIOD) / 8; //in bytes
	}

	PRINT(" == Link Bandwidth (!! Includes packet overhead and request packets !!)")
	PRINT("    Req Link("<<reqbwpeak<<" GB/s peak)  Rsp Link("<<rspbwpeak<<" GB/s peak)");
	double reqtotal = 0;
	double rsptotal = 0;
	for(int l=0; l<NUM_LINK_BUSES; l++)
	{
		reqtotal += (1-(float)requestLinkIdle[l]/(float)elapsedCycles) * reqbwpeak;
		rsptotal += (1-(float)responseLinkIdle[l]/(float)elapsedCycles) * rspbwpeak;
		PRINTN("      "<<(1-(float)requestLinkIdle[l]/(float)elapsedCycles) * reqbwpeak<<" GB/s             ");
		requestLinkIdle[l]=0;
		PRINT((1-(float)responseLinkIdle[l]/(float)elapsedCycles) * rspbwpeak<<" GB/s");
		responseLinkIdle[l]=0;
	}


	PRINT("     -----------");
	PRINT("      "<<reqtotal/NUM_LINK_BUSES<<"          "<<rsptotal/NUM_LINK_BUSES<<" (avgs)");


	PRINT(" == Channel Usage and Stats ("<<(NUM_RANKS * gigabytesPerRank)<<"GB/Chan == "<<NUM_RANKS * gigabytesPerRank * NUM_CHANNELS<<" GB total)");
	PRINT("     reqs   workQAvg  workQMax idleBanks   actBanks  preBanks  refBanks  (totalBanks) BusIdle  BW("<<bw<<")  RRQMax("<<CHANNEL_RETURN_Q_MAX/TRANSACTION_SIZE<<")   RRQFull lifetimeRequests");
	float totalDRAMbw = 0;
	for(unsigned i=0; i<NUM_CHANNELS; i++)
	{
		//compute each DRAM channel's BW
		double DRAMBandwidth= (bw * (1 - ((double)channels[i]->DRAMBusIdleCount/(double)dramCyclesElapsed))) * 1E9 / (1<<30);

		statsOut<<DRAMBandwidth<<",";

		totalDRAMbw += DRAMBandwidth;
		totalRequestsAtChannels+=channelCounters[i];
		channelCountersLifetime[i]+=channelCounters[i];

		// since trying to actually format strings with stream operators is a huge pain
		snprintf(tmp_str, MAX_TMP_STR, "%d]%9d%10.4f%10d%10.4f%10.4f%10.4f%10.4f%10.4f%10.2f%10.3f%10d(%d)%10d%10ld\n",
		         i,
		         channelCounters[i],
		         (float)channels[i]->simpleController.commandQueueAverage/dramCyclesElapsed,
		         channels[i]->simpleController.commandQueueMax,
		         (float)channels[i]->simpleController.numIdleBanksAverage/dramCyclesElapsed,
		         (float)channels[i]->simpleController.numActBanksAverage/dramCyclesElapsed,
		         (float)channels[i]->simpleController.numPreBanksAverage/dramCyclesElapsed,
		         (float)channels[i]->simpleController.numRefBanksAverage/dramCyclesElapsed,
		         (float)(channels[i]->simpleController.numIdleBanksAverage+
		                 channels[i]->simpleController.numActBanksAverage+
		                 channels[i]->simpleController.numPreBanksAverage+
		                 channels[i]->simpleController.numRefBanksAverage)/dramCyclesElapsed,
		         100*((float)channels[i]->DRAMBusIdleCount/(float)dramCyclesElapsed),
		         DRAMBandwidth,
		         channels[i]->readReturnQueueMax,
		         (int)channels[i]->readReturnQueue.size(),
		         channels[i]->simpleController.RRQFull,
		         channelCountersLifetime[i]

		        );

		for(int r=0; r<NUM_RANKS; r++)
		{
			for(int b=0; b<NUM_BANKS; b++)
			{
				//PRINTN(channels[i]->simpleController.bankStates[r][b]);
			}
		}

		//reset
		channels[i]->simpleController.commandQueueAverage=0;
		channels[i]->simpleController.numIdleBanksAverage=0;
		channels[i]->simpleController.numActBanksAverage=0;
		channels[i]->simpleController.numPreBanksAverage=0;
		channels[i]->simpleController.numRefBanksAverage=0;
		channels[i]->simpleController.commandQueueMax=0;
		channels[i]->readReturnQueueMax=0;
		channels[i]->DRAMBusIdleCount=0;
		channelCounters[i]=0;
		channels[i]->simpleController.RRQFull=0;
		cmdQFull[i]=0;

		PRINTN(tmp_str);
	}

	//separates bandwidth numbers and power numbers
	statsOut<<";";

	PRINT("                                                                                          AVG : "<<totalDRAMbw/NUM_CHANNELS);
	PRINT(" == Requests seen at Channels");
	PRINT("  -- Reads  : "<<readCounter);
	PRINT("  -- Writes : "<<writeCounter);
	PRINT("            = "<<totalRequestsAtChannels);
	readCounter = 0;
	writeCounter = 0;
	totalRequestsAtChannels = 0;

	//
	//
	//POWER
	//
	//
	PRINT(" == Channel Power");
	powerOut<<currentClockCycle * CPU_CLK_PERIOD / 1000000<<",";

	bool detailedOutput = false;
	bool shortOutput = true;
	float allChanAveragePower = 0;
	for(unsigned c=0; c<NUM_CHANNELS; c++)
	{
		float totalChannelPower = 0;
		PRINTN("    -- Channel "<<c);
		for(unsigned r=0; r<NUM_RANKS; r++)
		{
			float backgroundPower = ((float)channels[c]->simpleController.backgroundEnergy[r] / (float) dramCyclesElapsed) * Vdd / 1000;
			float burstPower = ((float)channels[c]->simpleController.burstEnergy[r] / (float) dramCyclesElapsed) * Vdd / 1000;
			float actprePower = ((float)channels[c]->simpleController.actpreEnergy[r] / (float) dramCyclesElapsed) * Vdd / 1000;
			float refreshPower = ((float)channels[c]->simpleController.refreshEnergy[r] / (float) dramCyclesElapsed) * Vdd / 1000;

			float averagePower = ((float)(channels[c]->simpleController.actpreEnergy[r] +
			                              channels[c]->simpleController.backgroundEnergy[r] +
			                              channels[c]->simpleController.burstEnergy[r] +
			                              channels[c]->simpleController.refreshEnergy[r]) / (float) dramCyclesElapsed) * Vdd / 1000;
			totalChannelPower += averagePower;

			if(!shortOutput)
			{
				PRINTN("     -- Rank "<<r<<" : ");
				if(detailedOutput)
				{
					PRINT(setprecision(4)<<"TOT :"<<averagePower<<"  bkg:"<<backgroundPower<<" brst:"<<burstPower<<" ap:"<<actprePower<<" ref:"<<refreshPower);
				}
				else
				{
					PRINTN(setprecision(4)<<averagePower<<"w ");
				}
			}

			//clear for next epoch
			channels[c]->simpleController.backgroundEnergy[r]=0;
			channels[c]->simpleController.burstEnergy[r]=0;
			channels[c]->simpleController.actpreEnergy[r]=0;
			channels[c]->simpleController.refreshEnergy[r]=0;
		}

		allChanAveragePower += totalChannelPower;
		statsOut<<totalChannelPower<<",";
		powerOut<<totalChannelPower<<",";

		PRINT(" -- DRAM Power : "<<totalChannelPower<<" w");
	}

	PRINT("   Average Power  : "<<allChanAveragePower/NUM_CHANNELS<<" w");
	PRINT("   Total Power    : "<<allChanAveragePower<<" w");
	PRINT("   SimpCont BG Power : "<<NUM_LINK_BUSES * SIMP_CONT_BACKGROUND_POWER<<" w");
	PRINT("   SimpCont Core Power : "<<NUM_CHANNELS * SIMP_CONT_CORE_POWER<<" w");
	PRINT("   System Power   : "<<allChanAveragePower + NUM_LINK_BUSES * SIMP_CONT_BACKGROUND_POWER + NUM_CHANNELS * SIMP_CONT_CORE_POWER<<" w");

	statsOut << ";" << allChanAveragePower/NUM_CHANNELS << endl;

	//compute static power from controllers
	powerOut<<SIMP_CONT_BACKGROUND_POWER * NUM_LINK_BUSES + NUM_CHANNELS * SIMP_CONT_CORE_POWER <<",";
	powerOut<<(SIMP_CONT_BACKGROUND_POWER * NUM_LINK_BUSES + NUM_CHANNELS * SIMP_CONT_CORE_POWER) + allChanAveragePower<<endl;

	PRINT(" == Time Check");
	PRINT("    CPU Time : "<<currentClockCycle * CPU_CLK_PERIOD<<"ns");
	PRINT("   DRAM Time : "<<(channels[0]->currentClockCycle * tCK)<<"ns");
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x268, %rsp            # imm = 0x268
movl %r8d, %ebp
movq %rdx, 0x30(%rsp)
movq %rsi, 0x28(%rsp)
movq %rdi, %rbx
movq 0x8(%rdi), %rcx
leaq -0x1(%rcx), %rax
movabsq $0x431bde82d7b634db, %rdx # imm = 0x431BDE82D7B634DB
mulq %rdx
shrq $0x12, %rdx
imulq $0xf4240, %rdx, %rax    # imm = 0xF4240
negq %rax
addq %rcx, %rax
decq %rax
cvtsi2ss %eax, %xmm0
divss 0xd4c6(%rip), %xmm0     # 0x130d8
cvttss2si %xmm0, %rcx
movq %rcx, %rdx
sarq $0x3f, %rdx
subss 0xd4b6(%rip), %xmm0     # 0x130dc
cvttss2si %xmm0, %rsi
andq %rdx, %rsi
orq %rcx, %rsi
testq %rax, %rax
movl $0x32dcd, %eax          # imm = 0x32DCD
cmovneq %rsi, %rax
movq %rax, 0x38(%rsp)
movq 0x1337f(%rip), %r14     # 0x18fc8
leaq 0xd7d2(%rip), %rsi      # 0x13422
movl $0x13, %edx
movq %r14, %rdi
callq 0x3200
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xd7ab(%rip), %rsi      # 0x13436
movl $0x9, %edx
movq %r14, %rdi
callq 0x3200
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0x1350a(%rip), %r14     # 0x191d0
cmpl $0x0, (%r14)
je 0x5e50
movl %ebp, %eax
xorps %xmm0, %xmm0
cvtsi2ss %rax, %xmm0
movaps %xmm0, 0x10(%rsp)
leaq 0xd4e8(%rip), %rbp      # 0x131ce
xorl %r12d, %r12d
xorl %r15d, %r15d
movl $0xa, %edx
movq 0x132d0(%rip), %r13     # 0x18fc8
movq %r13, %rdi
leaq 0xd73e(%rip), %rsi      # 0x13440
callq 0x3200
movq %r13, %rdi
movq %r15, %rsi
callq 0x3120
movq %rax, %r13
movl $0x14, %edx
movq %rax, %rdi
leaq 0xd727(%rip), %rsi      # 0x1344b
callq 0x3200
movq 0x88(%rbx), %rax
movl (%rax,%r15,4), %eax
xorps %xmm0, %xmm0
cvtsi2ss %rax, %xmm0
divss 0x10(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movq %r13, %rdi
callq 0x32e0
movq %rax, %r13
movl $0x2, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3200
movq 0x10(%rbx), %rax
movq 0x18(%rax,%r12), %rsi
subq 0x10(%rax,%r12), %rsi
sarq $0x3, %rsi
movq %r13, %rdi
callq 0x3120
movq %rax, %r13
movl $0x16, %edx
movq %rax, %rdi
leaq 0xd6d3(%rip), %rsi      # 0x13460
callq 0x3200
movq 0xa0(%rbx), %rax
movl (%rax,%r15,4), %eax
xorps %xmm0, %xmm0
cvtsi2ss %rax, %xmm0
divss 0x10(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movq %r13, %rdi
callq 0x32e0
movq %rax, %r13
movl $0x2, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3200
movq 0x10(%rbx), %rax
movq 0x30(%rax,%r12), %rsi
subq 0x28(%rax,%r12), %rsi
sarq $0x3, %rsi
movq %r13, %rdi
callq 0x3120
movq %rax, %r13
movl $0x1, %edx
movq %rax, %rdi
leaq 0xd6c7(%rip), %rsi      # 0x134bd
callq 0x3200
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r13, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
movq 0x88(%rbx), %rax
xorl %ecx, %ecx
movl %ecx, (%rax,%r15,4)
movq 0xa0(%rbx), %rax
movl %ecx, (%rax,%r15,4)
incq %r15
movl (%r14), %eax
addq $0x40, %r12
cmpq %rax, %r15
jb 0x5cec
jmp 0x5e5f
movl %ebp, %eax
xorps %xmm0, %xmm0
cvtsi2ss %rax, %xmm0
movaps %xmm0, 0x10(%rsp)
leaq 0xd611(%rip), %rsi      # 0x13477
movl $0x47, %edx
movq 0x13156(%rip), %rbp     # 0x18fc8
movq %rbp, %rdi
callq 0x3200
movq (%rbp), %rax
movq -0x18(%rax), %rdi
addq %rbp, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %rbp, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xd616(%rip), %rsi      # 0x134bf
movl $0xd, %edx
movq %rbp, %rdi
callq 0x3200
movsd 0xd252(%rip), %xmm0     # 0x13110
movq %rbp, %rdi
callq 0x32e0
movq %rax, %r14
leaq 0xd5fd(%rip), %rsi      # 0x134cd
movl $0x16, %edx
movq %rax, %rdi
callq 0x3200
movsd 0xd233(%rip), %xmm0     # 0x13118
movq %r14, %rdi
callq 0x32e0
movq %rax, %r14
leaq 0xd5ed(%rip), %rsi      # 0x134e4
movl $0xb, %edx
movq %rax, %rdi
callq 0x3200
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
movq 0x160(%rbx), %rax
movaps 0x10(%rsp), %xmm0
shufps $0x0, %xmm0, %xmm0      # xmm0 = xmm0[0,0,0,0]
movaps %xmm0, 0x40(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, (%rsp)
xorl %r12d, %r12d
leaq 0xd59f(%rip), %r15      # 0x134f0
leaq 0xd5ab(%rip), %r13      # 0x13503
xorl %r14d, %r14d
movq 0x100(%rbx), %rcx
movss (%rax,%r14,4), %xmm0
movss (%rcx,%r14,4), %xmm1
unpcklpd %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
movapd 0xd0d6(%rip), %xmm0     # 0x13050
orpd %xmm0, %xmm1
subpd %xmm0, %xmm1
cvtpd2ps %xmm1, %xmm0
divps 0x40(%rsp), %xmm0
movaps 0xd0ce(%rip), %xmm1     # 0x13060
subps %xmm0, %xmm1
mulps 0xd0d4(%rip), %xmm1     # 0x13070
cvtps2pd %xmm1, %xmm0
movapd (%rsp), %xmm1
addpd %xmm0, %xmm1
movapd %xmm1, (%rsp)
movl $0x6, %edx
movq %rbp, %rdi
leaq 0xd540(%rip), %rsi      # 0x134fc
callq 0x3200
movq 0x100(%rbx), %rax
movl (%rax,%r14,4), %eax
xorps %xmm0, %xmm0
cvtsi2ss %rax, %xmm0
divss 0x10(%rsp), %xmm0
movss 0xd0fe(%rip), %xmm1     # 0x130e0
subss %xmm0, %xmm1
mulss 0xd0f6(%rip), %xmm1     # 0x130e4
xorps %xmm0, %xmm0
cvtss2sd %xmm1, %xmm0
movq %rbp, %rdi
callq 0x32e0
movl $0x12, %edx
movq %rax, %rdi
movq %r15, %rsi
callq 0x3200
movq 0x100(%rbx), %rax
movl %r12d, (%rax,%r14,4)
movq 0x160(%rbx), %rax
movl (%rax,%r14,4), %eax
xorps %xmm0, %xmm0
cvtsi2ss %rax, %xmm0
divss 0x10(%rsp), %xmm0
movss 0xd0a7(%rip), %xmm1     # 0x130e0
subss %xmm0, %xmm1
mulss 0xd0a3(%rip), %xmm1     # 0x130e8
xorps %xmm0, %xmm0
cvtss2sd %xmm1, %xmm0
movq %rbp, %rdi
callq 0x32e0
movq %rax, %rbp
movl $0x5, %edx
movq %rax, %rdi
movq %r13, %rsi
callq 0x3200
movq (%rbp), %rax
movq -0x18(%rax), %rdi
addq %rbp, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %rbp, %rdi
movq 0x12f3f(%rip), %rbp     # 0x18fc8
callq 0x3030
movq %rax, %rdi
callq 0x3130
movq 0x160(%rbx), %rax
movl %r12d, (%rax,%r14,4)
incq %r14
cmpq $0x4, %r14
jne 0x5f5b
leaq 0xd454(%rip), %rsi      # 0x13509
movl $0x10, %edx
movq %rbp, %rdi
callq 0x3200
movq (%rbp), %rax
movq -0x18(%rax), %rdi
addq %rbp, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %rbp, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xd40b(%rip), %rsi      # 0x134fc
movl $0x6, %edx
movq %rbp, %rdi
callq 0x3200
movapd (%rsp), %xmm0
mulsd 0xd015(%rip), %xmm0     # 0x13120
movq %rbp, %rdi
callq 0x32e0
movq %rax, %r14
leaq 0xd3db(%rip), %rsi      # 0x134f8
movl $0xa, %edx
movq %rax, %rdi
callq 0x3200
movapd (%rsp), %xmm0
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
mulsd 0xcfe5(%rip), %xmm0     # 0x13120
movq %r14, %rdi
callq 0x32e0
movq %rax, %r14
leaq 0xd3cd(%rip), %rsi      # 0x1351a
movl $0x7, %edx
movq %rax, %rdi
callq 0x3200
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xd39a(%rip), %rsi      # 0x13522
movl $0x1d, %edx
movq %rbp, %rdi
callq 0x3200
movl $0x20, %esi
movq %rbp, %rdi
callq 0x3120
movq %rax, %r14
leaq 0xd394(%rip), %rsi      # 0x13540
movl $0xb, %edx
movq %rax, %rdi
callq 0x3200
movl $0x100, %esi            # imm = 0x100
movq %r14, %rdi
callq 0x3120
movq %rax, %r14
leaq 0xd37c(%rip), %rsi      # 0x1354c
movl $0xa, %edx
movq %rax, %rdi
callq 0x3200
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xd34c(%rip), %rsi      # 0x13557
movl $0x62, %edx
movq %rbp, %rdi
callq 0x3200
movsd 0xcf08(%rip), %xmm0     # 0x13128
movq %rbp, %rdi
callq 0x32e0
movq %rax, %r14
leaq 0xd388(%rip), %rsi      # 0x135ba
movl $0xa, %edx
movq %rax, %rdi
callq 0x3200
movl $0x10, %esi
movq %r14, %rdi
callq 0x3120
movq %rax, %r14
leaq 0xd36f(%rip), %rsi      # 0x135c5
movl $0x1c, %edx
movq %rax, %rdi
callq 0x3200
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
movq 0x38(%rsp), %rcx
movq %rcx, %xmm0
punpckldq 0xcde4(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0xcdec(%rip), %xmm0     # 0x13090
movapd %xmm0, %xmm2
unpckhpd %xmm0, %xmm2            # xmm2 = xmm2[1],xmm0[1]
testq %rcx, %rcx
js 0x62b8
cvtsi2ss %rcx, %xmm1
jmp 0x62cd
movq %rcx, %rax
shrq %rax
andl $0x1, %ecx
orq %rax, %rcx
cvtsi2ss %rcx, %xmm1
addss %xmm1, %xmm1
movss %xmm1, 0x40(%rsp)
addsd %xmm0, %xmm2
xorpd %xmm0, %xmm0
movss %xmm0, (%rsp)
xorl %r12d, %r12d
xorl %ebp, %ebp
movapd %xmm2, 0x50(%rsp)
movq %rbp, 0x10(%rsp)
movq 0x28(%rbx), %rax
movq (%rax,%r12,8), %rax
movl 0x27c(%rax), %eax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd %xmm2, %xmm0
movsd 0xce1e(%rip), %xmm1     # 0x13130
subsd %xmm0, %xmm1
mulsd 0xce0a(%rip), %xmm1     # 0x13128
mulsd 0xce12(%rip), %xmm1     # 0x13138
mulsd 0xce12(%rip), %xmm1     # 0x13140
movsd %xmm1, 0x38(%rsp)
movq 0x28(%rsp), %rdi
movapd %xmm1, %xmm0
callq 0x32e0
movl $0x1, %edx
movq %rax, %rdi
leaq 0xd291(%rip), %rsi      # 0x135e2
callq 0x3200
xorps %xmm1, %xmm1
cvtss2sd (%rsp), %xmm1
movq 0x40(%rbx), %rax
movq 0x58(%rbx), %rcx
movl (%rax,%r12,4), %ebp
movq (%rcx,%r12,8), %r10
addq %rbp, %r10
movq %r10, (%rcx,%r12,8)
movq 0x28(%rbx), %rax
movq (%rax,%r12,8), %rax
movl 0x24(%rax), %ecx
xorps %xmm0, %xmm0
cvtsi2ss %rcx, %xmm0
movsd 0x38(%rsp), %xmm7
addsd %xmm7, %xmm1
movsd %xmm1, (%rsp)
movl 0x20(%rax), %r9d
movss 0x40(%rsp), %xmm8
divss %xmm8, %xmm0
cvtss2sd %xmm0, %xmm0
movl 0x28(%rax), %ecx
xorps %xmm1, %xmm1
cvtsi2ss %rcx, %xmm1
movl 0x2c(%rax), %edx
xorps %xmm2, %xmm2
cvtsi2ss %rdx, %xmm2
divss %xmm8, %xmm1
cvtss2sd %xmm1, %xmm1
divss %xmm8, %xmm2
cvtss2sd %xmm2, %xmm2
movl 0x30(%rax), %esi
cvtsi2ss %rsi, %xmm3
movl 0x34(%rax), %edi
cvtsi2ss %rdi, %xmm4
divss %xmm8, %xmm3
cvtss2sd %xmm3, %xmm3
addl %edx, %ecx
leal (%rdi,%rsi), %edx
addl %ecx, %edx
cvtsi2ss %rdx, %xmm5
divss %xmm8, %xmm4
cvtss2sd %xmm4, %xmm4
divss %xmm8, %xmm5
cvtss2sd %xmm5, %xmm5
movl 0x27c(%rax), %ecx
cvtsi2ss %rcx, %xmm6
divss %xmm8, %xmm6
mulss 0xccca(%rip), %xmm6     # 0x130ec
cvtss2sd %xmm6, %xmm6
movl 0x1f8(%rax), %r11d
movq 0x248(%rax), %rcx
movl 0x228(%rax), %edx
movl %ecx, %esi
subl %edx, %esi
shrl $0x3, %esi
cmpq $0x1, %rcx
adcl $-0x1, %esi
shll $0x6, %esi
movq 0x230(%rax), %rcx
subq 0x238(%rax), %rcx
shrq $0x3, %rcx
movq 0x220(%rax), %r15
subq 0x210(%rax), %r15
shrq $0x3, %r15
addl %ecx, %r15d
addl %esi, %r15d
movq %rbx, %r14
movl 0xfc(%rax), %ebx
movl $0x200, %esi            # imm = 0x200
leaq 0x60(%rsp), %r13
movq %r13, %rdi
leaq 0xd152(%rip), %rdx      # 0x135e4
movl %r12d, %ecx
movl %ebp, %r8d
movb $0x8, %al
pushq %r10
pushq %rbx
movq %r14, %rbx
pushq %r15
pushq %r11
callq 0x32d0
addq $0x20, %rsp
cvtsd2ss (%rsp), %xmm0
movss %xmm0, (%rsp)
addq %rbp, 0x10(%rsp)
movq 0x10(%rsp), %rbp
movq 0x28(%r14), %rax
movq (%rax,%r12,8), %rax
xorl %edx, %edx
movl %edx, 0x1f8(%rax)
movl %edx, 0x27c(%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x20(%rax)
movq $0x0, 0x30(%rax)
movq 0x40(%r14), %rcx
movl %edx, (%rcx,%r12,4)
movl %edx, 0xfc(%rax)
movq 0x1b0(%r14), %rax
movl %edx, (%rax,%r12,4)
movq %r13, %rdi
callq 0x30c0
movq 0x12aba(%rip), %rdi     # 0x18fc8
movq %r13, %rsi
movq %rax, %rdx
callq 0x3200
movapd 0x50(%rsp), %xmm2
movq 0x28(%rsp), %rdi
incq %r12
cmpq $0x8, %r12
jne 0x62eb
leaq 0xdc73(%rip), %rsi      # 0x141ab
movl $0x1, %edx
callq 0x3200
leaq 0xd0e8(%rip), %rsi      # 0x13631
movl $0x60, %edx
movq 0x12a73(%rip), %r15     # 0x18fc8
movq %r15, %rdi
callq 0x3200
movss (%rsp), %xmm0
mulss 0xcb86(%rip), %xmm0     # 0x130f0
cvtss2sd %xmm0, %xmm0
movq %r15, %rdi
callq 0x32e0
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xd0eb(%rip), %rsi      # 0x13692
movl $0x1d, %edx
movq %r15, %rdi
callq 0x3200
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xd0ce(%rip), %rsi      # 0x136b0
movl $0xe, %edx
movq %r15, %rdi
callq 0x3200
movl 0x1c8(%rbx), %esi
movq %r15, %rdi
callq 0x3120
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xd091(%rip), %rsi      # 0x136bf
movl $0xe, %edx
movq %r15, %rdi
callq 0x3200
movl 0x1cc(%rbx), %esi
movq %r15, %rdi
callq 0x3120
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xd054(%rip), %rsi      # 0x136ce
movl $0xe, %edx
movq %r15, %rdi
callq 0x3200
movq %r15, %rdi
movq %rbp, %rsi
callq 0x3120
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
movq $0x0, 0x1c8(%rbx)
leaq 0xd00f(%rip), %rsi      # 0x136dd
movl $0x11, %edx
movq %r15, %rdi
callq 0x3200
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
movq 0x8(%rbx), %rax
testq %rax, %rax
js 0x6712
cvtsi2ss %rax, %xmm0
jmp 0x6727
movq %rax, %rcx
shrq %rcx
andl $0x1, %eax
orq %rcx, %rax
cvtsi2ss %rax, %xmm0
addss %xmm0, %xmm0
mulss 0xc9c5(%rip), %xmm0     # 0x130f4
divss 0xc9c1(%rip), %xmm0     # 0x130f8
cvtss2sd %xmm0, %xmm0
movq 0x30(%rsp), %rdi
callq 0x32e0
leaq 0xce96(%rip), %r14      # 0x135e2
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3200
xorps %xmm0, %xmm0
movss %xmm0, (%rsp)
xorl %ebp, %ebp
movq 0x1285b(%rip), %r12     # 0x18fc8
xorl %r15d, %r15d
movl $0xf, %edx
movq %r12, %rdi
leaq 0xcf70(%rip), %rsi      # 0x136ef
callq 0x3200
movq %r12, %rdi
movq %r15, %rsi
callq 0x3120
movq 0x28(%rbx), %rax
movq (%rax,%r15,8), %rsi
movq 0x108(%rsi), %rax
movq 0x120(%rsi), %rcx
movq 0x138(%rsi), %rdx
movq 0x150(%rsi), %rsi
xorl %edi, %edi
xorps %xmm0, %xmm0
movss 0x40(%rsp), %xmm2
movss 0xc936(%rip), %xmm3     # 0x130fc
movss 0xc932(%rip), %xmm4     # 0x13100
movq (%rax,%rdi,8), %r8
addq (%rdx,%rdi,8), %r8
addq (%rcx,%rdi,8), %r8
addq (%rsi,%rdi,8), %r8
js 0x67ea
xorps %xmm1, %xmm1
cvtsi2ss %r8, %xmm1
jmp 0x6803
movq %r8, %r9
shrq %r9
andl $0x1, %r8d
orq %r9, %r8
xorps %xmm1, %xmm1
cvtsi2ss %r8, %xmm1
addss %xmm1, %xmm1
divss %xmm2, %xmm1
mulss %xmm3, %xmm1
divss %xmm4, %xmm1
addss %xmm1, %xmm0
movq %rbp, (%rax,%rdi,8)
movq %rbp, (%rcx,%rdi,8)
movq %rbp, (%rdx,%rdi,8)
movq %rbp, (%rsi,%rdi,8)
incq %rdi
cmpq $0x4, %rdi
jne 0x67ce
movss (%rsp), %xmm1
addss %xmm0, %xmm1
movss %xmm1, (%rsp)
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x28(%rsp), %rdi
callq 0x32e0
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3200
movq 0x30(%rsp), %rdi
movsd 0x10(%rsp), %xmm0
callq 0x32e0
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3200
movl $0x11, %edx
movq %r12, %rdi
leaq 0xce72(%rip), %rsi      # 0x136ff
callq 0x3200
movq %r12, %rdi
movsd 0x10(%rsp), %xmm0
callq 0x32e0
movq %rax, %r13
movl $0x2, %edx
movq %rax, %rdi
leaq 0xce5f(%rip), %rsi      # 0x13711
callq 0x3200
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r13, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
incq %r15
cmpq $0x8, %r15
jne 0x6770
leaq 0xce21(%rip), %rsi      # 0x13714
movl $0x14, %edx
movq %r12, %rdi
callq 0x3200
movss 0xc7e8(%rip), %xmm0     # 0x130f0
mulss (%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x10(%rsp)
movq %r12, %rdi
callq 0x32e0
movq %rax, %r15
leaq 0xcde8(%rip), %r14      # 0x13711
movl $0x2, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3200
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xcdc2(%rip), %rsi      # 0x13729
movl $0x14, %edx
movq %r12, %rdi
callq 0x3200
xorps %xmm0, %xmm0
cvtss2sd (%rsp), %xmm0
movq %r12, %rdi
callq 0x32e0
movq %rax, %r15
movl $0x2, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3200
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xcd79(%rip), %rsi      # 0x1373e
movl $0x17, %edx
movq %r12, %rdi
callq 0x3200
movl $0x1c, %esi
movq %r12, %rdi
callq 0x3120
movq %rax, %r15
movl $0x2, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3200
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xcd36(%rip), %rsi      # 0x13756
movl $0x19, %edx
movq %r12, %rdi
callq 0x3200
movsd 0xc713(%rip), %xmm0     # 0x13148
movq %r12, %rdi
callq 0x32e0
movq %rax, %r15
movl $0x2, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3200
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xccf2(%rip), %rsi      # 0x13770
movl $0x14, %edx
movq %r12, %rdi
callq 0x3200
movss 0xc671(%rip), %xmm0     # 0x13104
movss (%rsp), %xmm1
addss %xmm0, %xmm1
addss %xmm0, %xmm1
xorps %xmm0, %xmm0
cvtss2sd %xmm1, %xmm0
movq %r12, %rdi
callq 0x32e0
movq %rax, %r15
movl $0x2, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3200
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xd6bb(%rip), %rsi      # 0x141ab
movl $0x1, %edx
movq 0x28(%rsp), %r14
movq %r14, %rdi
callq 0x3200
movq %r14, %rdi
movsd 0x10(%rsp), %xmm0
callq 0x32e0
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
movsd 0xc60e(%rip), %xmm0     # 0x13150
movq 0x30(%rsp), %r14
movq %r14, %rdi
callq 0x32e0
leaq 0xca8c(%rip), %rsi      # 0x135e2
movl $0x1, %edx
movq %rax, %rdi
callq 0x3200
movss (%rsp), %xmm0
addss 0xc598(%rip), %xmm0     # 0x13108
cvtss2sd %xmm0, %xmm0
movq %r14, %rdi
callq 0x32e0
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xcbd8(%rip), %rsi      # 0x13785
movl $0xe, %edx
movq %r12, %rdi
callq 0x3200
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r12, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xcbab(%rip), %rsi      # 0x13794
movl $0xf, %edx
movq %r12, %rdi
callq 0x3200
movq 0x8(%rbx), %rax
testq %rax, %rax
js 0x6c09
xorps %xmm0, %xmm0
cvtsi2ss %rax, %xmm0
jmp 0x6c21
movq %rax, %rcx
shrq %rcx
andl $0x1, %eax
orq %rcx, %rax
xorps %xmm0, %xmm0
cvtsi2ss %rax, %xmm0
addss %xmm0, %xmm0
mulss 0xc4cb(%rip), %xmm0     # 0x130f4
cvtss2sd %xmm0, %xmm0
movq %r12, %rdi
callq 0x32e0
movq %rax, %r15
leaq 0xd249(%rip), %r14      # 0x13e88
movl $0x2, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3200
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3130
leaq 0xcb27(%rip), %rsi      # 0x137a4
movl $0xf, %edx
movq %r12, %rdi
callq 0x3200
movq 0x28(%rbx), %rax
movq (%rax), %rax
movq 0x8(%rax), %rax
testq %rax, %rax
js 0x6ca4
xorps %xmm0, %xmm0
cvtsi2ss %rax, %xmm0
jmp 0x6cbc
movq %rax, %rcx
shrq %rcx
andl $0x1, %eax
orq %rcx, %rax
xorps %xmm0, %xmm0
cvtsi2ss %rax, %xmm0
addss %xmm0, %xmm0
mulss 0xc438(%rip), %xmm0     # 0x130fc
cvtss2sd %xmm0, %xmm0
movq %r12, %rdi
callq 0x32e0
movq %rax, %rbx
movl $0x2, %edx
movq %rax, %rdi
movq %r14, %rsi
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
callq 0x3130
addq $0x268, %rsp            # imm = 0x268
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq