// File: rossy[P]crossc/SPIRV-Cross/spirv_hlsl.cpp
// Function: spirv_cross::CompilerHLSL::emit_hlsl_entry_point()
void CompilerHLSL::emit_hlsl_entry_point()
{
	vector<string> arguments;

	if (require_input)
		arguments.push_back("SPIRV_Cross_Input stage_input");

	// Add I/O blocks as separate arguments with appropriate storage qualifier.
	for (auto &id : ir.ids)
	{
		if (id.get_type() == TypeVariable)
		{
			auto &var = id.get<SPIRVariable>();
			auto &type = get<SPIRType>(var.basetype);
			bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock);

			if (var.storage != StorageClassInput && var.storage != StorageClassOutput)
				continue;

			if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self))
			{
				if (var.storage == StorageClassInput)
				{
					arguments.push_back(join("in ", variable_decl(type, join("stage_input", to_name(var.self)))));
				}
				else if (var.storage == StorageClassOutput)
				{
					arguments.push_back(join("out ", variable_decl(type, join("stage_output", to_name(var.self)))));
				}
			}
		}
	}

	auto &execution = get_entry_point();

	switch (execution.model)
	{
	case ExecutionModelGLCompute:
	{
		SpecializationConstant wg_x, wg_y, wg_z;
		get_work_group_size_specialization_constants(wg_x, wg_y, wg_z);

		uint32_t x = execution.workgroup_size.x;
		uint32_t y = execution.workgroup_size.y;
		uint32_t z = execution.workgroup_size.z;

		if (wg_x.id)
			x = get<SPIRConstant>(wg_x.id).scalar();
		if (wg_y.id)
			y = get<SPIRConstant>(wg_y.id).scalar();
		if (wg_z.id)
			z = get<SPIRConstant>(wg_z.id).scalar();

		statement("[numthreads(", x, ", ", y, ", ", z, ")]");
		break;
	}
	case ExecutionModelFragment:
		if (execution.flags.get(ExecutionModeEarlyFragmentTests))
			statement("[earlydepthstencil]");
		break;
	default:
		break;
	}

	statement(require_output ? "SPIRV_Cross_Output " : "void ", "main(", merge(arguments), ")");
	begin_scope();
	bool legacy = hlsl_options.shader_model <= 30;

	// Copy builtins from entry point arguments to globals.
	active_input_builtins.for_each_bit([&](uint32_t i) {
		auto builtin = builtin_to_glsl(static_cast<BuiltIn>(i), StorageClassInput);
		switch (static_cast<BuiltIn>(i))
		{
		case BuiltInFragCoord:
			// VPOS in D3D9 is sampled at integer locations, apply half-pixel offset to be consistent.
			// TODO: Do we need an option here? Any reason why a D3D9 shader would be used
			// on a D3D10+ system with a different rasterization config?
			if (legacy)
				statement(builtin, " = stage_input.", builtin, " + float4(0.5f, 0.5f, 0.0f, 0.0f);");
			else
				statement(builtin, " = stage_input.", builtin, ";");
			break;

		case BuiltInVertexId:
		case BuiltInVertexIndex:
		case BuiltInInstanceId:
		case BuiltInInstanceIndex:
			// D3D semantics are uint, but shader wants int.
			statement(builtin, " = int(stage_input.", builtin, ");");
			break;

		case BuiltInNumWorkgroups:
		case BuiltInPointCoord:
		case BuiltInSubgroupSize:
		case BuiltInSubgroupLocalInvocationId:
			break;

		case BuiltInSubgroupEqMask:
			// Emulate these ...
			// No 64-bit in HLSL, so have to do it in 32-bit and unroll.
			statement("gl_SubgroupEqMask = 1u << (WaveGetLaneIndex() - uint4(0, 32, 64, 96));");
			statement("if (WaveGetLaneIndex() >= 32) gl_SubgroupEqMask.x = 0;");
			statement("if (WaveGetLaneIndex() >= 64 || WaveGetLaneIndex() < 32) gl_SubgroupEqMask.y = 0;");
			statement("if (WaveGetLaneIndex() >= 96 || WaveGetLaneIndex() < 64) gl_SubgroupEqMask.z = 0;");
			statement("if (WaveGetLaneIndex() < 96) gl_SubgroupEqMask.w = 0;");
			break;

		case BuiltInSubgroupGeMask:
			// Emulate these ...
			// No 64-bit in HLSL, so have to do it in 32-bit and unroll.
			statement("gl_SubgroupGeMask = ~((1u << (WaveGetLaneIndex() - uint4(0, 32, 64, 96))) - 1u);");
			statement("if (WaveGetLaneIndex() >= 32) gl_SubgroupGeMask.x = 0u;");
			statement("if (WaveGetLaneIndex() >= 64) gl_SubgroupGeMask.y = 0u;");
			statement("if (WaveGetLaneIndex() >= 96) gl_SubgroupGeMask.z = 0u;");
			statement("if (WaveGetLaneIndex() < 32) gl_SubgroupGeMask.y = ~0u;");
			statement("if (WaveGetLaneIndex() < 64) gl_SubgroupGeMask.z = ~0u;");
			statement("if (WaveGetLaneIndex() < 96) gl_SubgroupGeMask.w = ~0u;");
			break;

		case BuiltInSubgroupGtMask:
			// Emulate these ...
			// No 64-bit in HLSL, so have to do it in 32-bit and unroll.
			statement("uint gt_lane_index = WaveGetLaneIndex() + 1;");
			statement("gl_SubgroupGtMask = ~((1u << (gt_lane_index - uint4(0, 32, 64, 96))) - 1u);");
			statement("if (gt_lane_index >= 32) gl_SubgroupGtMask.x = 0u;");
			statement("if (gt_lane_index >= 64) gl_SubgroupGtMask.y = 0u;");
			statement("if (gt_lane_index >= 96) gl_SubgroupGtMask.z = 0u;");
			statement("if (gt_lane_index >= 128) gl_SubgroupGtMask.w = 0u;");
			statement("if (gt_lane_index < 32) gl_SubgroupGtMask.y = ~0u;");
			statement("if (gt_lane_index < 64) gl_SubgroupGtMask.z = ~0u;");
			statement("if (gt_lane_index < 96) gl_SubgroupGtMask.w = ~0u;");
			break;

		case BuiltInSubgroupLeMask:
			// Emulate these ...
			// No 64-bit in HLSL, so have to do it in 32-bit and unroll.
			statement("uint le_lane_index = WaveGetLaneIndex() + 1;");
			statement("gl_SubgroupLeMask = (1u << (le_lane_index - uint4(0, 32, 64, 96))) - 1u;");
			statement("if (le_lane_index >= 32) gl_SubgroupLeMask.x = ~0u;");
			statement("if (le_lane_index >= 64) gl_SubgroupLeMask.y = ~0u;");
			statement("if (le_lane_index >= 96) gl_SubgroupLeMask.z = ~0u;");
			statement("if (le_lane_index >= 128) gl_SubgroupLeMask.w = ~0u;");
			statement("if (le_lane_index < 32) gl_SubgroupLeMask.y = 0u;");
			statement("if (le_lane_index < 64) gl_SubgroupLeMask.z = 0u;");
			statement("if (le_lane_index < 96) gl_SubgroupLeMask.w = 0u;");
			break;

		case BuiltInSubgroupLtMask:
			// Emulate these ...
			// No 64-bit in HLSL, so have to do it in 32-bit and unroll.
			statement("gl_SubgroupLtMask = (1u << (WaveGetLaneIndex() - uint4(0, 32, 64, 96))) - 1u;");
			statement("if (WaveGetLaneIndex() >= 32) gl_SubgroupLtMask.x = ~0u;");
			statement("if (WaveGetLaneIndex() >= 64) gl_SubgroupLtMask.y = ~0u;");
			statement("if (WaveGetLaneIndex() >= 96) gl_SubgroupLtMask.z = ~0u;");
			statement("if (WaveGetLaneIndex() < 32) gl_SubgroupLtMask.y = 0u;");
			statement("if (WaveGetLaneIndex() < 64) gl_SubgroupLtMask.z = 0u;");
			statement("if (WaveGetLaneIndex() < 96) gl_SubgroupLtMask.w = 0u;");
			break;

		case BuiltInClipDistance:
			for (uint32_t clip = 0; clip < clip_distance_count; clip++)
				statement("gl_ClipDistance[", clip, "] = stage_input.gl_ClipDistance", clip / 4, ".", "xyzw"[clip & 3],
				          ";");
			break;

		case BuiltInCullDistance:
			for (uint32_t cull = 0; cull < cull_distance_count; cull++)
				statement("gl_CullDistance[", cull, "] = stage_input.gl_CullDistance", cull / 4, ".", "xyzw"[cull & 3],
				          ";");
			break;

		default:
			statement(builtin, " = stage_input.", builtin, ";");
			break;
		}
	});

	// Copy from stage input struct to globals.
	for (auto &id : ir.ids)
	{
		if (id.get_type() == TypeVariable)
		{
			auto &var = id.get<SPIRVariable>();
			auto &type = get<SPIRType>(var.basetype);
			bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock);

			if (var.storage != StorageClassInput)
				continue;

			bool need_matrix_unroll = var.storage == StorageClassInput && execution.model == ExecutionModelVertex;

			if (!block && !var.remapped_variable && type.pointer && !is_builtin_variable(var) &&
			    interface_variable_exists_in_entry_point(var.self))
			{
				auto name = to_name(var.self);
				auto &mtype = get<SPIRType>(var.basetype);
				if (need_matrix_unroll && mtype.columns > 1)
				{
					// Unroll matrices.
					for (uint32_t col = 0; col < mtype.columns; col++)
						statement(name, "[", col, "] = stage_input.", name, "_", col, ";");
				}
				else
				{
					statement(name, " = stage_input.", name, ";");
				}
			}

			// I/O blocks don't use the common stage input/output struct, but separate outputs.
			if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self))
			{
				auto name = to_name(var.self);
				statement(name, " = stage_input", name, ";");
			}
		}
	}

	// Run the shader.
	if (execution.model == ExecutionModelVertex)
		statement("vert_main();");
	else if (execution.model == ExecutionModelFragment)
		statement("frag_main();");
	else if (execution.model == ExecutionModelGLCompute)
		statement("comp_main();");
	else
		SPIRV_CROSS_THROW("Unsupported shader stage.");

	// Copy block outputs.
	for (auto &id : ir.ids)
	{
		if (id.get_type() == TypeVariable)
		{
			auto &var = id.get<SPIRVariable>();
			auto &type = get<SPIRType>(var.basetype);
			bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock);

			if (var.storage != StorageClassOutput)
				continue;

			// I/O blocks don't use the common stage input/output struct, but separate outputs.
			if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self))
			{
				auto name = to_name(var.self);
				statement("stage_output", name, " = ", name, ";");
			}
		}
	}

	// Copy stage outputs.
	if (require_output)
	{
		statement("SPIRV_Cross_Output stage_output;");

		// Copy builtins from globals to return struct.
		active_output_builtins.for_each_bit([&](uint32_t i) {
			// PointSize doesn't exist in HLSL.
			if (i == BuiltInPointSize)
				return;

			switch (static_cast<BuiltIn>(i))
			{
			case BuiltInClipDistance:
				for (uint32_t clip = 0; clip < clip_distance_count; clip++)
					statement("stage_output.gl_ClipDistance", clip / 4, ".", "xyzw"[clip & 3], " = gl_ClipDistance[",
					          clip, "];");
				break;

			case BuiltInCullDistance:
				for (uint32_t cull = 0; cull < cull_distance_count; cull++)
					statement("stage_output.gl_CullDistance", cull / 4, ".", "xyzw"[cull & 3], " = gl_CullDistance[",
					          cull, "];");
				break;

			default:
			{
				auto builtin_expr = builtin_to_glsl(static_cast<BuiltIn>(i), StorageClassOutput);
				statement("stage_output.", builtin_expr, " = ", builtin_expr, ";");
				break;
			}
			}
		});

		for (auto &id : ir.ids)
		{
			if (id.get_type() == TypeVariable)
			{
				auto &var = id.get<SPIRVariable>();
				auto &type = get<SPIRType>(var.basetype);
				bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock);

				if (var.storage != StorageClassOutput)
					continue;

				if (!block && var.storage != StorageClassFunction && !var.remapped_variable && type.pointer &&
				    !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self))
				{
					auto name = to_name(var.self);

					if (legacy && execution.model == ExecutionModelFragment)
					{
						string output_filler;
						for (uint32_t size = type.vecsize; size < 4; ++size)
							output_filler += ", 0.0";

						statement("stage_output.", name, " = float4(", name, output_filler, ");");
					}
					else
					{
						statement("stage_output.", name, " = ", name, ";");
					}
				}
			}
		}

		statement("return stage_output;");
	}

	end_scope();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4a0, %rsp            # imm = 0x4A0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x398(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x30390
