// File: /workspace/github_cpp_makefile_star2_O2/rossy[P]crossc/SPIRV-Cross/spirv_msl.cpp
// Function: spirv_cross::CompilerMSL::emit_atomic_func_op(unsigned int, unsigned int, char const*, unsigned int, unsigned int, bool, unsigned int, unsigned int, bool, bool, unsigned int)
void CompilerMSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id, const char *op, uint32_t mem_order_1,
                                      uint32_t mem_order_2, bool has_mem_order_2, uint32_t obj, uint32_t op1,
                                      bool op1_is_pointer, bool op1_is_literal, uint32_t op2)
{
	forced_temporaries.insert(result_id);

	string exp = string(op) + "(";

	auto &type = expression_type(obj);
	exp += "(volatile ";
	auto *var = maybe_get_backing_variable(obj);
	if (!var)
		SPIRV_CROSS_THROW("No backing variable for atomic operation.");
	exp += get_argument_address_space(*var);
	exp += " atomic_";
	exp += type_to_glsl(type);
	exp += "*)";

	exp += "&";
	exp += to_enclosed_expression(obj);

	bool is_atomic_compare_exchange_strong = op1_is_pointer && op1;

	if (is_atomic_compare_exchange_strong)
	{
		assert(strcmp(op, "atomic_compare_exchange_weak_explicit") == 0);
		assert(op2);
		assert(has_mem_order_2);
		exp += ", &";
		exp += to_name(result_id);
		exp += ", ";
		exp += to_expression(op2);
		exp += ", ";
		exp += get_memory_order(mem_order_1);
		exp += ", ";
		exp += get_memory_order(mem_order_2);
		exp += ")";

		// MSL only supports the weak atomic compare exchange,
		// so emit a CAS loop here.
		statement(variable_decl(type, to_name(result_id)), ";");
		statement("do");
		begin_scope();
		statement(to_name(result_id), " = ", to_expression(op1), ";");
		end_scope_decl(join("while (!", exp, ")"));
		set<SPIRExpression>(result_id, to_name(result_id), result_type, true);
	}
	else
	{
		assert(strcmp(op, "atomic_compare_exchange_weak_explicit") != 0);
		if (op1)
		{
			if (op1_is_literal)
				exp += join(", ", op1);
			else
				exp += ", " + to_expression(op1);
		}
		if (op2)
			exp += ", " + to_expression(op2);

		exp += string(", ") + get_memory_order(mem_order_1);
		if (has_mem_order_2)
			exp += string(", ") + get_memory_order(mem_order_2);

		exp += ")";
		emit_op(result_type, result_id, exp, false);
	}

	flush_all_atomic_capable_variables();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rcx, %r15
movl %esi, %ebp
movq %rdi, %rbx
movl %esi, 0x74(%rsp)
leaq 0x2c(%rsp), %rsi
movl %edx, (%rsi)
addq $0x228, %rdi            # imm = 0x228
callq 0x1af30
leaq 0x8(%rsp), %rdi
leaq 0x30(%rsp), %rdx
movq %r15, %rsi
callq 0x6100
leaq 0x284d9(%rip), %rdx     # 0x9dc29
leaq 0x50(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0xab3f
movl 0xb8(%rsp), %r12d
leaq 0x8(%rsp), %rdi
callq 0x6548
movq %rbx, %rdi
movl %r12d, %esi
callq 0x104b0
movq %rax, %r14
leaq 0x27e19(%rip), %rsi     # 0x9d59f
leaq 0x50(%rsp), %rdi
callq 0x64d0
movq %rbx, %rdi
movl %r12d, %esi
callq 0x1067e
testq %rax, %rax
je 0x75ca0
leaq 0x8(%rsp), %rdi
movq %rbx, %rsi
movq %rax, %rdx
callq 0x6f534
leaq 0x50(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x64f0
leaq 0x8(%rsp), %rdi
callq 0x6548
leaq 0x27e00(%rip), %rsi     # 0x9d5d4
leaq 0x50(%rsp), %rdi
callq 0x64d0
movq (%rbx), %rax
leaq 0x8(%rsp), %rdi
movq %rbx, %rsi
movq %r14, %rdx
xorl %ecx, %ecx
callq *0x98(%rax)
leaq 0x50(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x64f0
leaq 0x8(%rsp), %rdi
callq 0x6548
leaq 0x1ecfb(%rip), %rsi     # 0x9450f
leaq 0x50(%rsp), %rdi
callq 0x64d0
leaq 0x27ea0(%rip), %rsi     # 0x9d6c5
leaq 0x50(%rsp), %rdi
callq 0x64d0
leaq 0x8(%rsp), %rdi
movq %rbx, %rsi
movl %r12d, %edx
callq 0x2beca
movl %ebp, 0x70(%rsp)
leaq 0x50(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x64f0
movb 0xc8(%rsp), %bpl
leaq 0x8(%rsp), %rdi
callq 0x6548
movl 0xc0(%rsp), %r13d
testl %r13d, %r13d
setne %r12b
andb %bpl, %r12b
leaq 0x27a35(%rip), %rsi     # 0x9d2b2
movq %r15, %rdi
callq 0x63d0
cmpb $0x1, %r12b
jne 0x75ac5
testl %eax, %eax
jne 0x75ce9
movl 0xd8(%rsp), %ebp
testl %ebp, %ebp
je 0x75d27
cmpb $0x0, 0xb0(%rsp)
je 0x75d46
leaq 0x27e08(%rip), %rsi     # 0x9d6c3
leaq 0x50(%rsp), %rdi
callq 0x64d0
movl 0x2c(%rsp), %edx
movq (%rbx), %rax
leaq 0x8(%rsp), %rdi
pushq $0x1
popq %rcx
movq %rbx, %rsi
callq *0x38(%rax)
leaq 0x50(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x64f0
leaq 0x8(%rsp), %rdi
callq 0x6548
leaq 0x1f791(%rip), %rsi     # 0x9508b
leaq 0x50(%rsp), %rdi
callq 0x64d0
leaq 0x8(%rsp), %rdi
movq %rbx, %rsi
movl %ebp, %edx
callq 0x2b9f0
leaq 0x50(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x64f0
leaq 0x8(%rsp), %rdi
callq 0x6548
leaq 0x1f758(%rip), %rsi     # 0x9508b
leaq 0x50(%rsp), %rdi
callq 0x64d0
leaq 0x27dc5(%rip), %rsi     # 0x9d709
leaq 0x50(%rsp), %rdi
callq 0x64d0
leaq 0x1f736(%rip), %rsi     # 0x9508b
leaq 0x50(%rsp), %rdi
callq 0x64d0
leaq 0x27da3(%rip), %rsi     # 0x9d709
leaq 0x50(%rsp), %rdi
callq 0x64d0
leaq 0x2007e(%rip), %rsi     # 0x959f5
leaq 0x50(%rsp), %rdi
callq 0x64d0
movl 0x2c(%rsp), %edx
movq (%rbx), %rax
leaq 0x30(%rsp), %rdi
pushq $0x1
popq %rcx
movq %rbx, %rsi
callq *0x38(%rax)
movq (%rbx), %rax
leaq 0x8(%rsp), %rdi
leaq 0x30(%rsp), %rcx
movq %rbx, %rsi
movq %r14, %rdx
xorl %r8d, %r8d
callq *0xc8(%rax)
leaq 0x240c8(%rip), %rdx     # 0x99a81
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x953a
leaq 0x8(%rsp), %rdi
callq 0x6548
leaq 0x30(%rsp), %rdi
callq 0x6548
leaq 0x1ce5d(%rip), %rsi     # 0x9283e
movq %rbx, %rdi
callq 0x475c4
movq %rbx, %rdi
callq 0x22d28
movl 0x2c(%rsp), %edx
movq (%rbx), %rax
leaq 0x8(%rsp), %rdi
pushq $0x1
popq %rcx
movq %rbx, %rsi
callq *0x38(%rax)
movl 0xc0(%rsp), %edx
leaq 0x30(%rsp), %rdi
movq %rbx, %rsi
callq 0x2b9f0
leaq 0x23fc9(%rip), %rdx     # 0x999ea
leaq 0x24059(%rip), %r8      # 0x99a81
leaq 0x8(%rsp), %rsi
leaq 0x30(%rsp), %rcx
movq %rbx, %rdi
callq 0x451e4
leaq 0x30(%rsp), %rdi
callq 0x6548
leaq 0x8(%rsp), %rdi
callq 0x6548
leaq 0x27c72(%rip), %rsi     # 0x9d6c7
leaq 0x1ff99(%rip), %rcx     # 0x959f5
leaq 0x8(%rsp), %rdi
leaq 0x50(%rsp), %rdx
callq 0x8188b
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x253d4
leaq 0x8(%rsp), %rdi
callq 0x6548
movl 0x2c(%rsp), %ebp
movq (%rbx), %rax
leaq 0x8(%rsp), %rdi
pushq $0x1
popq %rcx
movq %rbx, %rsi
movl %ebp, %edx
callq *0x38(%rax)
leaq 0x30(%rsp), %r8
movb $0x1, (%r8)
leaq 0x8(%rsp), %rdx
leaq 0x74(%rsp), %rcx
movq %rbx, %rdi
movl %ebp, %esi
callq 0x436b4
leaq 0x8(%rsp), %rdi
callq 0x6548
jmp 0x75c7f
testl %eax, %eax
je 0x75d08
testl %r13d, %r13d
je 0x75b58
cmpb $0x0, 0xd0(%rsp)
je 0x75b0f
leaq 0x1f5a4(%rip), %rsi     # 0x9508b
leaq 0x8(%rsp), %rdi
leaq 0xc0(%rsp), %rdx
callq 0x464c7
leaq 0x50(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x64f0
leaq 0x8(%rsp), %rdi
jmp 0x75b53
leaq 0x30(%rsp), %rdi
movq %rbx, %rsi
movl %r13d, %edx
callq 0x2b9f0
leaq 0x1f565(%rip), %rsi     # 0x9508b
leaq 0x8(%rsp), %rdi
leaq 0x30(%rsp), %rdx
callq 0x463dd
leaq 0x50(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x64f0
leaq 0x8(%rsp), %rdi
callq 0x6548
leaq 0x30(%rsp), %rdi
callq 0x6548
movl 0xd8(%rsp), %edx
testl %edx, %edx
movl 0x70(%rsp), %ebp
je 0x75bad
leaq 0x30(%rsp), %rdi
movq %rbx, %rsi
callq 0x2b9f0
leaq 0x1f510(%rip), %rsi     # 0x9508b
leaq 0x8(%rsp), %rdi
leaq 0x30(%rsp), %rdx
callq 0x463dd
leaq 0x50(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x64f0
leaq 0x8(%rsp), %rdi
callq 0x6548
leaq 0x30(%rsp), %rdi
callq 0x6548
leaq 0x1f4d7(%rip), %rsi     # 0x9508b
leaq 0x30(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x6100
leaq 0x27b3f(%rip), %rdx     # 0x9d709
leaq 0x8(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0xab3f
leaq 0x50(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x64f0
leaq 0x8(%rsp), %rdi
callq 0x6548
leaq 0x30(%rsp), %rdi
callq 0x6548
cmpb $0x0, 0xb0(%rsp)
je 0x75c55
leaq 0x1f47e(%rip), %rsi     # 0x9508b
leaq 0x30(%rsp), %rdi
leaq 0x7(%rsp), %rdx
callq 0x6100
leaq 0x27ae6(%rip), %rdx     # 0x9d709
leaq 0x8(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0xab3f
leaq 0x50(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x64f0
leaq 0x8(%rsp), %rdi
callq 0x6548
leaq 0x30(%rsp), %rdi
callq 0x6548
leaq 0x1fd99(%rip), %rsi     # 0x959f5
leaq 0x50(%rsp), %rdi
callq 0x64d0
movl 0x2c(%rsp), %edx
leaq 0x50(%rsp), %rcx
movq %rbx, %rdi
movl %ebp, %esi
xorl %r8d, %r8d
xorl %r9d, %r9d
callq 0x2f196
movq %rbx, %rdi
callq 0x10912
leaq 0x50(%rsp), %rdi
callq 0x6548
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x10
popq %rdi
callq 0x6140
movq %rax, %r14
leaq 0x278f8(%rip), %rsi     # 0x9d5aa
leaq 0x8(%rsp), %rdi
leaq 0x30(%rsp), %rdx
callq 0x6100
movb $0x1, %bpl
leaq 0x8(%rsp), %rsi
movq %r14, %rdi
callq 0x6f6e
xorl %ebp, %ebp
leaq 0x710e6(%rip), %rsi     # 0xe6dc0
movq 0x722ff(%rip), %rdx     # 0xe7fe0
movq %r14, %rdi
callq 0x6490
leaq 0x278ed(%rip), %rdi     # 0x9d5dd
leaq 0x256c4(%rip), %rsi     # 0x9b3bb
leaq 0x27918(%rip), %rcx     # 0x9d616
movl $0xa44, %edx            # imm = 0xA44
callq 0x61c0
leaq 0x279c1(%rip), %rdi     # 0x9d6d0
leaq 0x256a5(%rip), %rsi     # 0x9b3bb
leaq 0x278f9(%rip), %rcx     # 0x9d616
movl $0xa5c, %edx            # imm = 0xA5C
callq 0x61c0
leaq 0x27981(%rip), %rdi     # 0x9d6af
leaq 0x25686(%rip), %rsi     # 0x9b3bb
leaq 0x278da(%rip), %rcx     # 0x9d616
movl $0xa45, %edx            # imm = 0xA45
callq 0x61c0
leaq 0x27966(%rip), %rdi     # 0x9d6b3
leaq 0x25667(%rip), %rsi     # 0x9b3bb
leaq 0x278bb(%rip), %rcx     # 0x9d616
movl $0xa46, %edx            # imm = 0xA46
callq 0x61c0
jmp 0x75db5
jmp 0x75dc4
jmp 0x75dfd
jmp 0x75e21
jmp 0x75e21
jmp 0x75db5
jmp 0x75dc4
jmp 0x75e21
jmp 0x75db5
jmp 0x75dc4
jmp 0x75e21
jmp 0x75dfd
jmp 0x75e21
jmp 0x75dfd
jmp 0x75e21
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x6548
jmp 0x75e00
jmp 0x75dfd
jmp 0x75e21
jmp 0x75db5
jmp 0x75dc4
jmp 0x75e21
jmp 0x75dfd
jmp 0x75e21
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x6548
jmp 0x75dc7
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
jmp 0x75e05
jmp 0x75dfd
jmp 0x75e21
jmp 0x75e21
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x6548
testb %bpl, %bpl
jne 0x75deb
jmp 0x75e24
movq %rax, %rbx
movq %r14, %rdi
callq 0x6200
jmp 0x75e24
jmp 0x75dfd
jmp 0x75e21
jmp 0x75dfd
jmp 0x75e21
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x6548
jmp 0x75e24
jmp 0x75e21
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
jmp 0x75e29
movq %rax, %rbx
jmp 0x75e2e
jmp 0x75e21
jmp 0x75e21
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x6548
movq %rbx, %rdi
callq 0x64b0