// File: /workspace/github_cpp_makefile_star2_O2/rossy[P]crossc/SPIRV-Cross/spirv_hlsl.cpp
// Function: spirv_cross::CompilerHLSL::emit_access_chain(spirv_cross::Instruction const&)
void CompilerHLSL::emit_access_chain(const Instruction &instruction)
{
	auto ops = stream(instruction);
	uint32_t length = instruction.length;

	bool need_byte_access_chain = false;
	auto &type = expression_type(ops[2]);
	const SPIRAccessChain *chain = nullptr;
	if (type.storage == StorageClassStorageBuffer || has_decoration(type.self, DecorationBufferBlock))
	{
		// If we are starting to poke into an SSBO, we are dealing with ByteAddressBuffers, and we need
		// to emit SPIRAccessChain rather than a plain SPIRExpression.
		uint32_t chain_arguments = length - 3;
		if (chain_arguments > type.array.size())
			need_byte_access_chain = true;
	}
	else
	{
		// Keep tacking on an existing access chain.
		chain = maybe_get<SPIRAccessChain>(ops[2]);
		if (chain)
			need_byte_access_chain = true;
	}

	if (need_byte_access_chain)
	{
		uint32_t to_plain_buffer_length = static_cast<uint32_t>(type.array.size());
		auto *backing_variable = maybe_get_backing_variable(ops[2]);

		string base;
		if (to_plain_buffer_length != 0)
		{
			bool need_transpose;
			base = access_chain(ops[2], &ops[3], to_plain_buffer_length, get<SPIRType>(ops[0]), &need_transpose);
		}
		else if (chain)
			base = chain->base;
		else
			base = to_expression(ops[2]);

		// Start traversing type hierarchy at the proper non-pointer types.
		auto *basetype = &get_non_pointer_type(type);

		// Traverse the type hierarchy down to the actual buffer types.
		for (uint32_t i = 0; i < to_plain_buffer_length; i++)
		{
			assert(basetype->parent_type);
			basetype = &get<SPIRType>(basetype->parent_type);
		}

		uint32_t matrix_stride = 0;
		bool row_major_matrix = false;

		// Inherit matrix information.
		if (chain)
		{
			matrix_stride = chain->matrix_stride;
			row_major_matrix = chain->row_major_matrix;
		}

		auto offsets =
		    flattened_access_chain_offset(*basetype, &ops[3 + to_plain_buffer_length],
		                                  length - 3 - to_plain_buffer_length, 0, 1, &row_major_matrix, &matrix_stride);

		auto &e = set<SPIRAccessChain>(ops[1], ops[0], type.storage, base, offsets.first, offsets.second);
		e.row_major_matrix = row_major_matrix;
		e.matrix_stride = matrix_stride;
		e.immutable = should_forward(ops[2]);
		e.loaded_from = backing_variable ? backing_variable->self : 0;

		if (chain)
		{
			e.dynamic_index += chain->dynamic_index;
			e.static_index += chain->static_index;
		}
	}
	else
	{
		CompilerGLSL::emit_instruction(instruction);
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rsi, %r15
movq %rdi, %rbx
callq 0x16f1e
movq %rax, %r14
movl 0x8(%r15), %r13d
movl 0x8(%rax), %esi
movq %rbx, %rdi
callq 0x104b0
movq %rax, %r12
cmpl $0xc, 0x64(%rax)
je 0x59894
movl 0x8(%r12), %esi
pushq $0x3
popq %rdx
movq %rbx, %rdi
callq 0x103d2
testb %al, %al
je 0x598ba
leal -0x3(%r13), %eax
movq 0x28(%r12), %rbp
subq 0x20(%r12), %rbp
sarq $0x2, %rbp
cmpq %rax, %rbp
jae 0x59958
movq $0x0, 0x10(%rsp)
jmp 0x598e2
movl 0x8(%r14), %esi
movq %rbx, %rdi
callq 0x17014
testq %rax, %rax
je 0x59958
movq %rax, 0x10(%rsp)
movq 0x28(%r12), %rbp
subq 0x20(%r12), %rbp
sarq $0x2, %rbp
movl 0x8(%r14), %esi
movq %rbx, %rdi
callq 0x1067e
leaq 0x58(%rsp), %rcx
movq %rcx, -0x10(%rcx)
andq $0x0, -0x8(%rcx)
movq %rax, 0x18(%rsp)
movb $0x0, (%rcx)
testl %ebp, %ebp
je 0x59971
movl (%r14), %esi
movl 0x8(%r14), %r15d
movq %rbx, %rdi
callq 0x90a4
leaq 0xc(%r14), %rcx
leaq 0xc(%rsp), %r10
leaq 0x20(%rsp), %rdi
movq %rbx, %rsi
movl %r15d, %edx
movl %ebp, %r8d
movq %rax, %r9
pushq $0x0
pushq %r10
callq 0x35814
popq %rax
popq %rcx
leaq 0x48(%rsp), %rdi
leaq 0x20(%rsp), %r15
movq %r15, %rsi
callq 0x6320
movq %r15, %rdi
callq 0x6548
jmp 0x5998d
movq %rbx, %rdi
movq %r15, %rsi
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x374a8
movq 0x10(%rsp), %rax
testq %rax, %rax
je 0x59ac4
leaq 0x18(%rax), %rsi
leaq 0x48(%rsp), %rdi
callq 0x6170
movq %rbx, %rdi
movq %r12, %rsi
callq 0x11e4a
addq $0x64, %r12
movl %ebp, %r15d
subl $0x1, %r15d
jb 0x599bd
movl 0x9c(%rax), %esi
testl %esi, %esi
je 0x59ada
movq %rbx, %rdi
callq 0x90a4
jmp 0x5999f
andl $0x0, 0xc(%rsp)
movb $0x0, 0xb(%rsp)
movq 0x10(%rsp), %rdx
testq %rdx, %rdx
je 0x599df
movl 0x60(%rdx), %ecx
movl %ecx, 0xc(%rsp)
movb 0x64(%rdx), %cl
movb %cl, 0xb(%rsp)
movl %ebp, %ecx
addl $0x3, %ecx
leaq (%r14,%rcx,4), %rcx
subl %ebp, %r13d
addl $-0x3, %r13d
subq $0x8, %rsp
leaq 0x14(%rsp), %r10
leaq 0x13(%rsp), %r11
leaq 0x28(%rsp), %rdi
movq %rbx, %rsi
movq %rax, %rdx
movl %r13d, %r8d
xorl %r9d, %r9d
pushq %r10
pushq %r11
pushq $0x1
callq 0x35a84
addq $0x20, %rsp
movl 0x4(%r14), %esi
leaq 0x40(%rsp), %rax
subq $0x8, %rsp
leaq 0x50(%rsp), %r8
leaq 0x28(%rsp), %r9
movq %rbx, %rdi
movq %r14, %rdx
movq %r12, %rcx
pushq %rax
callq 0x63314
popq %rcx
popq %rdx
movq 0x10(%rsp), %r12
movq %rax, %r15
movb 0xb(%rsp), %al
movb %al, 0x64(%r15)
movl 0xc(%rsp), %eax
movl %eax, 0x60(%r15)
movl 0x8(%r14), %esi
movq %rbx, %rdi
callq 0x2f360
movb %al, 0x65(%r15)
movq 0x18(%rsp), %rax
testq %rax, %rax
je 0x59a7c
movl 0x8(%rax), %eax
jmp 0x59a7e
xorl %eax, %eax
movl %eax, 0x5c(%r15)
testq %r12, %r12
je 0x59aa1
leaq 0x38(%r12), %rsi
movq %r15, %rdi
addq $0x38, %rdi
callq 0x64f0
movl 0x58(%r12), %eax
addl %eax, 0x58(%r15)
leaq 0x20(%rsp), %rdi
callq 0x6548
leaq 0x48(%rsp), %rdi
callq 0x6548
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl 0x8(%r14), %edx
leaq 0x20(%rsp), %rdi
movq %rbx, %rsi
callq 0x2b9f0
jmp 0x5993c
leaq 0x3f91a(%rip), %rdi     # 0x993fb
leaq 0x3f929(%rip), %rsi     # 0x99411
leaq 0x3f93d(%rip), %rcx     # 0x9942c
movl $0xdf1, %edx            # imm = 0xDF1
callq 0x61c0
jmp 0x59b12
jmp 0x59b12
jmp 0x59b12
jmp 0x59b12
jmp 0x59b12
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x6548
jmp 0x59b15
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
callq 0x6548
movq %rbx, %rdi
callq 0x64b0
nop