// File: /workspace/github_cpp_makefile_star2_O2/rossy[P]crossc/SPIRV-Cross/spirv_glsl.cpp
// Function: spirv_cross::CompilerGLSL::emit_texture_op(spirv_cross::Instruction const&)
void CompilerGLSL::emit_texture_op(const Instruction &i)
{
	auto *ops = stream(i);
	auto op = static_cast<Op>(i.op);
	uint32_t length = i.length;

	vector<uint32_t> inherited_expressions;

	uint32_t result_type = ops[0];
	uint32_t id = ops[1];
	uint32_t img = ops[2];
	uint32_t coord = ops[3];
	uint32_t dref = 0;
	uint32_t comp = 0;
	bool gather = false;
	bool proj = false;
	bool fetch = false;
	const uint32_t *opt = nullptr;

	inherited_expressions.push_back(coord);

	switch (op)
	{
	case OpImageSampleDrefImplicitLod:
	case OpImageSampleDrefExplicitLod:
		dref = ops[4];
		opt = &ops[5];
		length -= 5;
		break;

	case OpImageSampleProjDrefImplicitLod:
	case OpImageSampleProjDrefExplicitLod:
		dref = ops[4];
		opt = &ops[5];
		length -= 5;
		proj = true;
		break;

	case OpImageDrefGather:
		dref = ops[4];
		opt = &ops[5];
		length -= 5;
		gather = true;
		break;

	case OpImageGather:
		comp = ops[4];
		opt = &ops[5];
		length -= 5;
		gather = true;
		break;

	case OpImageFetch:
	case OpImageRead: // Reads == fetches in Metal (other langs will not get here)
		opt = &ops[4];
		length -= 4;
		fetch = true;
		break;

	case OpImageSampleProjImplicitLod:
	case OpImageSampleProjExplicitLod:
		opt = &ops[4];
		length -= 4;
		proj = true;
		break;

	default:
		opt = &ops[4];
		length -= 4;
		break;
	}

	// Bypass pointers because we need the real image struct
	auto &type = expression_type(img);
	auto &imgtype = get<SPIRType>(type.self);

	uint32_t coord_components = 0;
	switch (imgtype.image.dim)
	{
	case spv::Dim1D:
		coord_components = 1;
		break;
	case spv::Dim2D:
		coord_components = 2;
		break;
	case spv::Dim3D:
		coord_components = 3;
		break;
	case spv::DimCube:
		coord_components = 3;
		break;
	case spv::DimBuffer:
		coord_components = 1;
		break;
	default:
		coord_components = 2;
		break;
	}

	if (dref)
		inherited_expressions.push_back(dref);

	if (proj)
		coord_components++;
	if (imgtype.image.arrayed)
		coord_components++;

	uint32_t bias = 0;
	uint32_t lod = 0;
	uint32_t grad_x = 0;
	uint32_t grad_y = 0;
	uint32_t coffset = 0;
	uint32_t offset = 0;
	uint32_t coffsets = 0;
	uint32_t sample = 0;
	uint32_t flags = 0;

	if (length)
	{
		flags = *opt++;
		length--;
	}

	auto test = [&](uint32_t &v, uint32_t flag) {
		if (length && (flags & flag))
		{
			v = *opt++;
			inherited_expressions.push_back(v);
			length--;
		}
	};

	test(bias, ImageOperandsBiasMask);
	test(lod, ImageOperandsLodMask);
	test(grad_x, ImageOperandsGradMask);
	test(grad_y, ImageOperandsGradMask);
	test(coffset, ImageOperandsConstOffsetMask);
	test(offset, ImageOperandsOffsetMask);
	test(coffsets, ImageOperandsConstOffsetsMask);
	test(sample, ImageOperandsSampleMask);

	string expr;
	bool forward = false;
	expr += to_function_name(img, imgtype, !!fetch, !!gather, !!proj, !!coffsets, (!!coffset || !!offset),
	                         (!!grad_x || !!grad_y), !!dref, lod);
	expr += "(";
	expr += to_function_args(img, imgtype, fetch, gather, proj, coord, coord_components, dref, grad_x, grad_y, lod,
	                         coffset, offset, bias, comp, sample, &forward);
	expr += ")";

	// texture(samplerXShadow) returns float. shadowX() returns vec4. Swizzle here.
	if (is_legacy() && image_is_comparison(imgtype, img))
		expr += ".r";

	emit_op(result_type, id, expr, forward);
	for (auto &inherit : inherited_expressions)
		inherit_expression_dependencies(id, inherit);

	switch (op)
	{
	case OpImageSampleDrefImplicitLod:
	case OpImageSampleImplicitLod:
	case OpImageSampleProjImplicitLod:
	case OpImageSampleProjDrefImplicitLod:
		register_control_dependent_expression(id);
		break;

	default:
		break;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x128, %rsp            # imm = 0x128
movq %rsi, %r15
movq %rdi, %rbx
callq 0x16f1e
movq %rax, %r14
movzwl (%r15), %r12d
movl 0x8(%r15), %r15d
movl %r15d, 0x10(%rsp)
xorps %xmm0, %xmm0
leaq 0xa0(%rsp), %r13
movaps %xmm0, (%r13)
andq $0x0, 0x10(%r13)
movl (%rax), %eax
movl %eax, 0x78(%rsp)
movl 0x4(%r14), %ebp
movl 0x8(%r14), %eax
movl %eax, 0x2c(%rsp)
movl 0xc(%r14), %eax
leaq 0x7c(%rsp), %rsi
movl %eax, (%rsi)
andl $0x0, 0x1c(%rsp)
movq %r13, %rdi
callq 0x6c06
leal -0x59(%r12), %eax
cmpl $0x9, %eax
ja 0x313a3
leaq 0x5f4d0(%rip), %rcx     # 0x907d0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl 0x10(%r14), %eax
movl %eax, 0x1c(%rsp)
addq $0x14, %r14
movq %r14, 0x20(%rsp)
addl $-0x5, %r15d
jmp 0x313b0
movl 0x10(%r14), %eax
movl %eax, 0x1c(%rsp)
addq $0x14, %r14
movq %r14, 0x20(%rsp)
addl $-0x5, %r15d
jmp 0x31364
addq $0x10, %r14
movq %r14, 0x20(%rsp)
addl $-0x4, %r15d
movl %r15d, 0x10(%rsp)
xorl %r14d, %r14d
movb $0x1, %al
movl %eax, 0x18(%rsp)
jmp 0x313c0
addq $0x10, %r14
movq %r14, 0x20(%rsp)
addl $-0x4, %r15d
movl %r15d, 0x10(%rsp)
movl $0x0, 0x18(%rsp)
movb $0x1, %r14b
jmp 0x313c0
movl 0x10(%r14), %eax
movl %eax, 0x1c(%rsp)
addq $0x14, %r14
movq %r14, 0x20(%rsp)
addl $-0x5, %r15d
movl %r15d, 0x10(%rsp)
movl $0x0, 0x18(%rsp)
movb $0x1, %al
movl %eax, 0x14(%rsp)
xorl %r14d, %r14d
jmp 0x313c8
addq $0x10, %r14
movq %r14, 0x20(%rsp)
addl $-0x4, %r15d
movl %r15d, 0x10(%rsp)
movl $0x0, 0x18(%rsp)
xorl %r14d, %r14d
movl $0x0, 0x14(%rsp)
movq $0x0, 0x30(%rsp)
movq %rbx, %rdi
movl 0x2c(%rsp), %esi
callq 0x104b0
movl 0x8(%rax), %esi
movq %rbx, %rdi
callq 0x90a4
movq %rax, %r15
movl 0x84(%rax), %eax
cmpq $0x6, %rax
jae 0x31403
leaq 0x60046(%rip), %rcx     # 0x91444
movl (%rcx,%rax,4), %eax
jmp 0x31406
pushq $0x2
popq %rax
movq %rax, 0x60(%rsp)
cmpl $0x0, 0x1c(%rsp)
je 0x31424
leaq 0xa0(%rsp), %rdi
leaq 0x1c(%rsp), %rsi
callq 0x6c06
movzbl 0x89(%r15), %eax
movl %eax, 0x68(%rsp)
andl $0x0, 0x5c(%rsp)
andl $0x0, 0x4c(%rsp)
andl $0x0, 0x48(%rsp)
andl $0x0, 0x44(%rsp)
andl $0x0, 0x40(%rsp)
andl $0x0, 0x3c(%rsp)
andl $0x0, 0x58(%rsp)
andl $0x0, 0x54(%rsp)
andl $0x0, 0x50(%rsp)
movl 0x10(%rsp), %eax
testl %eax, %eax
je 0x3147f
movq 0x20(%rsp), %rcx
leaq 0x4(%rcx), %rdx
movq %rdx, 0x20(%rsp)
movl (%rcx), %ecx
movl %ecx, 0x50(%rsp)
decl %eax
movl %eax, 0x10(%rsp)
movq %r15, 0x70(%rsp)
movq %r12, 0xe0(%rsp)
leaq 0x10(%rsp), %rax
leaq 0x108(%rsp), %rdi
movq %rax, (%rdi)
leaq 0x50(%rsp), %rax
movq %rax, 0x8(%rdi)
leaq 0x20(%rsp), %rax
movq %rax, 0x10(%rdi)
movq %r13, 0x18(%rdi)
leaq 0x5c(%rsp), %rsi
pushq $0x1
popq %rdx
callq 0x31874
leaq 0x108(%rsp), %rdi
leaq 0x4c(%rsp), %rsi
pushq $0x2
popq %rdx
callq 0x31874
leaq 0x108(%rsp), %rdi
leaq 0x48(%rsp), %rsi
pushq $0x4
popq %rdx
callq 0x31874
leaq 0x108(%rsp), %rdi
leaq 0x44(%rsp), %rsi
pushq $0x4
popq %rdx
callq 0x31874
leaq 0x108(%rsp), %rdi
leaq 0x40(%rsp), %rsi
pushq $0x8
popq %rdx
callq 0x31874
leaq 0x108(%rsp), %rdi
leaq 0x3c(%rsp), %rsi
pushq $0x10
popq %rdx
callq 0x31874
leaq 0x108(%rsp), %rdi
leaq 0x58(%rsp), %rsi
pushq $0x20
popq %rdx
callq 0x31874
leaq 0x108(%rsp), %rdi
leaq 0x54(%rsp), %rsi
pushq $0x40
popq %rdx
callq 0x31874
movzbl %r14b, %r13d
leaq 0x90(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
xorl %ecx, %ecx
movb %cl, (%rax)
movb %cl, 0xf(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x58(%rsp)
setne %al
movl 0x3c(%rsp), %ecx
xorl %r10d, %r10d
orl 0x40(%rsp), %ecx
setne %r10b
movl 0x44(%rsp), %ecx
xorl %r15d, %r15d
orl 0x48(%rsp), %ecx
setne %r15b
xorl %r12d, %r12d
cmpl $0x0, 0x1c(%rsp)
setne %r12b
movl 0x4c(%rsp), %r14d
movq (%rbx), %rcx
movq 0xd8(%rcx), %r11
movzbl 0x18(%rsp), %r8d
movzbl 0x14(%rsp), %r9d
leaq 0xe8(%rsp), %rdi
movq %rbx, %rsi
movl 0x2c(%rsp), %edx
movq 0x70(%rsp), %rcx
movl %r8d, 0x18(%rsp)
movl %r9d, 0x14(%rsp)
pushq %r14
pushq %r12
pushq %r15
pushq %r10
pushq %rax
pushq %r13
callq *%r11
addq $0x30, %rsp
leaq 0x80(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x64f0
leaq 0xe8(%rsp), %rdi
callq 0x6548
leaq 0x6c612(%rip), %rsi     # 0x9dc29
leaq 0x80(%rsp), %rdi
callq 0x64d0
movq 0x60(%rsp), %r15
addl %r13d, %r15d
addl 0x68(%rsp), %r15d
movl 0x7c(%rsp), %eax
movq %rax, 0x60(%rsp)
movl 0x1c(%rsp), %eax
movq %rax, 0xd0(%rsp)
movl 0x48(%rsp), %eax
movq %rax, 0xc8(%rsp)
movl 0x44(%rsp), %eax
movq %rax, 0xc0(%rsp)
movl 0x4c(%rsp), %eax
movl 0x40(%rsp), %r10d
movl 0x3c(%rsp), %r14d
movl 0x5c(%rsp), %r11d
movq %r13, 0x68(%rsp)
movl 0x54(%rsp), %r13d
movq (%rbx), %rcx
movq 0xe0(%rcx), %rcx
movq %rcx, 0xd8(%rsp)
subq $0x8, %rsp
leaq 0xf0(%rsp), %rdi
movq %rbx, %rsi
movl 0x34(%rsp), %edx
movq 0x78(%rsp), %rcx
movl 0x20(%rsp), %r8d
movl 0x1c(%rsp), %r9d
leaq 0x17(%rsp), %r12
pushq %r12
pushq %r13
pushq 0x48(%rsp)
pushq %r11
pushq %r14
pushq %r10
pushq %rax
pushq 0x100(%rsp)
pushq 0x110(%rsp)
pushq 0x120(%rsp)
pushq %r15
pushq 0xc0(%rsp)
pushq 0xd0(%rsp)
callq *0x148(%rsp)
addq $0x70, %rsp
leaq 0x80(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x64f0
leaq 0xe8(%rsp), %rdi
callq 0x6548
leaq 0x642d9(%rip), %rsi     # 0x959f5
leaq 0x80(%rsp), %rdi
callq 0x64d0
movq 0xe0(%rsp), %r12
movq %rbx, %rdi
callq 0x41b9c
testb %al, %al
je 0x31766
movq %rbx, %rdi
movq 0x70(%rsp), %rsi
movl 0x2c(%rsp), %edx
callq 0x16cd4
testb %al, %al
je 0x31766
leaq 0x61db3(%rip), %rsi     # 0x9350c
leaq 0x80(%rsp), %rdi
callq 0x64d0
movzbl 0xf(%rsp), %r8d
leaq 0x80(%rsp), %rcx
movq %rbx, %rdi
movl 0x78(%rsp), %esi
movl %ebp, %edx
xorl %r9d, %r9d
callq 0x2f196
movq 0xa0(%rsp), %r14
movq 0xa8(%rsp), %r15
cmpq %r15, %r14
je 0x317ad
movl (%r14), %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0x13128
addq $0x4, %r14
jmp 0x31795
addl $-0x57, %r12d
cmpl $0x6, %r12d
ja 0x317ca
pushq $0x55
popq %rax
btl %r12d, %eax
jae 0x317ca
movq %rbx, %rdi
movl %ebp, %esi
callq 0x318aa
leaq 0x80(%rsp), %rdi
callq 0x6548
leaq 0xa0(%rsp), %rdi
callq 0x6cf8
addq $0x128, %rsp            # imm = 0x128
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl 0x10(%r14), %eax
movq %rax, 0x30(%rsp)
addq $0x14, %r14
movq %r14, 0x20(%rsp)
addl $-0x5, %r15d
movl %r15d, 0x10(%rsp)
movb $0x1, %al
movl %eax, 0x14(%rsp)
movl $0x0, 0x18(%rsp)
xorl %r14d, %r14d
jmp 0x313d1
jmp 0x31849
jmp 0x3182d
jmp 0x3184e
movq %rax, %rbx
leaq 0xe8(%rsp), %rdi
callq 0x6548
jmp 0x31851
jmp 0x3184e
jmp 0x31849
jmp 0x31849
jmp 0x31849
jmp 0x3184e
movq %rax, %rbx
jmp 0x3185e
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x6548
leaq 0xa0(%rsp), %rdi
callq 0x6cf8
movq %rbx, %rdi
callq 0x64b0
nop