// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %edx, %ebp
movl %esi, %r14d
movq %rdi, %rbx
callq 0x4e47c
movq %rbx, %rdi
movl %r14d, %esi
callq 0x12fb0
movq %rbx, %rdi
callq 0x13028
movl %ebp, %r15d
movq 0x80(%rbx), %rax
movb (%rax,%r15), %al
testb $0x1, %al
je 0x4e84c
movq %rbx, %rdi
movl %r14d, %esi
callq 0x7870
cmpl %ebp, 0xb4(%rax)
jne 0x4e841
leaq 0x6c1b0(%rip), %rsi     # 0xba9df
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x588f8
movq 0x80(%rbx), %rax
movb (%rax,%r15), %al
testb $0x14, %al
je 0x4e8cf
movq 0x418(%rbx), %rcx
testq %rcx, %rcx
sete %dl
testb $0x4, %al
sete %al
orb %dl, %al
jne 0x4e8b6
movl 0xb4(%rcx), %esi
cmpl $-0x1, %esi
je 0x4e8b6
movq %rbx, %rdi
callq 0x7870
cmpl %ebp, 0x1c(%rax)
jne 0x4e8b6
movq 0x418(%rbx), %rdx
cmpb $0x0, 0xb2(%rdx)
jne 0x4e89c
movb $0x1, %al
movb %al, 0x1d0(%rbx)
movb %al, 0xb2(%rdx)
addq $0x8, %rdx
leaq 0x6f710(%rip), %rsi     # 0xbdfb7
leaq 0x6c13b(%rip), %rcx     # 0xba9e9
movq %rbx, %rdi
callq 0x589fe
leaq 0x733fb(%rip), %rsi     # 0xc1cb8
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x509dc
cmpl %ebp, %r14d
je 0x4e8fe
movl %eax, %ecx
andb $0x2, %cl
jne 0x4e8fe
testb $0x8, %al
jne 0x4e915
movq %rbx, %rdi
movl %ebp, %esi
callq 0x7870
movq %rbx, %rdi
movq %rax, %rsi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x4d4da
movq %rbx, %rdi
movl %r14d, %esi
movl %ebp, %edx
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x4e5ee
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq