// File: /workspace/github_cpp_makefile_star2_O2/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, 0x30(%rsp)
movl %r9d, 0xc(%rsp)
movq %r8, %rbp
movq %rcx, %r14
movq %rdx, 0x50(%rsp)
movl %esi, %r13d
movq %rdi, %r15
pushq $0x18
popq %rdi
callq 0x2170
movq %rax, %rbx
leal 0x2(%r13), %eax
shlq $0x3, %rax
cmpl $-0x2, %r13d
pushq $-0x1
popq %rdi
cmovgeq %rax, %rdi
xorpd %xmm0, %xmm0
movupd %xmm0, (%rbx)
andq $0x0, 0x10(%rbx)
callq 0x2040
andq $0x0, (%rax)
xorl %edx, %edx
testl %r13d, %r13d
movl $0x0, %ecx
cmovgl %r13d, %ecx
cmpq %rdx, %rcx
je 0x1eb1e
movsd 0x8(%r15,%rdx,8), %xmm0
subsd (%r15,%rdx,8), %xmm0
movsd %xmm0, 0x8(%rax,%rdx,8)
incq %rdx
jmp 0x1eb01
movq %r15, 0x18(%rsp)
movq %r14, 0x58(%rsp)
movq %rax, 0x10(%rsp)
pushq $0x18
popq %rdi
callq 0x2170
movq 0x10(%rsp), %rcx
movslq %r13d, %r15
leal 0x1(%r13), %edx
movl %edx, 0x20(%rsp)
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq %rax, 0x48(%rsp)
andq $0x0, 0x10(%rax)
pushq $0x1
popq %r12
movapd 0x7e7d(%rip), %xmm2     # 0x269e0
movapd 0x30(%rsp), %xmm1
movq %r13, 0x68(%rsp)
cmpl %r13d, %r12d
jg 0x1ebfc
movslq %r12d, %r14
movsd (%rcx,%r14,8), %xmm0
andpd %xmm2, %xmm0
ucomisd %xmm0, %xmm1
jbe 0x1ebb0
movl %r12d, %eax
movl %eax, %r13d
cmpq %r15, %r14
jg 0x1ebb5
movl %r14d, %eax
movsd (%rcx,%r14,8), %xmm0
andpd %xmm2, %xmm0
incq %r14
ucomisd %xmm0, %xmm1
ja 0x1eb8d
decl %r14d
jmp 0x1ebbc
incl %r12d
jmp 0x1eb6e
movl 0x20(%rsp), %eax
movl %eax, %r14d
pushq $0x8
popq %rdi
callq 0x2170
movq %rax, (%rsp)
movl %r12d, (%rax)
movl %r13d, 0x4(%rax)
movq 0x48(%rsp), %rdi
movq %rsp, %rsi
callq 0x1f37c
movl %r14d, %r12d
movq 0x10(%rsp), %rcx
movq 0x68(%rsp), %r13
movapd 0x30(%rsp), %xmm1
movapd 0x7de9(%rip), %xmm2     # 0x269e0
jmp 0x1eb6e
xorl %r14d, %r14d
movq 0x48(%rsp), %r12
movq 0x8(%r12), %rax
subq (%r12), %rax
shrq $0x3, %rax
cltq
cmpq %rax, %r14
jge 0x1ee40
movq %r12, %rdi
movq %r14, %rsi
callq 0x1f39a
movq (%rax), %rax
cmpl $0x2, (%rax)
jl 0x1ed23
movq %r12, %rdi
movq %r14, %rsi
callq 0x1f39a
movq (%rax), %rax
movl 0x4(%rax), %eax
incl %eax
cmpl %r13d, %eax
jge 0x1ed23
movq %r12, %rdi
movq %r14, %rsi
callq 0x1f39a
movq (%rax), %rax
movslq (%rax), %rax
movq 0x10(%rsp), %rcx
movsd -0x8(%rcx,%rax,8), %xmm0
ucomisd 0x543d(%rip), %xmm0     # 0x240b0
jbe 0x1ed23
movq %r12, %rdi
movq %r14, %rsi
callq 0x1f39a
movq (%rax), %rax
movslq 0x4(%rax), %rax
movq 0x10(%rsp), %rcx
xorpd %xmm0, %xmm0
ucomisd 0x8(%rcx,%rax,8), %xmm0
jbe 0x1ed23
pushq $0x30
popq %rdi
callq 0x2170
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rax, (%rsp)
movq %r12, %rdi
movq %r14, %rsi
callq 0x1f39a
movq (%rax), %rax
movl (%rax), %eax
movl %eax, 0x20(%rsp)
movq %r12, %rdi
movq %r14, %rsi
callq 0x1f39a
movq (%rax), %rcx
movl 0x20(%rsp), %eax
addl 0x4(%rcx), %eax
cltd
pushq $0x2
popq %rcx
idivl %ecx
movq (%rsp), %rcx
movl %eax, (%rcx)
andl $0x0, 0x4(%rcx)
xorpd %xmm0, %xmm0
movupd %xmm0, 0x10(%rcx)
movl 0xc(%rsp), %edx
movl %edx, 0x8(%rcx)
cltq
movq 0x18(%rsp), %rdx
movsd (%rdx,%rax,8), %xmm0
movsd %xmm0, 0x20(%rcx)
movq %rbx, %rdi
movq %rsp, %rsi
callq 0x1f35e
movq %r12, %rdi
movq %r14, %rsi
callq 0x1f39a
movq (%rax), %rax
cmpl $0x2, (%rax)
jl 0x1ee2d
movq %r12, %rdi
movq %r14, %rsi
callq 0x1f39a
movq (%rax), %rax
movl 0x4(%rax), %eax
incl %eax
cmpl %r13d, %eax
jge 0x1ee2d
movq %r12, %rdi
movq %r14, %rsi
callq 0x1f39a
movq (%rax), %rax
movslq (%rax), %rax
movq 0x10(%rsp), %rcx
xorpd %xmm0, %xmm0
ucomisd -0x8(%rcx,%rax,8), %xmm0
jbe 0x1ee2d
movq %r12, %rdi
movq %r14, %rsi
callq 0x1f39a
movq (%rax), %rax
movslq 0x4(%rax), %rax
movq 0x10(%rsp), %rcx
movsd 0x8(%rcx,%rax,8), %xmm0
ucomisd 0x530f(%rip), %xmm0     # 0x240b0
jbe 0x1ee2d
pushq $0x30
popq %rdi
callq 0x2170
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rax, (%rsp)
movq %r12, %rdi
movq %r14, %rsi
callq 0x1f39a
movq (%rax), %rax
movl (%rax), %eax
movl %eax, 0x20(%rsp)
movq %r12, %rdi
movq %r14, %rsi
callq 0x1f39a
movq (%rax), %rcx
movl 0x20(%rsp), %eax
addl 0x4(%rcx), %eax
cltd
pushq $0x2
popq %rcx
idivl %ecx
movq (%rsp), %rcx
movl %eax, (%rcx)
movl $0x1, 0x4(%rcx)
xorpd %xmm0, %xmm0
movupd %xmm0, 0x10(%rcx)
movl 0xc(%rsp), %edx
movl %edx, 0x8(%rcx)
cltq
movq 0x18(%rsp), %rdx
movsd (%rdx,%rax,8), %xmm0
movsd %xmm0, 0x20(%rcx)
movq %rbx, %rdi
movq %rsp, %rsi
callq 0x1f35e
incq %r14
movq 0x10(%rsp), %rcx
movapd 0x30(%rsp), %xmm1
jmp 0x1ec04
movapd 0x92a8(%rip), %xmm2     # 0x280f0
xorpd %xmm1, %xmm2
pushq $0x1
popq %r14
pushq $0x2
popq %r12
movapd %xmm2, 0x20(%rsp)
cmpq %r15, %r14
jge 0x1ef65
cmpl %r13d, %r12d
jge 0x1ef5a
movsd -0x8(%rcx,%r12,8), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1eee7
ucomisd (%rcx,%r12,8), %xmm2
jbe 0x1eee7
pushq $0x30
popq %rdi
movsd %xmm0, 0x60(%rsp)
callq 0x2170
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rax, (%rsp)
movl %r14d, (%rax)
movupd %xmm0, 0x10(%rax)
movl 0xc(%rsp), %ecx
movl %ecx, 0x8(%rax)
movq 0x18(%rsp), %rcx
movsd -0x8(%rcx,%r12,8), %xmm0
movsd %xmm0, 0x20(%rax)
movq %rbx, %rdi
movq %rsp, %rsi
callq 0x1f35e
movsd 0x60(%rsp), %xmm0
movapd 0x20(%rsp), %xmm2
movapd 0x30(%rsp), %xmm1
movq 0x10(%rsp), %rcx
ucomisd %xmm0, %xmm2
jbe 0x1ef5a
movsd (%rcx,%r12,8), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1ef5a
pushq $0x30
popq %rdi
callq 0x2170
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rax, (%rsp)
movl %r14d, (%rax)
movl $0x1, 0x4(%rax)
movupd %xmm0, 0x10(%rax)
movl 0xc(%rsp), %ecx
movl %ecx, 0x8(%rax)
movq 0x18(%rsp), %rcx
movsd -0x8(%rcx,%r12,8), %xmm0
movsd %xmm0, 0x20(%rax)
movq %rbx, %rdi
movq %rsp, %rsi
callq 0x1f35e
movapd 0x20(%rsp), %xmm2
movapd 0x30(%rsp), %xmm1
movq 0x10(%rsp), %rcx
incq %r12
incq %r14
jmp 0x1ee5a
movq (%rbx), %rdi
movq 0x8(%rbx), %rsi
movq %rsi, %rdx
subq %rdi, %rdx
movabsq $0x7fffffff0, %rax      # imm = 0x7FFFFFFF0
testq %rax, %rdx
je 0x1f1ea
leaq -0x50f(%rip), %rdx      # 0x1ea7d
callq 0xd2d0
pushq $0x30
popq %r14
movq %r14, %rdi
callq 0x2170
movq %rax, 0x30(%rsp)
xorpd %xmm0, %xmm0
movapd %xmm0, (%rax)
movapd %xmm0, 0x10(%rax)
movapd %xmm0, 0x20(%rax)
movq %rsp, %rcx
movq %rax, (%rcx)
pushq $0x1
popq %rcx
movl %ecx, 0x4(%rax)
movupd %xmm0, 0x10(%rax)
movl 0xc(%rsp), %ecx
movl %ecx, 0x8(%rax)
movq 0x18(%rsp), %r12
movsd (%r12), %xmm0
movsd %xmm0, 0x20(%rax)
movq %r14, %rdi
callq 0x2170
movq %rax, %r14
xorps %xmm0, %xmm0
movaps %xmm0, (%rax)
movaps %xmm0, 0x10(%rax)
movaps %xmm0, 0x20(%rax)
leaq 0x70(%rsp), %rax
movq %r14, (%rax)
decl %r13d
movl %r13d, (%r14)
pushq $0x1
popq %rax
movl %eax, 0x4(%r14)
movups %xmm0, 0x10(%r14)
movl 0xc(%rsp), %eax
movl %eax, 0x8(%r14)
movsd -0x8(%r12,%r15,8), %xmm0
movsd %xmm0, 0x20(%r14)
movq %rbx, %rdi
xorl %esi, %esi
callq 0xcfc8
movq (%rax), %rax
xorl %ecx, %ecx
cmpl $0x0, 0x4(%rax)
sete %cl
movq 0x30(%rsp), %rax
movl %ecx, 0x4(%rax)
movq 0x8(%rbx), %rax
movq -0x8(%rax), %rax
xorl %ecx, %ecx
cmpl $0x0, 0x4(%rax)
sete %cl
movl %ecx, 0x4(%r14)
movq %rbx, %rdi
movq %rsp, %rsi
callq 0x1f35e
movq %rbx, %rdi
leaq 0x70(%rsp), %rsi
callq 0x1f35e
movq (%rbx), %rdi
movq 0x8(%rbx), %rsi
leaq -0x600(%rip), %rdx      # 0x1ea7d
callq 0xd2d0
xorl %r14d, %r14d
xorl %r12d, %r12d
movq 0x8(%rbx), %rdx
subq (%rbx), %rdx
shrq $0x3, %rdx
movslq %edx, %rax
cmpq %rax, %r14
jge 0x1f147
testq %r14, %r14
je 0x1f0d2
leaq -0x1(%r14), %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0xcfc8
movq (%rax), %rax
movl 0x4(%rax), %r13d
movq %rbx, %rdi
movq %r14, %rsi
callq 0xcfc8
movq (%rax), %rax
cmpl 0x4(%rax), %r13d
je 0x1f23d
movq %rbx, %rdi
movq %r14, %rsi
callq 0xcfc8
movq (%rax), %rax
xorl %ecx, %ecx
cmpl 0x4(%rax), %ecx
movl $0x0, %r15d
sbbl %r15d, %r15d
orl $0x1, %r15d
movslq %r12d, %r12
movq %rbx, %rdi
movq %r14, %rsi
callq 0xcfc8
movq (%rax), %rax
movslq (%rax), %rax
cmpq %rax, %r12
jge 0x1f115
movl %r15d, (%rbp,%r12,4)
incq %r12
jmp 0x1f0f5
movq %rbx, %rdi
movq %r14, %rsi
callq 0xcfc8
movq (%rax), %rax
movslq (%rax), %rax
andl $0x0, (%rbp,%rax,4)
movq %rbx, %rdi
movq %r14, %rsi
callq 0xcfc8
movq (%rax), %rax
movl (%rax), %r12d
incl %r12d
incq %r14
jmp 0x1f088
cmpb $0x0, 0x1607d(%rip)     # 0x351cb
jne 0x1f202
xorl %r14d, %r14d
movq 0x58(%rsp), %r12
movq 0x50(%rsp), %r13
movq 0x8(%rbx), %rax
subq (%rbx), %rax
shrq $0x3, %rax
cltq
cmpq %rax, %r14
jge 0x1f1a8
movq %rbx, %rdi
movq %r14, %rsi
callq 0xcfc8
movq (%rax), %rax
cmpl $0x0, 0x4(%rax)
movq %r13, %r15
je 0x1f18d
movq %r12, %r15
movq %rbx, %rdi
movq %r14, %rsi
callq 0xcfc8
movq %r15, %rdi
movq %rax, %rsi
callq 0x1f35e
incq %r14
jmp 0x1f161
movq 0x10(%rsp), %rdi
callq 0x2210
xorl %ebx, %ebx
pushq $0x8
popq %r14
movq 0x48(%rsp), %r15
movq 0x8(%r15), %rax
subq (%r15), %rax
shrq $0x3, %rax
cltq
cmpq %rax, %rbx
jge 0x1f1f3
movq %r15, %rdi
movq %rbx, %rsi
callq 0x1f39a
movq (%rax), %rdi
movq %r14, %rsi
callq 0x2180
incq %rbx
jmp 0x1f1bd
cmpb $0x1, 0x15fda(%rip)     # 0x351cb
je 0x1f21f
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x15dd7(%rip), %rax     # 0x34fe0
movq (%rax), %rdi
leaq 0x93fb(%rip), %rsi      # 0x2860e
xorl %eax, %eax
callq 0x2240
jmp 0x1f154
shrq $0x3, %rdx
movq 0x15db6(%rip), %rax     # 0x34fe0
movq (%rax), %rdi
leaq 0x93da(%rip), %rsi      # 0x2860e
xorl %eax, %eax
callq 0x2240
jmp 0x1f1f3
movq 0x15d9c(%rip), %rax     # 0x34fe0
movq (%rax), %r12
movq %rbx, %rdi
movq %r15, %rsi
callq 0xcfc8
movq (%rax), %rax
movl (%rax), %ebp
movq %rbx, %rdi
movq %r14, %rsi
callq 0xcfc8
movq (%rax), %rax
movl (%rax), %r15d
movq %rbx, %rdi
movq %r14, %rsi
callq 0xcfc8
movq (%rax), %rax
movl 0x4(%rax), %r8d
leaq 0x9367(%rip), %rsi      # 0x285e8
movq %r12, %rdi
movl %ebp, %edx
movl %r15d, %ecx
xorl %eax, %eax
callq 0x2240
xorl %edi, %edi
callq 0x21d0