// File: /workspace/github_cpp_makefile_star2_O3/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
cmpl $0x4f, %esi
jle 0xa04ff
leal -0x57(%r15), %ecx
cmpl $0x36, %ecx
ja 0xa064f
movl $0x6ff, %eax            # imm = 0x6FF
btq %rcx, %rax
jae 0xa0548
movq 0x8(%rbx), %rcx
movl $0x18, %eax
cmpb $0x0, 0x7df(%rcx)
jne 0xa04f4
xorl %eax, %eax
addq $0x28, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
cmpl $0xc, %r15d
je 0xa05da
cmpl $0x39, %r15d
je 0xa05a0
cmpl $0x3e, %r15d
jne 0xa04f2
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 0xa0699
callq 0x12a72
jmp 0xa06ba
movl $0x1900, %eax           # imm = 0x1900
btq %rcx, %rax
jae 0xa0640
leaq 0x10(%rbx), %rdi
xorl %eax, %eax
cmpl $0x63, %r15d
setne %al
leaq (%r14,%rax,8), %rsi
callq 0x21d9e
movl (%rax), %esi
testl %esi, %esi
je 0xa0591
movq 0x8(%rbx), %rdi
callq 0xa3ea
movq %rax, %rcx
movl $0xe, %eax
cmpl $0x5, 0x84(%rcx)
je 0xa04f4
cmpl $0x5f, %r15d
je 0xa04e0
jmp 0xa04f2
movq 0x8(%rbx), %rdi
movl (%r14), %esi
callq 0xa3ea
movq 0x20(%rax), %rcx
movq 0x28(%rax), %rdx
movq %rdx, %rax
subq %rcx, %rax
sarq $0x2, %rax
cmpq $0x2, %rax
jb 0xa0686
cmpq $0x7, %rax
jae 0xa077f
addl $0x7, %eax
jmp 0xa04f4
movl 0x8(%r14), %esi
movq 0x8(%rbx), %rdi
callq 0x579b2
cmpl $0x1, 0xc(%rax)
jne 0xa04f2
movl 0xc(%r14), %eax
cmpl $0x48, %eax
jg 0xa0732
cmpl $0xb, %eax
je 0xa0757
cmpl $0xc, %eax
je 0xa076b
cmpl $0x22, %eax
jne 0xa04f2
movq 0x8(%rbx), %rdi
movl (%r14), %esi
callq 0xa3ea
movl 0x18(%rax), %ecx
leal -0x2(%rcx), %eax
cmpl $0x3, %eax
jae 0xa04f2
movl $0x13, %eax
subl %ecx, %eax
jmp 0xa04f4
movl $0x1, %eax
cmpq $0x36, %rcx
je 0xa04f4
cmpl $0x50, %r15d
jne 0xa04f2
movq 0x8(%rbx), %rdi
movl (%r14), %esi
callq 0xa3ea
movq %rax, %rcx
movq 0x28(%rax), %rax
subq 0x20(%rcx), %rax
sarq $0x2, %rax
cmpq $0x2, %rax
jb 0xa04f2
addl $0x6, %eax
jmp 0xa04f4
movl $0x8, %eax
cmpq %rcx, %rdx
jne 0xa04f4
jmp 0xa04f2
leaq 0x10(%rbx), %rdi
leaq 0x4(%rsp), %rsi
callq 0x21d9e
movl (%rax), %esi
testl %esi, %esi
je 0xa074f
movq 0x8(%rbx), %rdi
callq 0xa3ea
movq %rax, %r14
movq 0x8(%rbx), %rdi
movl %ebp, %esi
callq 0xc7b4
testq %rax, %rax
je 0xa06df
cmpl $0x7, 0x10(%rax)
jne 0xa06df
cmpb $0x1, 0x39(%rax)
jne 0xa06df
movb 0x5b(%rax), %bpl
jmp 0xa06e1
xorl %ebp, %ebp
testq %r14, %r14
je 0xa04f2
movq 0x8(%rbx), %rdi
movq %r14, %rsi
callq 0x13482
notb %al
orb %bpl, %al
testb $0x1, %al
jne 0xa04f2
movq 0x28(%r14), %rcx
subq 0x20(%r14), %rcx
sarq $0x2, %rcx
movl $0x8, %eax
cmpq $0x2, %rcx
jb 0xa04f4
cmpq $0x7, %rcx
jae 0xa07e5
addl $0x7, %ecx
movl %ecx, %eax
jmp 0xa04f4
cmpl $0x49, %eax
je 0xa0761
cmpl $0x4a, %eax
je 0xa0775
cmpl $0x4b, %eax
jne 0xa04f2
movl $0x6, %eax
jmp 0xa04f4
xorl %r14d, %r14d
jmp 0xa06bd
movl $0x2, %eax
jmp 0xa04f4
movl $0x4, %eax
jmp 0xa04f4
movl $0x3, %eax
jmp 0xa04f4
movl $0x5, %eax
jmp 0xa04f4
movl $0x10, %edi
callq 0x6140
movq %rax, %rbx
leaq 0x18(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x22cb0(%rip), %rsi     # 0xc344c
leaq 0x22ce2(%rip), %rdx     # 0xc3485
leaq 0x8(%rsp), %rdi
callq 0x7be0
movb $0x1, %bpl
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x6320
leaq 0x5b604(%rip), %rax     # 0xfbdc8
addq $0x10, %rax
movq %rax, (%rbx)
xorl %ebp, %ebp
leaq 0x5b5dc(%rip), %rsi     # 0xfbdb0
movq 0x5c7fd(%rip), %rdx     # 0xfcfd8
movq %rbx, %rdi
callq 0x6470
jmp 0xa0849
movl $0x10, %edi
callq 0x6140
movq %rax, %rbx
leaq 0x18(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x22c4a(%rip), %rsi     # 0xc344c
leaq 0x22c7c(%rip), %rdx     # 0xc3485
leaq 0x8(%rsp), %rdi
callq 0x7be0
movb $0x1, %bpl
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x6320
leaq 0x5b59e(%rip), %rax     # 0xfbdc8
addq $0x10, %rax
movq %rax, (%rbx)
xorl %ebp, %ebp
leaq 0x5b576(%rip), %rsi     # 0xfbdb0
movq 0x5c797(%rip), %rdx     # 0xfcfd8
movq %rbx, %rdi
callq 0x6470
jmp 0xa084d
jmp 0xa086e
movq %rax, %r14
movq 0x8(%rsp), %rdi
cmpq %r15, %rdi
je 0xa0867
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x6260
testb %bpl, %bpl
jne 0xa0871
jmp 0xa0879
movq %rax, %r14
movq %rbx, %rdi
callq 0x6200
movq %r14, %rdi
callq 0x64a0
nop