movq -0x398(%rbp), %rax
testb $0x1, 0x7a9(%rax)
je 0xc4910
leaq -0x41(%rbp), %rdi
movq %rdi, -0x3a0(%rbp)
callq 0x7650
movq -0x3a0(%rbp), %rdx
leaq 0x837c8(%rip), %rsi     # 0x148079
leaq -0x40(%rbp), %rdi
callq 0x7520
jmp 0xc48bc
leaq -0x20(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0xecd0
jmp 0xc48cb
leaq -0x40(%rbp), %rdi
callq 0x7708
leaq -0x41(%rbp), %rdi
callq 0x73d0
jmp 0xc4910
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc4902
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x7708
leaq -0x41(%rbp), %rdi
callq 0x73d0
jmp 0xc5ba2
movq -0x398(%rbp), %rax
addq $0x8, %rax
addq $0x18, %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rdi
callq 0xf940
movq %rax, -0x68(%rbp)
movq -0x60(%rbp), %rdi
callq 0xf970
movq %rax, -0x70(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0xf9a0
testb $0x1, %al
jne 0xc4953
jmp 0xc4d56
leaq -0x68(%rbp), %rdi
callq 0xf9e0
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
callq 0xfa00
movl %eax, -0x3a4(%rbp)
jmp 0xc4971
movl -0x3a4(%rbp), %eax
cmpl $0x2, %eax
jne 0xc4d46
movq -0x78(%rbp), %rdi
callq 0xfd10
movq %rax, -0x3b0(%rbp)
jmp 0xc4992
movq -0x398(%rbp), %rdi
movq -0x3b0(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
movl 0xc(%rax), %esi
callq 0xea90
movq %rax, -0x3b8(%rbp)
jmp 0xc49b9
movq -0x398(%rbp), %rdi
movq -0x3b8(%rbp), %rax
movq %rax, -0x88(%rbp)
addq $0x38, %rdi
movq -0x88(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, %esi
callq 0xead0
movq %rax, %rdi
addq $0x60, %rdi
movl $0x2, %esi
callq 0xef50
movb %al, -0x3b9(%rbp)
jmp 0xc49fc
movb -0x3b9(%rbp), %al
andb $0x1, %al
movb %al, -0x89(%rbp)
movq -0x80(%rbp), %rax
cmpl $0x1, 0x10(%rax)
je 0xc4a34
movq -0x80(%rbp), %rax
cmpl $0x3, 0x10(%rax)
je 0xc4a34
jmp 0xc4d48
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc5ba2
testb $0x1, -0x89(%rbp)
je 0xc4d44
movq -0x398(%rbp), %rdi
movq -0x80(%rbp), %rsi
callq 0x205a0
movb %al, -0x3ba(%rbp)
jmp 0xc4a59
movb -0x3ba(%rbp), %al
testb $0x1, %al
jne 0xc4d44
jmp 0xc4a69
movq -0x398(%rbp), %rdi
movq -0x80(%rbp), %rax
movl 0x8(%rax), %esi
callq 0x21c10
movb %al, -0x3bb(%rbp)
jmp 0xc4a84
movb -0x3bb(%rbp), %al
testb $0x1, %al
jne 0xc4a93
jmp 0xc4d44
movq -0x80(%rbp), %rax
cmpl $0x1, 0x10(%rax)
jne 0xc4beb
movq -0x398(%rbp), %rsi
movq -0x88(%rbp), %rax
movq %rax, -0x3c8(%rbp)
movq -0x80(%rbp), %rax
movl 0x8(%rax), %edx
movq (%rsi), %rax
movq 0x38(%rax), %rax
leaq -0x110(%rbp), %rdi
movl $0x1, %ecx
callq *%rax
jmp 0xc4ad4
leaq 0x8360e(%rip), %rsi     # 0x1480e9
leaq -0xf0(%rbp), %rdi
leaq -0x110(%rbp), %rdx
callq 0xa4350
jmp 0xc4af0
movq -0x3c8(%rbp), %rdx
movq -0x398(%rbp), %rsi
movq (%rsi), %rax
movq 0xc8(%rax), %rax
leaq -0xd0(%rbp), %rdi
leaq -0xf0(%rbp), %rcx
xorl %r8d, %r8d
callq *%rax
jmp 0xc4b1d
leaq 0x7ca67(%rip), %rsi     # 0x14158b
leaq -0xb0(%rbp), %rdi
leaq -0xd0(%rbp), %rdx
callq 0xa7430
jmp 0xc4b39
leaq -0x20(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0xecd0
jmp 0xc4b4b
leaq -0xb0(%rbp), %rdi
callq 0x7708
leaq -0xd0(%rbp), %rdi
callq 0x7708
leaq -0xf0(%rbp), %rdi
callq 0x7708
leaq -0x110(%rbp), %rdi
callq 0x7708
jmp 0xc4d42
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc4bda
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc4bce
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc4bc2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x7708
leaq -0xd0(%rbp), %rdi
callq 0x7708
leaq -0xf0(%rbp), %rdi
callq 0x7708
leaq -0x110(%rbp), %rdi
callq 0x7708
jmp 0xc5ba2
movq -0x80(%rbp), %rax
cmpl $0x3, 0x10(%rax)
jne 0xc4d40
movq -0x398(%rbp), %rsi
movq -0x88(%rbp), %rax
movq %rax, -0x3d0(%rbp)
movq -0x80(%rbp), %rax
movl 0x8(%rax), %edx
movq (%rsi), %rax
movq 0x38(%rax), %rax
leaq -0x190(%rbp), %rdi
movl $0x1, %ecx
callq *%rax
jmp 0xc4c2c
leaq 0x795f2(%rip), %rsi     # 0x13e225
leaq -0x170(%rbp), %rdi
leaq -0x190(%rbp), %rdx
callq 0xdb800
jmp 0xc4c48
movq -0x3d0(%rbp), %rdx
movq -0x398(%rbp), %rsi
movq (%rsi), %rax
movq 0xc8(%rax), %rax
leaq -0x150(%rbp), %rdi
leaq -0x170(%rbp), %rcx
xorl %r8d, %r8d
callq *%rax
jmp 0xc4c75
leaq 0x7fe2b(%rip), %rsi     # 0x144aa7
leaq -0x130(%rbp), %rdi
leaq -0x150(%rbp), %rdx
callq 0xdb750
jmp 0xc4c91
leaq -0x20(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0xecd0
jmp 0xc4ca3
leaq -0x130(%rbp), %rdi
callq 0x7708
leaq -0x150(%rbp), %rdi
callq 0x7708
leaq -0x170(%rbp), %rdi
callq 0x7708
leaq -0x190(%rbp), %rdi
callq 0x7708
jmp 0xc4d40
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc4d2f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc4d23
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc4d17
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x130(%rbp), %rdi
callq 0x7708
leaq -0x150(%rbp), %rdi
callq 0x7708
leaq -0x170(%rbp), %rdi
callq 0x7708
leaq -0x190(%rbp), %rdi
callq 0x7708
jmp 0xc5ba2
jmp 0xc4d42
jmp 0xc4d44
jmp 0xc4d46
jmp 0xc4d48
leaq -0x68(%rbp), %rdi
callq 0xfbd0
jmp 0xc493d
movq -0x398(%rbp), %rdi
callq 0x25150
movq %rax, -0x3d8(%rbp)
jmp 0xc4d6b
movq -0x3d8(%rbp), %rax
movq %rax, -0x198(%rbp)
movq -0x198(%rbp), %rax
movl 0xb8(%rax), %eax
movl %eax, -0x3dc(%rbp)
subl $0x4, %eax
je 0xc4f23
jmp 0xc4d97
movl -0x3dc(%rbp), %eax
subl $0x5, %eax
jne 0xc4f65
jmp 0xc4da8
movq -0x398(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
leaq -0x1a8(%rbp), %rdx
leaq -0x1b0(%rbp), %rcx
callq 0x251e0
jmp 0xc4dcb
movq -0x198(%rbp), %rax
movl 0xa0(%rax), %eax
movl %eax, -0x1b4(%rbp)
movq -0x198(%rbp), %rax
movl 0xa4(%rax), %eax
movl %eax, -0x1b8(%rbp)
movq -0x198(%rbp), %rax
movl 0xa8(%rax), %eax
movl %eax, -0x1bc(%rbp)
cmpl $0x0, -0x1a0(%rbp)
je 0xc4e4c
movq -0x398(%rbp), %rdi
movl -0x1a0(%rbp), %esi
callq 0x31910
movq %rax, -0x3e8(%rbp)
jmp 0xc4e28
movq -0x3e8(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x2f560
movl %eax, -0x3ec(%rbp)
jmp 0xc4e40
movl -0x3ec(%rbp), %eax
movl %eax, -0x1b4(%rbp)
cmpl $0x0, -0x1a8(%rbp)
je 0xc4e94
movq -0x398(%rbp), %rdi
movl -0x1a8(%rbp), %esi
callq 0x31910
movq %rax, -0x3f8(%rbp)
jmp 0xc4e70
movq -0x3f8(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x2f560
movl %eax, -0x3fc(%rbp)
jmp 0xc4e88
movl -0x3fc(%rbp), %eax
movl %eax, -0x1b8(%rbp)
cmpl $0x0, -0x1b0(%rbp)
je 0xc4edc
movq -0x398(%rbp), %rdi
movl -0x1b0(%rbp), %esi
callq 0x31910
movq %rax, -0x408(%rbp)
jmp 0xc4eb8
movq -0x408(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x2f560
movl %eax, -0x40c(%rbp)
jmp 0xc4ed0
movl -0x40c(%rbp), %eax
movl %eax, -0x1bc(%rbp)
movq -0x398(%rbp), %rdi
leaq 0x831ba(%rip), %rcx     # 0x1480a4
movq %rsp, %rax
movq %rcx, 0x8(%rax)
leaq -0x1bc(%rbp), %rcx
movq %rcx, (%rax)
leaq 0x83195(%rip), %rsi     # 0x148097
leaq 0x7f686(%rip), %r9      # 0x14458f
leaq -0x1b4(%rbp), %rdx
leaq -0x1b8(%rbp), %r8
movq %r9, %rcx
callq 0xdb8b0
jmp 0xc4f21
jmp 0xc4f67
movq -0x198(%rbp), %rdi
addq $0x60, %rdi
movl $0x9, %esi
callq 0xef50
movb %al, -0x40d(%rbp)
jmp 0xc4f40
movb -0x40d(%rbp), %al
testb $0x1, %al
jne 0xc4f4c
jmp 0xc4f63
movq -0x398(%rbp), %rdi
leaq 0x8314d(%rip), %rsi     # 0x1480a7
callq 0x11210
jmp 0xc4f61
jmp 0xc4f63
jmp 0xc4f67
jmp 0xc4f67
movq -0x398(%rbp), %rax
movb 0x7a8(%rax), %dl
leaq 0x83140(%rip), %rcx     # 0x1480bb
leaq 0x830ad(%rip), %rax     # 0x14802f
testb $0x1, %dl
cmovneq %rcx, %rax
movq %rax, -0x1c8(%rbp)
leaq -0x1e8(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x9f2c0
jmp 0xc4fa2
movq -0x398(%rbp), %rdi
leaq 0x8311f(%rip), %rdx     # 0x1480cf
leaq 0x7ff42(%rip), %r8      # 0x144ef9
leaq -0x1c8(%rbp), %rsi
leaq -0x1e8(%rbp), %rcx
callq 0xdba30
jmp 0xc4fcc
leaq -0x1e8(%rbp), %rdi
callq 0x7708
movq -0x398(%rbp), %rdi
callq 0x5c200
jmp 0xc4fe6
movq -0x398(%rbp), %rax
movl 0x788(%rax), %ecx
subl $0x1f, %ecx
setb -0x1e9(%rbp)
movq %rax, %rdi
addq $0x2d0, %rdi            # imm = 0x2D0
movq %rax, -0x200(%rbp)
leaq -0x1e9(%rbp), %rax
movq %rax, -0x1f8(%rbp)
leaq -0x200(%rbp), %rsi
callq 0xc5bc0
jmp 0xc502a
movq -0x398(%rbp), %rax
addq $0x8, %rax
addq $0x18, %rax
movq %rax, -0x208(%rbp)
movq -0x208(%rbp), %rdi
callq 0xf940
movq %rax, -0x210(%rbp)
movq -0x208(%rbp), %rdi
callq 0xf970
movq %rax, -0x218(%rbp)
leaq -0x210(%rbp), %rdi
leaq -0x218(%rbp), %rsi
callq 0xf9a0
testb $0x1, %al
jne 0xc5082
jmp 0xc5469
leaq -0x210(%rbp), %rdi
callq 0xf9e0
movq %rax, -0x220(%rbp)
movq -0x220(%rbp), %rdi
callq 0xfa00
movl %eax, -0x414(%rbp)
jmp 0xc50a9
movl -0x414(%rbp), %eax
cmpl $0x2, %eax
jne 0xc5456
movq -0x220(%rbp), %rdi
callq 0xfd10
movq %rax, -0x420(%rbp)
jmp 0xc50cd
movq -0x398(%rbp), %rdi
movq -0x420(%rbp), %rax
movq %rax, -0x228(%rbp)
movq -0x228(%rbp), %rax
movl 0xc(%rax), %esi
callq 0xea90
movq %rax, -0x428(%rbp)
jmp 0xc50fa
movq -0x398(%rbp), %rdi
movq -0x428(%rbp), %rax
movq %rax, -0x230(%rbp)
addq $0x38, %rdi
movq -0x230(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, %esi
callq 0xead0
movq %rax, %rdi
addq $0x60, %rdi
movl $0x2, %esi
callq 0xef50
movb %al, -0x429(%rbp)
jmp 0xc513d
movb -0x429(%rbp), %al
andb $0x1, %al
movb %al, -0x231(%rbp)
movq -0x228(%rbp), %rax
cmpl $0x1, 0x10(%rax)
je 0xc517a
jmp 0xc5458
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x7708
jmp 0xc5ba2
movq -0x228(%rbp), %rcx
xorl %eax, %eax
cmpl $0x1, 0x10(%rcx)
movb %al, -0x42a(%rbp)
jne 0xc51a6
movq -0x198(%rbp), %rax
cmpl $0x0, 0xb8(%rax)
sete %al
movb %al, -0x42a(%rbp)
movb -0x42a(%rbp), %al
andb $0x1, %al
movb %al, -0x232(%rbp)
testb $0x1, -0x231(%rbp)
jne 0xc5379
movq -0x228(%rbp), %rax
testb $0x1, 0x5b(%rax)
jne 0xc5379
movq -0x230(%rbp), %rax
testb $0x1, 0x60(%rax)
je 0xc5379
movq -0x398(%rbp), %rdi
movq -0x228(%rbp), %rsi
callq 0x205a0
movb %al, -0x42b(%rbp)
jmp 0xc51fe
movb -0x42b(%rbp), %al
testb $0x1, %al
jne 0xc5379
jmp 0xc520e
movq -0x398(%rbp), %rdi
movq -0x228(%rbp), %rax
movl 0x8(%rax), %esi
callq 0x21c10
movb %al, -0x42c(%rbp)
jmp 0xc522c
movb -0x42c(%rbp), %al
testb $0x1, %al
jne 0xc523b
jmp 0xc5379
movq -0x398(%rbp), %rsi
movq -0x228(%rbp), %rax
movl 0x8(%rax), %edx
movq (%rsi), %rax
movq 0x38(%rax), %rax
leaq -0x258(%rbp), %rdi
movl $0x1, %ecx
callq *%rax
jmp 0xc5263
movq -0x398(%rbp), %rdi
movq -0x228(%rbp), %rax
movl 0xc(%rax), %esi
callq 0xea90
movq %rax, -0x438(%rbp)
jmp 0xc5282
movq -0x438(%rbp), %rax
movq %rax, -0x260(%rbp)
testb $0x1, -0x232(%rbp)
je 0xc5345
movq -0x260(%rbp), %rax
cmpl $0x1, 0x18(%rax)
jbe 0xc5345
movl $0x0, -0x264(%rbp)
movl -0x264(%rbp), %eax
movq -0x260(%rbp), %rcx
cmpl 0x18(%rcx), %eax
jae 0xc5343
movq -0x398(%rbp), %rdi
leaq 0x83dce(%rip), %rcx     # 0x1490a6
movq %rsp, %rax
movq %rcx, 0x10(%rax)
leaq -0x264(%rbp), %rcx
movq %rcx, 0x8(%rax)
leaq 0x8322d(%rip), %rdx     # 0x14851e
movq %rdx, (%rax)
leaq 0x880ad(%rip), %rdx     # 0x14d3a8
leaq 0x82dd3(%rip), %r8      # 0x1480d5
leaq -0x258(%rbp), %r9
movq %r9, %rsi
callq 0xdbb70
jmp 0xc5313
jmp 0xc5315
movl -0x264(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x264(%rbp)
jmp 0xc52b8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x258(%rbp), %rdi
callq 0x7708
jmp 0xc5ba2
jmp 0xc536d
movq -0x398(%rbp), %rdi
leaq 0x82d83(%rip), %rdx     # 0x1480d6
leaq 0x83d4c(%rip), %r8      # 0x1490a6
leaq -0x258(%rbp), %rcx
movq %rcx, %rsi
callq 0xdbd10
jmp 0xc536b
jmp 0xc536d
leaq -0x258(%rbp), %rdi
callq 0x7708
testb $0x1, -0x231(%rbp)
je 0xc5454
movq -0x398(%rbp), %rdi
movq -0x228(%rbp), %rsi
callq 0x205a0
movb %al, -0x439(%rbp)
jmp 0xc53a1
movb -0x439(%rbp), %al
testb $0x1, %al
jne 0xc5454
jmp 0xc53b1
movq -0x398(%rbp), %rdi
movq -0x228(%rbp), %rax
movl 0x8(%rax), %esi
callq 0x21c10
movb %al, -0x43a(%rbp)
jmp 0xc53cf
movb -0x43a(%rbp), %al
testb $0x1, %al
jne 0xc53db
jmp 0xc5454
movq -0x398(%rbp), %rsi
movq -0x228(%rbp), %rax
movl 0x8(%rax), %edx
movq (%rsi), %rax
movq 0x38(%rax), %rax
leaq -0x288(%rbp), %rdi
movl $0x1, %ecx
callq *%rax
jmp 0xc5403
movq -0x398(%rbp), %rdi
leaq 0x82cd5(%rip), %rdx     # 0x1480e6
leaq 0x83c8e(%rip), %r8      # 0x1490a6
leaq -0x288(%rbp), %rcx
movq %rcx, %rsi
callq 0xdbe50
jmp 0xc5429
leaq -0x288(%rbp), %rdi
callq 0x7708
jmp 0xc5454
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x288(%rbp), %rdi
callq 0x7708
jmp 0xc5ba2
jmp 0xc5456
jmp 0xc5458
leaq -0x210(%rbp), %rdi
callq 0xfbd0
jmp 0xc5066
movq -0x198(%rbp), %rax
cmpl $0x0, 0xb8(%rax)
jne 0xc5493
movq -0x398(%rbp), %rdi
leaq 0x82c6e(%rip), %rsi     # 0x1480f5
callq 0xdbf90
jmp 0xc548e
jmp 0xc55bb
movq -0x198(%rbp), %rax
cmpl $0x4, 0xb8(%rax)
jne 0xc54bd
movq -0x398(%rbp), %rdi
leaq 0x82c51(%rip), %rsi     # 0x148102
callq 0xdbf90
jmp 0xc54b8
jmp 0xc55b9
movq -0x198(%rbp), %rax
cmpl $0x5, 0xb8(%rax)
jne 0xc54e7
movq -0x398(%rbp), %rdi
leaq 0x82c34(%rip), %rsi     # 0x14810f
callq 0xdbf90
jmp 0xc54e2
jmp 0xc55b7
movb $0x1, -0x2aa(%rbp)
movl $0x10, %edi
callq 0x71a0
movq %rax, -0x450(%rbp)
leaq -0x2a9(%rbp), %rdi
movq %rdi, -0x448(%rbp)
callq 0x7650
movq -0x448(%rbp), %rdx
leaq 0x82bfc(%rip), %rsi     # 0x14811c
leaq -0x2a8(%rbp), %rdi
callq 0x7520
jmp 0xc552e
movq -0x450(%rbp), %rdi
leaq -0x2a8(%rbp), %rsi
callq 0x9c50
jmp 0xc5543
movq -0x450(%rbp), %rdi
movb $0x0, -0x2aa(%rbp)
leaq 0xe8880(%rip), %rsi     # 0x1addd8
leaq -0xbb8cf(%rip), %rdx    # 0x9c90
callq 0x7610
jmp 0xc5bb4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc558f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x2a8(%rbp), %rdi
callq 0x7708
leaq -0x2a9(%rbp), %rdi
callq 0x73d0
testb $0x1, -0x2aa(%rbp)
jne 0xc55a6
jmp 0xc55b2
movq -0x450(%rbp), %rdi
callq 0x72c0
jmp 0xc5ba2
jmp 0xc55b9
jmp 0xc55bb
movq -0x398(%rbp), %rax
addq $0x8, %rax
addq $0x18, %rax
movq %rax, -0x2b8(%rbp)
movq -0x2b8(%rbp), %rdi
callq 0xf940
movq %rax, -0x2c0(%rbp)
movq -0x2b8(%rbp), %rdi
callq 0xf970
movq %rax, -0x2c8(%rbp)
leaq -0x2c0(%rbp), %rdi
leaq -0x2c8(%rbp), %rsi
callq 0xf9a0
testb $0x1, %al
jne 0xc5613
jmp 0xc57e8
leaq -0x2c0(%rbp), %rdi
callq 0xf9e0
movq %rax, -0x2d0(%rbp)
movq -0x2d0(%rbp), %rdi
callq 0xfa00
movl %eax, -0x454(%rbp)
jmp 0xc563a
movl -0x454(%rbp), %eax
cmpl $0x2, %eax
jne 0xc57d5
movq -0x2d0(%rbp), %rdi
callq 0xfd10
movq %rax, -0x460(%rbp)
jmp 0xc565e
movq -0x398(%rbp), %rdi
movq -0x460(%rbp), %rax
movq %rax, -0x2d8(%rbp)
movq -0x2d8(%rbp), %rax
movl 0xc(%rax), %esi
callq 0xea90
movq %rax, -0x468(%rbp)
jmp 0xc568b
movq -0x398(%rbp), %rdi
movq -0x468(%rbp), %rax
movq %rax, -0x2e0(%rbp)
addq $0x38, %rdi
movq -0x2e0(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, %esi
callq 0xead0
movq %rax, %rdi
addq $0x60, %rdi
movl $0x2, %esi
callq 0xef50
movb %al, -0x469(%rbp)
jmp 0xc56ce
movb -0x469(%rbp), %al
andb $0x1, %al
movb %al, -0x2e1(%rbp)
movq -0x2d8(%rbp), %rax
cmpl $0x3, 0x10(%rax)
je 0xc56ee
jmp 0xc57d7
testb $0x1, -0x2e1(%rbp)
je 0xc57d3
movq -0x398(%rbp), %rdi
movq -0x2d8(%rbp), %rsi
callq 0x205a0
movb %al, -0x46a(%rbp)
jmp 0xc5716
movb -0x46a(%rbp), %al
testb $0x1, %al
jne 0xc57d3
jmp 0xc5726
movq -0x398(%rbp), %rdi
movq -0x2d8(%rbp), %rax
movl 0x8(%rax), %esi
callq 0x21c10
movb %al, -0x46b(%rbp)
jmp 0xc5744
movb -0x46b(%rbp), %al
testb $0x1, %al
jne 0xc5753
jmp 0xc57d3
movq -0x398(%rbp), %rsi
movq -0x2d8(%rbp), %rax
movl 0x8(%rax), %edx
movq (%rsi), %rax
movq 0x38(%rax), %rax
leaq -0x308(%rbp), %rdi
movl $0x1, %ecx
callq *%rax
jmp 0xc577b
movq -0x398(%rbp), %rdi
leaq 0x78a9c(%rip), %rsi     # 0x13e225
leaq 0x8387f(%rip), %rcx     # 0x14900f
leaq 0x8390f(%rip), %r9      # 0x1490a6
leaq -0x308(%rbp), %r8
movq %r8, %rdx
callq 0xdc0b0
jmp 0xc57a8
leaq -0x308(%rbp), %rdi
callq 0x7708
jmp 0xc57d3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x308(%rbp), %rdi
callq 0x7708
jmp 0xc5ba2
jmp 0xc57d5
jmp 0xc57d7
leaq -0x2c0(%rbp), %rdi
callq 0xfbd0
jmp 0xc55f7
movq -0x398(%rbp), %rax
testb $0x1, 0x7a8(%rax)
je 0xc5b82
movq -0x398(%rbp), %rdi
leaq 0x8292c(%rip), %rsi     # 0x148136
callq 0x9e950
jmp 0xc5811
movq -0x398(%rbp), %rax
movq %rax, %rdi
addq $0x310, %rdi            # imm = 0x310
movq %rax, -0x310(%rbp)
leaq -0x310(%rbp), %rsi
callq 0xc5db0
jmp 0xc5837
movq -0x398(%rbp), %rax
addq $0x8, %rax
addq $0x18, %rax
movq %rax, -0x318(%rbp)
movq -0x318(%rbp), %rdi
callq 0xf940
movq %rax, -0x320(%rbp)
movq -0x318(%rbp), %rdi
callq 0xf970
movq %rax, -0x328(%rbp)
leaq -0x320(%rbp), %rdi
leaq -0x328(%rbp), %rsi
callq 0xf9a0
testb $0x1, %al
jne 0xc588f
jmp 0xc5b6b
leaq -0x320(%rbp), %rdi
callq 0xf9e0
movq %rax, -0x330(%rbp)
movq -0x330(%rbp), %rdi
callq 0xfa00
movl %eax, -0x470(%rbp)
jmp 0xc58b6
movl -0x470(%rbp), %eax
cmpl $0x2, %eax
jne 0xc5b58
movq -0x330(%rbp), %rdi
callq 0xfd10
movq %rax, -0x478(%rbp)
jmp 0xc58da
movq -0x398(%rbp), %rdi
movq -0x478(%rbp), %rax
movq %rax, -0x338(%rbp)
movq -0x338(%rbp), %rax
movl 0xc(%rax), %esi
callq 0xea90
movq %rax, -0x480(%rbp)
jmp 0xc5907
movq -0x398(%rbp), %rdi
movq -0x480(%rbp), %rax
movq %rax, -0x340(%rbp)
addq $0x38, %rdi
movq -0x340(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, %esi
callq 0xead0
movq %rax, %rdi
addq $0x60, %rdi
movl $0x2, %esi
callq 0xef50
movb %al, -0x481(%rbp)
jmp 0xc594a
movb -0x481(%rbp), %al
andb $0x1, %al
movb %al, -0x341(%rbp)
movq -0x338(%rbp), %rax
cmpl $0x3, 0x10(%rax)
je 0xc596a
jmp 0xc5b5a
testb $0x1, -0x341(%rbp)
jne 0xc5b56
movq -0x338(%rbp), %rax
cmpl $0x7, 0x10(%rax)
je 0xc5b56
movq -0x338(%rbp), %rax
testb $0x1, 0x5b(%rax)
jne 0xc5b56
movq -0x340(%rbp), %rax
testb $0x1, 0x60(%rax)
je 0xc5b56
movq -0x398(%rbp), %rdi
movq -0x338(%rbp), %rsi
callq 0x205a0
movb %al, -0x482(%rbp)
jmp 0xc59c5
movb -0x482(%rbp), %al
testb $0x1, %al
jne 0xc5b56
jmp 0xc59d5
movq -0x398(%rbp), %rdi
movq -0x338(%rbp), %rax
movl 0x8(%rax), %esi
callq 0x21c10
movb %al, -0x483(%rbp)
jmp 0xc59f3
movb -0x483(%rbp), %al
testb $0x1, %al
jne 0xc5a02
jmp 0xc5b56
movq -0x398(%rbp), %rsi
movq -0x338(%rbp), %rax
movl 0x8(%rax), %edx
movq (%rsi), %rax
movq 0x38(%rax), %rax
leaq -0x368(%rbp), %rdi
movl $0x1, %ecx
callq *%rax
jmp 0xc5a2a
testb $0x1, -0x1e9(%rbp)
je 0xc5afd
movq -0x198(%rbp), %rax
cmpl $0x4, 0xb8(%rax)
jne 0xc5afd
leaq -0x388(%rbp), %rdi
callq 0x7530
movq -0x340(%rbp), %rax
movl 0x14(%rax), %eax
movl %eax, -0x38c(%rbp)
cmpl $0x4, -0x38c(%rbp)
jae 0xc5ab5
leaq 0x826e0(%rip), %rsi     # 0x148157
leaq -0x388(%rbp), %rdi
callq 0x7340
jmp 0xc5a85
jmp 0xc5a87
movl -0x38c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38c(%rbp)
jmp 0xc5a67
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x388(%rbp), %rdi
callq 0x7708
jmp 0xc5b48
movq -0x398(%rbp), %rdi
leaq 0x835e2(%rip), %rcx     # 0x1490a5
movq %rsp, %rax
movq %rcx, (%rax)
leaq 0x8268d(%rip), %rsi     # 0x14815d
leaq 0x82694(%rip), %rcx     # 0x14816b
leaq -0x368(%rbp), %r8
leaq -0x388(%rbp), %r9
movq %r8, %rdx
callq 0xdc200
jmp 0xc5aef
leaq -0x388(%rbp), %rdi
callq 0x7708
jmp 0xc5b3a
movq -0x398(%rbp), %rdi
leaq 0x82652(%rip), %rsi     # 0x14815d
leaq 0x834fd(%rip), %rcx     # 0x14900f
leaq 0x8358d(%rip), %r9      # 0x1490a6
leaq -0x368(%rbp), %r8
movq %r8, %rdx
callq 0xdc370
jmp 0xc5b2a
jmp 0xc5b3a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc5b48
leaq -0x368(%rbp), %rdi
callq 0x7708
jmp 0xc5b56
leaq -0x368(%rbp), %rdi
callq 0x7708
jmp 0xc5ba2
jmp 0xc5b58
jmp 0xc5b5a
leaq -0x320(%rbp), %rdi
callq 0xfbd0
jmp 0xc5873
movq -0x398(%rbp), %rdi
leaq 0x825fd(%rip), %rsi     # 0x148176
callq 0x11f80
jmp 0xc5b80
jmp 0xc5b82
movq -0x398(%rbp), %rdi
callq 0x876c0
jmp 0xc5b90
leaq -0x20(%rbp), %rdi
callq 0x14cd0
addq $0x4a0, %rsp            # imm = 0x4A0
popq %rbp
retq
leaq -0x20(%rbp), %rdi
callq 0x14cd0
movq -0x50(%rbp), %rdi
callq 0x7640
nopw %cs:(%rax,%rax)