// File: /workspace/github_cpp_makefile_star2_O2/rossy[P]crossc/SPIRV-Cross/spirv_glsl.cpp
// Function: spirv_cross::CompilerGLSL::emit_block_chain(spirv_cross::SPIRBlock&)
void CompilerGLSL::emit_block_chain(SPIRBlock &block)
{
	propagate_loop_dominators(block);

	bool select_branch_to_true_block = false;
	bool skip_direct_branch = false;
	bool emitted_for_loop_header = false;
	bool force_complex_continue_block = false;

	emit_hoisted_temporaries(block.declare_temporary);

	SPIRBlock::ContinueBlockType continue_type = SPIRBlock::ContinueNone;
	if (block.continue_block)
		continue_type = continue_block_type(get<SPIRBlock>(block.continue_block));

	// If we have loop variables, stop masking out access to the variable now.
	for (auto var : block.loop_variables)
		get<SPIRVariable>(var).loop_variable_enable = true;

	// This is the method often used by spirv-opt to implement loops.
	// The loop header goes straight into the continue block.
	// However, don't attempt this on ESSL 1.0, because if a loop variable is used in a continue block,
	// it *MUST* be used in the continue block. This loop method will not work.
	if (!is_legacy_es() && block_is_loop_candidate(block, SPIRBlock::MergeToSelectContinueForLoop))
	{
		flush_undeclared_variables(block);
		if (attempt_emit_loop_header(block, SPIRBlock::MergeToSelectContinueForLoop))
		{
			select_branch_to_true_block = true;
			emitted_for_loop_header = true;
			force_complex_continue_block = true;
		}
	}
	// This is the older loop behavior in glslang which branches to loop body directly from the loop header.
	else if (block_is_loop_candidate(block, SPIRBlock::MergeToSelectForLoop))
	{
		flush_undeclared_variables(block);
		if (attempt_emit_loop_header(block, SPIRBlock::MergeToSelectForLoop))
		{
			// The body of while, is actually just the true block, so always branch there unconditionally.
			select_branch_to_true_block = true;
			emitted_for_loop_header = true;
		}
	}
	// This is the newer loop behavior in glslang which branches from Loop header directly to
	// a new block, which in turn has a OpBranchSelection without a selection merge.
	else if (block_is_loop_candidate(block, SPIRBlock::MergeToDirectForLoop))
	{
		flush_undeclared_variables(block);
		if (attempt_emit_loop_header(block, SPIRBlock::MergeToDirectForLoop))
		{
			skip_direct_branch = true;
			emitted_for_loop_header = true;
		}
	}
	else if (continue_type == SPIRBlock::DoWhileLoop)
	{
		flush_undeclared_variables(block);
		emit_while_loop_initializers(block);
		// We have some temporaries where the loop header is the dominator.
		// We risk a case where we have code like:
		// for (;;) { create-temporary; break; } consume-temporary;
		// so force-declare temporaries here.
		emit_hoisted_temporaries(block.potential_declare_temporary);
		statement("do");
		begin_scope();

		emit_block_instructions(block);
	}
	else if (block.merge == SPIRBlock::MergeLoop)
	{
		flush_undeclared_variables(block);
		emit_while_loop_initializers(block);

		// We have a generic loop without any distinguishable pattern like for, while or do while.
		get<SPIRBlock>(block.continue_block).complex_continue = true;
		continue_type = SPIRBlock::ComplexLoop;

		// We have some temporaries where the loop header is the dominator.
		// We risk a case where we have code like:
		// for (;;) { create-temporary; break; } consume-temporary;
		// so force-declare temporaries here.
		emit_hoisted_temporaries(block.potential_declare_temporary);
		statement("for (;;)");
		begin_scope();

		emit_block_instructions(block);
	}
	else
	{
		emit_block_instructions(block);
	}

	// If we didn't successfully emit a loop header and we had loop variable candidates, we have a problem
	// as writes to said loop variables might have been masked out, we need a recompile.
	if (!emitted_for_loop_header && !block.loop_variables.empty())
	{
		force_recompile = true;
		for (auto var : block.loop_variables)
			get<SPIRVariable>(var).loop_variable = false;
		block.loop_variables.clear();
	}

	flush_undeclared_variables(block);
	bool emit_next_block = true;

	// Handle end of block.
	switch (block.terminator)
	{
	case SPIRBlock::Direct:
		// True when emitting complex continue block.
		if (block.loop_dominator == block.next_block)
		{
			branch(block.self, block.next_block);
			emit_next_block = false;
		}
		// True if MergeToDirectForLoop succeeded.
		else if (skip_direct_branch)
			emit_next_block = false;
		else if (is_continue(block.next_block) || is_break(block.next_block) || is_conditional(block.next_block))
		{
			branch(block.self, block.next_block);
			emit_next_block = false;
		}
		break;

	case SPIRBlock::Select:
		// True if MergeToSelectForLoop or MergeToSelectContinueForLoop succeeded.
		if (select_branch_to_true_block)
		{
			if (force_complex_continue_block)
			{
				assert(block.true_block == block.continue_block);

				// We're going to emit a continue block directly here, so make sure it's marked as complex.
				auto &complex_continue = get<SPIRBlock>(block.continue_block).complex_continue;
				bool old_complex = complex_continue;
				complex_continue = true;
				branch(block.self, block.true_block);
				complex_continue = old_complex;
			}
			else
				branch(block.self, block.true_block);
		}
		else
			branch(block.self, block.condition, block.true_block, block.false_block);
		break;

	case SPIRBlock::MultiSelect:
	{
		auto &type = expression_type(block.condition);
		bool uint32_t_case = type.basetype == SPIRType::UInt;

		SPIRBlock *old_emitting_switch = current_emitting_switch;
		current_emitting_switch = &block;

		if (block.need_ladder_break)
			statement("bool _", block.self, "_ladder_break = false;");

		emit_block_hints(block);
		statement("switch (", to_expression(block.condition), ")");
		begin_scope();

		// Multiple case labels can branch to same block, so find all unique blocks.
		bool emitted_default = false;
		unordered_set<uint32_t> emitted_blocks;

		for (auto &c : block.cases)
		{
			if (emitted_blocks.count(c.block) != 0)
				continue;

			// Emit all case labels which branch to our target.
			// FIXME: O(n^2), revisit if we hit shaders with 100++ case labels ...
			for (auto &other_case : block.cases)
			{
				if (other_case.block == c.block)
				{
					auto case_value = uint32_t_case ? convert_to_string(uint32_t(other_case.value)) :
					                                  convert_to_string(int32_t(other_case.value));
					statement("case ", case_value, ":");
				}
			}

			// Maybe we share with default block?
			if (block.default_block == c.block)
			{
				statement("default:");
				emitted_default = true;
			}

			// Complete the target.
			emitted_blocks.insert(c.block);

			begin_scope();
			branch(block.self, c.block);
			end_scope();
		}

		if (!emitted_default)
		{
			if (block.default_block != block.next_block)
			{
				statement("default:");
				begin_scope();
				if (is_break(block.default_block))
					SPIRV_CROSS_THROW("Cannot break; out of a switch statement and out of a loop at the same time ...");
				branch(block.self, block.default_block);
				end_scope();
			}
			else if (flush_phi_required(block.self, block.next_block))
			{
				statement("default:");
				begin_scope();
				flush_phi(block.self, block.next_block);
				statement("break;");
				end_scope();
			}
		}

		end_scope();

		if (block.need_ladder_break)
		{
			statement("if (_", block.self, "_ladder_break)");
			begin_scope();
			statement("break;");
			end_scope();
		}

		current_emitting_switch = old_emitting_switch;
		break;
	}

	case SPIRBlock::Return:
		for (auto &line : current_function->fixup_hooks_out)
			line();

		if (processing_entry_point)
			emit_fixup();

		if (block.return_value)
		{
			auto &type = expression_type(block.return_value);
			if (!type.array.empty() && !backend.can_return_array)
			{
				// If we cannot return arrays, we will have a special out argument we can write to instead.
				// The backend is responsible for setting this up, and redirection the return values as appropriate.
				if (ir.ids.at(block.return_value).get_type() != TypeUndef)
					emit_array_copy("SPIRV_Cross_return_value", block.return_value);

				if (!block_is_outside_flow_control_from_block(get<SPIRBlock>(current_function->entry_block), block) ||
				    block.loop_dominator != SPIRBlock::NoDominator)
				{
					statement("return;");
				}
			}
			else
			{
				// OpReturnValue can return Undef, so don't emit anything for this case.
				if (ir.ids.at(block.return_value).get_type() != TypeUndef)
					statement("return ", to_expression(block.return_value), ";");
			}
		}
		// If this block is the very final block and not called from control flow,
		// we do not need an explicit return which looks out of place. Just end the function here.
		// In the very weird case of for(;;) { return; } executing return is unconditional,
		// but we actually need a return here ...
		else if (!block_is_outside_flow_control_from_block(get<SPIRBlock>(current_function->entry_block), block) ||
		         block.loop_dominator != SPIRBlock::NoDominator)
		{
			statement("return;");
		}
		break;

	case SPIRBlock::Kill:
		statement(backend.discard_literal, ";");
		break;

	case SPIRBlock::Unreachable:
		emit_next_block = false;
		break;

	default:
		SPIRV_CROSS_THROW("Unimplemented block terminator.");
	}

	if (block.next_block && emit_next_block)
	{
		// If we hit this case, we're dealing with an unconditional branch, which means we will output
		// that block after this. If we had selection merge, we already flushed phi variables.
		if (block.merge != SPIRBlock::MergeSelection)
			flush_phi(block.self, block.next_block);

		// For merge selects we might have ignored the fact that a merge target
		// could have been a break; or continue;
		// We will need to deal with it here.
		if (is_loop_break(block.next_block))
		{
			// Cannot check for just break, because switch statements will also use break.
			assert(block.merge == SPIRBlock::MergeSelection);
			statement("break;");
		}
		else if (is_continue(block.next_block))
		{
			assert(block.merge == SPIRBlock::MergeSelection);
			branch_to_continue(block.self, block.next_block);
		}
		else
			emit_block_chain(get<SPIRBlock>(block.next_block));
	}

	if (block.merge == SPIRBlock::MergeLoop)
	{
		if (continue_type == SPIRBlock::DoWhileLoop)
		{
			// Make sure that we run the continue block to get the expressions set, but this
			// should become an empty string.
			// We have no fallbacks if we cannot forward everything to temporaries ...
			auto statements = emit_continue_block(block.continue_block);
			if (!statements.empty())
			{
				// The DoWhile block has side effects, force ComplexLoop pattern next pass.
				get<SPIRBlock>(block.continue_block).complex_continue = true;
				force_recompile = true;
			}

			end_scope_decl(join("while (", to_expression(get<SPIRBlock>(block.continue_block).condition), ")"));
		}
		else
			end_scope();

		// We cannot break out of two loops at once, so don't check for break; here.
		// Using block.self as the "from" block isn't quite right, but it has the same scope
		// and dominance structure, so it's fine.
		if (is_continue(block.merge_block))
			branch_to_continue(block.self, block.merge_block);
		else
			emit_block_chain(get<SPIRBlock>(block.merge_block));
	}

	// Forget about control dependent expressions now.
	block.invalidate_expressions.clear();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %rsi, %r15
movq %rdi, %r13
callq 0x3fc56
leaq 0x68(%r15), %rsi
movq %r13, %rdi
callq 0x408ce
movl 0x20(%r15), %esi
testl %esi, %esi
je 0x3eb30
movq %r13, %rdi
callq 0x6bf0
movq %r13, %rdi
movq %rax, %rsi
callq 0x12510
movl %eax, %r12d
jmp 0x3eb33
xorl %r12d, %r12d
movq 0xd0(%r15), %rbx
movq 0xd8(%r15), %r14
cmpq %r14, %rbx
je 0x3eb5a
movl (%rbx), %esi
movq %r13, %rdi
callq 0x9c0e
movb $0x1, 0x65(%rax)
addq $0x4, %rbx
jmp 0x3eb41
cmpb $0x1, 0x43c(%r13)
jne 0x3eb71
cmpl $0x12c, 0x438(%r13) # imm = 0x12C
jb 0x3ebb1
pushq $0x2
popq %rdx
movq %r13, %rdi
movq %r15, %rsi
callq 0x121c6
testb %al, %al
je 0x3ebb1
movq %r13, %rdi
movq %r15, %rsi
callq 0x4081e
pushq $0x2
popq %rdx
movq %r13, %rdi
movq %r15, %rsi
callq 0x4039e
testb %al, %al
je 0x3eccb
movb $0x1, %bpl
xorl %ebx, %ebx
movb $0x1, %r14b
jmp 0x3ed1d
movq %r13, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x121c6
testb %al, %al
je 0x3ebec
movq %r13, %rdi
movq %r15, %rsi
callq 0x4081e
xorl %ebx, %ebx
movq %r13, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x4039e
testb %al, %al
je 0x3eccb
movb $0x1, %bpl
jmp 0x3ed1a
pushq $0x1
popq %rdx
movq %r13, %rdi
movq %r15, %rsi
callq 0x121c6
testb %al, %al
je 0x3ec28
movq %r13, %rdi
movq %r15, %rsi
callq 0x4081e
pushq $0x1
popq %rdx
movq %r13, %rdi
movq %r15, %rsi
callq 0x4039e
testb %al, %al
je 0x3eccb
movb $0x1, %bl
xorl %ebp, %ebp
jmp 0x3ed1a
cmpl $0x3, %r12d
jne 0x3ec66
movq %r13, %rdi
movq %r15, %rsi
callq 0x4081e
movq %r13, %rdi
movq %r15, %rsi
callq 0x3fe8e
leaq 0x80(%r15), %rsi
movq %r13, %rdi
callq 0x408ce
leaq 0x53be4(%rip), %rsi     # 0x9283e
movq %r13, %rdi
callq 0x475c4
pushq $0x3
jmp 0x3ecb6
cmpl $0x1, 0x10(%r15)
jne 0x3ecc0
movq %r13, %rdi
movq %r15, %rsi
callq 0x4081e
movq %r13, %rdi
movq %r15, %rsi
callq 0x3fe8e
movl 0x20(%r15), %esi
movq %r13, %rdi
callq 0x6bf0
movb $0x1, 0xb1(%rax)
leaq 0x80(%r15), %rsi
movq %r13, %rdi
callq 0x408ce
leaq 0x56d8f(%rip), %rsi     # 0x95a3b
movq %r13, %rdi
callq 0x47680
pushq $0x4
popq %r12
movq %r13, %rdi
callq 0x22d28
movq %r13, %rdi
movq %r15, %rsi
callq 0x3746c
movq 0xd0(%r15), %rbx
movq 0xd8(%r15), %r14
cmpq %r14, %rbx
je 0x3ed16
movb $0x1, 0x1d0(%r13)
cmpq %r14, %rbx
je 0x3ecff
movl (%rbx), %esi
movq %r13, %rdi
callq 0x9c0e
movb $0x0, 0x64(%rax)
addq $0x4, %rbx
jmp 0x3ece6
movq 0xd0(%r15), %rax
cmpq %rax, 0xd8(%r15)
je 0x3ed16
movq %rax, 0xd8(%r15)
xorl %ebp, %ebp
xorl %ebx, %ebx
xorl %r14d, %r14d
movq %r13, %rdi
movq %r15, %rsi
callq 0x4081e
movl 0xc(%r15), %eax
decl %eax
cmpl $0x5, %eax
ja 0x3f44c
leaq 0x525c2(%rip), %rcx     # 0x91300
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl 0x18(%r15), %edx
movl 0xb4(%r15), %eax
cmpl %edx, %eax
jne 0x3f11c
movl 0x8(%r15), %esi
movq %r13, %rdi
movl %eax, %edx
jmp 0x3f13c
movq %r15, %r14
movq 0x148(%r13), %rax
movq 0x98(%rax), %r15
movq 0xa0(%rax), %rbx
cmpq %rbx, %r15
je 0x3ed93
movq %r15, %rdi
callq 0x46c38
addq $0x20, %r15
jmp 0x3ed80
cmpb $0x0, 0x5d8(%r13)
je 0x3edaa
movq (%r13), %rax
movq %r13, %rdi
callq *0xc0(%rax)
movq %r14, %r15
movl 0x24(%r14), %esi
testl %esi, %esi
je 0x3f24e
movq %r13, %rdi
callq 0x104b0
movq 0x20(%rax), %rcx
cmpq 0x28(%rax), %rcx
je 0x3edd9
cmpb $0x0, 0x62e(%r13)
je 0x3f205
leaq 0x20(%r13), %rdi
movl 0x24(%r15), %esi
callq 0x7584
cmpl $0xd, 0x8(%rax)
je 0x3f28b
movl 0x24(%r15), %edx
leaq 0x18(%rsp), %r15
movq %r15, %rdi
movq %r13, %rsi
callq 0x2b9f0
leaq 0x56d5b(%rip), %rsi     # 0x95b66
leaq 0x5ac6f(%rip), %rcx     # 0x99a81
movq %r13, %rdi
movq %r15, %rdx
callq 0x474ea
leaq 0x18(%rsp), %rdi
callq 0x6548
jmp 0x3ee7b
testb %bpl, %bpl
je 0x3f0ff
testb %r14b, %r14b
je 0x3f146
movl 0x2c(%r15), %esi
cmpl 0x20(%r15), %esi
jne 0x3f4b9
movq %r15, %r14
movq %r13, %rdi
callq 0x6bf0
movq %rax, %r15
movb 0xb1(%rax), %bl
movb $0x1, 0xb1(%rax)
movl 0x8(%r14), %esi
movl 0x2c(%r14), %edx
movq %r13, %rdi
callq 0x3f8dc
movb %bl, 0xb1(%r15)
movq %r14, %r15
jmp 0x3f28b
movl %r12d, 0x10(%rsp)
movl 0x28(%r15), %esi
movq %r13, %rdi
callq 0x104b0
movl 0xc(%rax), %eax
movl %eax, 0x14(%rsp)
movq 0x418(%r13), %rax
movq %rax, 0x70(%rsp)
movq %r15, 0x418(%r13)
cmpb $0x1, 0xb2(%r15)
jne 0x3eed2
leaq 0x8(%r15), %rdx
leaq 0x56be8(%rip), %rsi     # 0x95aab
leaq 0x56be8(%rip), %rcx     # 0x95ab2
movq %r13, %rdi
callq 0x4773c
movq (%r13), %rax
movq %r13, %rdi
movq %r15, %rsi
callq *0x158(%rax)
movl 0x28(%r15), %edx
movq %r15, %r12
leaq 0x18(%rsp), %r15
movq %r15, %rdi
movq %r13, %rsi
callq 0x2b9f0
leaq 0x56bc9(%rip), %rsi     # 0x95ac9
leaq 0x56aee(%rip), %rcx     # 0x959f5
movq %r13, %rdi
movq %r15, %rdx
callq 0x47816
leaq 0x18(%rsp), %r14
movq %r14, %rdi
callq 0x6548
movq %r13, %rdi
callq 0x22d28
leaq 0x48(%rsp), %rax
movq %rax, -0x30(%rax)
movq $0x1, -0x28(%rax)
xorps %xmm0, %xmm0
movups %xmm0, -0x20(%rax)
movl $0x3f800000, -0x10(%rax) # imm = 0x3F800000
movups %xmm0, -0x8(%rax)
movq 0x98(%r12), %rcx
movq 0xa0(%r12), %rax
movq %rax, 0x80(%rsp)
leaq 0x8(%r12), %rax
movq %rax, 0x8(%rsp)
movl $0x0, 0x4(%rsp)
leaq 0x50(%rsp), %rbp
movq %r12, %r15
movq %r12, 0x78(%rsp)
cmpq 0x80(%rsp), %rcx
je 0x3f08f
movq %rcx, %rbx
leaq 0x4(%rcx), %r12
movq %r14, %rdi
movq %r12, %rsi
callq 0x1aeea
testq %rax, %rax
jne 0x3f068
movq %r13, %r14
movq 0x98(%r15), %r13
movq 0xa0(%r15), %r15
cmpq %r15, %r13
je 0x3f00e
movl 0x4(%r13), %eax
cmpl (%r12), %eax
jne 0x3f008
movl (%r13), %esi
cmpl $0x5, 0x14(%rsp)
jne 0x3efdf
movq %rbp, %rdi
callq 0x1c182
jmp 0x3efe7
movq %rbp, %rdi
callq 0x4a613
movq %r14, %rdi
leaq 0x56ae1(%rip), %rsi     # 0x95ad2
movq %rbp, %rdx
leaq 0x50229(%rip), %rcx     # 0x8f224
callq 0x478f0
movq %rbp, %rdi
callq 0x6548
addq $0x8, %r13
jmp 0x3efbb
movq 0x78(%rsp), %r15
movl 0x34(%r15), %eax
cmpl (%r12), %eax
movq %r14, %r13
leaq 0x18(%rsp), %r14
jne 0x3f03a
movb $0x1, %al
movl %eax, 0x4(%rsp)
movq %r13, %rdi
leaq 0x56aa3(%rip), %rsi     # 0x95ad8
callq 0x47680
movq %r14, %rdi
movq %r12, %rsi
callq 0x1af30
movq %r13, %rdi
callq 0x22d28
movq 0x8(%rsp), %rax
movl (%rax), %esi
movl (%r12), %edx
movq %r13, %rdi
callq 0x3f8dc
movq %r13, %rdi
callq 0x3650a
movq %rbx, %rcx
addq $0x8, %rcx
jmp 0x3ef81
leaq 0x5e0(%r13), %rsi
leaq 0x5a9ff(%rip), %rdx     # 0x99a81
movq %r13, %rdi
callq 0x45036
jmp 0x3f28b
testb $0x1, 0x4(%rsp)
movl 0x10(%rsp), %r12d
jne 0x3f19e
movl 0x34(%r15), %edx
cmpl 0x18(%r15), %edx
jne 0x3f15b
movq 0x8(%rsp), %rax
movl (%rax), %esi
movq %r13, %rdi
callq 0x3f644
testb %al, %al
je 0x3f19e
leaq 0x56a0d(%rip), %rsi     # 0x95ad8
movq %r13, %rdi
callq 0x47680
movq %r13, %rdi
callq 0x22d28
movl 0x8(%r15), %esi
movl 0x18(%r15), %edx
movq %r13, %rdi
callq 0x3f670
leaq 0x5db7e(%rip), %rsi     # 0x9cc70
movq %r13, %rdi
callq 0x4120e
jmp 0x3f196
movl 0x8(%r15), %esi
movl 0x28(%r15), %edx
movl 0x2c(%r15), %ecx
movl 0x30(%r15), %r8d
movq %r13, %rdi
callq 0x3fa20
jmp 0x3f28b
testb %bl, %bl
jne 0x3f308
movq 0x80(%r13), %rax
testb $0x1e, (%rax,%rdx)
je 0x3f28b
movl 0x8(%r15), %esi
movq %r13, %rdi
callq 0x3f8dc
jmp 0x3f308
movl 0x8(%r15), %esi
movl 0x2c(%r15), %edx
movq %r13, %rdi
callq 0x3f8dc
jmp 0x3f28b
leaq 0x56976(%rip), %rsi     # 0x95ad8
movq %r13, %rdi
callq 0x47680
movq %r13, %rdi
callq 0x22d28
movl 0x34(%r15), %edx
movq 0x80(%r13), %rax
testb $0x14, (%rax,%rdx)
jne 0x3f4d8
movq 0x8(%rsp), %rax
movl (%rax), %esi
movq %r13, %rdi
callq 0x3f8dc
movq %r13, %rdi
callq 0x3650a
movq %r13, %rdi
callq 0x3650a
cmpb $0x1, 0xb2(%r15)
jne 0x3f1ea
leaq 0x56979(%rip), %rsi     # 0x95b30
leaq 0x56978(%rip), %rcx     # 0x95b36
movq %r13, %rdi
movq 0x8(%rsp), %rdx
callq 0x479ca
movq %r13, %rdi
callq 0x22d28
leaq 0x5da96(%rip), %rsi     # 0x9cc70
movq %r13, %rdi
callq 0x4120e
movq %r13, %rdi
callq 0x3650a
movq 0x70(%rsp), %rax
movq %rax, 0x418(%r13)
leaq 0x18(%rsp), %rdi
callq 0xb51c
jmp 0x3f28b
leaq 0x20(%r13), %rdi
movl 0x24(%r15), %esi
callq 0x7584
cmpl $0xd, 0x8(%rax)
je 0x3f24e
leaq 0x56926(%rip), %rsi     # 0x95b45
leaq 0x18(%rsp), %rdi
leaq 0x50(%rsp), %rdx
callq 0x6100
movl 0x24(%r15), %edx
movq (%r13), %rax
leaq 0x18(%rsp), %rsi
movq %r13, %rdi
callq *0x150(%rax)
leaq 0x18(%rsp), %rdi
callq 0x6548
movq 0x148(%r13), %rax
movl 0x60(%rax), %esi
movq %r13, %rdi
callq 0x6bf0
movq %r13, %rdi
movq %rax, %rsi
movq %r15, %rdx
callq 0x1239e
testb %al, %al
je 0x3f27c
cmpl $-0x1, 0xb4(%r15)
je 0x3f28b
leaq 0x568db(%rip), %rsi     # 0x95b5e
movq %r13, %rdi
callq 0x47aa4
movl 0x18(%r15), %edx
testl %edx, %edx
je 0x3f308
cmpl $0x2, 0x10(%r15)
je 0x3f2aa
movl 0x8(%r15), %esi
movq %r13, %rdi
callq 0x3f670
movl 0x18(%r15), %edx
movl %edx, %eax
movq 0x80(%r13), %rcx
movb (%rcx,%rax), %al
testb $0x4, %al
jne 0x3f2d5
testb $0x2, %al
jne 0x3f2f1
movq %r13, %rdi
movl %edx, %esi
callq 0x6bf0
movq %r13, %rdi
movq %rax, %rsi
callq 0x3eae8
jmp 0x3f308
cmpl $0x2, 0x10(%r15)
jne 0x3f42d
leaq 0x5d989(%rip), %rsi     # 0x9cc70
movq %r13, %rdi
callq 0x4120e
jmp 0x3f308
cmpl $0x2, 0x10(%r15)
jne 0x3f49a
movl 0x8(%r15), %esi
movq %r13, %rdi
callq 0x3f790
cmpl $0x1, 0x10(%r15)
jne 0x3f404
cmpl $0x3, %r12d
jne 0x3f3c8
movl 0x20(%r15), %edx
movq %r15, %rbx
leaq 0x18(%rsp), %r15
movq %r15, %rdi
movq %r13, %rsi
callq 0x3fd5c
cmpq $0x0, 0x8(%r15)
movq %rbx, %r15
je 0x3f359
movl 0x20(%r15), %esi
movq %r13, %rdi
callq 0x6bf0
movb $0x1, %cl
movb %cl, 0xb1(%rax)
movb %cl, 0x1d0(%r13)
movl 0x20(%r15), %esi
movq %r13, %rdi
callq 0x6bf0
movl 0x28(%rax), %edx
leaq 0x88(%rsp), %rdi
movq %r13, %rsi
callq 0x2b9f0
leaq 0x56678(%rip), %rsi     # 0x959f7
leaq 0x5666f(%rip), %rcx     # 0x959f5
leaq 0x50(%rsp), %rdi
leaq 0x88(%rsp), %rdx
callq 0x47b60
leaq 0x50(%rsp), %rsi
movq %r13, %rdi
callq 0x253d4
leaq 0x50(%rsp), %rdi
callq 0x6548
leaq 0x88(%rsp), %rdi
callq 0x6548
leaq 0x18(%rsp), %rdi
callq 0x6548
jmp 0x3f3d0
movq %r13, %rdi
callq 0x3650a
movl 0x1c(%r15), %edx
movq 0x80(%r13), %rax
testb $0x2, (%rax,%rdx)
jne 0x3f3f8
movq %r13, %rdi
movl %edx, %esi
callq 0x6bf0
movq %r13, %rdi
movq %rax, %rsi
callq 0x3eae8
jmp 0x3f404
movl 0x8(%r15), %esi
movq %r13, %rdi
callq 0x3f790
movq 0xe8(%r15), %rax
cmpq %rax, 0xf0(%r15)
je 0x3f41b
movq %rax, 0xf0(%r15)
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x5675a(%rip), %rdi     # 0x95b8e
leaq 0x528ed(%rip), %rsi     # 0x91d28
leaq 0x5662b(%rip), %rcx     # 0x95a6d
movl $0x2727, %edx           # imm = 0x2727
callq 0x61c0
pushq $0x10
popq %rdi
callq 0x6140
movq %rax, %r14
leaq 0x56710(%rip), %rsi     # 0x95b6e
leaq 0x18(%rsp), %rdi
leaq 0x50(%rsp), %rdx
callq 0x6100
movb $0x1, %bpl
leaq 0x18(%rsp), %rsi
movq %r14, %rdi
callq 0x6f6e
xorl %ebp, %ebp
leaq 0xa793a(%rip), %rsi     # 0xe6dc0
movq 0xa8b53(%rip), %rdx     # 0xe7fe0
movq %r14, %rdi
callq 0x6490
jmp 0x3f524
leaq 0x566ed(%rip), %rdi     # 0x95b8e
leaq 0x52880(%rip), %rsi     # 0x91d28
leaq 0x565be(%rip), %rcx     # 0x95a6d
movl $0x272c, %edx           # imm = 0x272C
callq 0x61c0
leaq 0x56584(%rip), %rdi     # 0x95a44
leaq 0x52861(%rip), %rsi     # 0x91d28
leaq 0x5659f(%rip), %rcx     # 0x95a6d
movl $0x267f, %edx           # imm = 0x267F
callq 0x61c0
pushq $0x10
popq %rdi
callq 0x6140
movq %rax, %r14
leaq 0x565f7(%rip), %rsi     # 0x95ae1
leaq 0x50(%rsp), %rdi
leaq 0x88(%rsp), %rdx
callq 0x6100
movb $0x1, %bpl
leaq 0x50(%rsp), %rsi
movq %r14, %rdi
callq 0x6f6e
xorl %ebp, %ebp
leaq 0xa78ab(%rip), %rsi     # 0xe6dc0
movq 0xa8ac4(%rip), %rdx     # 0xe7fe0
movq %r14, %rdi
callq 0x6490
jmp 0x3f597
movq %rax, %rbx
jmp 0x3f5c8
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x6548
testb %bpl, %bpl
jne 0x3f545
jmp 0x3f5be
movq %rax, %rbx
movq %r14, %rdi
callq 0x6200
jmp 0x3f5be
jmp 0x3f597
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x6548
testb %bpl, %bpl
jne 0x3f568
jmp 0x3f5c8
movq %rax, %rbx
movq %r14, %rdi
callq 0x6200
jmp 0x3f5c8
jmp 0x3f597
jmp 0x3f597
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x6548
jmp 0x3f588
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x6548
jmp 0x3f59a
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x6548
jmp 0x3f5c8
jmp 0x3f5ac
jmp 0x3f5ac
jmp 0x3f5ac
movq %rax, %rbx
jmp 0x3f5be
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x6548
leaq 0x18(%rsp), %rdi
callq 0xb51c
movq %rbx, %rdi
callq 0x64b0