// File: /workspace/github_cpp_makefile_star2_O1/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 %r12
pushq %rbx
subq $0x10, %rsp
movq %rdx, %r14
movq %rdi, %rbx
movl $0x0, 0x4(%rsp)
cmpl $0xe2, %esi
jle 0x13c3b
leal -0xe5(%rsi), %eax
cmpl $0xe, %eax
jb 0x13c53
cmpl $0xe3, %esi
je 0x13c53
cmpl $0xe4, %esi
je 0x13cc4
jmp 0x13c64
leal -0x39(%rsi), %eax
cmpl $0x9, %eax
ja 0x13cb4
leaq 0xa1cc6(%rip), %rdx     # 0xb5910
movslq (%rdx,%rax,4), %rax
addq %rdx, %rax
jmpq *%rax
cmpl $0x3, %ecx
jae 0x13c5c
xorl %ebp, %ebp
jmp 0x13ca5
movl 0x8(%r14), %eax
movl %eax, 0x4(%rsp)
movl 0x4(%rsp), %esi
movb $0x1, %bpl
testl %esi, %esi
je 0x13ca5
movq 0x8(%rbx), %rdi
callq 0x1bc26
testq %rax, %rax
je 0x13ca5
movl 0x10(%rax), %eax
cmpl $0xc, %eax
ja 0x13ca5
movl $0x160f, %ecx           # imm = 0x160F
btl %eax, %ecx
jae 0x13ca5
movq 0x10(%rbx), %rdi
leaq 0x8(%rsp), %rdx
movq %rdi, (%rdx)
leaq 0x4(%rsp), %rsi
callq 0x1fc02
movl %ebp, %eax
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
cmpl $0xc, %esi
je 0x13db5
cmpl $0x53, %esi
je 0x13c53
jmp 0x13c64
testl %ecx, %ecx
je 0x13c58
movl (%r14), %eax
jmp 0x13c60
cmpl $0x3, %ecx
jb 0x13c58
addl $-0x3, %ecx
je 0x13c64
addq $0xc, %r14
movl %ecx, %r12d
movl $0x160f, %ebp           # imm = 0x160F
leaq 0x8(%rsp), %r15
movq 0x8(%rbx), %rdi
movl (%r14), %esi
callq 0x1bc26
testq %rax, %rax
je 0x13d1a
movl 0x10(%rax), %eax
cmpl $0xc, %eax
ja 0x13d1a
btl %eax, %ebp
jae 0x13d1a
movq 0x10(%rbx), %rdi
movq %rdi, 0x8(%rsp)
movq %r14, %rsi
movq %r15, %rdx
callq 0x1fc02
addq $0x4, %r14
decq %r12
jne 0x13ce8
jmp 0x13c64
cmpl $0x2, %ecx
jb 0x13c58
movq 0x8(%rbx), %rdi
movl (%r14), %esi
callq 0x1bc26
testq %rax, %rax
je 0x13d6a
movl 0x10(%rax), %eax
cmpl $0xc, %eax
ja 0x13d6a
movl $0x160f, %ecx           # imm = 0x160F
btl %eax, %ecx
jae 0x13d6a
movq 0x10(%rbx), %rdi
leaq 0x8(%rsp), %rdx
movq %rdi, (%rdx)
leaq 0x4(%rsp), %rsi
callq 0x1fc02
movq 0x8(%rbx), %rdi
movl 0x4(%r14), %esi
callq 0x1bc26
testq %rax, %rax
je 0x13c64
movl 0x10(%rax), %eax
cmpl $0xc, %eax
ja 0x13c64
movl $0x160f, %ecx           # imm = 0x160F
btl %eax, %ecx
jae 0x13c64
movq 0x10(%rbx), %rdi
leaq 0x8(%rsp), %rdx
movq %rdi, (%rdx)
leaq 0x4(%rsp), %rsi
callq 0x1fc02
jmp 0x13c64
cmpl $0x5, %ecx
jb 0x13c58
movl 0x8(%r14), %esi
movq 0x8(%rbx), %rdi
callq 0x1bc60
cmpl $0x3, 0xc(%rax)
jne 0x13c64
cmpl $0x1, 0xc(%r14)
jne 0x13c64
movq 0x8(%rbx), %rdi
movl 0x10(%r14), %esi
callq 0x1bc26
testq %rax, %rax
je 0x13c64
movl 0x10(%rax), %eax
cmpl $0xc, %eax
ja 0x13c64
movl $0x160f, %ecx           # imm = 0x160F
btl %eax, %ecx
jae 0x13c64
addq $0x10, %r14
movq 0x10(%rbx), %rdi
leaq 0x8(%rsp), %rdx
movq %rdi, (%rdx)
movq %r14, %rsi
jmp 0x13dab
nop