// File: rossy[P]crossc/SPIRV-Cross/spirv_cross.cpp
// Function: spirv_cross::Compiler::DummySamplerForCombinedImageHandler::handle(spv::Op, unsigned int const*, unsigned int)
bool Compiler::DummySamplerForCombinedImageHandler::handle(Op opcode, const uint32_t *args, uint32_t length)
{
	if (need_dummy_sampler)
	{
		// No need to traverse further, we know the result.
		return false;
	}

	switch (opcode)
	{
	case OpLoad:
	{
		if (length < 3)
			return false;

		uint32_t result_type = args[0];

		auto &type = compiler.get<SPIRType>(result_type);
		bool separate_image =
		    type.basetype == SPIRType::Image && type.image.sampled == 1 && type.image.dim != DimBuffer;

		// If not separate image, don't bother.
		if (!separate_image)
			return true;

		uint32_t id = args[1];
		uint32_t ptr = args[2];
		compiler.set<SPIRExpression>(id, "", result_type, true);
		compiler.register_read(id, ptr, true);
		break;
	}

	case OpImageFetch:
	case OpImageQuerySizeLod:
	case OpImageQuerySize:
	case OpImageQueryLevels:
	case OpImageQuerySamples:
	{
		// If we are fetching or querying LOD from a plain OpTypeImage, we must pre-combine with our dummy sampler.
		auto *var = compiler.maybe_get_backing_variable(args[2]);
		if (var)
		{
			auto &type = compiler.get<SPIRType>(var->basetype);
			if (type.basetype == SPIRType::Image && type.image.sampled == 1 && type.image.dim != DimBuffer)
				need_dummy_sampler = true;
		}

		break;
	}

	case OpInBoundsAccessChain:
	case OpAccessChain:
	{
		if (length < 3)
			return false;

		uint32_t result_type = args[0];
		auto &type = compiler.get<SPIRType>(result_type);
		bool separate_image =
		    type.basetype == SPIRType::Image && type.image.sampled == 1 && type.image.dim != DimBuffer;
		if (!separate_image)
			return true;

		uint32_t id = args[1];
		uint32_t ptr = args[2];
		compiler.set<SPIRExpression>(id, "", result_type, true);
		compiler.register_read(id, ptr, true);

		// Other backends might use SPIRAccessChain for this later.
		compiler.ir.ids[id].set_allow_type_rewrite();
		break;
	}

	default:
		break;
	}

	return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x78(%rbp)
testb $0x1, 0x10(%rax)
je 0x26e30
movb $0x0, -0x1(%rbp)
jmp 0x2709f
movl -0x14(%rbp), %eax
movl %eax, -0x7c(%rbp)
subl $0x3d, %eax
je 0x26e81
jmp 0x26e3d
movl -0x7c(%rbp), %eax
addl $-0x41, %eax
subl $0x2, %eax
jb 0x26fb4
jmp 0x26e4e
movl -0x7c(%rbp), %eax
subl $0x5f, %eax
je 0x26f4a
jmp 0x26e5c
movl -0x7c(%rbp), %eax
addl $-0x67, %eax
subl $0x2, %eax
jb 0x26f4a
jmp 0x26e6d
movl -0x7c(%rbp), %eax
addl $-0x6a, %eax
subl $0x2, %eax
jb 0x26f4a
jmp 0x27099
cmpl $0x3, -0x24(%rbp)
jae 0x26e90
movb $0x0, -0x1(%rbp)
jmp 0x2709f
movq -0x78(%rbp), %rax
movq -0x20(%rbp), %rcx
movl (%rcx), %ecx
movl %ecx, -0x28(%rbp)
movq 0x8(%rax), %rdi
movl -0x28(%rbp), %esi
callq 0xea90
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rcx
xorl %eax, %eax
cmpl $0xd, 0xc(%rcx)
movb %al, -0x7d(%rbp)
jne 0x26edf
movq -0x30(%rbp), %rcx
xorl %eax, %eax
cmpl $0x1, 0x8c(%rcx)
movb %al, -0x7d(%rbp)
jne 0x26edf
movq -0x30(%rbp), %rax
cmpl $0x5, 0x84(%rax)
setne %al
movb %al, -0x7d(%rbp)
movb -0x7d(%rbp), %al
andb $0x1, %al
movb %al, -0x31(%rbp)
testb $0x1, -0x31(%rbp)
jne 0x26ef6
movb $0x1, -0x1(%rbp)
jmp 0x2709f
movq -0x78(%rbp), %rax
movq -0x20(%rbp), %rcx
movl 0x4(%rcx), %ecx
movl %ecx, -0x38(%rbp)
movq -0x20(%rbp), %rcx
movl 0x8(%rcx), %ecx
movl %ecx, -0x3c(%rbp)
movq 0x8(%rax), %rdi
movl -0x38(%rbp), %esi
movb $0x1, -0x3d(%rbp)
leaq 0x11797e(%rip), %rdx    # 0x13e89e
leaq -0x28(%rbp), %rcx
leaq -0x3d(%rbp), %r8
callq 0x30ef0
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0x38(%rbp), %esi
movl -0x3c(%rbp), %edx
movl $0x1, %ecx
callq 0x1fb20
jmp 0x2709b
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x20(%rbp), %rax
movl 0x8(%rax), %esi
callq 0x1fa90
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x26faf
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x48(%rbp), %rax
movl 0xc(%rax), %esi
callq 0xea90
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
cmpl $0xd, 0xc(%rax)
jne 0x26fad
movq -0x50(%rbp), %rax
cmpl $0x1, 0x8c(%rax)
jne 0x26fad
movq -0x50(%rbp), %rax
cmpl $0x5, 0x84(%rax)
je 0x26fad
movq -0x78(%rbp), %rax
movb $0x1, 0x10(%rax)
jmp 0x26faf
jmp 0x2709b
cmpl $0x3, -0x24(%rbp)
jae 0x26fc3
movb $0x0, -0x1(%rbp)
jmp 0x2709f
movq -0x78(%rbp), %rax
movq -0x20(%rbp), %rcx
movl (%rcx), %ecx
movl %ecx, -0x54(%rbp)
movq 0x8(%rax), %rdi
movl -0x54(%rbp), %esi
callq 0xea90
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rcx
xorl %eax, %eax
cmpl $0xd, 0xc(%rcx)
movb %al, -0x7e(%rbp)
jne 0x27012
movq -0x60(%rbp), %rcx
xorl %eax, %eax
cmpl $0x1, 0x8c(%rcx)
movb %al, -0x7e(%rbp)
jne 0x27012
movq -0x60(%rbp), %rax
cmpl $0x5, 0x84(%rax)
setne %al
movb %al, -0x7e(%rbp)
movb -0x7e(%rbp), %al
andb $0x1, %al
movb %al, -0x61(%rbp)
testb $0x1, -0x61(%rbp)
jne 0x27026
movb $0x1, -0x1(%rbp)
jmp 0x2709f
movq -0x78(%rbp), %rax
movq -0x20(%rbp), %rcx
movl 0x4(%rcx), %ecx
movl %ecx, -0x68(%rbp)
movq -0x20(%rbp), %rcx
movl 0x8(%rcx), %ecx
movl %ecx, -0x6c(%rbp)
movq 0x8(%rax), %rdi
movl -0x68(%rbp), %esi
movb $0x1, -0x6d(%rbp)
leaq 0x11784e(%rip), %rdx    # 0x13e89e
leaq -0x54(%rbp), %rcx
leaq -0x6d(%rbp), %r8
callq 0x30ef0
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0x68(%rbp), %esi
movl -0x6c(%rbp), %edx
movl $0x1, %ecx
callq 0x1fb20
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rdi
addq $0x8, %rdi
addq $0x18, %rdi
movl -0x68(%rbp), %eax
movl %eax, %esi
callq 0xbdb0
movq %rax, %rdi
callq 0x30f50
jmp 0x2709b
jmp 0x2709b
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x80, %rsp
popq %rbp
retq
nopl (%rax)