// File: /workspace/github_cpp_makefile_star2_O1/rossy[P]crossc/SPIRV-Cross/spirv_msl.cpp
// Function: spirv_cross::CompilerMSL::emit_glsl_op(unsigned int, unsigned int, unsigned int, unsigned int const*, unsigned int)
void CompilerMSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, const uint32_t *args, uint32_t count)
{
	GLSLstd450 op = static_cast<GLSLstd450>(eop);

	switch (op)
	{
	case GLSLstd450Atan2:
		emit_binary_func_op(result_type, id, args[0], args[1], "atan2");
		break;
	case GLSLstd450InverseSqrt:
		emit_unary_func_op(result_type, id, args[0], "rsqrt");
		break;
	case GLSLstd450RoundEven:
		emit_unary_func_op(result_type, id, args[0], "rint");
		break;

	case GLSLstd450FindSMsb:
		emit_unary_func_op(result_type, id, args[0], "findSMSB");
		break;
	case GLSLstd450FindUMsb:
		emit_unary_func_op(result_type, id, args[0], "findUMSB");
		break;

	case GLSLstd450PackSnorm4x8:
		emit_unary_func_op(result_type, id, args[0], "pack_float_to_snorm4x8");
		break;
	case GLSLstd450PackUnorm4x8:
		emit_unary_func_op(result_type, id, args[0], "pack_float_to_unorm4x8");
		break;
	case GLSLstd450PackSnorm2x16:
		emit_unary_func_op(result_type, id, args[0], "pack_float_to_snorm2x16");
		break;
	case GLSLstd450PackUnorm2x16:
		emit_unary_func_op(result_type, id, args[0], "pack_float_to_unorm2x16");
		break;

	case GLSLstd450PackHalf2x16:
	{
		auto expr = join("as_type<uint>(half2(", to_expression(args[0]), "))");
		emit_op(result_type, id, expr, should_forward(args[0]));
		inherit_expression_dependencies(id, args[0]);
		break;
	}

	case GLSLstd450UnpackSnorm4x8:
		emit_unary_func_op(result_type, id, args[0], "unpack_snorm4x8_to_float");
		break;
	case GLSLstd450UnpackUnorm4x8:
		emit_unary_func_op(result_type, id, args[0], "unpack_unorm4x8_to_float");
		break;
	case GLSLstd450UnpackSnorm2x16:
		emit_unary_func_op(result_type, id, args[0], "unpack_snorm2x16_to_float");
		break;
	case GLSLstd450UnpackUnorm2x16:
		emit_unary_func_op(result_type, id, args[0], "unpack_unorm2x16_to_float");
		break;

	case GLSLstd450UnpackHalf2x16:
	{
		auto expr = join("float2(as_type<half2>(", to_expression(args[0]), "))");
		emit_op(result_type, id, expr, should_forward(args[0]));
		inherit_expression_dependencies(id, args[0]);
		break;
	}

	case GLSLstd450PackDouble2x32:
		emit_unary_func_op(result_type, id, args[0], "unsupported_GLSLstd450PackDouble2x32"); // Currently unsupported
		break;
	case GLSLstd450UnpackDouble2x32:
		emit_unary_func_op(result_type, id, args[0], "unsupported_GLSLstd450UnpackDouble2x32"); // Currently unsupported
		break;

	case GLSLstd450MatrixInverse:
	{
		auto &mat_type = get<SPIRType>(result_type);
		switch (mat_type.columns)
		{
		case 2:
			emit_unary_func_op(result_type, id, args[0], "spvInverse2x2");
			break;
		case 3:
			emit_unary_func_op(result_type, id, args[0], "spvInverse3x3");
			break;
		case 4:
			emit_unary_func_op(result_type, id, args[0], "spvInverse4x4");
			break;
		default:
			break;
		}
		break;
	}

	case GLSLstd450FMin:
		// If the result type isn't float, don't bother calling the specific
		// precise::/fast:: version. Metal doesn't have those for half and
		// double types.
		if (get<SPIRType>(result_type).basetype != SPIRType::Float)
			emit_binary_func_op(result_type, id, args[0], args[1], "min");
		else
			emit_binary_func_op(result_type, id, args[0], args[1], "fast::min");
		break;

	case GLSLstd450FMax:
		if (get<SPIRType>(result_type).basetype != SPIRType::Float)
			emit_binary_func_op(result_type, id, args[0], args[1], "max");
		else
			emit_binary_func_op(result_type, id, args[0], args[1], "fast::max");
		break;

	case GLSLstd450FClamp:
		// TODO: If args[1] is 0 and args[2] is 1, emit a saturate() call.
		if (get<SPIRType>(result_type).basetype != SPIRType::Float)
			emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "clamp");
		else
			emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "fast::clamp");
		break;

	case GLSLstd450NMin:
		if (get<SPIRType>(result_type).basetype != SPIRType::Float)
			emit_binary_func_op(result_type, id, args[0], args[1], "min");
		else
			emit_binary_func_op(result_type, id, args[0], args[1], "precise::min");
		break;

	case GLSLstd450NMax:
		if (get<SPIRType>(result_type).basetype != SPIRType::Float)
			emit_binary_func_op(result_type, id, args[0], args[1], "max");
		else
			emit_binary_func_op(result_type, id, args[0], args[1], "precise::max");
		break;

	case GLSLstd450NClamp:
		// TODO: If args[1] is 0 and args[2] is 1, emit a saturate() call.
		if (get<SPIRType>(result_type).basetype != SPIRType::Float)
			emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "clamp");
		else
			emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "precise::clamp");
		break;

		// TODO:
		//        GLSLstd450InterpolateAtCentroid (centroid_no_perspective qualifier)
		//        GLSLstd450InterpolateAtSample (sample_no_perspective qualifier)
		//        GLSLstd450InterpolateAtOffset

	default:
		CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
		break;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x50, %rsp
