// File: /workspace/github_cpp_makefile_star2_O3/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 0x1b2ac
movq %rax, %r14
movl 0x8(%r15), %r13d
movl 0x8(%rax), %esi
movq %rbx, %rdi
callq 0x12a72
movq %rax, %r12
cmpl $0xc, 0x64(%rax)
je 0x6ea1a
movl 0x8(%r12), %esi
movq %rbx, %rdi
movl $0x3, %edx
callq 0x12974
testb %al, %al
je 0x6ea40
leal -0x3(%r13), %eax
movq 0x28(%r12), %rbp
subq 0x20(%r12), %rbp
sarq $0x2, %rbp
cmpq %rax, %rbp
jae 0x6eaf5
movq $0x0, 0x10(%rsp)
jmp 0x6ea68
movl 0x8(%r14), %esi
movq %rbx, %rdi
callq 0x1b3f0
testq %rax, %rax
je 0x6eaf5
movq %rax, 0x10(%rsp)
movq 0x28(%r12), %rbp
subq 0x20(%r12), %rbp
sarq $0x2, %rbp
movl 0x8(%r14), %esi
movq %rbx, %rdi
callq 0x12c9a
movq %rax, 0x60(%rsp)
leaq 0x50(%rsp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
testl %ebp, %ebp
je 0x6eb0e
movl (%r14), %esi
movl 0x8(%r14), %r15d
movq %rbx, %rdi
callq 0xa3ea
leaq 0xc(%r14), %rcx
leaq 0xc(%rsp), %r10
leaq 0x18(%rsp), %rdi
movq %rbx, %rsi
movl %r15d, %edx
movl %ebp, %r8d
movq %rax, %r9
pushq $0x0
pushq %r10
callq 0x41b4e
addq $0x10, %rsp
leaq 0x40(%rsp), %rdi
leaq 0x18(%rsp), %r15
movq %r15, %rsi
callq 0x6310
movq (%r15), %rdi
leaq 0x28(%rsp), %rax
cmpq %rax, %rdi
je 0x6eb2a
movq 0x28(%rsp), %rsi
incq %rsi
callq 0x6260
jmp 0x6eb2a
movq %rbx, %rdi
movq %r15, %rsi
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x44260
movq 0x10(%rsp), %rax
testq %rax, %rax
je 0x6ec8f
leaq 0x18(%rax), %rsi
leaq 0x40(%rsp), %rdi
callq 0x6170
movq %rbx, %rdi
movq %r12, %rsi
callq 0x14ac0
testl %ebp, %ebp
je 0x6eb57
movl %ebp, %r15d
movl 0x9c(%rax), %esi
testl %esi, %esi
je 0x6eca5
movq %rbx, %rdi
callq 0xa3ea
decl %r15d
jne 0x6eb3c
movl $0x0, 0xc(%rsp)
movb $0x0, 0xb(%rsp)
movq 0x10(%rsp), %rdx
testq %rdx, %rdx
je 0x6eb7c
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 0x20(%rsp), %rdi
movq %rbx, %rsi
movq %rax, %rdx
movl %r13d, %r8d
xorl %r9d, %r9d
pushq %r10
pushq %r11
pushq $0x1
callq 0x41e64
addq $0x20, %rsp
addq $0x64, %r12
movl 0x4(%r14), %esi
leaq 0x38(%rsp), %rax
subq $0x8, %rsp
leaq 0x48(%rsp), %r8
leaq 0x20(%rsp), %r9
movq %rbx, %rdi
movq %r14, %rdx
movq %r12, %rcx
pushq %rax
callq 0x7b498
addq $0x10, %rsp
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 0x39684
movb %al, 0x65(%r15)
movq 0x60(%rsp), %rax
testq %rax, %rax
je 0x6ec1f
movl 0x8(%rax), %eax
jmp 0x6ec21
xorl %eax, %eax
movl %eax, 0x5c(%r15)
testq %r12, %r12
je 0x6ec49
movq %r15, %rdi
addq $0x38, %rdi
movq 0x38(%r12), %rsi
movq 0x40(%r12), %rdx
callq 0x60b0
movl 0x58(%r12), %eax
addl %eax, 0x58(%r15)
leaq 0x28(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x6ec64
movq 0x28(%rsp), %rsi
incq %rsi
callq 0x6260
movq 0x40(%rsp), %rdi
leaq 0x50(%rsp), %rax
cmpq %rax, %rdi
je 0x6ec80
movq 0x50(%rsp), %rsi
incq %rsi
callq 0x6260
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl 0x8(%r14), %edx
leaq 0x18(%rsp), %rdi
movq %rbx, %rsi
callq 0x33f8a
jmp 0x6eac7
leaq 0x4f7bf(%rip), %rdi     # 0xbe46b
leaq 0x4f7ce(%rip), %rsi     # 0xbe481
leaq 0x4f7e2(%rip), %rcx     # 0xbe49c
movl $0xdf1, %edx            # imm = 0xDF1
callq 0x61b0
jmp 0x6ecee
jmp 0x6ecee
jmp 0x6ecee
jmp 0x6ecee
jmp 0x6ecee
movq %rax, %rbx
leaq 0x28(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x6ecf1
movq 0x28(%rsp), %rsi
incq %rsi
callq 0x6260
jmp 0x6ecf1
movq %rax, %rbx
movq 0x40(%rsp), %rdi
leaq 0x50(%rsp), %rax
cmpq %rax, %rdi
je 0x6ed0d
movq 0x50(%rsp), %rsi
incq %rsi
callq 0x6260
movq %rbx, %rdi
callq 0x64a0
nop