// File: /workspace/github_cpp_makefile_star2_O1/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 $0x88, %rsp
movapd %xmm0, 0x20(%rsp)
movl %r9d, 0x4(%rsp)
movq %r8, 0x68(%rsp)
movq %rcx, 0x78(%rsp)
movq %rdx, 0x70(%rsp)
movl %esi, %ebx
movq %rdi, %r14
movl $0x18, %edi
callq 0x2180
movq %rax, %rbp
movq %rbx, 0x18(%rsp)
movslq %ebx, %r15
leaq 0x10(,%r15,8), %rax
cmpl $-0x2, %r15d
movq $-0x1, %rdi
cmovgeq %rax, %rdi
xorpd %xmm0, %xmm0
movupd %xmm0, (%rbp)
xorl %ebx, %ebx
movq %rbx, 0x10(%rbp)
callq 0x2040
movq %rbx, (%rax)
movq %r15, 0x80(%rsp)
testl %r15d, %r15d
jle 0x2483b
movq 0x18(%rsp), %rcx
leal 0x1(%rcx), %edx
movl $0x1, %ecx
movsd (%r14,%rcx,8), %xmm0
subsd -0x8(%r14,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
incq %rcx
cmpq %rcx, %rdx
jne 0x24821
movq %r14, 0x38(%rsp)
movq %rax, 0x8(%rsp)
movl $0x18, %edi
callq 0x2180
movq 0x8(%rsp), %rsi
movq %rax, %r13
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq $0x0, 0x10(%rax)
movq 0x18(%rsp), %rdi
movl %edi, %r14d
testl %edi, %edi
movq %rbp, 0x40(%rsp)
movapd 0x20(%rsp), %xmm1
jle 0x2495e
leal 0x1(%rdi), %eax
movl %eax, 0x50(%rsp)
movl $0x1, %r15d
movapd 0x9149(%rip), %xmm2     # 0x2d9e0
leaq 0x10(%rsp), %r12
movslq %r15d, %rax
movsd (%rsi,%rax,8), %xmm0
andpd %xmm2, %xmm0
ucomisd %xmm0, %xmm1
jbe 0x248ed
movl %r15d, %ebp
movl %r15d, %ebx
cmpl %edi, %r15d
jg 0x248fb
movsd (%rsi,%rax,8), %xmm0
andpd %xmm2, %xmm0
ucomisd %xmm0, %xmm1
movl %r15d, %ebp
movl %r15d, %ebx
jbe 0x248fb
cmpq %r14, %rax
jge 0x248f5
movsd 0x8(%rsi,%rax,8), %xmm0
incq %rax
andpd %xmm2, %xmm0
ucomisd %xmm0, %xmm1
ja 0x248ce
leal -0x1(%rax), %ebp
movl %eax, %ebx
jmp 0x248fb
incl %r15d
movl %r15d, %ebx
jmp 0x24953
movl %edi, %ebp
movl 0x50(%rsp), %ebx
movl $0x8, %edi
callq 0x2180
movq $0x0, (%rax)
movq %rax, 0x10(%rsp)
movl %r15d, (%rax)
movl %ebp, 0x4(%rax)
movq 0x8(%r13), %rsi
cmpq 0x10(%r13), %rsi
je 0x2492b
movq %rax, (%rsi)
addq $0x8, 0x8(%r13)
jmp 0x24936
movq %r13, %rdi
movq %r12, %rdx
callq 0x2573a
movq 0x40(%rsp), %rbp
movq 0x8(%rsp), %rsi
movq 0x18(%rsp), %rdi
movapd 0x20(%rsp), %xmm1
movapd 0x908d(%rip), %xmm2     # 0x2d9e0
movl %ebx, %r15d
cmpl %edi, %ebx
jle 0x2489c
movq (%r13), %r15
movq 0x8(%r13), %rdx
subq %r15, %rdx
sarq $0x3, %rdx
testl %edx, %edx
jle 0x24b57
xorl %r12d, %r12d
xorpd %xmm2, %xmm2
cmpq %r12, %rdx
jbe 0x252d7
movq (%r15,%r12,8), %rcx
movslq (%rcx), %rax
cmpq $0x2, %rax
jl 0x24a50
movslq 0x4(%rcx), %rcx
leal 0x1(%rcx), %edx
cmpl %edi, %edx
jge 0x24a50
movsd -0x8(%rsi,%rax,8), %xmm0
ucomisd %xmm2, %xmm0
jbe 0x24a50
ucomisd 0x8(%rsi,%rcx,8), %xmm2
jbe 0x24a50
movl $0x30, %edi
callq 0x2180
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rax, 0x10(%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 $0x0, 0x4(%rax)
movupd %xmm0, 0x10(%rax)
movl 0x4(%rsp), %edx
movl %edx, 0x8(%rax)
movslq %ecx, %rcx
movq 0x38(%rsp), %rdx
movsd (%rdx,%rcx,8), %xmm0
movsd %xmm0, 0x20(%rax)
movq 0x8(%rbp), %rsi
cmpq 0x10(%rbp), %rsi
je 0x24a2f
movq %rax, (%rsi)
addq $0x8, 0x8(%rbp)
jmp 0x24a3c
movq %rbp, %rdi
leaq 0x10(%rsp), %rdx
callq 0x2565e
movq 0x8(%rsp), %rsi
movq 0x18(%rsp), %rdi
movapd 0x20(%rsp), %xmm1
xorpd %xmm2, %xmm2
movq (%r13), %rbx
movq 0x8(%r13), %rdx
subq %rbx, %rdx
sarq $0x3, %rdx
cmpq %r12, %rdx
jbe 0x252d7
movq (%rbx,%r12,8), %rcx
movslq (%rcx), %rax
cmpq $0x2, %rax
jl 0x24b33
movslq 0x4(%rcx), %rcx
leal 0x1(%rcx), %edx
cmpl %edi, %edx
jge 0x24b33
ucomisd -0x8(%rsi,%rax,8), %xmm2
jbe 0x24b33
movsd 0x8(%rsi,%rcx,8), %xmm0
ucomisd %xmm2, %xmm0
jbe 0x24b33
movl $0x30, %edi
callq 0x2180
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rax, 0x10(%rsp)
movq (%rbx,%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 0x4(%rsp), %edx
movl %edx, 0x8(%rax)
movslq %ecx, %rcx
movq 0x38(%rsp), %rdx
movsd (%rdx,%rcx,8), %xmm0
movsd %xmm0, 0x20(%rax)
movq 0x8(%rbp), %rsi
cmpq 0x10(%rbp), %rsi
je 0x24b12
movq %rax, (%rsi)
addq $0x8, 0x8(%rbp)
jmp 0x24b1f
movq %rbp, %rdi
leaq 0x10(%rsp), %rdx
callq 0x2565e
movq 0x8(%rsp), %rsi
movq 0x18(%rsp), %rdi
movapd 0x20(%rsp), %xmm1
xorpd %xmm2, %xmm2
incq %r12
movq (%r13), %r15
movq 0x8(%r13), %rax
subq %r15, %rax
movq %rax, %rdx
sarq $0x3, %rdx
shrq $0x3, %rax
cltq
cmpq %rax, %r12
jl 0x2497c
cmpl $0x2, %edi
jl 0x24cb5
movapd 0xa588(%rip), %xmm2     # 0x2f0f0
xorpd %xmm1, %xmm2
movl $0x1, %r12d
leaq 0x10(%rsp), %rbx
movapd %xmm2, 0x50(%rsp)
movq %r12, %r15
incq %r12
cmpq %r14, %r12
jae 0x24cac
movsd (%rsi,%r15,8), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x24c1c
ucomisd 0x8(%rsi,%r15,8), %xmm2
jbe 0x24c1c
movl $0x30, %edi
callq 0x2180
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rax, 0x10(%rsp)
movl %r15d, (%rax)
movl $0x0, 0x4(%rax)
movupd %xmm0, 0x10(%rax)
movl 0x4(%rsp), %ecx
movl %ecx, 0x8(%rax)
movq 0x38(%rsp), %rcx
movsd (%rcx,%r15,8), %xmm0
movsd %xmm0, 0x20(%rax)
movq 0x8(%rbp), %rsi
cmpq 0x10(%rbp), %rsi
je 0x24c00
movq %rax, (%rsi)
addq $0x8, 0x8(%rbp)
jmp 0x24c0b
movq %rbp, %rdi
movq %rbx, %rdx
callq 0x2565e
movq 0x8(%rsp), %rsi
movapd 0x20(%rsp), %xmm1
movapd 0x50(%rsp), %xmm2
ucomisd (%rsi,%r15,8), %xmm2
jbe 0x24cac
movsd 0x8(%rsi,%r15,8), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x24cac
movl $0x30, %edi
callq 0x2180
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rax, 0x10(%rsp)
movl %r15d, (%rax)
movl $0x1, 0x4(%rax)
movupd %xmm0, 0x10(%rax)
movl 0x4(%rsp), %ecx
movl %ecx, 0x8(%rax)
movq 0x38(%rsp), %rcx
movsd (%rcx,%r15,8), %xmm0
movsd %xmm0, 0x20(%rax)
movq 0x8(%rbp), %rsi
cmpq 0x10(%rbp), %rsi
je 0x24c90
movq %rax, (%rsi)
addq $0x8, 0x8(%rbp)
jmp 0x24c9b
movq %rbp, %rdi
movq %rbx, %rdx
callq 0x2565e
movq 0x8(%rsp), %rsi
movapd 0x20(%rsp), %xmm1
movapd 0x50(%rsp), %xmm2
cmpq %r12, %r14
jne 0x24b7d
movq (%rbp), %r12
movq 0x8(%rbp), %r15
movq %r15, %rbx
subq %r12, %rbx
movq %rbx, %rdx
sarq $0x3, %rdx
movabsq $0x7fffffff0, %rax      # imm = 0x7FFFFFFF0
testq %rax, %rbx
je 0x24de0
movq %r13, 0x60(%rsp)
cmpq %r15, %r12
je 0x24e6f
bsrq %rdx, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x583(%rip), %rcx      # 0x2477c
movq %r12, %rdi
movq %r15, %rsi
callq 0x10dc5
leaq 0x8(%r12), %r13
cmpq $0x81, %rbx
jl 0x24e0a
movq %r15, 0x20(%rsp)
movl $0x8, %r14d
movq %r13, %r15
movq %r12, %rbx
movq %rbx, %rcx
leaq (%r12,%r14), %rbx
movq (%r12,%r14), %rbp
movq (%r12), %rdx
movl (%rbp), %eax
cmpl (%rdx), %eax
jge 0x24d56
movq %r13, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x22b0
movq %r12, %rcx
jmp 0x24d79
movq (%rcx), %rdx
movq %rbx, %rcx
cmpl (%rdx), %eax
jge 0x24d79
movq %r15, %rdx
leaq -0x8(%rdx), %rcx
movq -0x10(%rdx), %rsi
movq -0x8(%rdx), %rdi
movq %rdi, (%rdx)
movq %rcx, %rdx
cmpl (%rsi), %eax
jl 0x24d63
movq %rbp, (%rcx)
addq $0x8, %r14
addq $0x8, %r15
cmpq $0x80, %r14
jne 0x24d2d
subq $-0x80, %r12
movq 0x20(%rsp), %r9
cmpq %r9, %r12
movq 0x40(%rsp), %rbp
je 0x24e6f
movq -0x8(%r12), %rsi
movq (%r12), %rax
movl (%rax), %ecx
movq %r12, %rdx
cmpl (%rsi), %ecx
jge 0x24dcf
movq %r12, %rsi
leaq -0x8(%rsi), %rdx
movq -0x10(%rsi), %rdi
movq -0x8(%rsi), %r8
movq %r8, (%rsi)
movq %rdx, %rsi
cmpl (%rdi), %ecx
jl 0x24db9
movq %rax, (%rdx)
addq $0x8, %r12
cmpq %r9, %r12
jne 0x24da4
jmp 0x24e6f
cmpb $0x1, 0x153ec(%rip)     # 0x3a1d3
jne 0x252a8
movq 0x151ec(%rip), %rax     # 0x39fe0
movq (%rax), %rdi
leaq 0xa810(%rip), %rsi      # 0x2f60e
xorl %eax, %eax
callq 0x2250
jmp 0x252a8
cmpq %r15, %r13
je 0x24e6f
movq %r12, %r14
movq %r14, %rdi
movq %r13, %r14
movq (%r13), %rbx
movq (%r12), %rcx
movl (%rbx), %eax
cmpl (%rcx), %eax
jge 0x24e40
movq %r14, %rdx
subq %r12, %rdx
subq %rdx, %rdi
addq $0x10, %rdi
movq %r12, %rsi
callq 0x22b0
movq %r12, %rcx
jmp 0x24e63
movq (%rdi), %rdx
movq %r14, %rcx
cmpl (%rdx), %eax
jge 0x24e63
movq %r14, %rdx
leaq -0x8(%rdx), %rcx
movq -0x10(%rdx), %rsi
movq -0x8(%rdx), %rdi
movq %rdi, (%rdx)
movq %rcx, %rdx
cmpl (%rsi), %eax
jl 0x24e4d
movq %rbx, (%rcx)
leaq 0x8(%r14), %r13
cmpq %r15, %r13
jne 0x24e12
movl $0x30, %edi
callq 0x2180
movq %rax, %r14
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rax, 0x10(%rsp)
movabsq $0x100000000, %rax      # imm = 0x100000000
movq %rax, (%r14)
movupd %xmm0, 0x10(%r14)
movl 0x4(%rsp), %ebx
movl %ebx, 0x8(%r14)
movq 0x38(%rsp), %r15
movsd (%r15), %xmm0
movsd %xmm0, 0x20(%r14)
movl $0x30, %edi
callq 0x2180
xorps %xmm0, %xmm0
movaps %xmm0, (%rax)
movaps %xmm0, 0x10(%rax)
movaps %xmm0, 0x20(%rax)
movq %rax, 0x48(%rsp)
movq 0x18(%rsp), %rcx
decl %ecx
movl %ecx, (%rax)
movl $0x1, 0x4(%rax)
movups %xmm0, 0x10(%rax)
movl %ebx, 0x8(%rax)
movq 0x80(%rsp), %rcx
movsd -0x8(%r15,%rcx,8), %xmm0
movsd %xmm0, 0x20(%rax)
movq (%rbp), %rcx
movq 0x8(%rbp), %rsi
cmpq %rcx, %rsi
je 0x2532f
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(%rbp), %rsi
je 0x24f47
movq %r14, (%rsi)
addq $0x8, 0x8(%rbp)
jmp 0x24f54
leaq 0x10(%rsp), %rdx
movq %rbp, %rdi
callq 0x2565e
movq 0x8(%rbp), %rsi
cmpq 0x10(%rbp), %rsi
je 0x24f6d
movq 0x48(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rbp)
jmp 0x24f7a
leaq 0x48(%rsp), %rdx
movq %rbp, %rdi
callq 0x2565e
movq (%rbp), %r14
movq 0x8(%rbp), %r15
cmpq %r15, %r14
je 0x250ed
movq %r15, %rbx
subq %r14, %rbx
movq %rbx, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x830(%rip), %rcx      # 0x2477c
movq %r14, %rdi
movq %r15, %rsi
callq 0x10dc5
leaq 0x8(%r14), %r12
cmpq $0x81, %rbx
jl 0x25086
movq %r15, 0x20(%rsp)
movl $0x8, %r15d
movq %r12, %r13
movq %r14, %rbx
movq %rbx, %rcx
leaq (%r14,%r15), %rbx
movq (%r14,%r15), %rbp
movq (%r14), %rdx
movl (%rbp), %eax
cmpl (%rdx), %eax
jge 0x25001
movq %r12, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x22b0
movq %r14, %rcx
jmp 0x25024
movq (%rcx), %rdx
movq %rbx, %rcx
cmpl (%rdx), %eax
jge 0x25024
movq %r13, %rdx
leaq -0x8(%rdx), %rcx
movq -0x10(%rdx), %rsi
movq -0x8(%rdx), %rdi
movq %rdi, (%rdx)
movq %rcx, %rdx
cmpl (%rsi), %eax
jl 0x2500e
movq %rbp, (%rcx)
addq $0x8, %r15
addq $0x8, %r13
cmpq $0x80, %r15
jne 0x24fd9
subq $-0x80, %r14
movq 0x20(%rsp), %r9
cmpq %r9, %r14
movq 0x40(%rsp), %rbp
je 0x250ed
movq -0x8(%r14), %rsi
movq (%r14), %rax
movl (%rax), %ecx
movq %r14, %rdx
cmpl (%rsi), %ecx
jge 0x25078
movq %r14, %rsi
leaq -0x8(%rsi), %rdx
movq -0x10(%rsi), %rdi
movq -0x8(%rsi), %r8
movq %r8, (%rsi)
movq %rdx, %rsi
cmpl (%rdi), %ecx
jl 0x25062
movq %rax, (%rdx)
addq $0x8, %r14
cmpq %r9, %r14
jne 0x2504f
jmp 0x250ed
cmpq %r15, %r12
je 0x250ed
movq %r15, %r13
movq %r14, %r15
movq %r15, %rdi
movq %r12, %r15
movq (%r12), %rbx
movq (%r14), %rcx
movl (%rbx), %eax
cmpl (%rcx), %eax
jge 0x250be
movq %r15, %rdx
subq %r14, %rdx
subq %rdx, %rdi
addq $0x10, %rdi
movq %r14, %rsi
callq 0x22b0
movq %r14, %rcx
jmp 0x250e1
movq (%rdi), %rdx
movq %r15, %rcx
cmpl (%rdx), %eax
jge 0x250e1
movq %r15, %rdx
leaq -0x8(%rdx), %rcx
movq -0x10(%rdx), %rsi
movq -0x8(%rdx), %rdi
movq %rdi, (%rdx)
movq %rcx, %rdx
cmpl (%rsi), %eax
jl 0x250cb
movq %rbx, (%rcx)
leaq 0x8(%r15), %r12
cmpq %r13, %r12
jne 0x25091
movq (%rbp), %rcx
movq 0x8(%rbp), %rdx
subq %rcx, %rdx
sarq $0x3, %rdx
testl %edx, %edx
movq 0x78(%rsp), %rbx
movq 0x70(%rsp), %r12
movq 0x68(%rsp), %r14
jle 0x251aa
movl %edx, %edi
andl $0x7fffffff, %edi       # imm = 0x7FFFFFFF
xorl %r8d, %r8d
xorl %eax, %eax
xorl %r9d, %r9d
testq %rax, %rax
je 0x25155
leaq -0x1(%rax), %rsi
cmpq %rsi, %rdx
jbe 0x2530a
cmpq %rax, %rdx
jbe 0x2531e
movq -0x8(%rcx,%rax,8), %r10
movq (%rcx,%rax,8), %r11
movl 0x4(%r10), %r10d
cmpl 0x4(%r11), %r10d
je 0x25313
cmpq %rdx, %rax
je 0x252f2
movq (%rcx,%rax,8), %rsi
cmpl 0x4(%rsi), %r8d
movl $0x0, %r10d
sbbl %r10d, %r10d
movl (%rsi), %r11d
cmpl %r11d, %r9d
jge 0x2518d
orl $0x1, %r10d
movslq %r9d, %r9
movl %r10d, (%r14,%r9,4)
incq %r9
movslq (%rsi), %r11
cmpq %r11, %r9
jl 0x2517e
movslq %r11d, %r9
movl $0x0, (%r14,%r9,4)
movl (%rsi), %r9d
incl %r9d
incq %rax
cmpq %rdi, %rax
jne 0x25123
cmpb $0x0, 0x15022(%rip)     # 0x3a1d3
jne 0x252ba
movq (%rbp), %rdx
movq 0x8(%rbp), %rax
subq %rdx, %rax
sarq $0x3, %rax
testl %eax, %eax
movq 0x8(%rsp), %rdi
jle 0x2524d
xorl %r15d, %r15d
xorl %r14d, %r14d
cmpq %r14, %rax
jbe 0x252e3
movq (%rdx,%r15), %rax
addq %r15, %rdx
cmpl $0x0, 0x4(%rax)
je 0x251ff
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x25216
movq %rax, (%rsi)
addq $0x8, 0x8(%rbx)
jmp 0x25228
movq 0x8(%r12), %rsi
cmpq 0x10(%r12), %rsi
je 0x2521b
movq %rax, (%rsi)
addq $0x8, 0x8(%r12)
jmp 0x25228
movq %rbx, %rdi
jmp 0x2521e
movq %r12, %rdi
callq 0x2565e
movq 0x8(%rsp), %rdi
incq %r14
movq (%rbp), %rdx
movq 0x8(%rbp), %rcx
subq %rdx, %rcx
movq %rcx, %rax
sarq $0x3, %rax
shrq $0x3, %rcx
movslq %ecx, %rcx
addq $0x8, %r15
cmpq %rcx, %r14
jl 0x251d5
callq 0x2220
movq 0x60(%rsp), %rbx
movq (%rbx), %rax
movq 0x8(%rbx), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
testl %edx, %edx
jle 0x252a8
xorl %r14d, %r14d
cmpq %r14, %rdx
jbe 0x252fe
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x25288
movl $0x8, %esi
callq 0x2190
incq %r14
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
subq %rax, %rcx
movq %rcx, %rdx
sarq $0x3, %rdx
shrq $0x3, %rcx
movslq %ecx, %rcx
cmpq %rcx, %r14
jl 0x2526c
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x14d1f(%rip), %rax     # 0x39fe0
movq (%rax), %rdi
leaq 0xa343(%rip), %rsi      # 0x2f60e
xorl %eax, %eax
callq 0x2250
jmp 0x251b7
leaq 0x85f8(%rip), %rdi      # 0x2d8d6
movq %r12, %rsi
jmp 0x25328
leaq 0x85ec(%rip), %rdi      # 0x2d8d6
movq %r14, %rsi
movq %rax, %rdx
jmp 0x25328
leaq 0x85dd(%rip), %rdi      # 0x2d8d6
movq %rdx, %rsi
jmp 0x25328
leaq 0x85d1(%rip), %rdi      # 0x2d8d6
movq %r14, %rsi
jmp 0x25328
leaq 0x85c5(%rip), %rdi      # 0x2d8d6
jmp 0x25328
movq %rbp, %rdi
movq %rax, %rdx
callq 0x56e2
leaq 0x85b1(%rip), %rdi      # 0x2d8d6
movq %rax, %rsi
xorl %eax, %eax
callq 0x2270
leaq 0x85a0(%rip), %rdi      # 0x2d8d6
xorl %esi, %esi
xorl %edx, %edx
jmp 0x25328