// File: rossy[P]crossc/SPIRV-Cross/spirv_msl.cpp
// Function: spirv_cross::CompilerMSL::compile[abi:cxx11]()
string CompilerMSL::compile()
{
	// Force a classic "C" locale, reverts when function returns
	ClassicLocale classic_locale;

	// Do not deal with GLES-isms like precision, older extensions and such.
	options.vulkan_semantics = true;
	options.es = false;
	options.version = 450;
	backend.float_literal_suffix = false;
	backend.half_literal_suffix = "h";
	backend.uint32_t_literal_suffix = true;
	backend.basic_int_type = "int";
	backend.basic_uint_type = "uint";
	backend.discard_literal = "discard_fragment()";
	backend.swizzle_is_function = false;
	backend.shared_is_implied = false;
	backend.use_initializer_list = true;
	backend.use_typed_initializer_list = true;
	backend.native_row_major_matrix = false;
	backend.flexible_member_array_supported = false;
	backend.can_declare_arrays_inline = false;
	backend.can_return_array = false;
	backend.boolean_mix_support = false;
	backend.allow_truncated_access_chain = true;
	backend.array_is_value_type = false;

	is_rasterization_disabled = msl_options.disable_rasterization;

	replace_illegal_names();

	struct_member_padding.clear();

	build_function_control_flow_graphs_and_analyze();
	update_active_builtins();
	analyze_image_and_sampler_usage();
	analyze_sampled_image_usage();
	build_implicit_builtins();

	fixup_image_load_store_access();

	set_enabled_interface_variables(get_active_interface_variables());
	if (aux_buffer_id)
		active_interface_variables.insert(aux_buffer_id);

	// Preprocess OpCodes to extract the need to output additional header content
	preprocess_op_codes();

	// Create structs to hold input, output and uniform variables.
	// Do output first to ensure out. is declared at top of entry function.
	qual_pos_var_name = "";
	stage_out_var_id = add_interface_block(StorageClassOutput);
	stage_in_var_id = add_interface_block(StorageClassInput);

	// Metal vertex functions that define no output must disable rasterization and return void.
	if (!stage_out_var_id)
		is_rasterization_disabled = true;

	// Convert the use of global variables to recursively-passed function parameters
	localize_global_variables();
	extract_global_variables_from_functions();

	// Mark any non-stage-in structs to be tightly packed.
	mark_packable_structs();

	// Metal does not allow dynamic array lengths.
	// Resolve any specialization constants that are used for array lengths.
	if (msl_options.resolve_specialized_array_lengths)
		resolve_specialized_array_lengths();

	uint32_t pass_count = 0;
	do
	{
		if (pass_count >= 3)
			SPIRV_CROSS_THROW("Over 3 compilation loops detected. Must be a bug!");

		reset();

		next_metal_resource_index = MSLResourceBinding(); // Start bindings at zero

		// Move constructor for this type is broken on GCC 4.9 ...
		buffer = unique_ptr<ostringstream>(new ostringstream());

		emit_header();
		emit_specialization_constants();
		emit_resources();
		emit_custom_functions();
		emit_function(get<SPIRFunction>(ir.default_entry_point), Bitset());

		pass_count++;
	} while (force_recompile);

	return buffer->str();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movq %rdi, -0x128(%rbp)
movq %rdi, %rax
movq %rax, -0x120(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x118(%rbp)
leaq -0x18(%rbp), %rdi
callq 0x105a0
movq -0x118(%rbp), %rax
movb $0x1, 0x43e(%rax)
movb $0x0, 0x43c(%rax)
movl $0x1c2, 0x438(%rax)     # imm = 0x1C2
movq %rax, %rdi
addq $0x5e0, %rdi            # imm = 0x5E0
movb $0x0, 0x600(%rax)
leaq 0x4e612(%rip), %rcx     # 0x141f51
movq %rcx, 0x618(%rax)
movb $0x1, 0x602(%rax)
leaq 0x4dedf(%rip), %rcx     # 0x141833
movq %rcx, 0x608(%rax)
leaq 0x59780(%rip), %rcx     # 0x14d0e2
movq %rcx, 0x610(%rax)
leaq 0x5709c(%rip), %rsi     # 0x14aa0c
callq 0x7510
jmp 0xf3977
movq -0x118(%rbp), %rdi
movb $0x0, 0x620(%rdi)
movb $0x0, 0x621(%rdi)
movb $0x1, 0x624(%rdi)
movb $0x1, 0x625(%rdi)
movb $0x0, 0x628(%rdi)
movb $0x0, 0x622(%rdi)
movb $0x0, 0x627(%rdi)
movb $0x0, 0x62e(%rdi)
movb $0x0, 0x62a(%rdi)
movb $0x1, 0x62f(%rdi)
movb $0x0, 0x632(%rdi)
movb 0x7dd(%rdi), %al
andb $0x1, %al
movb %al, 0x937(%rdi)
movq (%rdi), %rax
movq 0x170(%rax), %rax
callq *%rax
jmp 0xf39e7
movq -0x118(%rbp), %rdi
addq $0x848, %rdi            # imm = 0x848
callq 0x113a50
movq -0x118(%rbp), %rdi
callq 0x2b500
jmp 0xf3a08
movq -0x118(%rbp), %rdi
callq 0x2b100
jmp 0xf3a16
movq -0x118(%rbp), %rdi
callq 0x2b230
jmp 0xf3a24
movq -0x118(%rbp), %rdi
callq 0xf3ec0
jmp 0xf3a32
movq -0x118(%rbp), %rdi
callq 0xf0d20
jmp 0xf3a40
movq -0x118(%rbp), %rdi
callq 0x58d80
jmp 0xf3a4e
movq -0x118(%rbp), %rsi
leaq -0x60(%rbp), %rdi
callq 0x21a10
jmp 0xf3a60
movq -0x118(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x21bd0
jmp 0xf3a72
leaq -0x60(%rbp), %rdi
callq 0x13900
movq -0x118(%rbp), %rax
cmpl $0x0, 0x7c8(%rax)
je 0xf3af8
movq -0x118(%rbp), %rsi
movq %rsi, %rdi
addq $0x158, %rdi            # imm = 0x158
addq $0x7c8, %rsi            # imm = 0x7C8
callq 0x2e890
movb %dl, -0x131(%rbp)
movq %rax, -0x130(%rbp)
jmp 0xf3ab7
movb -0x131(%rbp), %al
movq -0x130(%rbp), %rcx
movq %rcx, -0x70(%rbp)
movb %al, -0x68(%rbp)
jmp 0xf3af8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0xf3ea6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x13900
jmp 0xf3ea6
movq -0x118(%rbp), %rdi
callq 0xf3f50
jmp 0xf3b06
movq -0x118(%rbp), %rdi
addq $0x940, %rdi            # imm = 0x940
leaq 0x4ad83(%rip), %rsi     # 0x13e89e
callq 0x7510
jmp 0xf3b22
movq -0x118(%rbp), %rdi
movl $0x3, %esi
callq 0xf41c0
movl %eax, -0x138(%rbp)
jmp 0xf3b3b
movq -0x118(%rbp), %rdi
movl -0x138(%rbp), %eax
movl %eax, 0x930(%rdi)
movl $0x1, %esi
callq 0xf41c0
movl %eax, -0x13c(%rbp)
jmp 0xf3b60
movq -0x118(%rbp), %rax
movl -0x13c(%rbp), %ecx
movl %ecx, 0x92c(%rax)
cmpl $0x0, 0x930(%rax)
jne 0xf3b8a
movq -0x118(%rbp), %rax
movb $0x1, 0x937(%rax)
movq -0x118(%rbp), %rdi
callq 0xf65a0
jmp 0xf3b98
movq -0x118(%rbp), %rdi
callq 0xf6690
jmp 0xf3ba6
movq -0x118(%rbp), %rdi
callq 0xf6990
jmp 0xf3bb4
movq -0x118(%rbp), %rax
testb $0x1, 0x7de(%rax)
je 0xf3bd4
movq -0x118(%rbp), %rdi
callq 0xf6ae0
jmp 0xf3bd2
jmp 0xf3bd4
movl $0x0, -0x74(%rbp)
cmpl $0x3, -0x74(%rbp)
jb 0xf3cb5
movb $0x1, -0x9a(%rbp)
movl $0x10, %edi
callq 0x71a0
movq %rax, -0x150(%rbp)
leaq -0x99(%rbp), %rdi
movq %rdi, -0x148(%rbp)
callq 0x7650
movq -0x148(%rbp), %rdx
leaq 0x4a7b1(%rip), %rsi     # 0x13e3cf
leaq -0x98(%rbp), %rdi
callq 0x7520
jmp 0xf3c2c
movq -0x150(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x9c50
jmp 0xf3c41
movq -0x150(%rbp), %rdi
movb $0x0, -0x9a(%rbp)
leaq 0xba182(%rip), %rsi     # 0x1addd8
leaq -0xe9fcd(%rip), %rdx    # 0x9c90
callq 0x7610
jmp 0xf3eb8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0xf3c8d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x7708
leaq -0x99(%rbp), %rdi
callq 0x73d0
testb $0x1, -0x9a(%rbp)
jne 0xf3ca4
jmp 0xf3cb0
movq -0x150(%rbp), %rdi
callq 0x72c0
jmp 0xf3ea6
movq -0x118(%rbp), %rdi
callq 0x578d0
jmp 0xf3cc3
xorps %xmm0, %xmm0
movups %xmm0, -0xb4(%rbp)
movaps %xmm0, -0xc0(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x112a30
movq -0x118(%rbp), %rax
movups -0xb7(%rbp), %xmm0
movups %xmm0, 0x919(%rax)
movaps -0xc0(%rbp), %xmm0
movups %xmm0, 0x910(%rax)
movl $0x178, %edi            # imm = 0x178
callq 0x7360
movq %rax, -0x158(%rbp)
jmp 0xf3d16
movq -0x158(%rbp), %rdi
callq 0x74f0
jmp 0xf3d24
movq -0x158(%rbp), %rsi
leaq -0xc8(%rbp), %rdi
movq %rdi, -0x160(%rbp)
callq 0x10620
movq -0x160(%rbp), %rsi
movq -0x118(%rbp), %rdi
addq $0x420, %rdi            # imm = 0x420
callq 0x10650
movq -0x160(%rbp), %rdi
callq 0x10680
movq -0x118(%rbp), %rdi
movq (%rdi), %rax
movq 0x78(%rax), %rax
callq *%rax
jmp 0xf3d76
movq -0x118(%rbp), %rdi
callq 0xf6b80
jmp 0xf3d84
movq -0x118(%rbp), %rdi
callq 0xf7210
jmp 0xf3d92
movq -0x118(%rbp), %rdi
callq 0xf75a0
jmp 0xf3da0
movq -0x118(%rbp), %rdi
movl 0x108(%rdi), %esi
callq 0x106d0
movq %rax, -0x168(%rbp)
jmp 0xf3dbb
xorps %xmm0, %xmm0
movaps %xmm0, -0xe0(%rbp)
movaps %xmm0, -0xf0(%rbp)
movaps %xmm0, -0x100(%rbp)
movaps %xmm0, -0x110(%rbp)
leaq -0x110(%rbp), %rdi
movq %rdi, -0x170(%rbp)
callq 0x10710
movq -0x118(%rbp), %rdi
movq -0x168(%rbp), %rsi
movq -0x170(%rbp), %rdx
callq 0x59ba0
jmp 0xf3e09
leaq -0x110(%rbp), %rdi
callq 0xf250
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
movq -0x118(%rbp), %rax
testb $0x1, 0x1d0(%rax)
jne 0xf3bdb
movq -0x118(%rbp), %rdi
addq $0x420, %rdi            # imm = 0x420
callq 0x10740
movq -0x128(%rbp), %rdi
movq %rax, %rsi
callq 0x7380
jmp 0xf3e56
leaq -0x18(%rbp), %rdi
callq 0x10760
movq -0x120(%rbp), %rax
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq
movq -0x158(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x178, %esi            # imm = 0x178
callq 0x7370
jmp 0xf3ea6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x110(%rbp), %rdi
callq 0xf250
leaq -0x18(%rbp), %rdi
callq 0x10760
movq -0x20(%rbp), %rdi
callq 0x7640
nopl (%rax,%rax)