// File: /workspace/github_c_makefile_star2_O3/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 %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rcx, %rbx
movl %edx, %ebp
movq %rdi, %r14
xorl %r15d, %r15d
movl %esi, %r12d
movzwl (%r14,%r12,2), %eax
movzwl %ax, %ecx
leal -0x2(%rcx), %edx
cmpl $0x5, %edx
jae 0x84b7
movslq %r12d, %rax
movzwl 0x6(%r14,%rax,2), %esi
movq %r14, %rdi
movl %ebp, %edx
movq %rbx, %rcx
callq 0x830e
testl %eax, %eax
je 0x84cb
movzwl (%r14,%r12,2), %eax
cmpw $0x7, %ax
jne 0x8434
movzwl (%rbx), %eax
leal 0xc(%rax), %ecx
cmpl %ebp, %ecx
jge 0x84ce
movslq %r12d, %r13
movzwl 0x2(%r14,%r13,2), %ecx
cmpw $0x1, (%r14,%rcx,2)
je 0x84ce
movq %rcx, %rdx
movzwl 0x2(%r14,%rdx,2), %edx
cmpw $0x1, (%r14,%rdx,2)
jne 0x838e
movzwl 0x4(%r14,%rdx,2), %esi
movl $0xffff0001, (%r14,%rax,2) # imm = 0xFFFF0001
movw %si, 0x4(%r14,%rax,2)
movzwl (%rbx), %edi
addl $0x3, %edi
movw %di, (%rbx)
movzwl %di, %edi
movw $0xffff, (%r14,%rdi,2)  # imm = 0xFFFF
movw %cx, 0x2(%r14,%rdi,2)
movw %r12w, 0x4(%r14,%rdi,2)
addw $0x3, (%rbx)
movw %ax, 0x6(%r14,%r13,2)
movw %r12w, 0x4(%r14,%rdx,2)
movw %dx, 0x2(%r14,%r13,2)
movw %ax, 0x2(%r14,%rsi,2)
movw %di, 0x4(%r14,%rcx,2)
movzwl 0x4(%r14,%r13,2), %eax
movzwl (%r14,%rax,2), %esi
cmpl $0x7, %esi
je 0x84ce
cmpl $0xffff, %esi           # imm = 0xFFFF
je 0x84ce
movl %eax, %ecx
movzwl %cx, %edx
cmpw $0x7, %si
je 0x8439
movzwl %si, %esi
cmpl $0xffff, %esi           # imm = 0xFFFF
je 0x8439
movzwl 0x4(%r14,%rdx,2), %ecx
movzwl (%r14,%rcx,2), %esi
jmp 0x8413
movslq %r12d, %r13
jmp 0x84ac
movzwl 0x2(%r14,%rdx,2), %esi
movzwl (%rbx), %edi
movl $0xffff0001, (%r14,%rdi,2) # imm = 0xFFFF0001
movw %ax, 0x4(%r14,%rdi,2)
movzwl (%rbx), %r8d
addl $0x3, %r8d
movw %r8w, (%rbx)
movzwl %r8w, %r8d
movw $0xffff, (%r14,%r8,2)   # imm = 0xFFFF
movw %si, 0x2(%r14,%r8,2)
movw %r12w, 0x4(%r14,%r8,2)
addw $0x3, (%rbx)
movw %di, 0x8(%r14,%r13,2)
movw %r12w, 0x2(%r14,%rdx,2)
movw %cx, 0x4(%r14,%r13,2)
movw %di, 0x2(%r14,%rax,2)
movw %r8w, 0x4(%r14,%rsi,2)
movzwl 0x8(%r14,%r13,2), %esi
movq %r14, %rdi
movl %ebp, %edx
movq %rbx, %rcx
callq 0x830e
testl %eax, %eax
je 0x84ce
movzwl 0x4(%r14,%r13,2), %esi
jmp 0x8324
cmpl $0xffff, %ecx           # imm = 0xFFFF
jne 0x835e
movl $0x1, %r15d
jmp 0x84ce
xorl %r15d, %r15d
movl %r15d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq