// File: rossy[P]crossc/SPIRV-Cross/spirv_glsl.cpp
// Function: spirv_cross::CompilerGLSL::branch(unsigned int, unsigned int)
void CompilerGLSL::branch(uint32_t from, uint32_t to)
{
	flush_phi(from, to);
	flush_control_dependent_expressions(from);
	flush_all_active_variables();

	// This is only a continue if we branch to our loop dominator.
	if ((ir.block_meta[to] & ParsedIR::BLOCK_META_LOOP_HEADER_BIT) != 0 && get<SPIRBlock>(from).loop_dominator == to)
	{
		// This can happen if we had a complex continue block which was emitted.
		// Once the continue block tries to branch to the loop header, just emit continue;
		// and end the chain here.
		statement("continue;");
	}
	else if (is_break(to))
	{
		// Very dirty workaround.
		// Switch constructs are able to break, but they cannot break out of a loop at the same time.
		// Only sensible solution is to make a ladder variable, which we declare at the top of the switch block,
		// write to the ladder here, and defer the break.
		// The loop we're breaking out of must dominate the switch block, or there is no ladder breaking case.
		if (current_emitting_switch && is_loop_break(to) && current_emitting_switch->loop_dominator != -1u &&
		    get<SPIRBlock>(current_emitting_switch->loop_dominator).merge_block == to)
		{
			if (!current_emitting_switch->need_ladder_break)
			{
				force_recompile = true;
				current_emitting_switch->need_ladder_break = true;
			}

			statement("_", current_emitting_switch->self, "_ladder_break = true;");
		}
		statement("break;");
	}
	else if (is_continue(to) || (from == to))
	{
		// For from == to case can happen for a do-while loop which branches into itself.
		// We don't mark these cases as continue blocks, but the only possible way to branch into
		// ourselves is through means of continue blocks.
		branch_to_continue(from, to);
	}
	else if (!is_conditional(to))
		emit_block_chain(get<SPIRBlock>(to));

	// It is important that we check for break before continue.
	// A block might serve two purposes, a break block for the inner scope, and
	// a continue block in the outer scope.
	// Inner scope always takes precedence.
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x18(%rbp)
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
callq 0x99760
movq -0x18(%rbp), %rdi
movl -0xc(%rbp), %esi
callq 0x20030
movq -0x18(%rbp), %rdi
callq 0x200e0
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
addq $0x78, %rdi
movl -0x10(%rbp), %eax
movl %eax, %esi
callq 0xa82d0
movzbl (%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x99c17
movq -0x18(%rbp), %rdi
movl -0xc(%rbp), %esi
callq 0x87d0
movl 0xb4(%rax), %eax
cmpl -0x10(%rbp), %eax
jne 0x99c17
movq -0x18(%rbp), %rdi
leaq 0xab2b6(%rip), %rsi     # 0x144ec3
callq 0xa81b0
jmp 0x99d3d
movq -0x18(%rbp), %rdi
movl -0x10(%rbp), %esi
callq 0xa82f0
testb $0x1, %al
jne 0x99c2c
jmp 0x99ce6
movq -0x18(%rbp), %rax
cmpq $0x0, 0x418(%rax)
je 0x99cd4
movq -0x18(%rbp), %rdi
movl -0x10(%rbp), %esi
callq 0xa8330
testb $0x1, %al
jne 0x99c53
jmp 0x99cd4
movq -0x18(%rbp), %rax
movq 0x418(%rax), %rax
cmpl $-0x1, 0xb4(%rax)
je 0x99cd4
movq -0x18(%rbp), %rdi
movq 0x418(%rdi), %rax
movl 0xb4(%rax), %esi
callq 0x87d0
movl 0x1c(%rax), %eax
cmpl -0x10(%rbp), %eax
jne 0x99cd4
movq -0x18(%rbp), %rax
movq 0x418(%rax), %rax
testb $0x1, 0xb2(%rax)
jne 0x99cb2
movq -0x18(%rbp), %rax
movb $0x1, 0x1d0(%rax)
movq 0x418(%rax), %rax
movb $0x1, 0xb2(%rax)
movq -0x18(%rbp), %rdi
movq 0x418(%rdi), %rdx
addq $0x8, %rdx
leaq 0xae856(%rip), %rsi     # 0x14851e
leaq 0xab1fe(%rip), %rcx     # 0x144ecd
callq 0xa8370
movq -0x18(%rbp), %rdi
leaq 0xb2695(%rip), %rsi     # 0x14c374
callq 0x9e710
jmp 0x99d3b
movq -0x18(%rbp), %rdi
movl -0x10(%rbp), %esi
callq 0x2fdb0
testb $0x1, %al
jne 0x99cfe
movl -0xc(%rbp), %eax
cmpl -0x10(%rbp), %eax
jne 0x99d0f
movq -0x18(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
callq 0x99960
jmp 0x99d39
movq -0x18(%rbp), %rdi
movl -0x10(%rbp), %esi
callq 0xa84a0
testb $0x1, %al
jne 0x99d37
movq -0x18(%rbp), %rdi
movl -0x10(%rbp), %esi
callq 0x87d0
movq -0x18(%rbp), %rdi
movq %rax, %rsi
callq 0x982d0
jmp 0x99d39
jmp 0x99d3b
jmp 0x99d3d
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)