// File: rossy[P]crossc/SPIRV-Cross/spirv_glsl.cpp
// Function: spirv_cross::CompilerGLSL::flattened_access_chain_offset[abi:cxx11](spirv_cross::SPIRType const&, unsigned int const*, unsigned int, unsigned int, unsigned int, bool*, unsigned int*)
std::pair<std::string, uint32_t> CompilerGLSL::flattened_access_chain_offset(const SPIRType &basetype,
                                                                             const uint32_t *indices, uint32_t count,
                                                                             uint32_t offset, uint32_t word_stride,
                                                                             bool *need_transpose,
                                                                             uint32_t *out_matrix_stride)
{
	// Start traversing type hierarchy at the proper non-pointer types.
	const auto *type = &get_non_pointer_type(basetype);

	// This holds the type of the current pointer which we are traversing through.
	// We always start out from a struct type which is the block.
	// This is primarily used to reflect the array strides and matrix strides later.
	// For the first access chain index, type_id won't be needed, so just keep it as 0, it will be set
	// accordingly as members of structs are accessed.
	assert(type->basetype == SPIRType::Struct);
	uint32_t type_id = 0;

	std::string expr;

	// Inherit matrix information in case we are access chaining a vector which might have come from a row major layout.
	bool row_major_matrix_needs_conversion = need_transpose ? *need_transpose : false;
	uint32_t matrix_stride = out_matrix_stride ? *out_matrix_stride : 0;

	for (uint32_t i = 0; i < count; i++)
	{
		uint32_t index = indices[i];

		// Arrays
		if (!type->array.empty())
		{
			// Here, the type_id will be a type ID for the array type itself.
			uint32_t array_stride = get_decoration(type_id, DecorationArrayStride);
			if (!array_stride)
				SPIRV_CROSS_THROW("SPIR-V does not define ArrayStride for buffer block.");

			auto *constant = maybe_get<SPIRConstant>(index);
			if (constant)
			{
				// Constant array access.
				offset += constant->scalar() * array_stride;
			}
			else
			{
				// Dynamic array access.
				if (array_stride % word_stride)
				{
					SPIRV_CROSS_THROW(
					    "Array stride for dynamic indexing must be divisible by the size of a 4-component vector. "
					    "Likely culprit here is a float or vec2 array inside a push constant block which is std430. "
					    "This cannot be flattened. Try using std140 layout instead.");
				}

				expr += to_enclosed_expression(index);
				expr += " * ";
				expr += convert_to_string(array_stride / word_stride);
				expr += " + ";
			}

			uint32_t parent_type = type->parent_type;
			type = &get<SPIRType>(parent_type);
			type_id = parent_type;

			// Type ID now refers to the array type with one less dimension.
		}
		// For structs, the index refers to a constant, which indexes into the members.
		// We also check if this member is a builtin, since we then replace the entire expression with the builtin one.
		else if (type->basetype == SPIRType::Struct)
		{
			index = get<SPIRConstant>(index).scalar();

			if (index >= type->member_types.size())
				SPIRV_CROSS_THROW("Member index is out of bounds!");

			offset += type_struct_member_offset(*type, index);
			type_id = type->member_types[index];

			auto &struct_type = *type;
			type = &get<SPIRType>(type->member_types[index]);

			if (type->columns > 1)
			{
				matrix_stride = type_struct_member_matrix_stride(struct_type, index);
				row_major_matrix_needs_conversion =
				    combined_decoration_for_member(struct_type, index).get(DecorationRowMajor);
			}
			else
				row_major_matrix_needs_conversion = false;
		}
		// Matrix -> Vector
		else if (type->columns > 1)
		{
			auto *constant = maybe_get<SPIRConstant>(index);
			if (constant)
			{
				index = get<SPIRConstant>(index).scalar();
				offset += index * (row_major_matrix_needs_conversion ? (type->width / 8) : matrix_stride);
			}
			else
			{
				uint32_t indexing_stride = row_major_matrix_needs_conversion ? (type->width / 8) : matrix_stride;
				// Dynamic array access.
				if (indexing_stride % word_stride)
				{
					SPIRV_CROSS_THROW(
					    "Matrix stride for dynamic indexing must be divisible by the size of a 4-component vector. "
					    "Likely culprit here is a row-major matrix being accessed dynamically. "
					    "This cannot be flattened. Try using std140 layout instead.");
				}

				expr += to_enclosed_expression(index);
				expr += " * ";
				expr += convert_to_string(indexing_stride / word_stride);
				expr += " + ";
			}

			uint32_t parent_type = type->parent_type;
			type = &get<SPIRType>(type->parent_type);
			type_id = parent_type;
		}
		// Vector -> Scalar
		else if (type->vecsize > 1)
		{
			auto *constant = maybe_get<SPIRConstant>(index);
			if (constant)
			{
				index = get<SPIRConstant>(index).scalar();
				offset += index * (row_major_matrix_needs_conversion ? matrix_stride : (type->width / 8));
			}
			else
			{
				uint32_t indexing_stride = row_major_matrix_needs_conversion ? matrix_stride : (type->width / 8);

				// Dynamic array access.
				if (indexing_stride % word_stride)
				{
					SPIRV_CROSS_THROW(
					    "Stride for dynamic vector indexing must be divisible by the size of a 4-component vector. "
					    "This cannot be flattened in legacy targets.");
				}

				expr += to_enclosed_expression(index);
				expr += " * ";
				expr += convert_to_string(indexing_stride / word_stride);
				expr += " + ";
			}

			uint32_t parent_type = type->parent_type;
			type = &get<SPIRType>(type->parent_type);
			type_id = parent_type;
		}
		else
			SPIRV_CROSS_THROW("Cannot subdivide a scalar value!");
	}

	if (need_transpose)
		*need_transpose = row_major_matrix_needs_conversion;
	if (out_matrix_stride)
		*out_matrix_stride = matrix_stride;

	return std::make_pair(expr, offset);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3e0, %rsp            # imm = 0x3E0
movq %rdi, -0x2d0(%rbp)
movq %rdi, %rax
movq %rax, -0x2c8(%rbp)
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movl 0x10(%rbp), %eax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movl %r9d, -0x28(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x2c0(%rbp)
movq -0x18(%rbp), %rsi
callq 0x22e00
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpl $0xc, 0xc(%rax)
jne 0x86343
jmp 0x86362
leaq 0xbd990(%rip), %rdi     # 0x143cda
leaq 0xbaedb(%rip), %rsi     # 0x14122c
movl $0x164d, %edx           # imm = 0x164D
leaq 0xbd9a0(%rip), %rcx     # 0x143cfd
callq 0x7260
movl $0x0, -0x34(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x7530
cmpq $0x0, 0x18(%rbp)
je 0x86387
movq 0x18(%rbp), %rax
movb (%rax), %al
movb %al, -0x2d1(%rbp)
jmp 0x86391
xorl %eax, %eax
movb %al, -0x2d1(%rbp)
jmp 0x86391
movb -0x2d1(%rbp), %al
andb $0x1, %al
movb %al, -0x59(%rbp)
cmpq $0x0, 0x20(%rbp)
je 0x863b1
movq 0x20(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x2d8(%rbp)
jmp 0x863bb
xorl %eax, %eax
movl %eax, -0x2d8(%rbp)
jmp 0x863bb
movl -0x2d8(%rbp), %eax
movl %eax, -0x60(%rbp)
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x24(%rbp), %eax
jae 0x87093
movq -0x20(%rbp), %rax
movl -0x64(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0x68(%rbp)
movq -0x30(%rbp), %rdi
addq $0x20, %rdi
callq 0x8690
testb $0x1, %al
jne 0x86764
movq -0x2c0(%rbp), %rdi
movl -0x34(%rbp), %esi
movl $0x6, %edx
callq 0x23520
movl %eax, -0x2dc(%rbp)
jmp 0x86415
movl -0x2dc(%rbp), %eax
movl %eax, -0x6c(%rbp)
cmpl $0x0, -0x6c(%rbp)
jne 0x86509
movb $0x1, -0xa2(%rbp)
movl $0x10, %edi
callq 0x71a0
movq %rax, -0x2f0(%rbp)
leaq -0xa1(%rbp), %rdi
movq %rdi, -0x2e8(%rbp)
callq 0x7650
movq -0x2e8(%rbp), %rdx
leaq 0xbd94c(%rip), %rsi     # 0x143dad
leaq -0xa0(%rbp), %rdi
callq 0x7520
jmp 0x8646f
movq -0x2f0(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x9c50
jmp 0x86484
movq -0x2f0(%rbp), %rdi
movb $0x0, -0xa2(%rbp)
leaq 0x12793f(%rip), %rsi    # 0x1addd8
leaq -0x7c810(%rip), %rdx    # 0x9c90
callq 0x7610
jmp 0x870f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x870e5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x864e1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x7708
leaq -0xa1(%rbp), %rdi
callq 0x73d0
testb $0x1, -0xa2(%rbp)
jne 0x864f8
jmp 0x86504
movq -0x2f0(%rbp), %rdi
callq 0x72c0
jmp 0x870e5
movq -0x2c0(%rbp), %rdi
movl -0x68(%rbp), %esi
callq 0xa2eb0
movq %rax, -0x2f8(%rbp)
jmp 0x86521
movq -0x2f8(%rbp), %rax
movq %rax, -0xb0(%rbp)
cmpq $0x0, -0xb0(%rbp)
je 0x86566
movq -0xb0(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x2f560
movl %eax, -0x2fc(%rbp)
jmp 0x86551
movl -0x2fc(%rbp), %eax
imull -0x6c(%rbp), %eax
addl -0x28(%rbp), %eax
movl %eax, -0x28(%rbp)
jmp 0x86720
movl -0x6c(%rbp), %eax
xorl %edx, %edx
divl 0x10(%rbp)
cmpl $0x0, %edx
je 0x86647
movb $0x1, -0xd2(%rbp)
movl $0x10, %edi
callq 0x71a0
movq %rax, -0x310(%rbp)
leaq -0xd1(%rbp), %rdi
movq %rdi, -0x308(%rbp)
callq 0x7650
movq -0x308(%rbp), %rdx
leaq 0xbd832(%rip), %rsi     # 0x143de2
leaq -0xd0(%rbp), %rdi
callq 0x7520
jmp 0x865be
movq -0x310(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x9c50
jmp 0x865d3
movq -0x310(%rbp), %rdi
movb $0x0, -0xd2(%rbp)
leaq 0x1277f0(%rip), %rsi    # 0x1addd8
leaq -0x7c95f(%rip), %rdx    # 0x9c90
callq 0x7610
jmp 0x870f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x8661f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0x7708
leaq -0xd1(%rbp), %rdi
callq 0x73d0
testb $0x1, -0xd2(%rbp)
jne 0x86636
jmp 0x86642
movq -0x310(%rbp), %rdi
callq 0x72c0
jmp 0x870e5
movq -0x2c0(%rbp), %rsi
movl -0x68(%rbp), %edx
leaq -0xf8(%rbp), %rdi
callq 0x72630
jmp 0x8665f
leaq -0x58(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x7470
jmp 0x86671
leaq -0xf8(%rbp), %rdi
callq 0x7708
leaq 0xbd3a4(%rip), %rsi     # 0x143a28
leaq -0x58(%rbp), %rdi
callq 0x7340
jmp 0x8668f
movl -0x6c(%rbp), %eax
movl 0x10(%rbp), %ecx
xorl %edx, %edx
divl %ecx
movl %eax, -0x11c(%rbp)
leaq -0x118(%rbp), %rdi
leaq -0x11c(%rbp), %rsi
callq 0xa22d0
jmp 0x866b4
leaq -0x58(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x7470
jmp 0x866c6
leaq -0x118(%rbp), %rdi
callq 0x7708
leaq 0xc6c58(%rip), %rsi     # 0x14d331
leaq -0x58(%rbp), %rdi
callq 0x7340
jmp 0x866e4
jmp 0x86720
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0xf8(%rbp), %rdi
callq 0x7708
jmp 0x870e5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x7708
jmp 0x870e5
movq -0x2c0(%rbp), %rdi
movq -0x30(%rbp), %rax
movl 0x9c(%rax), %eax
movl %eax, -0x120(%rbp)
movl -0x120(%rbp), %esi
callq 0xea90
movq %rax, -0x318(%rbp)
jmp 0x8674b
movq -0x318(%rbp), %rax
movq %rax, -0x30(%rbp)
movl -0x120(%rbp), %eax
movl %eax, -0x34(%rbp)
jmp 0x87083
movq -0x30(%rbp), %rax
cmpl $0xc, 0xc(%rax)
jne 0x869d0
movq -0x2c0(%rbp), %rdi
movl -0x68(%rbp), %esi
callq 0x31910
movq %rax, -0x320(%rbp)
jmp 0x8678a
movq -0x320(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x2f560
movl %eax, -0x324(%rbp)
jmp 0x867a2
movl -0x324(%rbp), %eax
movl %eax, -0x68(%rbp)
movl -0x68(%rbp), %eax
movq %rax, -0x330(%rbp)
movq -0x30(%rbp), %rdi
addq $0x68, %rdi
callq 0x8650
movq %rax, %rcx
movq -0x330(%rbp), %rax
cmpq %rcx, %rax
jb 0x868a5
movb $0x1, -0x142(%rbp)
movl $0x10, %edi
callq 0x71a0
movq %rax, -0x340(%rbp)
leaq -0x141(%rbp), %rdi
movq %rdi, -0x338(%rbp)
callq 0x7650
movq -0x338(%rbp), %rdx
leaq 0xbd21e(%rip), %rsi     # 0x143a2c
leaq -0x140(%rbp), %rdi
callq 0x7520
jmp 0x8681c
movq -0x340(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x9c50
jmp 0x86831
movq -0x340(%rbp), %rdi
movb $0x0, -0x142(%rbp)
leaq 0x127592(%rip), %rsi    # 0x1addd8
leaq -0x7cbbd(%rip), %rdx    # 0x9c90
callq 0x7610
jmp 0x870f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x8687d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x7708
leaq -0x141(%rbp), %rdi
callq 0x73d0
testb $0x1, -0x142(%rbp)
jne 0x86894
jmp 0x868a0
movq -0x340(%rbp), %rdi
callq 0x72c0
jmp 0x870e5
movq -0x2c0(%rbp), %rdi
movq -0x30(%rbp), %rsi
movl -0x68(%rbp), %edx
callq 0x24050
movl %eax, -0x344(%rbp)
jmp 0x868c0
movl -0x344(%rbp), %ecx
movl -0x28(%rbp), %eax
addl %ecx, %eax
movl %eax, -0x28(%rbp)
movq -0x30(%rbp), %rdi
addq $0x68, %rdi
movl -0x68(%rbp), %eax
movl %eax, %esi
callq 0x8570
movl (%rax), %eax
movl %eax, -0x34(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x150(%rbp)
movq -0x30(%rbp), %rdi
addq $0x68, %rdi
movl -0x68(%rbp), %eax
movl %eax, %esi
callq 0x8570
movq -0x2c0(%rbp), %rdi
movl (%rax), %esi
callq 0xea90
movq %rax, -0x350(%rbp)
jmp 0x86919
movq -0x350(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x1, 0x18(%rax)
jbe 0x869c7
movq -0x2c0(%rbp), %rdi
movq -0x150(%rbp), %rsi
movl -0x68(%rbp), %edx
callq 0x24290
movl %eax, -0x354(%rbp)
jmp 0x86950
movq -0x2c0(%rbp), %rsi
movl -0x354(%rbp), %eax
movl %eax, -0x60(%rbp)
movq -0x150(%rbp), %rdx
movl -0x68(%rbp), %ecx
leaq -0x190(%rbp), %rdi
callq 0x2c660
jmp 0x86978
leaq -0x190(%rbp), %rdi
movl $0x4, %esi
callq 0xef50
movb %al, -0x355(%rbp)
jmp 0x86991
movb -0x355(%rbp), %al
andb $0x1, %al
movb %al, -0x59(%rbp)
leaq -0x190(%rbp), %rdi
callq 0xf250
jmp 0x869cb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x190(%rbp), %rdi
callq 0xf250
jmp 0x870e5
movb $0x0, -0x59(%rbp)
jmp 0x87081
movq -0x30(%rbp), %rax
cmpl $0x1, 0x18(%rax)
jbe 0x86cc0
movq -0x2c0(%rbp), %rdi
movl -0x68(%rbp), %esi
callq 0xa2eb0
movq %rax, -0x360(%rbp)
jmp 0x869f6
movq -0x360(%rbp), %rax
movq %rax, -0x198(%rbp)
cmpq $0x0, -0x198(%rbp)
je 0x86a8b
movq -0x2c0(%rbp), %rdi
movl -0x68(%rbp), %esi
callq 0x31910
movq %rax, -0x368(%rbp)
jmp 0x86a26
movq -0x368(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x2f560
movl %eax, -0x36c(%rbp)
jmp 0x86a3e
movl -0x36c(%rbp), %eax
movl %eax, -0x68(%rbp)
movl -0x68(%rbp), %eax
movl %eax, -0x370(%rbp)
testb $0x1, -0x59(%rbp)
je 0x86a68
movq -0x30(%rbp), %rax
movl 0x10(%rax), %eax
shrl $0x3, %eax
movl %eax, -0x374(%rbp)
jmp 0x86a71
movl -0x60(%rbp), %eax
movl %eax, -0x374(%rbp)
movl -0x370(%rbp), %eax
movl -0x374(%rbp), %ecx
imull %ecx, %eax
addl -0x28(%rbp), %eax
movl %eax, -0x28(%rbp)
jmp 0x86c78
testb $0x1, -0x59(%rbp)
je 0x86aa3
movq -0x30(%rbp), %rax
movl 0x10(%rax), %eax
shrl $0x3, %eax
movl %eax, -0x378(%rbp)
jmp 0x86aac
movl -0x60(%rbp), %eax
movl %eax, -0x378(%rbp)
movl -0x378(%rbp), %eax
movl %eax, -0x19c(%rbp)
movl -0x19c(%rbp), %eax
xorl %edx, %edx
divl 0x10(%rbp)
cmpl $0x0, %edx
je 0x86b9c
movb $0x1, -0x1c2(%rbp)
movl $0x10, %edi
callq 0x71a0
movq %rax, -0x388(%rbp)
leaq -0x1c1(%rbp), %rdi
movq %rdi, -0x380(%rbp)
callq 0x7650
movq -0x380(%rbp), %rdx
leaq 0xbd3cc(%rip), %rsi     # 0x143ed1
leaq -0x1c0(%rbp), %rdi
callq 0x7520
jmp 0x86b13
movq -0x388(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x9c50
jmp 0x86b28
movq -0x388(%rbp), %rdi
movb $0x0, -0x1c2(%rbp)
leaq 0x12729b(%rip), %rsi    # 0x1addd8
leaq -0x7ceb4(%rip), %rdx    # 0x9c90
callq 0x7610
jmp 0x870f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x86b74
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x1c0(%rbp), %rdi
callq 0x7708
leaq -0x1c1(%rbp), %rdi
callq 0x73d0
testb $0x1, -0x1c2(%rbp)
jne 0x86b8b
jmp 0x86b97
movq -0x388(%rbp), %rdi
callq 0x72c0
jmp 0x870e5
movq -0x2c0(%rbp), %rsi
movl -0x68(%rbp), %edx
leaq -0x1e8(%rbp), %rdi
callq 0x72630
jmp 0x86bb4
leaq -0x58(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x7470
jmp 0x86bc6
leaq -0x1e8(%rbp), %rdi
callq 0x7708
leaq 0xbce4f(%rip), %rsi     # 0x143a28
leaq -0x58(%rbp), %rdi
callq 0x7340
jmp 0x86be4
movl -0x19c(%rbp), %eax
movl 0x10(%rbp), %ecx
xorl %edx, %edx
divl %ecx
movl %eax, -0x20c(%rbp)
leaq -0x208(%rbp), %rdi
leaq -0x20c(%rbp), %rsi
callq 0xa22d0
jmp 0x86c0c
leaq -0x58(%rbp), %rdi
leaq -0x208(%rbp), %rsi
callq 0x7470
jmp 0x86c1e
leaq -0x208(%rbp), %rdi
callq 0x7708
leaq 0xc6700(%rip), %rsi     # 0x14d331
leaq -0x58(%rbp), %rdi
callq 0x7340
jmp 0x86c3c
jmp 0x86c78
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x7708
jmp 0x870e5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x208(%rbp), %rdi
callq 0x7708
jmp 0x870e5
movq -0x2c0(%rbp), %rdi
movq -0x30(%rbp), %rax
movl 0x9c(%rax), %eax
movl %eax, -0x210(%rbp)
movq -0x30(%rbp), %rax
movl 0x9c(%rax), %esi
callq 0xea90
movq %rax, -0x390(%rbp)
jmp 0x86ca7
movq -0x390(%rbp), %rax
movq %rax, -0x30(%rbp)
movl -0x210(%rbp), %eax
movl %eax, -0x34(%rbp)
jmp 0x8707f
movq -0x30(%rbp), %rax
cmpl $0x1, 0x14(%rax)
jbe 0x86fb0
movq -0x2c0(%rbp), %rdi
movl -0x68(%rbp), %esi
callq 0xa2eb0
movq %rax, -0x398(%rbp)
jmp 0x86ce6
movq -0x398(%rbp), %rax
movq %rax, -0x218(%rbp)
cmpq $0x0, -0x218(%rbp)
je 0x86d7b
movq -0x2c0(%rbp), %rdi
movl -0x68(%rbp), %esi
callq 0x31910
movq %rax, -0x3a0(%rbp)
jmp 0x86d16
movq -0x3a0(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x2f560
movl %eax, -0x3a4(%rbp)
jmp 0x86d2e
movl -0x3a4(%rbp), %eax
movl %eax, -0x68(%rbp)
movl -0x68(%rbp), %eax
movl %eax, -0x3a8(%rbp)
testb $0x1, -0x59(%rbp)
je 0x86d51
movl -0x60(%rbp), %eax
movl %eax, -0x3ac(%rbp)
jmp 0x86d61
movq -0x30(%rbp), %rax
movl 0x10(%rax), %eax
shrl $0x3, %eax
movl %eax, -0x3ac(%rbp)
movl -0x3a8(%rbp), %eax
movl -0x3ac(%rbp), %ecx
imull %ecx, %eax
addl -0x28(%rbp), %eax
movl %eax, -0x28(%rbp)
jmp 0x86f68
testb $0x1, -0x59(%rbp)
je 0x86d8c
movl -0x60(%rbp), %eax
movl %eax, -0x3b0(%rbp)
jmp 0x86d9c
movq -0x30(%rbp), %rax
movl 0x10(%rax), %eax
shrl $0x3, %eax
movl %eax, -0x3b0(%rbp)
movl -0x3b0(%rbp), %eax
movl %eax, -0x21c(%rbp)
movl -0x21c(%rbp), %eax
xorl %edx, %edx
divl 0x10(%rbp)
cmpl $0x0, %edx
je 0x86e8c
movb $0x1, -0x242(%rbp)
movl $0x10, %edi
callq 0x71a0
movq %rax, -0x3c0(%rbp)
leaq -0x241(%rbp), %rdi
movq %rdi, -0x3b8(%rbp)
callq 0x7650
movq -0x3b8(%rbp), %rdx
leaq 0xbd1b7(%rip), %rsi     # 0x143fac
leaq -0x240(%rbp), %rdi
callq 0x7520
jmp 0x86e03
movq -0x3c0(%rbp), %rdi
leaq -0x240(%rbp), %rsi
callq 0x9c50
jmp 0x86e18
movq -0x3c0(%rbp), %rdi
movb $0x0, -0x242(%rbp)
leaq 0x126fab(%rip), %rsi    # 0x1addd8
leaq -0x7d1a4(%rip), %rdx    # 0x9c90
callq 0x7610
jmp 0x870f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x86e64
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x240(%rbp), %rdi
callq 0x7708
leaq -0x241(%rbp), %rdi
callq 0x73d0
testb $0x1, -0x242(%rbp)
jne 0x86e7b
jmp 0x86e87
movq -0x3c0(%rbp), %rdi
callq 0x72c0
jmp 0x870e5
movq -0x2c0(%rbp), %rsi
movl -0x68(%rbp), %edx
leaq -0x268(%rbp), %rdi
callq 0x72630
jmp 0x86ea4
leaq -0x58(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0x7470
jmp 0x86eb6
leaq -0x268(%rbp), %rdi
callq 0x7708
leaq 0xbcb5f(%rip), %rsi     # 0x143a28
leaq -0x58(%rbp), %rdi
callq 0x7340
jmp 0x86ed4
movl -0x21c(%rbp), %eax
movl 0x10(%rbp), %ecx
xorl %edx, %edx
divl %ecx
movl %eax, -0x28c(%rbp)
leaq -0x288(%rbp), %rdi
leaq -0x28c(%rbp), %rsi
callq 0xa22d0
jmp 0x86efc
leaq -0x58(%rbp), %rdi
leaq -0x288(%rbp), %rsi
callq 0x7470
jmp 0x86f0e
leaq -0x288(%rbp), %rdi
callq 0x7708
leaq 0xc6410(%rip), %rsi     # 0x14d331
leaq -0x58(%rbp), %rdi
callq 0x7340
jmp 0x86f2c
jmp 0x86f68
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x268(%rbp), %rdi
callq 0x7708
jmp 0x870e5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x288(%rbp), %rdi
callq 0x7708
jmp 0x870e5
movq -0x2c0(%rbp), %rdi
movq -0x30(%rbp), %rax
movl 0x9c(%rax), %eax
movl %eax, -0x290(%rbp)
movq -0x30(%rbp), %rax
movl 0x9c(%rax), %esi
callq 0xea90
movq %rax, -0x3c8(%rbp)
jmp 0x86f97
movq -0x3c8(%rbp), %rax
movq %rax, -0x30(%rbp)
movl -0x290(%rbp), %eax
movl %eax, -0x34(%rbp)
jmp 0x8707d
movb $0x1, -0x2b2(%rbp)
movl $0x10, %edi
callq 0x71a0
movq %rax, -0x3d8(%rbp)
leaq -0x2b1(%rbp), %rdi
movq %rdi, -0x3d0(%rbp)
callq 0x7650
movq -0x3d0(%rbp), %rdx
leaq 0xbca62(%rip), %rsi     # 0x143a4b
leaq -0x2b0(%rbp), %rdi
callq 0x7520
jmp 0x86ff7
movq -0x3d8(%rbp), %rdi
leaq -0x2b0(%rbp), %rsi
callq 0x9c50
jmp 0x8700c
movq -0x3d8(%rbp), %rdi
movb $0x0, -0x2b2(%rbp)
leaq 0x126db7(%rip), %rsi    # 0x1addd8
leaq -0x7d398(%rip), %rdx    # 0x9c90
callq 0x7610
jmp 0x870f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x87058
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0x7708
leaq -0x2b1(%rbp), %rdi
callq 0x73d0
testb $0x1, -0x2b2(%rbp)
jne 0x8706f
jmp 0x8707b
movq -0x3d8(%rbp), %rdi
callq 0x72c0
jmp 0x870e5
jmp 0x8707f
jmp 0x87081
jmp 0x87083
jmp 0x87085
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x863cb
cmpq $0x0, 0x18(%rbp)
je 0x870a6
movb -0x59(%rbp), %cl
movq 0x18(%rbp), %rax
andb $0x1, %cl
movb %cl, (%rax)
cmpq $0x0, 0x20(%rbp)
je 0x870b6
movl -0x60(%rbp), %ecx
movq 0x20(%rbp), %rax
movl %ecx, (%rax)
movq -0x2d0(%rbp), %rdi
leaq -0x58(%rbp), %rsi
leaq -0x28(%rbp), %rdx
callq 0xa49d0
jmp 0x870cc
leaq -0x58(%rbp), %rdi
callq 0x7708
movq -0x2c8(%rbp), %rax
addq $0x3e0, %rsp            # imm = 0x3E0
popq %rbp
retq
leaq -0x58(%rbp), %rdi
callq 0x7708
movq -0x78(%rbp), %rdi
callq 0x7640
nopw (%rax,%rax)