// File: /workspace/github_cpp_makefile_star2_O1/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 0xa136f
leal -0x57(%r15), %ecx
cmpl $0x36, %ecx
ja 0xa14ef
movl $0x6ff, %eax            # imm = 0x6FF
btq %rcx, %rax
jae 0xa13bc
movq 0x8(%rbx), %rcx
movl $0x18, %eax
cmpb $0x0, 0x7df(%rcx)
je 0xa1598
jmp 0xa159a
cmpl $0xc, %r15d
je 0xa1463
cmpl $0x39, %r15d
je 0xa1427
cmpl $0x3e, %r15d
jne 0xa1598
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 0xa1530
callq 0x12aba
jmp 0xa1551
movl $0x1900, %eax           # imm = 0x1900
btq %rcx, %rax
jae 0xa14e0
leaq 0x10(%rbx), %rdi
xorl %eax, %eax
cmpl $0x63, %r15d
setne %al
leaq (%r14,%rax,8), %rsi
callq 0x22474
movl (%rax), %esi
testl %esi, %esi
je 0xa1400
movq 0x8(%rbx), %rdi
callq 0xa426
cmpl $0x5, 0x84(%rax)
jne 0xa1400
movl $0xe, %eax
jmp 0xa1420
cmpl $0x5f, %r15d
jne 0xa1592
movq 0x8(%rbx), %rax
cmpb $0x0, 0x7df(%rax)
je 0xa1592
movl $0x18, %eax
movb $0x1, %cl
jmp 0xa1594
movq 0x8(%rbx), %rdi
movl (%r14), %esi
callq 0xa426
movq 0x20(%rax), %rcx
movq 0x28(%rax), %rdx
movq %rdx, %rax
subq %rcx, %rax
sarq $0x2, %rax
cmpq $0x2, %rax
jb 0xa151f
cmpq $0x7, %rax
jae 0xa1631
addl $0x7, %eax
movb $0x1, %cl
jmp 0xa152a
movl 0x8(%r14), %esi
movq 0x8(%rbx), %rdi
callq 0x581ac
cmpl $0x1, 0xc(%rax)
jne 0xa1592
movl 0xc(%r14), %edx
movl $0x1, %ecx
cmpl $0x48, %edx
jg 0xa15cf
cmpl $0xb, %edx
je 0xa15ed
cmpl $0xc, %edx
je 0xa15fb
cmpl $0x22, %edx
jne 0xa1624
movq 0x8(%rbx), %rdi
movl (%r14), %esi
callq 0xa426
movl 0x18(%rax), %eax
movl $0x1, %ecx
cmpl $0x2, %eax
je 0xa1610
cmpl $0x4, %eax
je 0xa1609
cmpl $0x3, %eax
jne 0xa1619
movl $0x10, %eax
jmp 0xa1615
movl $0x1, %eax
cmpq $0x36, %rcx
je 0xa159a
cmpl $0x50, %r15d
jne 0xa1598
movq 0x8(%rbx), %rdi
movl (%r14), %esi
callq 0xa426
movq %rax, %rcx
movq 0x28(%rax), %rax
subq 0x20(%rcx), %rax
sarq $0x2, %rax
cmpq $0x2, %rax
jb 0xa1598
addl $0x6, %eax
jmp 0xa159a
cmpq %rcx, %rdx
setne %cl
movl $0x8, %eax
testb %cl, %cl
je 0xa1598
jmp 0xa159a
leaq 0x10(%rbx), %rdi
leaq 0x4(%rsp), %rsi
callq 0x22474
movl (%rax), %esi
testl %esi, %esi
je 0xa15e5
movq 0x8(%rbx), %rdi
callq 0xa426
movq %rax, %r14
movq 0x8(%rbx), %rdi
movl %ebp, %esi
callq 0xc7f4
testq %rax, %rax
je 0xa1576
cmpl $0x7, 0x10(%rax)
jne 0xa1576
cmpb $0x1, 0x39(%rax)
jne 0xa1576
movb 0x5b(%rax), %bpl
jmp 0xa1578
xorl %ebp, %ebp
testq %r14, %r14
je 0xa1592
movq 0x8(%rbx), %rdi
movq %r14, %rsi
callq 0x1350a
notb %al
orb %bpl, %al
testb $0x1, %al
je 0xa15a5
xorl %ecx, %ecx
testb %cl, %cl
jne 0xa159a
xorl %eax, %eax
addq $0x28, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movq 0x28(%r14), %rdx
subq 0x20(%r14), %rdx
sarq $0x2, %rdx
movl $0x8, %eax
movb $0x1, %cl
cmpq $0x2, %rdx
jb 0xa1594
cmpq $0x7, %rdx
jae 0xa1697
addl $0x7, %edx
movl %edx, %eax
jmp 0xa1594
cmpl $0x49, %edx
je 0xa15f4
cmpl $0x4a, %edx
je 0xa1602
cmpl $0x4b, %edx
jne 0xa1624
movl $0x6, %eax
jmp 0xa1626
xorl %r14d, %r14d
jmp 0xa1554
movl $0x2, %eax
jmp 0xa1626
movl $0x4, %eax
jmp 0xa1626
movl $0x3, %eax
jmp 0xa1626
movl $0x5, %eax
jmp 0xa1626
movl $0xf, %eax
jmp 0xa1615
movl $0x11, %eax
xorl %edx, %edx
jmp 0xa1620
movl $0x3, %ecx
movb $0x1, %dl
testb %dl, %dl
je 0xa1626
xorl %ecx, %ecx
cmpl $0x1, %ecx
sete %cl
jmp 0xa1594
movl $0x10, %edi
callq 0x6140
movq %rax, %rbx
leaq 0x18(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x22e2e(%rip), %rsi     # 0xc447c
leaq 0x22e60(%rip), %rdx     # 0xc44b5
leaq 0x8(%rsp), %rdi
callq 0x7c64
movb $0x1, %bpl
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x6320
leaq 0x5b722(%rip), %rax     # 0xfcd98
addq $0x10, %rax
movq %rax, (%rbx)
xorl %ebp, %ebp
leaq 0x5b6fa(%rip), %rsi     # 0xfcd80
movq 0x5c94b(%rip), %rdx     # 0xfdfd8
movq %rbx, %rdi
callq 0x6470
jmp 0xa16fb
movl $0x10, %edi
callq 0x6140
movq %rax, %rbx
leaq 0x18(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x22dc8(%rip), %rsi     # 0xc447c
leaq 0x22dfa(%rip), %rdx     # 0xc44b5
leaq 0x8(%rsp), %rdi
callq 0x7c64
movb $0x1, %bpl
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x6320
leaq 0x5b6bc(%rip), %rax     # 0xfcd98
addq $0x10, %rax
movq %rax, (%rbx)
xorl %ebp, %ebp
leaq 0x5b694(%rip), %rsi     # 0xfcd80
movq 0x5c8e5(%rip), %rdx     # 0xfdfd8
movq %rbx, %rdi
callq 0x6470
jmp 0xa16ff
jmp 0xa171b
movq %rax, %r14
movq 0x8(%rsp), %rdi
cmpq %r15, %rdi
je 0xa1721
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x6260
jmp 0xa1721
movq %rax, %r14
movb $0x1, %bpl
testb %bpl, %bpl
je 0xa172e
movq %rbx, %rdi
callq 0x6200
movq %r14, %rdi
callq 0x64a0