// File: /workspace/github_cpp_makefile_star2_O3/gersteinlab[P]MUSIC/src/ms_min_max_utils.cpp
// Function: get_extrema_per_plateaus(double*, int, std::vector<t_extrema_node*, std::allocator<t_extrema_node*>>*, std::vector<t_extrema_node*, std::allocator<t_extrema_node*>>*, int*, int, double)
void get_extrema_per_plateaus(double* data, int l_signal,
	vector<t_extrema_node*>* maxes, 
	vector<t_extrema_node*>* mins,
	int* derivative_sign_map,
	int i_scale,
	double zero_deriv)
{
	vector<t_extrema_node*>* extrema_nodes = new vector<t_extrema_node*>();

	double* deriv = new double[l_signal + 2];
	//vector<int>* plateau_locs = new vector<int>();
	//// Following can be implemented with 
	//deriv[0] = 0;
	//for(int i = 1; i < l_signal; i++)
	//{
	//	deriv[i] = data[i] - data[i-1];

	//	if(fabs(deriv[i]) < zero_deriv)
	//	{
	//		//fprintf(stderr, "Pleateau loc: %d\n", i);
	//		plateau_locs->push_back(i);
	//	}
	//	else
	//	{
	//	}
	//} // i loop.

	//// Form the plateau signal.
	//vector<t_plateau*>* plateaus = new vector<t_plateau*>();

	//int* plateau_signal = new int[l_signal];
	//memset(plateau_signal, 0, sizeof(int) * l_signal);
	//int n_pl_pts = (int)plateau_locs->size(); 
	//int i = 0; 
	//while(i < n_pl_pts)
	//{
	//	int cur_start = plateau_locs->at(i);
	//	int cur_end = plateau_locs->at(i);

	//	while(i+1 < n_pl_pts &&
	//		plateau_locs->at(i+1) == plateau_locs->at(i)+1)
	//	{			
	//		cur_end = plateau_locs->at(i+1);

	//		i++;
	//	} // plateau finder loop.

	//	i++;

	//	t_plateau* new_plateau = new t_plateau();
	//	new_plateau->start = cur_start;
	//	new_plateau->end = cur_end;
	//	//fprintf(stderr, "Pleateau: %d-%d\n", cur_start, cur_end);

	//	plateaus->push_back(new_plateau);
	//} // i loop.	

	deriv[0] = 0;
	for(int i = 1; i <= l_signal; i++)
	{
			deriv[i] = data[i] - data[i-1];
	} // i loop.

	vector<t_plateau*>* plateaus = new vector<t_plateau*>();

	int i = 1;
	int cur_start = -1;
	int cur_end = -1;
	while(i <= l_signal)
	{
		// Are we starting a new plateau here?
		if(fabs(deriv[i]) < zero_deriv)
		{
			// Plateau: Get the beginning and the end.
			cur_start = i;
			cur_end = i;
			while(i <= l_signal &&
					fabs(deriv[i]) < zero_deriv)
			{
				cur_end = i;
				i++;
			} // i loop.

			t_plateau* new_plateau = new t_plateau();
			new_plateau->start = cur_start;
			new_plateau->end = cur_end;
			plateaus->push_back(new_plateau);
		}
		else
		{
			i++;
		}
	} // i loop.

	// Go over all the plateaus and set the max/min ver plateau.
	int l_win = 1;
	for(int i_pl = 0; i_pl < (int)plateaus->size(); i_pl++)
	{
		if(plateaus->at(i_pl)->start > l_win &&
			plateaus->at(i_pl)->end+l_win < l_signal &&
			deriv[plateaus->at(i_pl)->start-l_win] > 0 &&
			deriv[plateaus->at(i_pl)->end+l_win] < 0)
		{
			t_extrema_node* new_ext_node = new t_extrema_node();
			new_ext_node->extrema_posn = (plateaus->at(i_pl)->start + plateaus->at(i_pl)->end) / 2;
			new_ext_node->extrema_type = EXTREMA_MAX;
			new_ext_node->higher_node = NULL;
			new_ext_node->lower_node = NULL;
			new_ext_node->scale = i_scale;
			new_ext_node->height_at_extrema = data[new_ext_node->extrema_posn];
			extrema_nodes->push_back(new_ext_node);
			//fprintf(stderr, "Adding max\n");
			//p2n->push_back((plateaus->at(i_pl)->start + plateaus->at(i_pl)->end) / 2);
		}

		if(plateaus->at(i_pl)->start > l_win &&
			plateaus->at(i_pl)->end+l_win < l_signal &&
			deriv[plateaus->at(i_pl)->start-l_win] < 0 &&
			deriv[plateaus->at(i_pl)->end+l_win] > 0)
		{
			t_extrema_node* new_ext_node = new t_extrema_node();
			new_ext_node->extrema_posn = (plateaus->at(i_pl)->start + plateaus->at(i_pl)->end) / 2;
			new_ext_node->extrema_type = EXTREMA_MIN;
			new_ext_node->higher_node = NULL;
			new_ext_node->lower_node = NULL;
			new_ext_node->scale = i_scale;
			new_ext_node->height_at_extrema = data[new_ext_node->extrema_posn];
			extrema_nodes->push_back(new_ext_node);
			//fprintf(stderr, "Adding max\n");
			//n2p->push_back((plateaus->at(i_pl)->start + plateaus->at(i_pl)->end) / 2);
		}
	} // i_pl loop.

	// Add the sudden changes.
	for(int i = 1; i < l_signal; i++)
	{
		if(i+1 < l_signal)
		{
			if(deriv[i] > zero_deriv &&
				deriv[i+1] < -1 * zero_deriv)
			{
				t_extrema_node* new_ext_node = new t_extrema_node();
				new_ext_node->extrema_posn = i;
				new_ext_node->extrema_type = EXTREMA_MAX;
				new_ext_node->higher_node = NULL;
				new_ext_node->lower_node = NULL;
				new_ext_node->scale = i_scale;
				new_ext_node->height_at_extrema = data[new_ext_node->extrema_posn];
				extrema_nodes->push_back(new_ext_node);
				//p2n->push_back(i);
			}

			if(deriv[i] < -1 * zero_deriv &&
				deriv[i+1] > zero_deriv)
			{
				t_extrema_node* new_ext_node = new t_extrema_node();
				new_ext_node->extrema_posn = i;
				new_ext_node->extrema_type = EXTREMA_MIN;
				new_ext_node->higher_node = NULL;
				new_ext_node->lower_node = NULL;
				new_ext_node->scale = i_scale;
				new_ext_node->height_at_extrema = data[new_ext_node->extrema_posn];
				extrema_nodes->push_back(new_ext_node);
				//n2p->push_back(i);
			}
		}
	} // i loop.

	if((int)extrema_nodes->size() == 0 ||
		(int)extrema_nodes->size() == 1)
	{
if(__DUMP_MIN_MAX_UTILS_MSGS__)
{
		fprintf(stderr, "Found %d extrema.\n", (int)extrema_nodes->size());
}
		return;
	}

	sort(extrema_nodes->begin(), extrema_nodes->end(), sort_extremas_per_posn);

	t_extrema_node* begin_ext_node = new t_extrema_node();
	begin_ext_node->extrema_posn = 0;
	begin_ext_node->extrema_type = EXTREMA_MIN;
	begin_ext_node->higher_node = NULL;
	begin_ext_node->lower_node = NULL;
	begin_ext_node->scale = i_scale;
	begin_ext_node->height_at_extrema = data[begin_ext_node->extrema_posn];

	t_extrema_node* end_ext_node = new t_extrema_node();
	end_ext_node->extrema_posn = l_signal-1;
	end_ext_node->extrema_type = EXTREMA_MIN;
	end_ext_node->higher_node = NULL;
	end_ext_node->lower_node = NULL;
	end_ext_node->scale = i_scale;
	end_ext_node->height_at_extrema = data[end_ext_node->extrema_posn];

	if(extrema_nodes->at(0)->extrema_type == EXTREMA_MAX)
	{
		begin_ext_node->extrema_type = EXTREMA_MIN;
	}
	else
	{
		begin_ext_node->extrema_type = EXTREMA_MAX;
	}

	if(extrema_nodes->back()->extrema_type == EXTREMA_MAX)
	{
		end_ext_node->extrema_type = EXTREMA_MIN;
	}
	else
	{
		end_ext_node->extrema_type = EXTREMA_MAX;
	}

	extrema_nodes->push_back(begin_ext_node);
	extrema_nodes->push_back(end_ext_node);

	sort(extrema_nodes->begin(), extrema_nodes->end(), sort_extremas_per_posn);

	// Set the derivative map.
	int i_cur_nuc = 0;
	for(int i_ext = 0; i_ext < (int)extrema_nodes->size(); i_ext++)
	{
		if(i_ext > 0 &&
			extrema_nodes->at(i_ext-1)->extrema_type == extrema_nodes->at(i_ext)->extrema_type)
		{
			fprintf(stderr, "Consecutive same extrema: %d, %d: %d\n", 
				extrema_nodes->at(i_ext-1)->extrema_posn, 
				extrema_nodes->at(i_ext)->extrema_posn, 
				extrema_nodes->at(i_ext)->extrema_type);
			exit(0);
		}

		int der_val = 0;
		if(extrema_nodes->at(i_ext)->extrema_type == EXTREMA_MAX)
		{
			der_val = 1;
		}
		else
		{
			der_val = -1;
		}

		for(int i_nuc = i_cur_nuc; i_nuc <= extrema_nodes->at(i_ext)->extrema_posn-1; i_nuc++)
		{
			derivative_sign_map[i_nuc] = der_val;
		} // i_nuc loop.

		derivative_sign_map[extrema_nodes->at(i_ext)->extrema_posn] = 0;
		i_cur_nuc = extrema_nodes->at(i_ext)->extrema_posn+1;
		//cur_type = extrema_nodes->at(i_ext)->extrema_type;
	} // i_ext loop.

if(__DUMP_MIN_MAX_UTILS_MSGS__)
{
	fprintf(stderr, "Found %d extrema.\n", (int)extrema_nodes->size());
}
	//for(int i = 0; i < 20; i++)
	//{
	//	fprintf(stderr, "%d: %d\n", extrema_nodes->at(i)->extrema_posn, extrema_nodes->at(i)->extrema_type);
	//}

	for(int i = 0; i < (int)extrema_nodes->size(); i++)
	{
		if(extrema_nodes->at(i)->extrema_type == EXTREMA_MAX)
		{
			maxes->push_back(extrema_nodes->at(i));
		}
		else
		{
			mins->push_back(extrema_nodes->at(i));
		}
	} // i loop.

	// Free memory. These are pretty large chunks of memory.
	delete [] deriv;
	//delete [] plateau_signal;
	for(int i_p = 0; i_p < (int)plateaus->size(); i_p++)
	{
		delete(plateaus->at(i_p));
	} // i_p loop.
	//delete plateau_locs;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movapd %xmm0, 0x20(%rsp)
movl %r9d, 0x14(%rsp)
movq %r8, 0x68(%rsp)
movq %rcx, %r13
movq %rdx, %r14
movl %esi, %r12d
movq %rdi, %r15
movl $0x18, %edi
callq 0x2180
leal 0x2(%r12), %ecx
shlq $0x3, %rcx
cmpl $-0x2, %r12d
movq $-0x1, %rdi
cmovgeq %rcx, %rdi
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
xorl %ebx, %ebx
movq %rax, 0x38(%rsp)
movq %rbx, 0x10(%rax)
callq 0x2040
movq %rbx, (%rax)
testl %r12d, %r12d
jle 0x24279
leal 0x1(%r12), %edx
movl $0x1, %ecx
movsd (%r15,%rcx,8), %xmm0
subsd -0x8(%r15,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
incq %rcx
cmpq %rcx, %rdx
jne 0x2425f
movq %r15, 0x30(%rsp)
movq %rax, (%rsp)
movq %r14, 0x70(%rsp)
movl $0x18, %edi
movq %r12, 0x18(%rsp)
callq 0x2180
movq 0x18(%rsp), %r9
movq %rax, %rbp
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq $0x0, 0x10(%rax)
movl %r9d, %r14d
testl %r9d, %r9d
jle 0x243a8
leal 0x1(%r9), %eax
movl %eax, 0x40(%rsp)
movl $0x1, %r15d
movapd 0x8710(%rip), %xmm2     # 0x2c9e0
movq (%rsp), %r8
movapd 0x20(%rsp), %xmm1
movslq %r15d, %rax
movsd (%r8,%rax,8), %xmm0
andpd %xmm2, %xmm0
ucomisd %xmm0, %xmm1
jbe 0x24331
movq %rbp, %r12
movl %r15d, %ebp
movl %r15d, %ebx
cmpl %r9d, %r15d
jg 0x24340
movsd (%r8,%rax,8), %xmm0
andpd %xmm2, %xmm0
ucomisd %xmm0, %xmm1
movl %r15d, %ebp
movl %r15d, %ebx
jbe 0x24340
cmpq %r14, %rax
jge 0x24339
movsd 0x8(%r8,%rax,8), %xmm0
incq %rax
andpd %xmm2, %xmm0
ucomisd %xmm0, %xmm1
ja 0x24311
leal -0x1(%rax), %ebp
movl %eax, %ebx
jmp 0x24340
incl %r15d
movl %r15d, %ebx
jmp 0x24392
movl %r9d, %ebp
movl 0x40(%rsp), %ebx
movl $0x8, %edi
callq 0x2180
movq %rax, 0x8(%rsp)
movl %r15d, (%rax)
movl %ebp, 0x4(%rax)
movq %r12, %rbp
movq 0x8(%r12), %rsi
cmpq 0x10(%r12), %rsi
je 0x2436e
movq %rax, (%rsi)
addq $0x8, 0x8(%rbp)
jmp 0x2437b
movq %rbp, %rdi
leaq 0x8(%rsp), %rdx
callq 0x2511e
movq (%rsp), %r8
movq 0x18(%rsp), %r9
movapd 0x20(%rsp), %xmm1
movapd 0x864e(%rip), %xmm2     # 0x2c9e0
movl %ebx, %r15d
cmpl %r9d, %ebx
jle 0x242da
movq (%rbp), %r15
movq 0x8(%rbp), %rax
jmp 0x243b7
xorl %r15d, %r15d
xorl %eax, %eax
movq (%rsp), %r8
movapd 0x20(%rsp), %xmm1
movq %rax, %rdx
subq %r15, %rdx
sarq $0x3, %rdx
testl %edx, %edx
movq 0x38(%rsp), %rbx
jle 0x245ad
xorl %r12d, %r12d
xorpd %xmm2, %xmm2
cmpq %r12, %rdx
jbe 0x24d08
movq (%r15,%r12,8), %rdx
movslq (%rdx), %rcx
cmpq $0x2, %rcx
jl 0x244ac
movslq 0x4(%rdx), %rdx
leal 0x1(%rdx), %esi
cmpl %r9d, %esi
jge 0x244ac
movsd -0x8(%r8,%rcx,8), %xmm0
ucomisd %xmm2, %xmm0
jbe 0x244ac
ucomisd 0x8(%r8,%rdx,8), %xmm2
jbe 0x244ac
movl $0x30, %edi
callq 0x2180
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rax, 0x8(%rsp)
movq (%r15,%r12,8), %rcx
movl 0x4(%rcx), %edx
addl (%rcx), %edx
movl %edx, %ecx
shrl $0x1f, %ecx
addl %edx, %ecx
sarl %ecx
movl %ecx, (%rax)
movupd %xmm0, 0x10(%rax)
movl 0x14(%rsp), %edx
movl %edx, 0x8(%rax)
movslq %ecx, %rcx
movq 0x30(%rsp), %rdx
movsd (%rdx,%rcx,8), %xmm0
movsd %xmm0, 0x20(%rax)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x24484
movq %rax, (%rsi)
addq $0x8, 0x8(%rbx)
jmp 0x24491
movq %rbx, %rdi
leaq 0x8(%rsp), %rdx
callq 0x25042
movq 0x18(%rsp), %r9
movapd 0x20(%rsp), %xmm1
movq (%rbp), %r15
movq 0x8(%rbp), %rax
movq (%rsp), %r8
xorpd %xmm2, %xmm2
movq %rax, %rdx
subq %r15, %rdx
sarq $0x3, %rdx
cmpq %r12, %rdx
jbe 0x24d08
movq (%r15,%r12,8), %rsi
movslq (%rsi), %rcx
cmpq $0x2, %rcx
jl 0x2459e
movslq 0x4(%rsi), %rsi
leal 0x1(%rsi), %edi
cmpl %r9d, %edi
jge 0x2459e
ucomisd -0x8(%r8,%rcx,8), %xmm2
jbe 0x2459e
movsd 0x8(%r8,%rsi,8), %xmm0
ucomisd %xmm2, %xmm0
jbe 0x2459e
movl $0x30, %edi
callq 0x2180
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rax, 0x8(%rsp)
movq (%r15,%r12,8), %rcx
movl 0x4(%rcx), %edx
addl (%rcx), %edx
movl %edx, %ecx
shrl $0x1f, %ecx
addl %edx, %ecx
sarl %ecx
movl %ecx, (%rax)
movl $0x1, 0x4(%rax)
movupd %xmm0, 0x10(%rax)
movl 0x14(%rsp), %edx
movl %edx, 0x8(%rax)
movslq %ecx, %rcx
movq 0x30(%rsp), %rdx
movsd (%rdx,%rcx,8), %xmm0
movsd %xmm0, 0x20(%rax)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x2456c
movq %rax, (%rsi)
addq $0x8, 0x8(%rbx)
jmp 0x24579
movq %rbx, %rdi
leaq 0x8(%rsp), %rdx
callq 0x25042
movq 0x18(%rsp), %r9
movapd 0x20(%rsp), %xmm1
movq (%rbp), %r15
movq 0x8(%rbp), %rax
movq %rax, %rdx
subq %r15, %rdx
sarq $0x3, %rdx
movq (%rsp), %r8
xorpd %xmm2, %xmm2
incq %r12
movslq %edx, %rcx
cmpq %rcx, %r12
jl 0x243d5
cmpl $0x2, %r9d
jl 0x2470c
movapd 0x9b31(%rip), %xmm2     # 0x2e0f0
xorpd %xmm1, %xmm2
movl $0x1, %r12d
movapd %xmm2, 0x40(%rsp)
movq %r12, %r15
incq %r12
cmpq %r14, %r12
jae 0x24703
movsd (%r8,%r15,8), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x24674
ucomisd 0x8(%r8,%r15,8), %xmm2
jbe 0x24674
movsd %xmm0, 0x58(%rsp)
movl $0x30, %edi
callq 0x2180
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rax, 0x8(%rsp)
movl %r15d, (%rax)
movupd %xmm0, 0x10(%rax)
movl 0x14(%rsp), %ecx
movl %ecx, 0x8(%rax)
movq 0x30(%rsp), %rcx
movsd (%rcx,%r15,8), %xmm0
movsd %xmm0, 0x20(%rax)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x24651
movq %rax, (%rsi)
addq $0x8, 0x8(%rbx)
jmp 0x2465e
movq %rbx, %rdi
leaq 0x8(%rsp), %rdx
callq 0x25042
movq (%rsp), %r8
movapd 0x20(%rsp), %xmm1
movapd 0x40(%rsp), %xmm2
movsd 0x58(%rsp), %xmm0
ucomisd %xmm0, %xmm2
jbe 0x24703
movsd 0x8(%r8,%r15,8), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x24703
movl $0x30, %edi
callq 0x2180
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rax, 0x8(%rsp)
movl %r15d, (%rax)
movl $0x1, 0x4(%rax)
movupd %xmm0, 0x10(%rax)
movl 0x14(%rsp), %ecx
movl %ecx, 0x8(%rax)
movq 0x30(%rsp), %rcx
movsd (%rcx,%r15,8), %xmm0
movsd %xmm0, 0x20(%rax)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x246e6
movq %rax, (%rsi)
addq $0x8, 0x8(%rbx)
jmp 0x246f3
movq %rbx, %rdi
leaq 0x8(%rsp), %rdx
callq 0x25042
movq (%rsp), %r8
movapd 0x20(%rsp), %xmm1
movapd 0x40(%rsp), %xmm2
cmpq %r12, %r14
jne 0x245cf
movq (%rbx), %r12
movq 0x8(%rbx), %r15
movq %r15, %r14
subq %r12, %r14
movq %r14, %rdx
sarq $0x3, %rdx
movabsq $0x7fffffff0, %rax      # imm = 0x7FFFFFFF0
testq %rax, %r14
je 0x24832
cmpq %r15, %r12
je 0x248b9
bsrq %rdx, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x57f(%rip), %rcx      # 0x241d1
movq %r12, %rdi
movq %r15, %rsi
callq 0x10afb
leaq 0x8(%r12), %rbx
cmpq $0x81, %r14
jl 0x2485c
movq %r15, 0x58(%rsp)
movq %rbp, 0x40(%rsp)
movq %r13, 0x20(%rsp)
movl $0x8, %r15d
movq %rbx, %r14
movq %r12, %r13
movq %r13, %rcx
leaq (%r12,%r15), %r13
movq (%r12,%r15), %rbp
movq (%r12), %rdx
movl (%rbp), %eax
cmpl (%rdx), %eax
jge 0x247b1
movq %rbx, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x22b0
movq %r12, %rcx
jmp 0x247cd
movq (%rcx), %rdx
movq %r13, %rcx
cmpl (%rdx), %eax
jge 0x247cd
movq %r14, %rcx
movq %rdx, (%rcx)
movq -0x10(%rcx), %rdx
addq $-0x8, %rcx
cmpl (%rdx), %eax
jl 0x247be
movq %rbp, (%rcx)
addq $0x8, %r15
addq $0x8, %r14
cmpq $0x80, %r15
jne 0x24788
subq $-0x80, %r12
movq 0x58(%rsp), %rdi
cmpq %rdi, %r12
movq 0x20(%rsp), %r13
movq 0x40(%rsp), %rbp
je 0x248b9
movq -0x8(%r12), %rcx
movq (%r12), %rax
movl (%rax), %edx
movq %r12, %rsi
cmpl (%rcx), %edx
jge 0x24821
movq %r12, %rsi
movq %rcx, (%rsi)
movq -0x10(%rsi), %rcx
addq $-0x8, %rsi
cmpl (%rcx), %edx
jl 0x24812
movq %rax, (%rsi)
addq $0x8, %r12
cmpq %rdi, %r12
jne 0x247fd
jmp 0x248b9
cmpb $0x1, 0x1499a(%rip)     # 0x391d3
jne 0x24cce
movq 0x1479a(%rip), %rax     # 0x38fe0
movq (%rax), %rdi
leaq 0x9dbe(%rip), %rsi      # 0x2e60e
xorl %eax, %eax
callq 0x2250
jmp 0x24cce
cmpq %r15, %rbx
je 0x248b9
movq %r12, %r14
movq %r14, %rdi
movq %rbx, %r14
movq (%rbx), %rbx
movq (%r12), %rcx
movl (%rbx), %eax
cmpl (%rcx), %eax
jge 0x24891
movq %r14, %rdx
subq %r12, %rdx
subq %rdx, %rdi
addq $0x10, %rdi
movq %r12, %rsi
callq 0x22b0
movq %r12, %rcx
jmp 0x248ad
movq (%rdi), %rdx
movq %r14, %rcx
cmpl (%rdx), %eax
jge 0x248ad
movq %r14, %rcx
movq %rdx, (%rcx)
movq -0x10(%rcx), %rdx
addq $-0x8, %rcx
cmpl (%rdx), %eax
jl 0x2489e
movq %rbx, (%rcx)
leaq 0x8(%r14), %rbx
cmpq %r15, %rbx
jne 0x24864
movl $0x30, %edi
callq 0x2180
movq %rax, %r14
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rax, 0x8(%rsp)
movl $0x1, %ebx
movl %ebx, 0x4(%rax)
movupd %xmm0, 0x10(%rax)
movl 0x14(%rsp), %r15d
movl %r15d, 0x8(%rax)
movq 0x30(%rsp), %r12
movsd (%r12), %xmm0
movsd %xmm0, 0x20(%rax)
movl $0x30, %edi
callq 0x2180
xorps %xmm0, %xmm0
movaps %xmm0, (%rax)
movaps %xmm0, 0x10(%rax)
movaps %xmm0, 0x20(%rax)
movq %rax, 0x60(%rsp)
movq 0x18(%rsp), %rdx
leal -0x1(%rdx), %ecx
movl %ecx, (%rax)
movl %ebx, 0x4(%rax)
movups %xmm0, 0x10(%rax)
movl %r15d, 0x8(%rax)
movslq %edx, %rcx
movsd -0x8(%r12,%rcx,8), %xmm0
movsd %xmm0, 0x20(%rax)
movq 0x38(%rsp), %rbx
movq (%rbx), %rcx
movq 0x8(%rbx), %rsi
cmpq %rcx, %rsi
je 0x24d51
movq (%rcx), %rcx
xorl %edx, %edx
cmpl $0x0, 0x4(%rcx)
sete %dl
movl %edx, 0x4(%r14)
movq -0x8(%rsi), %rcx
xorl %edx, %edx
cmpl $0x0, 0x4(%rcx)
sete %dl
movl %edx, 0x4(%rax)
cmpq 0x10(%rbx), %rsi
je 0x24990
movq %r14, (%rsi)
movq 0x8(%rbx), %rsi
addq $0x8, %rsi
movq %rsi, 0x8(%rbx)
jmp 0x249a1
leaq 0x8(%rsp), %rdx
movq %rbx, %rdi
callq 0x25042
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x249bd
movq 0x60(%rsp), %rax
movq %rax, (%rsi)
movq 0x8(%rbx), %r12
addq $0x8, %r12
movq %r12, 0x8(%rbx)
jmp 0x249ce
leaq 0x60(%rsp), %rdx
movq %rbx, %rdi
callq 0x25042
movq 0x8(%rbx), %r12
movq (%rbx), %r15
cmpq %r12, %r15
je 0x24b32
movq %r12, %r14
subq %r15, %r14
movq %r14, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x82a(%rip), %rcx      # 0x241d1
movq %r15, %rdi
movq %r12, %rsi
callq 0x10afb
leaq 0x8(%r15), %rbx
cmpq $0x81, %r14
jl 0x24ad6
movq %r12, 0x18(%rsp)
movq %rbp, 0x40(%rsp)
movq %r13, 0x20(%rsp)
movl $0x8, %r12d
movq %rbx, %r14
movq %r15, %r13
movq %r13, %rcx
leaq (%r15,%r12), %r13
movq (%r15,%r12), %rbp
movq (%r15), %rdx
movl (%rbp), %eax
cmpl (%rdx), %eax
jge 0x24a5a
movq %rbx, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x22b0
movq %r15, %rcx
jmp 0x24a76
movq (%rcx), %rdx
movq %r13, %rcx
cmpl (%rdx), %eax
jge 0x24a76
movq %r14, %rcx
movq %rdx, (%rcx)
movq -0x10(%rcx), %rdx
addq $-0x8, %rcx
cmpl (%rdx), %eax
jl 0x24a67
movq %rbp, (%rcx)
addq $0x8, %r12
addq $0x8, %r14
cmpq $0x80, %r12
jne 0x24a32
subq $-0x80, %r15
movq 0x18(%rsp), %rdi
cmpq %rdi, %r15
movq 0x20(%rsp), %r13
movq 0x40(%rsp), %rbp
je 0x24b32
movq -0x8(%r15), %rcx
movq (%r15), %rax
movl (%rax), %edx
movq %r15, %rsi
cmpl (%rcx), %edx
jge 0x24ac8
movq %r15, %rsi
movq %rcx, (%rsi)
movq -0x10(%rsi), %rcx
addq $-0x8, %rsi
cmpl (%rcx), %edx
jl 0x24ab9
movq %rax, (%rsi)
addq $0x8, %r15
cmpq %rdi, %r15
jne 0x24aa6
jmp 0x24b32
cmpq %r12, %rbx
je 0x24b32
movq %r15, %r14
movq %r14, %rdi
movq %rbx, %r14
movq (%rbx), %rbx
movq (%r15), %rcx
movl (%rbx), %eax
cmpl (%rcx), %eax
jge 0x24b0a
movq %r14, %rdx
subq %r15, %rdx
subq %rdx, %rdi
addq $0x10, %rdi
movq %r15, %rsi
callq 0x22b0
movq %r15, %rcx
jmp 0x24b26
movq (%rdi), %rdx
movq %r14, %rcx
cmpl (%rdx), %eax
jge 0x24b26
movq %r14, %rcx
movq %rdx, (%rcx)
movq -0x10(%rcx), %rdx
addq $-0x8, %rcx
cmpl (%rdx), %eax
jl 0x24b17
movq %rbx, (%rcx)
leaq 0x8(%r14), %rbx
cmpq %r12, %rbx
jne 0x24ade
movq 0x38(%rsp), %rbx
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
testl %edx, %edx
movq 0x70(%rsp), %r15
movq 0x68(%rsp), %r14
jle 0x24be7
movl %edx, %edi
andl $0x7fffffff, %edi       # imm = 0x7FFFFFFF
xorl %r8d, %r8d
xorl %ecx, %ecx
xorl %r9d, %r9d
testq %rcx, %rcx
je 0x24b99
leaq -0x1(%rcx), %rsi
cmpq %rsi, %rdx
jbe 0x24d2c
cmpq %rcx, %rdx
jbe 0x24d40
movq -0x8(%rax,%rcx,8), %r10
movq (%rax,%rcx,8), %r11
movl 0x4(%r10), %r10d
cmpl 0x4(%r11), %r10d
je 0x24d35
cmpq %rdx, %rcx
je 0x24d20
movq (%rax,%rcx,8), %rsi
cmpl 0x4(%rsi), %r8d
movl $0x0, %r10d
sbbl %r10d, %r10d
movslq (%rsi), %r11
cmpl %r11d, %r9d
jge 0x24bd1
orl $0x1, %r10d
movslq %r9d, %r9
movl %r10d, (%r14,%r9,4)
incq %r9
movslq (%rsi), %r11
cmpq %r11, %r9
jl 0x24bc2
movl $0x0, (%r14,%r11,4)
movl (%rsi), %r9d
incl %r9d
incq %rcx
cmpq %rdi, %rcx
jne 0x24b67
cmpb $0x0, 0x145e5(%rip)     # 0x391d3
jne 0x24cdd
testl %edx, %edx
movq (%rsp), %rdi
jle 0x24c80
xorl %r14d, %r14d
xorl %ebx, %ebx
cmpq %rbx, %rdx
jbe 0x24d14
movq (%rax,%r14), %rcx
addq %r14, %rax
cmpl $0x0, 0x4(%rcx)
je 0x24c2f
movq 0x8(%r13), %rsi
cmpq 0x10(%r13), %rsi
je 0x24c43
movq %rcx, (%rsi)
addq $0x8, 0x8(%r13)
jmp 0x24c57
movq 0x8(%r15), %rsi
cmpq 0x10(%r15), %rsi
je 0x24c48
movq %rcx, (%rsi)
addq $0x8, 0x8(%r15)
jmp 0x24c57
movq %r13, %rdi
jmp 0x24c4b
movq %r15, %rdi
movq %rax, %rdx
callq 0x25042
movq (%rsp), %rdi
incq %rbx
movq 0x38(%rsp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
subq %rax, %rcx
movq %rcx, %rdx
sarq $0x3, %rdx
shrq $0x3, %rcx
movslq %ecx, %rcx
addq $0x8, %r14
cmpq %rcx, %rbx
jl 0x24c05
callq 0x2220
movq (%rbp), %rax
movq 0x8(%rbp), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
testl %edx, %edx
jle 0x24cce
xorl %ebx, %ebx
cmpq %rbx, %rdx
jbe 0x24d14
movq (%rax,%rbx,8), %rdi
movl $0x8, %esi
callq 0x2190
incq %rbx
movq (%rbp), %rax
movq 0x8(%rbp), %rcx
subq %rax, %rcx
movq %rcx, %rdx
sarq $0x3, %rdx
shrq $0x3, %rcx
movslq %ecx, %rcx
cmpq %rcx, %rbx
jl 0x24c9a
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x142fc(%rip), %rax     # 0x38fe0
movq (%rax), %rdi
leaq 0x9920(%rip), %rsi      # 0x2e60e
xorl %eax, %eax
callq 0x2250
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
jmp 0x24bf4
leaq 0x7bc1(%rip), %rdi      # 0x2c8d0
movq %r12, %rsi
jmp 0x24d4a
leaq 0x7bb5(%rip), %rdi      # 0x2c8d0
movq %rbx, %rsi
jmp 0x24d4a
leaq 0x7ba9(%rip), %rdi      # 0x2c8d0
movq %rdx, %rsi
jmp 0x24d4a
leaq 0x7b9d(%rip), %rdi      # 0x2c8d0
jmp 0x24d4a
movq %rbx, %rdi
movq %rcx, %rdx
callq 0x557a
leaq 0x7b89(%rip), %rdi      # 0x2c8d0
movq %rcx, %rsi
xorl %eax, %eax
callq 0x2270
leaq 0x7b78(%rip), %rdi      # 0x2c8d0
xorl %esi, %esi
xorl %edx, %edx
jmp 0x24d4a