// File: /workspace/github_cpp_makefile_star2_O3/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 0x92b45
leaq 0x2d06b(%rip), %rdx     # 0xbfb94
movslq (%rdx,%rax,4), %rax
addq %rdx, %rax
jmpq *%rax
movl (%r15), %ecx
movl 0x4(%r15), %r8d
leaq 0x2b5da(%rip), %r9      # 0xbe11a
jmp 0x92e5b
cmpl $0x2, %ecx
jne 0x92b59
movl (%r15), %ecx
leaq 0x2fc12(%rip), %r8      # 0xc2766
jmp 0x92e1c
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 0x3dce4
movl (%r15), %ecx
leaq 0x2fc8b(%rip), %r8      # 0xc2809
jmp 0x92e1c
movl (%r15), %ecx
leaq 0x2fbde(%rip), %r8      # 0xc276b
jmp 0x92e1c
movl (%r15), %edx
leaq 0x30(%rsp), %r12
movq %r12, %rdi
movq %r14, %rsi
callq 0x33f8a
leaq 0x2fc2f(%rip), %rsi     # 0xc27db
leaq 0x2f91d(%rip), %rcx     # 0xc24d0
leaq 0x10(%rsp), %rdi
movq %r12, %rdx
callq 0xa5cf2
leaq 0x40(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x92bdb
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x6260
movl (%r15), %esi
movq %r14, %rdi
callq 0x39684
movzbl %al, %r8d
leaq 0x10(%rsp), %rcx
movq %r14, %rdi
movl %ebp, %esi
movl %ebx, %edx
xorl %r9d, %r9d
callq 0x3942c
movl (%r15), %edx
movq %r14, %rdi
movl %ebx, %esi
callq 0x1616c
jmp 0x92cd2
movl (%r15), %ecx
leaq 0x2fbd6(%rip), %r8      # 0xc27f0
jmp 0x92e1c
movl (%r15), %ecx
leaq 0x2fc13(%rip), %r8      # 0xc283c
jmp 0x92e1c
movq %r14, %rdi
movl %ebp, %esi
callq 0xa3ea
cmpl $0xa, 0xc(%rax)
movl (%r15), %ecx
movl 0x4(%r15), %r8d
movl 0x8(%r15), %r9d
jne 0x92e97
leaq 0x2fca3(%rip), %rax     # 0xc28f7
jmp 0x92e9e
movl (%r15), %edx
leaq 0x30(%rsp), %r12
movq %r12, %rdi
movq %r14, %rsi
callq 0x33f8a
leaq 0x2fbe3(%rip), %rsi     # 0xc2856
leaq 0x2f856(%rip), %rcx     # 0xc24d0
leaq 0x10(%rsp), %rdi
movq %r12, %rdx
callq 0xa5d8e
leaq 0x40(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x92ca2
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x6260
movl (%r15), %esi
movq %r14, %rdi
callq 0x39684
movzbl %al, %r8d
leaq 0x10(%rsp), %rcx
movq %r14, %rdi
movl %ebp, %esi
movl %ebx, %edx
xorl %r9d, %r9d
callq 0x3942c
movl (%r15), %edx
movq %r14, %rdi
movl %ebx, %esi
callq 0x1616c
leaq 0x20(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x92eae
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x6260
jmp 0x92eae
movq %r14, %rdi
movl %ebp, %esi
callq 0xa3ea
cmpl $0xa, 0xc(%rax)
movl (%r15), %ecx
movl 0x4(%r15), %r8d
jne 0x92e54
leaq 0x2fbcb(%rip), %r9      # 0xc28e3
jmp 0x92e5b
movl (%r15), %ecx
leaq 0x2fa9c(%rip), %r8      # 0xc27c3
jmp 0x92e1c
movl (%r15), %ecx
leaq 0x2fa3e(%rip), %r8      # 0xc2774
jmp 0x92e1c
movl (%r15), %ecx
leaq 0x2fadd(%rip), %r8      # 0xc2822
jmp 0x92e1c
movq %r14, %rdi
movl %ebp, %esi
callq 0xa3ea
cmpl $0xa, 0xc(%rax)
movl (%r15), %ecx
movl 0x4(%r15), %r8d
jne 0x92dae
leaq 0x2fba8(%rip), %r9      # 0xc2910
jmp 0x92e5b
movl (%r15), %ecx
leaq 0x2b340(%rip), %r8      # 0xbe0b7
jmp 0x92e1c
movl (%r15), %ecx
leaq 0x2fa25(%rip), %r8      # 0xc27ab
jmp 0x92e1c
movq %r14, %rdi
movl %ebp, %esi
callq 0xa3ea
cmpl $0xa, 0xc(%rax)
movl (%r15), %ecx
movl 0x4(%r15), %r8d
jne 0x92dae
leaq 0x2fb44(%rip), %r9      # 0xc28ed
jmp 0x92e5b
leaq 0x2fb64(%rip), %r9      # 0xc2919
jmp 0x92e5b
movl (%r15), %ecx
leaq 0x2face(%rip), %r8      # 0xc2892
jmp 0x92e1c
movq %r14, %rdi
movl %ebp, %esi
callq 0xa3ea
movl 0x18(%rax), %eax
cmpl $0x4, %eax
je 0x92eca
cmpl $0x3, %eax
je 0x92ebb
cmpl $0x2, %eax
jne 0x92eae
movl (%r15), %ecx
leaq 0x2fac1(%rip), %r8      # 0xc28b9
jmp 0x92e1c
movl (%r15), %ecx
leaq 0x2f990(%rip), %r8      # 0xc2794
jmp 0x92e1c
movl (%r15), %ecx
leaq 0x2f96d(%rip), %r8      # 0xc277d
jmp 0x92e1c
movl (%r15), %ecx
leaq 0x2fa51(%rip), %r8      # 0xc286d
movq %r14, %rdi
movl %ebp, %esi
movl %ebx, %edx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x39f86
movq %r14, %rdi
movl %ebp, %esi
callq 0xa3ea
cmpl $0xa, 0xc(%rax)
movl (%r15), %ecx
movl 0x4(%r15), %r8d
jne 0x92e54
leaq 0x2fab1(%rip), %r9      # 0xc2903
jmp 0x92e5b
leaq 0x2fab1(%rip), %r9      # 0xc290c
movq %r14, %rdi
movl %ebp, %esi
movl %ebx, %edx
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x3a096
movq %r14, %rdi
movl %ebp, %esi
callq 0xa3ea
cmpl $0xa, 0xc(%rax)
movl (%r15), %ecx
movl 0x4(%r15), %r8d
movl 0x8(%r15), %r9d
jne 0x92e97
leaq 0x2fa88(%rip), %rax     # 0xc291d
jmp 0x92e9e
leaq 0x2fa88(%rip), %rax     # 0xc2926
movq %rax, (%rsp)
movq %r14, %rdi
movl %ebp, %esi
movl %ebx, %edx
callq 0x3a620
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movl (%r15), %ecx
leaq 0x2fa02(%rip), %r8      # 0xc28c7
jmp 0x92e1c
movl (%r15), %ecx
leaq 0x2fa01(%rip), %r8      # 0xc28d5
jmp 0x92e1c
jmp 0x92edb
movq %rax, %rbx
leaq 0x40(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x92f13
movq 0x40(%rsp), %rsi
jmp 0x92f0b
jmp 0x92ef5
movq %rax, %rbx
leaq 0x20(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x92f13
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x6260
movq %rbx, %rdi
callq 0x64a0
nop