// File: rossy[P]crossc/SPIRV-Cross/spirv_hlsl.cpp
// Function: spirv_cross::CompilerHLSL::emit_function_prototype(spirv_cross::SPIRFunction&, spirv_cross::Bitset const&)
void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &return_flags)
{
	if (func.self != ir.default_entry_point)
		add_function_overload(func);

	auto &execution = get_entry_point();
	// Avoid shadow declarations.
	local_variable_names = resource_names;

	string decl;

	auto &type = get<SPIRType>(func.return_type);
	if (type.array.empty())
	{
		decl += flags_to_precision_qualifiers_glsl(type, return_flags);
		decl += type_to_glsl(type);
		decl += " ";
	}
	else
	{
		// We cannot return arrays in HLSL, so "return" through an out variable.
		decl = "void ";
	}

	if (func.self == ir.default_entry_point)
	{
		if (execution.model == ExecutionModelVertex)
			decl += "vert_main";
		else if (execution.model == ExecutionModelFragment)
			decl += "frag_main";
		else if (execution.model == ExecutionModelGLCompute)
			decl += "comp_main";
		else
			SPIRV_CROSS_THROW("Unsupported execution model.");
		processing_entry_point = true;
	}
	else
		decl += to_name(func.self);

	decl += "(";

	if (!type.array.empty())
	{
		// Fake array returns by writing to an out array instead.
		decl += "out ";
		decl += type_to_glsl(type);
		decl += " ";
		decl += "SPIRV_Cross_return_value";
		decl += type_to_array_glsl(type);
		if (!func.arguments.empty())
			decl += ", ";
	}

	for (auto &arg : func.arguments)
	{
		// Might change the variable name if it already exists in this function.
		// SPIRV OpName doesn't have any semantic effect, so it's valid for an implementation
		// to use same name for variables.
		// Since we want to make the GLSL debuggable and somewhat sane, use fallback names for variables which are duplicates.
		add_local_variable_name(arg.id);

		decl += argument_decl(arg);

		// Flatten a combined sampler to two separate arguments in modern HLSL.
		auto &arg_type = get<SPIRType>(arg.type);
		if (hlsl_options.shader_model > 30 && arg_type.basetype == SPIRType::SampledImage &&
		    arg_type.image.dim != DimBuffer)
		{
			// Manufacture automatic sampler arg for SampledImage texture
			decl += ", ";
			decl += join(image_is_comparison(arg_type, arg.id) ? "SamplerComparisonState " : "SamplerState ",
			             to_sampler_expression(arg.id), type_to_array_glsl(arg_type));
		}

		if (&arg != &func.arguments.back())
			decl += ", ";

		// Hold a pointer to the parameter so we can invalidate the readonly field if needed.
		auto *var = maybe_get<SPIRVariable>(arg.id);
		if (var)
			var->parameter = &arg;
	}

	decl += ")";
	statement(decl);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x200, %rsp            # imm = 0x200
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rcx
movq %rcx, -0x1c0(%rbp)
movq -0x10(%rbp), %rax
movl 0x8(%rax), %eax
cmpl 0x108(%rcx), %eax
je 0xc40d1
movq -0x1c0(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x97940
movq -0x1c0(%rbp), %rdi
callq 0x25150
movq -0x1c0(%rbp), %rdi
movq %rax, -0x20(%rbp)
movq %rdi, %rsi
addq $0x488, %rsi            # imm = 0x488
addq $0x450, %rdi            # imm = 0x450
callq 0x11580
leaq -0x40(%rbp), %rdi
callq 0x7530
movq -0x1c0(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0xc(%rax), %esi
callq 0xea90
movq %rax, -0x1c8(%rbp)
jmp 0xc4123
movq -0x1c8(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
addq $0x20, %rdi
callq 0x8690
testb $0x1, %al
jne 0xc4144
jmp 0xc41e9
movq -0x1c0(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x61830
movq %rax, -0x1d0(%rbp)
jmp 0xc4161
movq -0x1d0(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x7340
jmp 0xc4173
movq -0x1c0(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq (%rsi), %rax
movq 0x98(%rax), %rax
leaq -0x78(%rbp), %rdi
xorl %ecx, %ecx
callq *%rax
jmp 0xc4192
leaq -0x40(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x7470
jmp 0xc41a1
leaq -0x78(%rbp), %rdi
callq 0x7708
leaq 0x7a6ec(%rip), %rsi     # 0x13e89d
leaq -0x40(%rbp), %rdi
callq 0x7340
jmp 0xc41bc
jmp 0xc41fd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc4846
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x7708
jmp 0xc4846
leaq 0x83e3f(%rip), %rsi     # 0x14802f
leaq -0x40(%rbp), %rdi
callq 0x7510
jmp 0xc41fb
jmp 0xc41fd
movq -0x1c0(%rbp), %rcx
movq -0x10(%rbp), %rax
movl 0x8(%rax), %eax
cmpl 0x108(%rcx), %eax
jne 0xc4367
movq -0x20(%rbp), %rax
cmpl $0x0, 0xb8(%rax)
jne 0xc423b
leaq 0x83e0a(%rip), %rsi     # 0x148035
leaq -0x40(%rbp), %rdi
callq 0x7340
jmp 0xc4236
jmp 0xc4357
movq -0x20(%rbp), %rax
cmpl $0x4, 0xb8(%rax)
jne 0xc425f
leaq 0x83df0(%rip), %rsi     # 0x14803f
leaq -0x40(%rbp), %rdi
callq 0x7340
jmp 0xc425a
jmp 0xc4355
movq -0x20(%rbp), %rax
cmpl $0x5, 0xb8(%rax)
jne 0xc4283
leaq 0x83dd6(%rip), %rsi     # 0x148049
leaq -0x40(%rbp), %rdi
callq 0x7340
jmp 0xc427e
jmp 0xc4353
movb $0x1, -0x9a(%rbp)
movl $0x10, %edi
callq 0x71a0
movq %rax, -0x1e0(%rbp)
leaq -0x99(%rbp), %rdi
movq %rdi, -0x1d8(%rbp)
callq 0x7650
movq -0x1d8(%rbp), %rdx
leaq 0x7a404(%rip), %rsi     # 0x13e6c0
leaq -0x98(%rbp), %rdi
callq 0x7520
jmp 0xc42ca
movq -0x1e0(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x9c50
jmp 0xc42df
movq -0x1e0(%rbp), %rdi
movb $0x0, -0x9a(%rbp)
leaq 0xe9ae4(%rip), %rsi     # 0x1addd8
leaq -0xba66b(%rip), %rdx    # 0x9c90
callq 0x7610
jmp 0xc4858
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc432b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x7708
leaq -0x99(%rbp), %rdi
callq 0x73d0
testb $0x1, -0x9a(%rbp)
jne 0xc4342
jmp 0xc434e
movq -0x1e0(%rbp), %rdi
callq 0x72c0
jmp 0xc4846
jmp 0xc4355
jmp 0xc4357
movq -0x1c0(%rbp), %rax
movb $0x1, 0x5d8(%rax)
jmp 0xc43c9
movq -0x1c0(%rbp), %rsi
movq -0x10(%rbp), %rax
movl 0x8(%rax), %edx
movq (%rsi), %rax
movq 0x38(%rax), %rax
leaq -0xc0(%rbp), %rdi
movl $0x1, %ecx
callq *%rax
jmp 0xc438c
leaq -0x40(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x7470
jmp 0xc439e
leaq -0xc0(%rbp), %rdi
callq 0x7708
jmp 0xc43c9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x7708
jmp 0xc4846
leaq 0x88f5d(%rip), %rsi     # 0x14d32d
leaq -0x40(%rbp), %rdi
callq 0x7340
jmp 0xc43db
movq -0x48(%rbp), %rdi
addq $0x20, %rdi
callq 0x8690
testb $0x1, %al
jne 0xc44fe
leaq 0x806b0(%rip), %rsi     # 0x144aa7
leaq -0x40(%rbp), %rdi
callq 0x7340
jmp 0xc4402
movq -0x1c0(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq (%rsi), %rax
movq 0x98(%rax), %rax
leaq -0xe0(%rbp), %rdi
xorl %ecx, %ecx
callq *%rax
jmp 0xc4424
leaq -0x40(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x7470
jmp 0xc4436
leaq -0xe0(%rbp), %rdi
callq 0x7708
leaq 0x7a454(%rip), %rsi     # 0x13e89d
leaq -0x40(%rbp), %rdi
callq 0x7340
jmp 0xc4454
leaq 0x80bee(%rip), %rsi     # 0x145049
leaq -0x40(%rbp), %rdi
callq 0x7340
jmp 0xc4466
movq -0x1c0(%rbp), %rsi
movq -0x48(%rbp), %rdx
leaq -0x100(%rbp), %rdi
callq 0x61340
jmp 0xc447f
leaq -0x40(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x7470
jmp 0xc4491
leaq -0x100(%rbp), %rdi
callq 0x7708
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
callq 0xdb650
testb $0x1, %al
jne 0xc44fc
leaq 0x800da(%rip), %rsi     # 0x14458f
leaq -0x40(%rbp), %rdi
callq 0x7340
jmp 0xc44c0
jmp 0xc44fc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x7708
jmp 0xc4846
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x7708
jmp 0xc4846
jmp 0xc44fe
movq -0x10(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x108(%rbp)
movq -0x108(%rbp), %rdi
callq 0x115b0
movq %rax, -0x110(%rbp)
movq -0x108(%rbp), %rdi
callq 0x115e0
movq %rax, -0x118(%rbp)
leaq -0x110(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x11610
testb $0x1, %al
jne 0xc454f
jmp 0xc4810
leaq -0x110(%rbp), %rdi
callq 0x11650
movq -0x1c0(%rbp), %rdi
movq %rax, -0x120(%rbp)
movq -0x120(%rbp), %rax
movl 0x4(%rax), %esi
callq 0x78460
jmp 0xc457a
movq -0x1c0(%rbp), %rsi
movq -0x120(%rbp), %rdx
leaq -0x140(%rbp), %rdi
callq 0x95e30
jmp 0xc4596
leaq -0x40(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x7470
jmp 0xc45a8
leaq -0x140(%rbp), %rdi
callq 0x7708
movq -0x1c0(%rbp), %rdi
movq -0x120(%rbp), %rax
movl (%rax), %esi
callq 0xea90
movq %rax, -0x1e8(%rbp)
jmp 0xc45d2
movq -0x1c0(%rbp), %rax
movq -0x1e8(%rbp), %rcx
movq %rcx, -0x148(%rbp)
cmpl $0x1e, 0x788(%rax)
jbe 0xc4776
movq -0x148(%rbp), %rax
cmpl $0xe, 0xc(%rax)
jne 0xc4776
movq -0x148(%rbp), %rax
cmpl $0x5, 0x84(%rax)
je 0xc4776
leaq 0x7ff6f(%rip), %rsi     # 0x14458f
leaq -0x40(%rbp), %rdi
callq 0x7340
jmp 0xc462b
movq -0x1c0(%rbp), %rdi
movq -0x148(%rbp), %rsi
movq -0x120(%rbp), %rax
movl 0x4(%rax), %edx
callq 0x2c890
movb %al, -0x1e9(%rbp)
jmp 0xc4650
movq -0x1c0(%rbp), %rsi
movb -0x1e9(%rbp), %dl
leaq 0x839ef(%rip), %rcx     # 0x148053
leaq 0x83a00(%rip), %rax     # 0x14806b
testb $0x1, %dl
cmovneq %rcx, %rax
movq %rax, -0x170(%rbp)
movq -0x120(%rbp), %rax
movl 0x4(%rax), %edx
leaq -0x190(%rbp), %rdi
callq 0xc3db0
jmp 0xc4691
movq -0x1c0(%rbp), %rsi
movq -0x148(%rbp), %rdx
leaq -0x1b0(%rbp), %rdi
callq 0x61340
jmp 0xc46ad
leaq -0x168(%rbp), %rdi
leaq -0x170(%rbp), %rsi
leaq -0x190(%rbp), %rdx
leaq -0x1b0(%rbp), %rcx
callq 0xdb690
jmp 0xc46d0
leaq -0x40(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x7470
jmp 0xc46e2
leaq -0x168(%rbp), %rdi
callq 0x7708
leaq -0x1b0(%rbp), %rdi
callq 0x7708
leaq -0x190(%rbp), %rdi
callq 0x7708
jmp 0xc4776
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x7708
jmp 0xc4846
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc4765
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc4759
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x7708
leaq -0x1b0(%rbp), %rdi
callq 0x7708
leaq -0x190(%rbp), %rdi
callq 0x7708
jmp 0xc4846
movq -0x120(%rbp), %rax
movq %rax, -0x1f8(%rbp)
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
callq 0x11670
movq %rax, %rcx
movq -0x1f8(%rbp), %rax
cmpq %rcx, %rax
je 0xc47b4
leaq 0x7fde8(%rip), %rsi     # 0x14458f
leaq -0x40(%rbp), %rdi
callq 0x7340
jmp 0xc47b2
jmp 0xc47b4
movq -0x1c0(%rbp), %rdi
movq -0x120(%rbp), %rax
movl 0x4(%rax), %esi
callq 0x116b0
movq %rax, -0x200(%rbp)
jmp 0xc47d3
movq -0x200(%rbp), %rax
movq %rax, -0x1b8(%rbp)
cmpq $0x0, -0x1b8(%rbp)
je 0xc47fd
movq -0x120(%rbp), %rcx
movq -0x1b8(%rbp), %rax
movq %rcx, 0x68(%rax)
jmp 0xc47ff
leaq -0x110(%rbp), %rdi
callq 0x11710
jmp 0xc4533
leaq 0x806e2(%rip), %rsi     # 0x144ef9
leaq -0x40(%rbp), %rdi
callq 0x7340
jmp 0xc4822
movq -0x1c0(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x10200
jmp 0xc4834
leaq -0x40(%rbp), %rdi
callq 0x7708
addq $0x200, %rsp            # imm = 0x200
popq %rbp
retq
leaq -0x40(%rbp), %rdi
callq 0x7708
movq -0x50(%rbp), %rdi
callq 0x7640
nopl (%rax,%rax)