movq %r8, %r15
movl %edx, %ebx
movl %esi, %ebp
movq %rdi, %r14
leal -0x19(%rcx), %eax
cmpl $0x38, %eax
ja 0x93765
leaq 0x2d43b(%rip), %rdx     # 0xc0b84
movslq (%rdx,%rax,4), %rax
addq %rdx, %rax
jmpq *%rax
movl (%r15), %ecx
movl 0x4(%r15), %r8d
leaq 0x2b9b2(%rip), %r9      # 0xbf112
jmp 0x93a7b
cmpl $0x2, %ecx
jne 0x93779
movl (%r15), %ecx
leaq 0x30022(%rip), %r8      # 0xc3796
jmp 0x93a3c
movq %r14, %rdi
movl %ebp, %esi
movl %ebx, %edx
movq %r15, %r8
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x3e548
movl (%r15), %ecx
leaq 0x3009b(%rip), %r8      # 0xc3839
jmp 0x93a3c
movl (%r15), %ecx
leaq 0x2ffee(%rip), %r8      # 0xc379b
jmp 0x93a3c
movl (%r15), %edx
leaq 0x30(%rsp), %r12
movq %r12, %rdi
movq %r14, %rsi
callq 0x345e6
leaq 0x3003f(%rip), %rsi     # 0xc380b
leaq 0x2fd2d(%rip), %rcx     # 0xc3500
leaq 0x10(%rsp), %rdi
movq %r12, %rdx
callq 0xa6bfe
leaq 0x40(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x937fb
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x6260
movl (%r15), %esi
movq %r14, %rdi
callq 0x39e96
movzbl %al, %r8d
leaq 0x10(%rsp), %rcx
movq %r14, %rdi
movl %ebp, %esi
movl %ebx, %edx
xorl %r9d, %r9d
callq 0x39bea
movl (%r15), %edx
movq %r14, %rdi
movl %ebx, %esi
callq 0x164e0
jmp 0x938f2
movl (%r15), %ecx
leaq 0x2ffe6(%rip), %r8      # 0xc3820
jmp 0x93a3c
movl (%r15), %ecx
leaq 0x30023(%rip), %r8      # 0xc386c
jmp 0x93a3c
movq %r14, %rdi
movl %ebp, %esi
callq 0xa426
cmpl $0xa, 0xc(%rax)
movl (%r15), %ecx
movl 0x4(%r15), %r8d
movl 0x8(%r15), %r9d
jne 0x93ab7
leaq 0x300b3(%rip), %rax     # 0xc3927
jmp 0x93abe
movl (%r15), %edx
leaq 0x30(%rsp), %r12
movq %r12, %rdi
movq %r14, %rsi
callq 0x345e6
leaq 0x2fff3(%rip), %rsi     # 0xc3886
leaq 0x2fc66(%rip), %rcx     # 0xc3500
leaq 0x10(%rsp), %rdi
movq %r12, %rdx
callq 0xa6c9a
leaq 0x40(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x938c2
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x6260
movl (%r15), %esi
movq %r14, %rdi
callq 0x39e96
movzbl %al, %r8d
leaq 0x10(%rsp), %rcx
movq %r14, %rdi
movl %ebp, %esi
movl %ebx, %edx
xorl %r9d, %r9d
callq 0x39bea
movl (%r15), %edx
movq %r14, %rdi
movl %ebx, %esi
callq 0x164e0
leaq 0x20(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x93ace
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x6260
jmp 0x93ace
movq %r14, %rdi
movl %ebp, %esi
callq 0xa426
cmpl $0xa, 0xc(%rax)
movl (%r15), %ecx
movl 0x4(%r15), %r8d
jne 0x93a74
leaq 0x2ffdb(%rip), %r9      # 0xc3913
jmp 0x93a7b
movl (%r15), %ecx
leaq 0x2feac(%rip), %r8      # 0xc37f3
jmp 0x93a3c
movl (%r15), %ecx
leaq 0x2fe4e(%rip), %r8      # 0xc37a4
jmp 0x93a3c
movl (%r15), %ecx
leaq 0x2feed(%rip), %r8      # 0xc3852
jmp 0x93a3c
movq %r14, %rdi
movl %ebp, %esi
callq 0xa426
cmpl $0xa, 0xc(%rax)
movl (%r15), %ecx
movl 0x4(%r15), %r8d
jne 0x939ce
leaq 0x2ffb8(%rip), %r9      # 0xc3940
jmp 0x93a7b
movl (%r15), %ecx
leaq 0x2b718(%rip), %r8      # 0xbf0af
jmp 0x93a3c
movl (%r15), %ecx
leaq 0x2fe35(%rip), %r8      # 0xc37db
jmp 0x93a3c
movq %r14, %rdi
movl %ebp, %esi
callq 0xa426
cmpl $0xa, 0xc(%rax)
movl (%r15), %ecx
movl 0x4(%r15), %r8d
jne 0x939ce
leaq 0x2ff54(%rip), %r9      # 0xc391d
jmp 0x93a7b
leaq 0x2ff74(%rip), %r9      # 0xc3949
jmp 0x93a7b
movl (%r15), %ecx
leaq 0x2fede(%rip), %r8      # 0xc38c2
jmp 0x93a3c
movq %r14, %rdi
movl %ebp, %esi
callq 0xa426
movl 0x18(%rax), %eax
cmpl $0x4, %eax
je 0x93aea
cmpl $0x3, %eax
je 0x93adb
cmpl $0x2, %eax
jne 0x93ace
movl (%r15), %ecx
leaq 0x2fed1(%rip), %r8      # 0xc38e9
jmp 0x93a3c
movl (%r15), %ecx
leaq 0x2fda0(%rip), %r8      # 0xc37c4
jmp 0x93a3c
movl (%r15), %ecx
leaq 0x2fd7d(%rip), %r8      # 0xc37ad
jmp 0x93a3c
movl (%r15), %ecx
leaq 0x2fe61(%rip), %r8      # 0xc389d
movq %r14, %rdi
movl %ebp, %esi
movl %ebx, %edx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x3a790
movq %r14, %rdi
movl %ebp, %esi
callq 0xa426
cmpl $0xa, 0xc(%rax)
movl (%r15), %ecx
movl 0x4(%r15), %r8d
jne 0x93a74
leaq 0x2fec1(%rip), %r9      # 0xc3933
jmp 0x93a7b
leaq 0x2fec1(%rip), %r9      # 0xc393c
movq %r14, %rdi
movl %ebp, %esi
movl %ebx, %edx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x3a8a0
movq %r14, %rdi
movl %ebp, %esi
callq 0xa426
cmpl $0xa, 0xc(%rax)
movl (%r15), %ecx
movl 0x4(%r15), %r8d
movl 0x8(%r15), %r9d
jne 0x93ab7
leaq 0x2fe98(%rip), %rax     # 0xc394d
jmp 0x93abe
leaq 0x2fe98(%rip), %rax     # 0xc3956
movq %rax, (%rsp)
movq %r14, %rdi
movl %ebp, %esi
movl %ebx, %edx
callq 0x3ae2a
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movl (%r15), %ecx
leaq 0x2fe12(%rip), %r8      # 0xc38f7
jmp 0x93a3c
movl (%r15), %ecx
leaq 0x2fe11(%rip), %r8      # 0xc3905
jmp 0x93a3c
jmp 0x93afb
movq %rax, %rbx
leaq 0x40(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x93b33
movq 0x40(%rsp), %rsi
jmp 0x93b2b
jmp 0x93b15
movq %rax, %rbx
leaq 0x20(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x93b33
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x6260
movq %rbx, %rdi
callq 0x64a0
nop