// File: /workspace/github_cpp_makefile_star2_O3/rossy[P]crossc/SPIRV-Cross/spirv_cross.cpp
// Function: spirv_cross::Compiler::InterfaceVariableAccessHandler::handle(spv::Op, unsigned int const*, unsigned int)
bool Compiler::InterfaceVariableAccessHandler::handle(Op opcode, const uint32_t *args, uint32_t length)
{
	uint32_t variable = 0;
	switch (opcode)
	{
	// Need this first, otherwise, GCC complains about unhandled switch statements.
	default:
		break;

	case OpFunctionCall:
	{
		// Invalid SPIR-V.
		if (length < 3)
			return false;

		uint32_t count = length - 3;
		args += 3;
		for (uint32_t i = 0; i < count; i++)
		{
			auto *var = compiler.maybe_get<SPIRVariable>(args[i]);
			if (var && storage_class_is_interface(var->storage))
				variables.insert(args[i]);
		}
		break;
	}

	case OpAtomicStore:
	case OpStore:
		// Invalid SPIR-V.
		if (length < 1)
			return false;
		variable = args[0];
		break;

	case OpCopyMemory:
	{
		if (length < 2)
			return false;

		auto *var = compiler.maybe_get<SPIRVariable>(args[0]);
		if (var && storage_class_is_interface(var->storage))
			variables.insert(variable);

		var = compiler.maybe_get<SPIRVariable>(args[1]);
		if (var && storage_class_is_interface(var->storage))
			variables.insert(variable);
		break;
	}

	case OpExtInst:
	{
		if (length < 5)
			return false;
		uint32_t extension_set = args[2];
		if (compiler.get<SPIRExtension>(extension_set).ext == SPIRExtension::SPV_AMD_shader_explicit_vertex_parameter)
		{
			enum AMDShaderExplicitVertexParameter
			{
				InterpolateAtVertexAMD = 1
			};

			auto op = static_cast<AMDShaderExplicitVertexParameter>(args[3]);

			switch (op)
			{
			case InterpolateAtVertexAMD:
			{
				auto *var = compiler.maybe_get<SPIRVariable>(args[4]);
				if (var && storage_class_is_interface(var->storage))
					variables.insert(args[4]);
				break;
			}

			default:
				break;
			}
		}
		break;
	}

	case OpAccessChain:
	case OpInBoundsAccessChain:
	case OpLoad:
	case OpCopyObject:
	case OpImageTexelPointer:
	case OpAtomicLoad:
	case OpAtomicExchange:
	case OpAtomicCompareExchange:
	case OpAtomicCompareExchangeWeak:
	case OpAtomicIIncrement:
	case OpAtomicIDecrement:
	case OpAtomicIAdd:
	case OpAtomicISub:
	case OpAtomicSMin:
	case OpAtomicUMin:
	case OpAtomicSMax:
	case OpAtomicUMax:
	case OpAtomicAnd:
	case OpAtomicOr:
	case OpAtomicXor:
		// Invalid SPIR-V.
		if (length < 3)
			return false;
		variable = args[2];
		break;
	}

	if (variable)
	{
		auto *var = compiler.maybe_get<SPIRVariable>(variable);
		if (var && storage_class_is_interface(var->storage))
			variables.insert(variable);
	}
	return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %r15
movq %rdi, %r14
movl $0x0, 0xc(%rsp)
movb $0x1, %bl
cmpl $0xe2, %esi
jle 0x13b41
leal -0xe5(%rsi), %eax
cmpl $0xe, %eax
jb 0x13b59
cmpl $0xe3, %esi
je 0x13b59
cmpl $0xe4, %esi
je 0x13bc5
jmp 0x13ba4
leal -0x39(%rsi), %eax
cmpl $0x9, %eax
ja 0x13bb5
leaq 0xa0de0(%rip), %rdx     # 0xb4930
movslq (%rdx,%rax,4), %rax
addq %rdx, %rax
jmpq *%rax
cmpl $0x3, %ecx
jae 0x13b62
xorl %ebx, %ebx
jmp 0x13ba4
movl 0x8(%r15), %esi
movl %esi, 0xc(%rsp)
testl %esi, %esi
je 0x13ba4
movq 0x8(%r14), %rdi
callq 0x1b5ca
testq %rax, %rax
je 0x13ba4
movl 0x10(%rax), %eax
cmpl $0xc, %eax
ja 0x13ba4
movl $0x160f, %ecx           # imm = 0x160F
btl %eax, %ecx
jae 0x13ba4
movq 0x10(%r14), %rdi
leaq 0x10(%rsp), %rdx
movq %rdi, (%rdx)
leaq 0xc(%rsp), %rsi
callq 0x1f510
movl %ebx, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0xc, %esi
je 0x13caf
cmpl $0x53, %esi
je 0x13b59
jmp 0x13ba4
testl %ecx, %ecx
je 0x13b5e
movl (%r15), %esi
jmp 0x13b66
cmpl $0x3, %ecx
jb 0x13b5e
addl $-0x3, %ecx
je 0x13d0b
addq $0xc, %r15
movl %ecx, %r13d
movl $0x160f, %ebp           # imm = 0x160F
leaq 0x10(%rsp), %r12
movq 0x8(%r14), %rdi
movl (%r15), %esi
callq 0x1b5ca
testq %rax, %rax
je 0x13c1f
movl 0x10(%rax), %eax
cmpl $0xc, %eax
ja 0x13c1f
btl %eax, %ebp
jae 0x13c1f
movq 0x10(%r14), %rdi
movq %rdi, 0x10(%rsp)
movq %r15, %rsi
movq %r12, %rdx
callq 0x1f510
addq $0x4, %r15
decq %r13
jne 0x13bed
jmp 0x13d0b
cmpl $0x2, %ecx
jb 0x13b5e
movq 0x8(%r14), %rdi
movl (%r15), %esi
callq 0x1b5ca
testq %rax, %rax
je 0x13c6f
movl 0x10(%rax), %eax
cmpl $0xc, %eax
ja 0x13c6f
movl $0x160f, %ecx           # imm = 0x160F
btl %eax, %ecx
jae 0x13c6f
movq 0x10(%r14), %rdi
leaq 0x10(%rsp), %rdx
movq %rdi, (%rdx)
leaq 0xc(%rsp), %rsi
callq 0x1f510
movq 0x8(%r14), %rdi
movl 0x4(%r15), %esi
callq 0x1b5ca
testq %rax, %rax
je 0x13d0b
movl 0x10(%rax), %eax
cmpl $0xc, %eax
ja 0x13d0b
movl $0x160f, %ecx           # imm = 0x160F
btl %eax, %ecx
jae 0x13d0b
movq 0x10(%r14), %rdi
leaq 0x10(%rsp), %rdx
movq %rdi, (%rdx)
leaq 0xc(%rsp), %rsi
callq 0x1f510
jmp 0x13d0b
cmpl $0x5, %ecx
jb 0x13b5e
movl 0x8(%r15), %esi
movq 0x8(%r14), %rdi
callq 0x1b604
cmpl $0x3, 0xc(%rax)
jne 0x13d0b
cmpl $0x1, 0xc(%r15)
jne 0x13d0b
movq 0x8(%r14), %rdi
movl 0x10(%r15), %esi
callq 0x1b5ca
testq %rax, %rax
je 0x13d0b
movl 0x10(%rax), %eax
cmpl $0xc, %eax
ja 0x13d0b
movl $0x160f, %ecx           # imm = 0x160F
btl %eax, %ecx
jae 0x13d0b
addq $0x10, %r15
movq 0x10(%r14), %rdi
leaq 0x10(%rsp), %rdx
movq %rdi, (%rdx)
movq %r15, %rsi
jmp 0x13ca8
movl 0xc(%rsp), %esi
jmp 0x13b6a