// File: /workspace/github_cpp_makefile_star2_O2/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 $0x298, %rsp            # imm = 0x298
movl %r8d, %ebp
movq %rdx, 0x28(%rsp)
movq %rsi, 0x20(%rsp)
movq %rdi, %rbx
movq 0x8(%rdi), %rax
decq %rax
xorl %r13d, %r13d
movl $0xf4240, %ecx          # imm = 0xF4240
xorl %edx, %edx
divq %rcx
movq %rdx, 0x30(%rsp)
cvtsi2ss %edx, %xmm0
divss 0xab04(%rip), %xmm0     # 0xf02c
cvttss2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subss 0xaaf4(%rip), %xmm0     # 0xf030
cvttss2si %xmm0, %rdx
andq %rcx, %rdx
orq %rax, %rdx
movq %rdx, 0x38(%rsp)
movq 0x11a75(%rip), %r14     # 0x15fc8
leaq 0xae80(%rip), %rsi      # 0xf3da
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0xae7d(%rip), %rsi      # 0xf3ee
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
movl %ebp, %eax
cvtsi2ss %rax, %xmm0
movaps %xmm0, 0x10(%rsp)
leaq 0xabf2(%rip), %rbp      # 0xf186
leaq 0xae7d(%rip), %r12      # 0xf418
leaq 0xaed3(%rip), %r14      # 0xf475
xorl %r15d, %r15d
leaq 0x11c04(%rip), %rax     # 0x161b0
movl (%rax), %eax
cmpq %rax, %r15
jae 0x46ac
movq 0x11a0a(%rip), %rdi     # 0x15fc8
leaq 0xae33(%rip), %rsi      # 0xf3f8
callq 0x2180
movq %rax, %rdi
movq %r15, %rsi
callq 0x2100
movq %rax, %rdi
leaq 0xae24(%rip), %rsi      # 0xf403
callq 0x2180
movq 0x88(%rbx), %rcx
movl (%rcx,%r15,4), %ecx
cvtsi2ss %rcx, %xmm0
divss 0x10(%rsp), %xmm0
movq %rax, %rdi
callq 0x2120
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
movq 0x10(%rbx), %rcx
movq 0x18(%rcx,%r13), %rsi
subq 0x10(%rcx,%r13), %rsi
sarq $0x3, %rsi
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
movq %r12, %rsi
callq 0x2180
movq 0xa0(%rbx), %rcx
movl (%rcx,%r15,4), %ecx
cvtsi2ss %rcx, %xmm0
divss 0x10(%rsp), %xmm0
movq %rax, %rdi
callq 0x2120
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2180
movq 0x10(%rbx), %rcx
movq 0x30(%rcx,%r13), %rsi
subq 0x28(%rcx,%r13), %rsi
sarq $0x3, %rsi
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
movq %r14, %rsi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
movq 0x88(%rbx), %rax
andl $0x0, (%rax,%r15,4)
movq 0xa0(%rbx), %rax
andl $0x0, (%rax,%r15,4)
incq %r15
addq $0x40, %r13
jmp 0x45a5
movq 0x11915(%rip), %r14     # 0x15fc8
leaq 0xad75(%rip), %rsi      # 0xf42f
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0xada6(%rip), %rsi      # 0xf477
movq %r14, %rdi
callq 0x2180
movsd 0xa97f(%rip), %xmm0     # 0xf060
movq %rax, %rdi
callq 0x2290
leaq 0xad95(%rip), %rsi      # 0xf485
movq %rax, %rdi
callq 0x2180
movsd 0xa968(%rip), %xmm0     # 0xf068
movq %rax, %rdi
callq 0x2290
leaq 0xad8d(%rip), %rsi      # 0xf49c
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
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 %ebp, %ebp
leaq 0xad77(%rip), %r15      # 0xf4b4
leaq 0xad64(%rip), %r12      # 0xf4a8
leaq 0xad70(%rip), %r13      # 0xf4bb
cmpq $0x4, %rbp
je 0x4855
movq 0x100(%rbx), %rax
movq 0x160(%rbx), %rcx
movss (%rax,%rbp,4), %xmm0
movss (%rcx,%rbp,4), %xmm1
unpcklpd %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
movapd 0xa937(%rip), %xmm0     # 0xf0b0
orpd %xmm0, %xmm1
subpd %xmm0, %xmm1
cvtpd2ps %xmm1, %xmm0
divps 0x40(%rsp), %xmm0
movaps 0xa92f(%rip), %xmm1     # 0xf0c0
subps %xmm0, %xmm1
mulps 0xa935(%rip), %xmm1     # 0xf0d0
cvtps2pd %xmm1, %xmm0
movapd (%rsp), %xmm1
addpd %xmm0, %xmm1
movapd %xmm1, (%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x2180
movq 0x100(%rbx), %rcx
movl (%rcx,%rbp,4), %ecx
cvtsi2ss %rcx, %xmm1
divss 0x10(%rsp), %xmm1
movss 0xa860(%rip), %xmm0     # 0xf034
subss %xmm1, %xmm0
mulss 0xa858(%rip), %xmm0     # 0xf038
movq %rax, %rdi
callq 0x2120
movq %rax, %rdi
movq %r12, %rsi
callq 0x2180
movq 0x100(%rbx), %rax
andl $0x0, (%rax,%rbp,4)
movq 0x160(%rbx), %rax
movl (%rax,%rbp,4), %eax
cvtsi2ss %rax, %xmm1
divss 0x10(%rsp), %xmm1
movss 0xa819(%rip), %xmm0     # 0xf034
subss %xmm1, %xmm0
mulss 0xa815(%rip), %xmm0     # 0xf03c
movq %r14, %rdi
callq 0x2120
movq %rax, %rdi
movq %r13, %rsi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
movq 0x160(%rbx), %rax
andl $0x0, (%rax,%rbp,4)
incq %rbp
jmp 0x474b
cmpq $0x0, 0x30(%rsp)
movl $0x32dcd, %eax          # imm = 0x32DCD
movq 0x38(%rsp), %r15
cmoveq %rax, %r15
movq 0x11758(%rip), %r14     # 0x15fc8
leaq 0xac4a(%rip), %rsi      # 0xf4c1
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0xac26(%rip), %rsi      # 0xf4b4
movq %r14, %rdi
callq 0x2180
movapd (%rsp), %xmm0
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
mulsd 0xa7c9(%rip), %xmm0     # 0xf070
movq %rax, %rdi
callq 0x2290
leaq 0xabfa(%rip), %rsi      # 0xf4b0
movq %rax, %rdi
callq 0x2180
movapd (%rsp), %xmm0
mulsd 0xa7a5(%rip), %xmm0     # 0xf070
movq %rax, %rdi
callq 0x2290
leaq 0xabf8(%rip), %rsi      # 0xf4d2
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0xabe9(%rip), %rsi      # 0xf4da
movq %r14, %rdi
callq 0x2180
pushq $0x20
popq %rsi
movq %rax, %rdi
callq 0x2100
leaq 0xabed(%rip), %rsi      # 0xf4f8
movq %rax, %rdi
callq 0x2180
movl $0x100, %esi            # imm = 0x100
movq %rax, %rdi
callq 0x2100
leaq 0xabdd(%rip), %rsi      # 0xf504
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0xabd1(%rip), %rsi      # 0xf50f
movq %r14, %rdi
callq 0x2180
movsd 0xa72a(%rip), %xmm0     # 0xf078
movq %rax, %rdi
callq 0x2290
leaq 0xac15(%rip), %rsi      # 0xf572
movq %rax, %rdi
callq 0x2180
pushq $0x10
popq %rsi
movq %rax, %rdi
callq 0x2100
leaq 0xac06(%rip), %rsi      # 0xf57d
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
movq %r15, %xmm0
punpckldq 0xa74c(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0xa754(%rip), %xmm0     # 0xf0f0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
movapd %xmm1, 0x50(%rsp)
testq %r15, %r15
js 0x49b6
cvtsi2ss %r15, %xmm1
jmp 0x49cc
movq %r15, %rax
shrq %rax
andl $0x1, %r15d
orq %rax, %r15
cvtsi2ss %r15, %xmm1
addss %xmm1, %xmm1
movss %xmm1, 0x40(%rsp)
movapd 0x50(%rsp), %xmm1
addsd %xmm0, %xmm1
movapd %xmm1, 0x50(%rsp)
xorpd %xmm0, %xmm0
movss %xmm0, (%rsp)
pushq $-0x8
popq %r15
xorl %r12d, %r12d
testq %r15, %r15
je 0x4c4f
movq 0x28(%rbx), %rax
movq 0x40(%rax,%r15,8), %rax
movl 0x27c(%rax), %eax
cvtsi2sd %rax, %xmm0
divsd 0x50(%rsp), %xmm0
movsd 0xa663(%rip), %xmm1     # 0xf080
subsd %xmm0, %xmm1
mulsd 0xa64f(%rip), %xmm1     # 0xf078
mulsd 0xa657(%rip), %xmm1     # 0xf088
mulsd 0xa657(%rip), %xmm1     # 0xf090
movsd %xmm1, 0x10(%rsp)
movq 0x20(%rsp), %rdi
movapd %xmm1, %xmm0
callq 0x2290
movq %rax, %rdi
leaq 0xab43(%rip), %rsi      # 0xf59a
callq 0x2180
movq 0x40(%rbx), %rax
movq 0x58(%rbx), %rcx
movl 0x20(%rax,%r15,4), %r13d
addq %r13, 0x40(%rcx,%r15,8)
cvtss2sd (%rsp), %xmm0
addsd 0x10(%rsp), %xmm0
movsd %xmm0, (%rsp)
movq 0x28(%rbx), %rax
movq 0x40(%rax,%r15,8), %rdi
movl 0x24(%rdi), %eax
cvtsi2ss %rax, %xmm0
movl 0x20(%rdi), %eax
movl %eax, 0x38(%rsp)
movss 0x40(%rsp), %xmm2
divss %xmm2, %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x30(%rsp)
movl 0x28(%rdi), %eax
cvtsi2ss %rax, %xmm0
divss %xmm2, %xmm0
movl 0x2c(%rdi), %ecx
cvtsi2ss %rcx, %xmm1
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x88(%rsp)
divss %xmm2, %xmm1
cvtss2sd %xmm1, %xmm0
movsd %xmm0, 0x80(%rsp)
movl 0x30(%rdi), %edx
cvtsi2ss %rdx, %xmm0
divss %xmm2, %xmm0
movl 0x34(%rdi), %esi
cvtsi2ss %rsi, %xmm1
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x78(%rsp)
divss %xmm2, %xmm1
addl %ecx, %eax
leal (%rsi,%rdx), %ecx
addl %eax, %ecx
cvtsi2ss %rcx, %xmm0
cvtss2sd %xmm1, %xmm1
movsd %xmm1, 0x70(%rsp)
divss %xmm2, %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x68(%rsp)
movl 0x27c(%rdi), %eax
cvtsi2ss %rax, %xmm0
divss %xmm2, %xmm0
mulss 0xa507(%rip), %xmm0     # 0xf040
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x60(%rsp)
movl 0x1f8(%rdi), %r14d
addq $0x200, %rdi            # imm = 0x200
callq 0x5364
movq %rax, %r10
movq 0x28(%rbx), %rax
movq 0x58(%rbx), %r11
movq 0x40(%rax,%r15,8), %rax
movq %rbx, %rbp
movq %r12, %rbx
movl 0xfc(%rax), %r12d
leal 0x8(%r15), %ecx
movl $0x200, %esi            # imm = 0x200
leaq 0x90(%rsp), %rdi
leaq 0xaa11(%rip), %rdx      # 0xf59c
movl %r13d, %r8d
movsd 0x30(%rsp), %xmm0
movl 0x38(%rsp), %r9d
movsd 0x88(%rsp), %xmm1
movsd 0x80(%rsp), %xmm2
movsd 0x78(%rsp), %xmm3
movsd 0x70(%rsp), %xmm4
movsd 0x68(%rsp), %xmm5
movsd 0x60(%rsp), %xmm6
movsd 0x10(%rsp), %xmm7
movb $0x8, %al
pushq 0x40(%r11,%r15,8)
pushq %r12
movq %rbx, %r12
movq %rbp, %rbx
pushq %r10
pushq %r14
callq 0x2280
addq $0x20, %rsp
movq 0x28(%rbp), %rax
movq 0x40(%rax,%r15,8), %rax
andl $0x0, 0x1f8(%rax)
andl $0x0, 0x27c(%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x20(%rax)
andq $0x0, 0x30(%rax)
movq 0x40(%rbp), %rcx
andl $0x0, 0x20(%rcx,%r15,4)
cvtsd2ss (%rsp), %xmm0
movss %xmm0, (%rsp)
addq %r13, %r12
andl $0x0, 0xfc(%rax)
movq 0x1b0(%rbp), %rax
andl $0x0, 0x20(%rax,%r15,4)
movq 0x1138e(%rip), %rdi     # 0x15fc8
leaq 0x90(%rsp), %rsi
callq 0x2180
incq %r15
jmp 0x49f2
leaq 0xb4c5(%rip), %rsi      # 0x1011b
movq 0x20(%rsp), %rdi
callq 0x2180
movq 0x11361(%rip), %r14     # 0x15fc8
leaq 0xa97b(%rip), %rsi      # 0xf5e9
movq %r14, %rdi
callq 0x2180
movss (%rsp), %xmm0
mulss 0xa3c1(%rip), %xmm0     # 0xf044
movq %rax, %rdi
callq 0x2120
movq %rax, %rdi
callq 0x20b0
leaq 0xa9b0(%rip), %rsi      # 0xf64a
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0xa9b7(%rip), %rsi      # 0xf668
movq %r14, %rdi
callq 0x2180
movl 0x1c8(%rbx), %esi
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
callq 0x20b0
leaq 0xa9a1(%rip), %rsi      # 0xf677
movq %r14, %rdi
callq 0x2180
movl 0x1cc(%rbx), %esi
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
callq 0x20b0
leaq 0xa98b(%rip), %rsi      # 0xf686
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
movq %r12, %rsi
callq 0x2100
movq %rax, %rdi
callq 0x20b0
andq $0x0, 0x1c8(%rbx)
leaq 0xa970(%rip), %rsi      # 0xf695
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
movq 0x8(%rbx), %rax
testq %rax, %rax
js 0x4d45
cvtsi2ss %rax, %xmm0
jmp 0x4d5a
movq %rax, %rcx
shrq %rcx
andl $0x1, %eax
orq %rcx, %rax
cvtsi2ss %rax, %xmm0
addss %xmm0, %xmm0
mulss 0xa2e6(%rip), %xmm0     # 0xf048
divss 0xa2e2(%rip), %xmm0     # 0xf04c
movq 0x28(%rsp), %rdi
callq 0x2120
leaq 0xa81f(%rip), %r14      # 0xf59a
movq %rax, %rdi
movq %r14, %rsi
callq 0x2180
xorps %xmm0, %xmm0
movss %xmm0, (%rsp)
xorl %r15d, %r15d
movq 0x11230(%rip), %r12     # 0x15fc8
leaq 0xa918(%rip), %rbp      # 0xf6b7
leaq 0xa923(%rip), %r13      # 0xf6c9
cmpq $0x8, %r15
je 0x4ee2
movq %r12, %rdi
leaq 0xa8ed(%rip), %rsi      # 0xf6a7
callq 0x2180
movq %rax, %rdi
movq %r15, %rsi
callq 0x2100
movss 0xa282(%rip), %xmm3     # 0xf054
movss 0xa276(%rip), %xmm2     # 0xf050
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
xorps %xmm4, %xmm4
xorl %edi, %edi
movss 0x40(%rsp), %xmm1
cmpq $0x4, %rdi
je 0x4e67
movq (%rax,%rdi,8), %r8
addq (%rdx,%rdi,8), %r8
addq (%rcx,%rdi,8), %r8
addq (%rsi,%rdi,8), %r8
js 0x4e28
cvtsi2ss %r8, %xmm0
jmp 0x4e3e
movq %r8, %r9
shrq %r9
andl $0x1, %r8d
orq %r9, %r8
cvtsi2ss %r8, %xmm0
addss %xmm0, %xmm0
divss %xmm1, %xmm0
mulss %xmm2, %xmm0
andq $0x0, (%rax,%rdi,8)
divss %xmm3, %xmm0
andq $0x0, (%rcx,%rdi,8)
addss %xmm0, %xmm4
andq $0x0, (%rdx,%rdi,8)
andq $0x0, (%rsi,%rdi,8)
incq %rdi
jmp 0x4e09
movss (%rsp), %xmm0
addss %xmm4, %xmm0
movss %xmm0, (%rsp)
movq 0x20(%rsp), %rdi
movaps %xmm4, %xmm0
movss %xmm4, 0x10(%rsp)
callq 0x2120
movq %rax, %rdi
movq %r14, %rsi
callq 0x2180
movq 0x28(%rsp), %rdi
movss 0x10(%rsp), %xmm0
callq 0x2120
movq %rax, %rdi
movq %r14, %rsi
callq 0x2180
movq %r12, %rdi
movq %rbp, %rsi
callq 0x2180
movq %rax, %rdi
movss 0x10(%rsp), %xmm0
callq 0x2120
movq %rax, %rdi
movq %r13, %rsi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
incq %r15
jmp 0x4da6
movq 0x110df(%rip), %r12     # 0x15fc8
leaq 0xa7dc(%rip), %rsi      # 0xf6cc
movq %r12, %rdi
callq 0x2180
movss 0xa144(%rip), %xmm0     # 0xf044
mulss (%rsp), %xmm0
movss %xmm0, 0x10(%rsp)
movq %rax, %rdi
callq 0x2120
leaq 0xa7af(%rip), %r14      # 0xf6c9
movq %rax, %rdi
movq %r14, %rsi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0xa7ad(%rip), %rsi      # 0xf6e1
movq %r12, %rdi
callq 0x2180
movq %rax, %rdi
movss (%rsp), %xmm0
callq 0x2120
movq %rax, %rdi
movq %r14, %rsi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0xa793(%rip), %rsi      # 0xf6f6
movq %r12, %rdi
callq 0x2180
pushq $0x1c
popq %rsi
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
movq %r14, %rsi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0xa77e(%rip), %rsi      # 0xf70e
movq %r12, %rdi
callq 0x2180
movsd 0xa0f8(%rip), %xmm0     # 0xf098
movq %rax, %rdi
callq 0x2290
movq %rax, %rdi
movq %r14, %rsi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0xa766(%rip), %rsi      # 0xf728
movq %r12, %rdi
callq 0x2180
movss 0xa086(%rip), %xmm1     # 0xf058
movss (%rsp), %xmm0
addss %xmm1, %xmm0
addss %xmm1, %xmm0
movq %rax, %rdi
callq 0x2120
movq %rax, %rdi
movq %r14, %rsi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0xb11a(%rip), %rsi      # 0x1011b
movq 0x20(%rsp), %rdi
callq 0x2180
movq %rax, %rdi
movss 0x10(%rsp), %xmm0
callq 0x2120
movq %rax, %rdi
callq 0x20b0
movsd 0xa077(%rip), %xmm0     # 0xf0a0
movq 0x28(%rsp), %r14
movq %r14, %rdi
callq 0x2290
leaq 0xa55d(%rip), %rsi      # 0xf59a
movq %rax, %rdi
callq 0x2180
movss (%rsp), %xmm0
addss 0xa00a(%rip), %xmm0     # 0xf05c
movq %r14, %rdi
callq 0x2120
movq %rax, %rdi
callq 0x20b0
leaq 0xa6d4(%rip), %rsi      # 0xf73d
movq %r12, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0xa6cc(%rip), %rsi      # 0xf74c
movq %r12, %rdi
callq 0x2180
movq 0x8(%rbx), %rcx
testq %rcx, %rcx
js 0x5098
cvtsi2ss %rcx, %xmm0
jmp 0x50ad
movq %rcx, %rdx
shrq %rdx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
mulss 0x9f93(%rip), %xmm0     # 0xf048
movq %rax, %rdi
callq 0x2120
leaq 0xad34(%rip), %r14      # 0xfdf8
movq %rax, %rdi
movq %r14, %rsi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0xa67e(%rip), %rsi      # 0xf75c
movq %r12, %rdi
callq 0x2180
movq 0x28(%rbx), %rcx
movq (%rcx), %rcx
movq 0x8(%rcx), %rcx
testq %rcx, %rcx
js 0x50fd
cvtsi2ss %rcx, %xmm0
jmp 0x5112
movq %rcx, %rdx
shrq %rdx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
mulss 0x9f36(%rip), %xmm0     # 0xf050
movq %rax, %rdi
callq 0x2120
movq %rax, %rdi
movq %r14, %rsi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
addq $0x298, %rsp            # imm = 0x298
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop