// File: /workspace/github_cpp_makefile_star2_O2/rossy[P]crossc/SPIRV-Cross/spirv_msl.cpp
// Function: spirv_cross::CompilerMSL::OpCodePreprocessor::get_spv_func_impl(spv::Op, unsigned int const*)
CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op opcode, const uint32_t *args)
{
	switch (opcode)
	{
	case OpFMod:
		return SPVFuncImplMod;

	case OpFunctionCall:
	{
		auto &return_type = compiler.get<SPIRType>(args[0]);
		if (return_type.array.size() > 1)
		{
			if (return_type.array.size() > SPVFuncImplArrayCopyMultidimMax)
				SPIRV_CROSS_THROW("Cannot support this many dimensions for arrays of arrays.");
			return static_cast<SPVFuncImpl>(SPVFuncImplArrayCopyMultidimBase + return_type.array.size());
		}
		else if (return_type.array.size() > 0)
			return SPVFuncImplArrayCopy;

		break;
	}

	case OpStore:
	{
		// Get the result type of the RHS. Since this is run as a pre-processing stage,
		// we must extract the result type directly from the Instruction, rather than the ID.
		uint32_t id_lhs = args[0];
		uint32_t id_rhs = args[1];

		const SPIRType *type = nullptr;
		if (compiler.ir.ids[id_rhs].get_type() != TypeNone)
		{
			// Could be a constant, or similar.
			type = &compiler.expression_type(id_rhs);
		}
		else
		{
			// Or ... an expression.
			uint32_t tid = result_types[id_rhs];
			if (tid)
				type = &compiler.get<SPIRType>(tid);
		}

		auto *var = compiler.maybe_get<SPIRVariable>(id_lhs);

		// Are we simply assigning to a statically assigned variable which takes a constant?
		// Don't bother emitting this function.
		bool static_expression_lhs =
		    var && var->storage == StorageClassFunction && var->statically_assigned && var->remapped_variable;
		if (type && compiler.is_array(*type) && !static_expression_lhs)
		{
			if (type->array.size() > 1)
			{
				if (type->array.size() > SPVFuncImplArrayCopyMultidimMax)
					SPIRV_CROSS_THROW("Cannot support this many dimensions for arrays of arrays.");
				return static_cast<SPVFuncImpl>(SPVFuncImplArrayCopyMultidimBase + type->array.size());
			}
			else
				return SPVFuncImplArrayCopy;
		}

		break;
	}

	case OpImageFetch:
	case OpImageRead:
	case OpImageWrite:
	{
		// Retrieve the image type, and if it's a Buffer, emit a texel coordinate function
		uint32_t tid = result_types[args[opcode == OpImageWrite ? 0 : 2]];
		if (tid && compiler.get<SPIRType>(tid).image.dim == DimBuffer)
			return SPVFuncImplTexelBufferCoords;

		if (opcode == OpImageFetch && compiler.msl_options.swizzle_texture_samples)
			return SPVFuncImplTextureSwizzle;

		break;
	}

	case OpImageSampleExplicitLod:
	case OpImageSampleProjExplicitLod:
	case OpImageSampleDrefExplicitLod:
	case OpImageSampleProjDrefExplicitLod:
	case OpImageSampleImplicitLod:
	case OpImageSampleProjImplicitLod:
	case OpImageSampleDrefImplicitLod:
	case OpImageSampleProjDrefImplicitLod:
	case OpImageGather:
	case OpImageDrefGather:
		if (compiler.msl_options.swizzle_texture_samples)
			return SPVFuncImplTextureSwizzle;
		break;

	case OpCompositeConstruct:
	{
		auto &type = compiler.get<SPIRType>(args[0]);
		if (type.array.size() > 1) // We need to use copies to build the composite.
			return static_cast<SPVFuncImpl>(SPVFuncImplArrayCopyMultidimBase + type.array.size() - 1);
		break;
	}

	case OpExtInst:
	{
		uint32_t extension_set = args[2];
		if (compiler.get<SPIRExtension>(extension_set).ext == SPIRExtension::GLSL)
		{
			GLSLstd450 op_450 = static_cast<GLSLstd450>(args[3]);
			switch (op_450)
			{
			case GLSLstd450Radians:
				return SPVFuncImplRadians;
			case GLSLstd450Degrees:
				return SPVFuncImplDegrees;
			case GLSLstd450FindILsb:
				return SPVFuncImplFindILsb;
			case GLSLstd450FindSMsb:
				return SPVFuncImplFindSMsb;
			case GLSLstd450FindUMsb:
				return SPVFuncImplFindUMsb;
			case GLSLstd450MatrixInverse:
			{
				auto &mat_type = compiler.get<SPIRType>(args[0]);
				switch (mat_type.columns)
				{
				case 2:
					return SPVFuncImplInverse2x2;
				case 3:
					return SPVFuncImplInverse3x3;
				case 4:
					return SPVFuncImplInverse4x4;
				default:
					break;
				}
				break;
			}
			default:
				break;
			}
		}
		break;
	}

	default:
		break;
	}
	return SPVFuncImplNone;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x28, %rsp
movq %rdx, %r14
movl %esi, %r15d
movq %rdi, %rbx
leal -0x57(%r15), %eax
cmpl $0x36, %eax
ja 0x7d7c6
movl $0x6ff, %ecx            # imm = 0x6FF
btq %rax, %rcx
jae 0x7d774
movq 0x8(%rbx), %rax
cmpb $0x0, 0x7df(%rax)
je 0x7d97d
pushq $0x18
popq %rax
jmp 0x7d97f
movl $0x1900, %ecx           # imm = 0x1900
btq %rax, %rcx
jae 0x7d7bc
leaq 0x10(%rbx), %rdi
xorl %eax, %eax
cmpl $0x63, %r15d
setne %al
leaq (%r14,%rax,8), %rsi
callq 0x1d40e
movl (%rax), %esi
testl %esi, %esi
je 0x7d7b1
movq 0x8(%rbx), %rdi
callq 0x90a4
cmpl $0x5, 0x84(%rax)
jne 0x7d7b1
pushq $0xe
jmp 0x7d76e
cmpl $0x5f, %r15d
je 0x7d75b
jmp 0x7d97d
cmpq $0x36, %rax
jne 0x7d7c6
pushq $0x1
jmp 0x7d76e
cmpl $0xc, %r15d
je 0x7d86e
cmpl $0x50, %r15d
je 0x7d8ee
cmpl $0x3e, %r15d
je 0x7d8c6
cmpl $0x39, %r15d
jne 0x7d97d
movq 0x8(%rbx), %rdi
movl (%r14), %esi
callq 0x90a4
movq 0x20(%rax), %rcx
movq 0x28(%rax), %rdx
movq %rdx, %rax
subq %rcx, %rax
sarq $0x2, %rax
cmpq $0x2, %rax
jb 0x7d914
cmpq $0x7, %rax
jb 0x7d9a2
pushq $0x10
popq %rdi
callq 0x6140
movq %rax, %rbx
leaq 0x20bd2(%rip), %rsi     # 0x9e404
leaq 0x8(%rsp), %rdi
leaq 0x4(%rsp), %rdx
callq 0x6100
movb $0x1, %bpl
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x6f6e
xorl %ebp, %ebp
leaq 0x69566(%rip), %rsi     # 0xe6dc0
movq 0x6a77f(%rip), %rdx     # 0xe7fe0
movq %rbx, %rdi
callq 0x6490
jmp 0x7da36
movl 0x8(%r14), %esi
movq 0x8(%rbx), %rdi
callq 0x4629c
cmpl $0x1, 0xc(%rax)
jne 0x7d97d
movl 0xc(%r14), %eax
cmpl $0xb, %eax
je 0x7d9e6
cmpl $0x4b, %eax
je 0x7d9df
cmpl $0x22, %eax
je 0x7d9b3
cmpl $0x49, %eax
je 0x7d9d8
cmpl $0x4a, %eax
je 0x7d9d1
cmpl $0xc, %eax
jne 0x7d97d
pushq $0x3
jmp 0x7d76e
movl (%r14), %ebp
movl 0x4(%r14), %esi
movl %esi, 0x4(%rsp)
movq 0x8(%rbx), %rdi
movq 0x20(%rdi), %rax
movq %rsi, %rcx
shlq $0x4, %rcx
cmpl $0x0, 0x8(%rax,%rcx)
je 0x7d91f
callq 0x104b0
jmp 0x7d93c
movq 0x8(%rbx), %rdi
movl (%r14), %esi
callq 0x90a4
movq %rax, %rcx
movq 0x28(%rax), %rax
subq 0x20(%rcx), %rax
sarq $0x2, %rax
cmpq $0x2, %rax
jb 0x7d97d
addl $0x6, %eax
jmp 0x7d97f
cmpq %rcx, %rdx
jne 0x7d9a7
jmp 0x7d97d
leaq 0x10(%rbx), %rdi
leaq 0x4(%rsp), %rsi
callq 0x1d40e
movl (%rax), %esi
testl %esi, %esi
je 0x7d9ae
movq 0x8(%rbx), %rdi
callq 0x90a4
movq %rax, %r14
movq 0x8(%rbx), %rdi
movl %ebp, %esi
callq 0xa9e4
testq %rax, %rax
je 0x7d961
cmpl $0x7, 0x10(%rax)
jne 0x7d961
cmpb $0x1, 0x39(%rax)
jne 0x7d961
movb 0x5b(%rax), %bpl
jmp 0x7d963
xorl %ebp, %ebp
testq %r14, %r14
je 0x7d97d
movq 0x8(%rbx), %rdi
movq %r14, %rsi
callq 0x10d6c
notb %al
orb %bpl, %al
testb $0x1, %al
je 0x7d98a
xorl %eax, %eax
addq $0x28, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movq 0x28(%r14), %rax
subq 0x20(%r14), %rax
sarq $0x2, %rax
cmpq $0x2, %rax
jb 0x7d9a7
cmpq $0x7, %rax
jae 0x7d9ed
addl $0x7, %eax
jmp 0x7d97f
pushq $0x8
jmp 0x7d76e
xorl %r14d, %r14d
jmp 0x7d93f
movq 0x8(%rbx), %rdi
movl (%r14), %esi
callq 0x90a4
movl 0x18(%rax), %ecx
leal -0x2(%rcx), %eax
cmpl $0x3, %eax
jae 0x7d97d
pushq $0x13
popq %rax
subl %ecx, %eax
jmp 0x7d97f
pushq $0x5
jmp 0x7d76e
pushq $0x4
jmp 0x7d76e
pushq $0x6
jmp 0x7d76e
pushq $0x2
jmp 0x7d76e
pushq $0x10
popq %rdi
callq 0x6140
movq %rax, %rbx
leaq 0x20a05(%rip), %rsi     # 0x9e404
leaq 0x8(%rsp), %rdi
leaq 0x3(%rsp), %rdx
callq 0x6100
movb $0x1, %bpl
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x6f6e
xorl %ebp, %ebp
leaq 0x69399(%rip), %rsi     # 0xe6dc0
movq 0x6a5b2(%rip), %rdx     # 0xe7fe0
movq %rbx, %rdi
callq 0x6490
jmp 0x7da3a
jmp 0x7da4e
movq %rax, %r14
leaq 0x8(%rsp), %rdi
callq 0x6548
testb %bpl, %bpl
jne 0x7da51
jmp 0x7da59
movq %rax, %r14
movq %rbx, %rdi
callq 0x6200
movq %r14, %rdi
callq 0x64b0
nop