// File: /workspace/github_c_makefile_star2_O3/mmcco[P]sljit/regex_src/regexJIT.c
// Function: compile_end_check
static int compile_end_check(struct compiler_common *compiler_common, struct sljit_label *end_check_label)
{
	struct sljit_compiler *compiler = compiler_common->compiler;
	struct sljit_jump *jump;
	struct sljit_jump *clear_states_jump;
	struct sljit_label *label;
	struct sljit_label *leave_label;
	struct sljit_label *begin_loop_label;

	/* Priority order: best_begin > best_end > best_id.
	   In other words:
	       if (new best_begin > old test_begin) do nothing
	       otherwise we know that new_end > old_end, since R_CURR_INDEX ever increasing
	       therefore we must overwrite all best_* variables (new_id also contains the highest id for this turn). */

	/* Both R_CURR_CHAR and R_BEST_BEGIN used as temporary regs. */

	if (!(compiler_common->flags & REGEX_MATCH_BEGIN)) {
		EMIT_OP1(SLJIT_MOV, R_CURR_CHAR, 0, SLJIT_MEM1(R_CURR_STATE), TERM_REL_OFFSET_OF(0, 2));
		EMIT_CMP(jump, !(compiler_common->flags & REGEX_MATCH_NON_GREEDY) ? SLJIT_LESS : SLJIT_LESS_EQUAL, SLJIT_MEM1(R_REGEX_MATCH), SLJIT_OFFSETOF(struct regex_match, best_begin), R_CURR_CHAR, 0);
		sljit_set_label(jump, end_check_label);

		EMIT_OP1(SLJIT_MOV, SLJIT_MEM1(R_REGEX_MATCH), SLJIT_OFFSETOF(struct regex_match, best_begin), R_CURR_CHAR, 0);
		if (!(compiler_common->flags & (REGEX_FAKE_MATCH_BEGIN | REGEX_FAKE_MATCH_END))) {
			EMIT_OP1(SLJIT_MOV, SLJIT_MEM1(R_REGEX_MATCH), SLJIT_OFFSETOF(struct regex_match, best_end), R_CURR_INDEX, 0);
		}
		else {
			if ((compiler_common->flags & (REGEX_FAKE_MATCH_BEGIN | REGEX_FAKE_MATCH_END)) == (REGEX_FAKE_MATCH_BEGIN | REGEX_FAKE_MATCH_END)) {
				EMIT_OP2(SLJIT_SUB, SLJIT_MEM1(R_REGEX_MATCH), SLJIT_OFFSETOF(struct regex_match, best_end), R_CURR_INDEX, 0, SLJIT_IMM, 2);
			}
			else {
				EMIT_OP2(SLJIT_SUB, SLJIT_MEM1(R_REGEX_MATCH), SLJIT_OFFSETOF(struct regex_match, best_end), R_CURR_INDEX, 0, SLJIT_IMM, 1);
			}
		}
		if (compiler_common->flags & REGEX_ID_CHECK) {
			EMIT_OP1(SLJIT_MOV, SLJIT_MEM1(R_REGEX_MATCH), SLJIT_OFFSETOF(struct regex_match, best_id), SLJIT_MEM1(R_CURR_STATE), TERM_REL_OFFSET_OF(0, 3));
		}

		EMIT_CMP(clear_states_jump, SLJIT_LESS, R_CURR_CHAR, 0, R_BEST_BEGIN, 0);

		EMIT_LABEL(leave_label);
		EMIT_OP1(SLJIT_MOV, R_BEST_BEGIN, 0, R_CURR_CHAR, 0);
		EMIT_JUMP(jump, SLJIT_JUMP);
		sljit_set_label(jump, end_check_label);

		/* A loop to clear all states, which are > (or >=) than R_CURR_CHAR. */
		EMIT_LABEL(label);
		sljit_set_label(clear_states_jump, label);

		EMIT_OP1(SLJIT_MOV, R_TEMP, 0, R_NEXT_HEAD, 0);
		EMIT_OP1(SLJIT_MOV, R_NEXT_HEAD, 0, SLJIT_IMM, 0);

		/* Begin of the loop. */
		EMIT_LABEL(begin_loop_label);
		EMIT_CMP(jump, SLJIT_EQUAL, R_TEMP, 0, SLJIT_IMM, 0);
		sljit_set_label(jump, leave_label);

		EMIT_OP2(SLJIT_ADD, R_TEMP, 0, R_TEMP, 0, R_CURR_STATE, 0);
		EMIT_OP1(SLJIT_MOV, R_BEST_BEGIN, 0, SLJIT_MEM1(R_TEMP), sizeof(long));
		EMIT_CMP(clear_states_jump, !(compiler_common->flags & REGEX_MATCH_NON_GREEDY) ? SLJIT_GREATER : SLJIT_GREATER_EQUAL, SLJIT_MEM1(R_TEMP), 2 * sizeof(long), R_CURR_CHAR, 0);

		/* Case 1: keep this case. */
		EMIT_OP1(SLJIT_MOV, SLJIT_MEM1(R_TEMP), sizeof(long), R_NEXT_HEAD, 0);
		EMIT_OP2(SLJIT_SUB, R_NEXT_HEAD, 0, R_TEMP, 0, R_CURR_STATE, 0);

		EMIT_OP1(SLJIT_MOV, R_TEMP, 0, R_BEST_BEGIN, 0);
		EMIT_JUMP(jump, SLJIT_JUMP);
		sljit_set_label(jump, begin_loop_label);

		/* Case 2: remove this case. */
		EMIT_LABEL(label);
		sljit_set_label(clear_states_jump, label);

		EMIT_OP1(SLJIT_MOV, SLJIT_MEM1(R_TEMP), sizeof(long), SLJIT_IMM, -1);

		EMIT_OP1(SLJIT_MOV, R_TEMP, 0, R_BEST_BEGIN, 0);
		EMIT_JUMP(jump, SLJIT_JUMP);
		sljit_set_label(jump, begin_loop_label);
	}
	else {
		EMIT_OP1(SLJIT_MOV, R_BEST_BEGIN, 0, SLJIT_IMM, 0);
		EMIT_OP1(SLJIT_MOV, SLJIT_MEM1(R_REGEX_MATCH), SLJIT_OFFSETOF(struct regex_match, best_begin), SLJIT_IMM, 0);
		EMIT_OP1(SLJIT_MOV, SLJIT_MEM1(R_REGEX_MATCH), SLJIT_OFFSETOF(struct regex_match, best_end), R_CURR_INDEX, 0);
		if (compiler_common->flags & REGEX_ID_CHECK) {
			EMIT_OP1(SLJIT_MOV, SLJIT_MEM1(R_REGEX_MATCH), SLJIT_OFFSETOF(struct regex_match, best_id), SLJIT_MEM1(R_CURR_STATE), TERM_REL_OFFSET_OF(0, 2));
		}
		EMIT_JUMP(jump, SLJIT_JUMP);
		sljit_set_label(jump, end_check_label);
	}
	return REGEX_NO_ERROR;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r12
movq %rdi, %r15
movq 0x68(%rdi), %r14
testb $0x1, 0x30(%rdi)
jne 0x55d0
movl $0x10, %r9d
movq %r14, %rdi
movl $0x20, %esi
movl $0x2, %edx
xorl %ecx, %ecx
movl $0x8c, %r8d
callq 0x9c63
movl $0x1, %ebx
testl %eax, %eax
jne 0x56dc
movl 0x30(%r15), %eax
andl $0x8, %eax
shrl $0x3, %eax
leal (%rax,%rax,2), %esi
addl $0x2, %esi
movl $0x20, %ecx
movq %r14, %rdi
movl $0x81, %edx
movl $0x2, %r8d
xorl %r9d, %r9d
callq 0x117ca
testq %rax, %rax
je 0x56dc
movq %rax, %rdi
movq %r12, %rsi
callq 0x78d1
movl $0x20, %ecx
movq %r14, %rdi
movl $0x20, %esi
movl $0x81, %edx
movl $0x2, %r8d
xorl %r9d, %r9d
callq 0x9c63
testl %eax, %eax
jne 0x56dc
movl $0x600, %ecx            # imm = 0x600
movl 0x30(%r15), %eax
andl %ecx, %eax
cmpl %ecx, %eax
je 0x5699
movl $0x28, %ecx
movq %r14, %rdi
testl %eax, %eax
jne 0x56b8
movl $0x20, %esi
movl $0x81, %edx
movl $0x5, %r8d
xorl %r9d, %r9d
callq 0x9c63
jmp 0x56d8
movq %r14, %rdi
movl $0x20, %esi
movl $0x4, %edx
xorl %ecx, %ecx
movl $0x40, %r8d
xorl %r9d, %r9d
callq 0x9c63
movl $0x1, %ebx
testl %eax, %eax
jne 0x56dc
movl $0x20, %ecx
movq %r14, %rdi
movl $0x20, %esi
movl $0x81, %edx
movl $0x40, %r8d
xorl %r9d, %r9d
callq 0x9c63
testl %eax, %eax
jne 0x56dc
movl $0x28, %ecx
movq %r14, %rdi
movl $0x20, %esi
movl $0x81, %edx
movl $0x5, %r8d
xorl %r9d, %r9d
callq 0x9c63
testl %eax, %eax
jne 0x56dc
testb $0x1, 0x31(%r15)
je 0x5678
movl $0x30, %ecx
movl $0x10, %r9d
movq %r14, %rdi
movl $0x20, %esi
movl $0x81, %edx
movl $0x8c, %r8d
callq 0x9c63
testl %eax, %eax
jne 0x56dc
movq %r14, %rdi
movl $0x16, %esi
callq 0x100e3
testq %rax, %rax
je 0x56dc
movq %rax, %rdi
movq %r12, %rsi
callq 0x78d1
xorl %ebx, %ebx
jmp 0x56dc
movl $0x28, %ecx
movq %r14, %rdi
movl $0x62, %esi
movl $0x81, %edx
movl $0x5, %r8d
xorl %r9d, %r9d
pushq $0x2
jmp 0x56cd
movl $0x62, %esi
movl $0x81, %edx
movl $0x5, %r8d
xorl %r9d, %r9d
pushq $0x1
pushq $0x40
callq 0xb023
addq $0x10, %rsp
testl %eax, %eax
je 0x56ed
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testb $0x1, 0x31(%r15)
je 0x571b
movl $0x30, %ecx
movl $0x18, %r9d
movq %r14, %rdi
movl $0x20, %esi
movl $0x81, %edx
movl $0x8c, %r8d
callq 0x9c63
testl %eax, %eax
jne 0x56dc
movq %r14, %rdi
movl $0x2, %esi
movl $0x2, %edx
xorl %ecx, %ecx
movl $0x4, %r8d
xorl %r9d, %r9d
callq 0x117ca
testq %rax, %rax
je 0x56dc
movq %rax, %rbp
movq %r14, %rdi
callq 0xfff6
testq %rax, %rax
je 0x56dc
movq %rax, %r13
movq %r14, %rdi
movl $0x20, %esi
movl $0x4, %edx
xorl %ecx, %ecx
movl $0x2, %r8d
xorl %r9d, %r9d
callq 0x9c63
testl %eax, %eax
jne 0x56dc
movq %r14, %rdi
movl $0x16, %esi
callq 0x100e3
testq %rax, %rax
je 0x56dc
movq %rax, %rdi
movq %r12, %rsi
callq 0x78d1
movq %r14, %rdi
callq 0xfff6
testq %rax, %rax
je 0x56dc
movq %rbp, %rdi
movq %rax, %rsi
callq 0x78d1
movq %r14, %rdi
movl $0x20, %esi
movl $0x3, %edx
xorl %ecx, %ecx
movl $0xa, %r8d
xorl %r9d, %r9d
callq 0x9c63
testl %eax, %eax
jne 0x56dc
movq %r14, %rdi
movl $0x20, %esi
movl $0xa, %edx
xorl %ecx, %ecx
movl $0x40, %r8d
xorl %r9d, %r9d
callq 0x9c63
testl %eax, %eax
jne 0x56dc
movq %r14, %rdi
callq 0xfff6
testq %rax, %rax
je 0x56dc
movq %rax, %r12
movq %r14, %rdi
xorl %esi, %esi
movl $0x3, %edx
xorl %ecx, %ecx
movl $0x40, %r8d
xorl %r9d, %r9d
callq 0x117ca
testq %rax, %rax
je 0x56dc
movq %rax, %rdi
movq %r13, %rsi
callq 0x78d1
movq %r14, %rdi
movl $0x60, %esi
movl $0x3, %edx
xorl %ecx, %ecx
movl $0x3, %r8d
xorl %r9d, %r9d
pushq $0x0
pushq $0xc
callq 0xb023
addq $0x10, %rsp
testl %eax, %eax
jne 0x56dc
xorl %r13d, %r13d
movl $0x8, %r9d
movq %r14, %rdi
movl $0x20, %esi
movl $0x4, %edx
xorl %ecx, %ecx
movl $0x83, %r8d
callq 0x9c63
testl %eax, %eax
jne 0x56dc
movl 0x30(%r15), %eax
andl $0x8, %eax
cmpl $0x1, %eax
adcl $0x3, %r13d
movl $0x10, %ecx
movq %r14, %rdi
movl %r13d, %esi
movl $0x83, %edx
movl $0x2, %r8d
xorl %r9d, %r9d
callq 0x117ca
testq %rax, %rax
je 0x56dc
movq %rax, %r15
movl $0x8, %ecx
movq %r14, %rdi
movl $0x20, %esi
movl $0x83, %edx
movl $0xa, %r8d
xorl %r9d, %r9d
callq 0x9c63
testl %eax, %eax
jne 0x56dc
movq %r14, %rdi
movl $0x62, %esi
movl $0xa, %edx
xorl %ecx, %ecx
movl $0x3, %r8d
xorl %r9d, %r9d
pushq $0x0
pushq $0xc
callq 0xb023
addq $0x10, %rsp
testl %eax, %eax
jne 0x56dc
movq %r14, %rdi
movl $0x20, %esi
movl $0x3, %edx
xorl %ecx, %ecx
movl $0x4, %r8d
xorl %r9d, %r9d
callq 0x9c63
testl %eax, %eax
jne 0x56dc
movq %r14, %rdi
movl $0x16, %esi
callq 0x100e3
testq %rax, %rax
je 0x56dc
movq %rax, %rdi
movq %r12, %rsi
callq 0x78d1
movq %r14, %rdi
callq 0xfff6
testq %rax, %rax
je 0x56dc
movq %r15, %rdi
movq %rax, %rsi
callq 0x78d1
movl $0x8, %ecx
movq %r14, %rdi
movl $0x20, %esi
movl $0x83, %edx
movl $0x40, %r8d
movq $-0x1, %r9
callq 0x9c63
testl %eax, %eax
jne 0x56dc
movq %r14, %rdi
movl $0x20, %esi
movl $0x3, %edx
xorl %ecx, %ecx
movl $0x4, %r8d
xorl %r9d, %r9d
jmp 0x566f