// File: /workspace/github_cpp_makefile_star2_O3/rossy[P]crossc/SPIRV-Cross/spirv_glsl.cpp
// Function: spirv_cross::CompilerGLSL::build_composite_combiner[abi:cxx11](unsigned int, unsigned int const*, unsigned int)
string CompilerGLSL::build_composite_combiner(uint32_t return_type, const uint32_t *elems, uint32_t length)
{
	uint32_t base = 0;
	string op;
	string subop;

	// Can only merge swizzles for vectors.
	auto &type = get<SPIRType>(return_type);
	bool can_apply_swizzle_opt = type.basetype != SPIRType::Struct && type.array.empty() && type.columns == 1;
	bool swizzle_optimization = false;

	for (uint32_t i = 0; i < length; i++)
	{
		auto *e = maybe_get<SPIRExpression>(elems[i]);

		// If we're merging another scalar which belongs to the same base
		// object, just merge the swizzles to avoid triggering more than 1 expression read as much as possible!
		if (can_apply_swizzle_opt && e && e->base_expression && e->base_expression == base)
		{
			// Only supposed to be used for vector swizzle -> scalar.
			assert(!e->expression.empty() && e->expression.front() == '.');
			subop += e->expression.substr(1, string::npos);
			swizzle_optimization = true;
		}
		else
		{
			// We'll likely end up with duplicated swizzles, e.g.
			// foobar.xyz.xyz from patterns like
			// OpVectorShuffle
			// OpCompositeExtract x 3
			// OpCompositeConstruct 3x + other scalar.
			// Just modify op in-place.
			if (swizzle_optimization)
			{
				if (backend.swizzle_is_function)
					subop += "()";

				// Don't attempt to remove unity swizzling if we managed to remove duplicate swizzles.
				// The base "foo" might be vec4, while foo.xyz is vec3 (OpVectorShuffle) and looks like a vec3 due to the .xyz tacked on.
				// We only want to remove the swizzles if we're certain that the resulting base will be the same vecsize.
				// Essentially, we can only remove one set of swizzles, since that's what we have control over ...
				// Case 1:
				//  foo.yxz.xyz: Duplicate swizzle kicks in, giving foo.yxz, we are done.
				//               foo.yxz was the result of OpVectorShuffle and we don't know the type of foo.
				// Case 2:
				//  foo.xyz: Duplicate swizzle won't kick in.
				//           If foo is vec3, we can remove xyz, giving just foo.
				if (!remove_duplicate_swizzle(subop))
					remove_unity_swizzle(base, subop);

				// Strips away redundant parens if we created them during component extraction.
				strip_enclosed_expression(subop);
				swizzle_optimization = false;
				op += subop;
			}
			else
				op += subop;

			if (i)
				op += ", ";
			subop = to_expression(elems[i]);
		}

		base = e ? e->base_expression : 0;
	}

	if (swizzle_optimization)
	{
		if (backend.swizzle_is_function)
			subop += "()";

		if (!remove_duplicate_swizzle(subop))
			remove_unity_swizzle(base, subop);
		// Strips away redundant parens if we created them during component extraction.
		strip_enclosed_expression(subop);
	}

	op += subop;
	return op;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %r8d, %ebx
movq %rcx, %r15
movq %rsi, %r14
leaq 0x10(%rdi), %r12
movq %r12, (%rdi)
xorl %eax, %eax
movq %rax, 0x8(%rdi)
movq %rdi, 0x10(%rsp)
movb %al, 0x10(%rdi)
leaq 0x28(%rsp), %r13
movq %r13, -0x10(%r13)
movq %rax, -0x8(%r13)
movb %al, (%r13)
movq %rsi, %rdi
movl %edx, %esi
movq %r12, 0x58(%rsp)
callq 0xa3ea
cmpl $0xc, 0xc(%rax)
je 0x43d6c
movq 0x20(%rax), %rcx
cmpq 0x28(%rax), %rcx
je 0x43fa3
movl $0x0, 0xc(%rsp)
testl %ebx, %ebx
je 0x43f64
movl %ebx, %eax
movq %rax, 0x60(%rsp)
xorl %r12d, %r12d
movl 0xc(%rsp), %eax
xorb $0x1, %al
movl %eax, 0xc(%rsp)
xorl %ebx, %ebx
xorl %r13d, %r13d
movl (%r15,%r12,4), %esi
movq %r14, %rdi
callq 0x1b3b6
movq %rax, %rbp
testq %rax, %rax
sete %al
orb 0xc(%rsp), %al
jne 0x43e2f
movl 0xc(%rbp), %eax
testl %eax, %eax
setne %cl
cmpl %ebx, %eax
sete %al
andb %cl, %al
cmpb $0x1, %al
jne 0x43e2f
cmpq $0x0, 0x18(%rbp)
je 0x43fb3
movq %rbp, %rsi
addq $0x10, %rsi
movq (%rsi), %rax
cmpb $0x2e, (%rax)
jne 0x43fb3
movl $0x1, %edx
leaq 0x38(%rsp), %rdi
movq $-0x1, %rcx
callq 0x6290
movq 0x38(%rsp), %rsi
movq 0x40(%rsp), %rdx
leaq 0x18(%rsp), %rdi
callq 0x60b0
movq 0x38(%rsp), %rdi
leaq 0x48(%rsp), %rax
cmpq %rax, %rdi
je 0x43e27
movq 0x48(%rsp), %rsi
incq %rsi
callq 0x6260
movb $0x1, %r13b
jmp 0x43eff
testb $0x1, %r13b
je 0x43e93
cmpb $0x1, 0x620(%r14)
jne 0x43e50
leaq 0x18(%rsp), %rdi
leaq 0x74b05(%rip), %rsi     # 0xb8950
callq 0x64e0
movq %r14, %rdi
leaq 0x18(%rsp), %rsi
callq 0x32d38
testb %al, %al
jne 0x43e70
movq %r14, %rdi
movl %ebx, %esi
leaq 0x18(%rsp), %rdx
callq 0x43b1c
leaq 0x18(%rsp), %rsi
callq 0x34594
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rdx
movq 0x10(%rsp), %rdi
callq 0x60b0
xorl %r13d, %r13d
jmp 0x43ea7
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rdx
movq 0x10(%rsp), %rdi
callq 0x60b0
testq %r12, %r12
je 0x43ebd
movq 0x10(%rsp), %rdi
leaq 0x761f3(%rip), %rsi     # 0xba0ab
callq 0x64e0
movl (%r15,%r12,4), %edx
leaq 0x38(%rsp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x33f8a
leaq 0x18(%rsp), %rdi
movq %rbx, %rsi
callq 0x6310
movq 0x38(%rsp), %rdi
leaq 0x48(%rsp), %rax
cmpq %rax, %rdi
je 0x43efa
movq 0x48(%rsp), %rsi
incq %rsi
callq 0x6260
testq %rbp, %rbp
je 0x43f04
movl 0xc(%rbp), %ebx
jmp 0x43f06
xorl %ebx, %ebx
incq %r12
cmpq %r12, 0x60(%rsp)
jne 0x43d95
testb $0x1, %r13b
leaq 0x28(%rsp), %r13
je 0x43f64
cmpb $0x1, 0x620(%r14)
jne 0x43f3a
leaq 0x74a20(%rip), %rsi     # 0xb8950
leaq 0x18(%rsp), %rdi
callq 0x64e0
leaq 0x18(%rsp), %rsi
movq %r14, %rdi
callq 0x32d38
testb %al, %al
jne 0x43f5a
leaq 0x18(%rsp), %rdx
movq %r14, %rdi
movl %ebx, %esi
callq 0x43b1c
leaq 0x18(%rsp), %rsi
callq 0x34594
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rdx
movq 0x10(%rsp), %rdi
callq 0x60b0
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x43f8f
movq 0x28(%rsp), %rsi
incq %rsi
callq 0x6260
movq 0x10(%rsp), %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x1, 0x18(%rax)
sete %al
movl %eax, 0xc(%rsp)
jmp 0x43d74
leaq 0x75c05(%rip), %rdi     # 0xb9bbf
leaq 0x72d87(%rip), %rsi     # 0xb6d48
leaq 0x75c2e(%rip), %rcx     # 0xb9bf6
movl $0x17ba, %edx           # imm = 0x17BA
callq 0x61b0
jmp 0x43ffb
jmp 0x43ffb
movq %rax, %rbx
movq 0x38(%rsp), %rdi
leaq 0x48(%rsp), %rax
cmpq %rax, %rdi
je 0x43ffe
movq 0x48(%rsp), %rsi
incq %rsi
callq 0x6260
jmp 0x43ffe
jmp 0x43ffb
jmp 0x43ffb
movq %rax, %rbx
movq 0x18(%rsp), %rdi
leaq 0x28(%rsp), %rax
cmpq %rax, %rdi
je 0x4401a
movq 0x28(%rsp), %rsi
incq %rsi
callq 0x6260
movq 0x10(%rsp), %rax
movq (%rax), %rdi
movq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x44037
movq (%rax), %rsi
incq %rsi
callq 0x6260
movq %rbx, %rdi
callq 0x64a0
nop