// File: /workspace/github_c_makefile_star2_O1/MikeGray-APH[P]LibLouisAPH/source/pattern.c
// Function: pattern_compile_3
static int pattern_compile_3(unichar *expr_data, int expr_at, const int expr_len, unichar *expr_crs)
{
	int expr_mrk, expr_start, expr_end, expr_sub_start, expr_sub_end;

	while(EXPR_TYPE(expr_at) != PTN_END)
	{
		if(   EXPR_TYPE(expr_at) == PTN_GROUP
		   || EXPR_TYPE(expr_at) == PTN_NOT
		   || EXPR_TYPE(expr_at) == PTN_OPTIONAL
		   || EXPR_TYPE(expr_at) == PTN_ZERO_MORE
		   || EXPR_TYPE(expr_at) == PTN_ONE_MORE)
		{
			if(!pattern_compile_3(expr_data, EXPR_DATA_0(expr_at), expr_len, expr_crs))
				return 0;
		}

		if(EXPR_TYPE(expr_at) == PTN_ALTERNATE)
		{
			if(*expr_crs + 12 >= expr_len)
				return 0;

			/*   get previous start expression,
			     can include alternate expressions   */
			expr_mrk = EXPR_PRV(expr_at);
			if(EXPR_TYPE(expr_mrk) == PTN_START)
				return 0;
			expr_sub_end = expr_mrk;
			while(EXPR_TYPE(expr_mrk) != PTN_START)
				expr_mrk = EXPR_PRV(expr_mrk);
			expr_sub_start = EXPR_NXT(expr_mrk);

			/*   create first start expression   */
			expr_start = *expr_crs;
			EXPR_TYPE(expr_start) = PTN_START;
			EXPR_PRV(expr_start) = PTN_END;
			EXPR_NXT(expr_start) = expr_sub_start;
			*expr_crs += 3;

			/*   create first end expression   */
			expr_end = *expr_crs;
			EXPR_TYPE(expr_end) = PTN_END;
			EXPR_PRV(expr_end) = expr_sub_end;
			EXPR_NXT(expr_end) = expr_at;
			*expr_crs += 3;

			/*   relink previous expression before sub expression   */
			EXPR_DATA_0(expr_at) = expr_start;
			EXPR_NXT(expr_mrk) = expr_at;
			EXPR_PRV(expr_at) = expr_mrk;

			/*   relink sub expression to start and end   */
			EXPR_PRV(expr_sub_start) = expr_start;
			EXPR_NXT(expr_sub_end) = expr_end;

			/*   get following PTN_END or PTN_ALTERNATE expression   */
			expr_mrk = EXPR_NXT(expr_at);
			if(EXPR_TYPE(expr_mrk) == PTN_END || EXPR_TYPE(expr_mrk) == PTN_ALTERNATE)
				return 0;
			expr_sub_start = expr_mrk;
			while(EXPR_TYPE(expr_mrk) != PTN_END && EXPR_TYPE(expr_mrk) != PTN_ALTERNATE)
				expr_mrk = EXPR_NXT(expr_mrk);
			expr_sub_end = EXPR_PRV(expr_mrk);

			/*   create first start expression   */
			expr_start = *expr_crs;
			EXPR_TYPE(expr_start) = PTN_START;
			EXPR_PRV(expr_start) = PTN_END;
			EXPR_NXT(expr_start) = expr_sub_start;
			*expr_crs += 3;

			/*   create first end expression   */
			expr_end = *expr_crs;
			EXPR_TYPE(expr_end) = PTN_END;
			EXPR_PRV(expr_end) = expr_sub_end;
			EXPR_NXT(expr_end) = expr_at;
			*expr_crs += 3;

			/*   relink following expression before sub expression   */
			EXPR_DATA_1(expr_at) = expr_start;
			EXPR_PRV(expr_mrk) = expr_at;
			EXPR_NXT(expr_at) = expr_mrk;

			/*   relink sub expression to start and end   */
			EXPR_PRV(expr_sub_start) = expr_start;
			EXPR_NXT(expr_sub_end) = expr_end;

			/*   check expressions were after alternate and got moved into
			     a sub expression, previous expressions already checked   */
			if(!pattern_compile_3(expr_data, EXPR_DATA_1(expr_at), expr_len, expr_crs))
				return 0;
		}

		expr_at = EXPR_NXT(expr_at);
	}

	return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rcx, %rbx
movl %edx, %ebp
movq %rdi, %r14
xorl %r15d, %r15d
movl %esi, %r12d
movzwl (%r14,%r12,2), %eax
leal -0x2(%rax), %ecx
cmpl $0x5, %ecx
jae 0x85a3
movslq %r12d, %rax
movzwl 0x6(%r14,%rax,2), %esi
movq %r14, %rdi
movl %ebp, %edx
movq %rbx, %rcx
callq 0x83f5
testl %eax, %eax
je 0x85b6
cmpw $0x7, (%r14,%r12,2)
jne 0x8595
movzwl (%rbx), %ecx
leal 0xc(%rcx), %eax
cmpl %ebp, %eax
jge 0x85b9
movslq %r12d, %rax
movzwl 0x2(%r14,%rax,2), %edx
cmpw $0x1, (%r14,%rdx,2)
je 0x85b9
cmpw $0x1, (%r14,%rdx,2)
movl %edx, %edi
movq %rdx, %rsi
je 0x8489
movq %rdx, %rsi
movzwl 0x2(%r14,%rsi,2), %esi
cmpw $0x1, (%r14,%rsi,2)
jne 0x8479
movl %esi, %edi
movzwl 0x4(%r14,%rsi,2), %r8d
movl $0xffff0001, (%r14,%rcx,2) # imm = 0xFFFF0001
movw %r8w, 0x4(%r14,%rcx,2)
movzwl (%rbx), %r9d
addl $0x3, %r9d
movw %r9w, (%rbx)
movzwl %r9w, %r9d
movw $0xffff, (%r14,%r9,2)   # imm = 0xFFFF
movw %dx, 0x2(%r14,%r9,2)
movw %r12w, 0x4(%r14,%r9,2)
addw $0x3, (%rbx)
movw %cx, 0x6(%r14,%rax,2)
movw %r12w, 0x4(%r14,%rsi,2)
movw %di, 0x2(%r14,%rax,2)
movw %cx, 0x2(%r14,%r8,2)
movw %r9w, 0x4(%r14,%rdx,2)
movzwl 0x4(%r14,%rax,2), %ecx
movzwl (%r14,%rcx,2), %edx
cmpl $0x7, %edx
je 0x85b9
cmpl $0xffff, %edx           # imm = 0xFFFF
je 0x85b9
movl %ecx, %edx
movzwl %dx, %esi
movzwl (%r14,%rsi,2), %edi
cmpl $0x7, %edi
je 0x8521
cmpl $0xffff, %edi           # imm = 0xFFFF
je 0x8521
movzwl 0x4(%r14,%rsi,2), %edx
jmp 0x8504
movzwl 0x2(%r14,%rsi,2), %edi
movzwl (%rbx), %r8d
movl $0xffff0001, (%r14,%r8,2) # imm = 0xFFFF0001
movw %cx, 0x4(%r14,%r8,2)
movzwl (%rbx), %r9d
addl $0x3, %r9d
movw %r9w, (%rbx)
movzwl %r9w, %r9d
movw $0xffff, (%r14,%r9,2)   # imm = 0xFFFF
movw %di, 0x2(%r14,%r9,2)
movw %r12w, 0x4(%r14,%r9,2)
addw $0x3, (%rbx)
movw %r8w, 0x8(%r14,%rax,2)
movw %r12w, 0x2(%r14,%rsi,2)
movw %dx, 0x4(%r14,%rax,2)
movw %r8w, 0x2(%r14,%rcx,2)
movw %r9w, 0x4(%r14,%rdi,2)
movzwl 0x8(%r14,%rax,2), %esi
movq %r14, %rdi
movl %ebp, %edx
movq %rbx, %rcx
callq 0x83f5
testl %eax, %eax
je 0x85b9
movslq %r12d, %rax
movzwl 0x4(%r14,%rax,2), %esi
jmp 0x8408
cmpl $0xffff, %eax           # imm = 0xFFFF
jne 0x843a
movl $0x1, %r15d
jmp 0x85b9
xorl %r15d, %r15d
movl %r15d, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq