// File: /workspace/github_c_makefile_star2_O3/jondurbin[P]dre2/src/dre2_match.c
// Function: dre2_matcher
struct dre2_single_match dre2_matcher( struct dre2 *graph, unsigned char *begin_ptr, unsigned char *input, int start, int direction, int length, int *r_temp, int *reachable, int *state )
{
  int i, j, k;
  int *swapper, *next_nodes, *previous_nodes;
  int iter, l_iter;
  int matched, single_match;
  int r;
  int count, previous_count;
  int found, complete, assertion, assertion_match;
  struct dre2_node *node;
  struct dre2_single_match ret;

  ret.match = NULL;
  ret.skip_to = DRE2_INFINITE;
  ret.assertion_match = false;

  i = 0;
  next_nodes = direction == DRE2_LEFT ? graph->v[start].p : graph->v[start].n;
  count = direction == DRE2_LEFT ? graph->v[start].p_count : graph->v[start].n_count;

  if ( start == 0 || start == graph->count - 1 )
  {
    for ( i = 0; i < count; i++ )
      reachable[i] = next_nodes[i];
    l_iter = i;
  } else
  {
    reachable[0] = start;
    l_iter = 1;
  }

  assertion_match = false;
  while ( true )
  {
    // Check for valid states.
    i = 0;
    iter = 0;
    matched = false;
    complete = false;
    for ( i = 0; i < l_iter; i++ )
    {
      r = reachable[i];
      node = &graph->v[r];

      // Check if the character matches the node.
      single_match = false;
      switch ( node->c )
      {
        case DRE2_BOL:
        case DRE2_EOF:
        case DRE2_EOL:
          assertion = true;
          break;
        default:
          assertion = false;
          break;
      }

      if ( node->c == DRE2_BOL )
      {
        if ( ( direction == DRE2_LEFT && input - begin_ptr == -1 ) || ( direction == DRE2_RIGHT && input - begin_ptr == 0 ) )
          single_match = true;
      } else if ( node->c == DRE2_EOL && ( *input == '\n' || *input == '\0' ) )
      {
        single_match = true;
      } else if ( node->c == DRE2_EOF && *input == '\0' )
      {
        single_match = true;
      } else if ( node->c == DRE2_EOF && *input == '\n' && input - begin_ptr + 1 == length )
      {
        single_match = true;
      } else if ( node->c == DRE2_EOF && *input == ' ' && input - begin_ptr + 1 == length - 1 )
      {
        single_match = true;
      } else if ( dre2_char_matches( graph, node, *input ) )
      {
        single_match = true;
      }

      if ( assertion && single_match )
        assertion_match = true;

      // Set the next possible nodes.
      if ( single_match == true )
      {
        matched = true;

        // Set the next state to include this node's neighbors/parents.
        next_nodes = direction == DRE2_LEFT ? node->p : node->n;
        count = direction == DRE2_LEFT ? node->p_count : node->n_count;
        for ( j = 0; j < count; j++ )
        {
          if ( !state[next_nodes[j]] )
          {
            state[next_nodes[j]] = true;
            r_temp[iter++] = next_nodes[j];
            if ( ( direction == DRE2_RIGHT && next_nodes[j] == graph->count - 1 ) || ( direction == DRE2_LEFT && next_nodes[j] == 0 ) )
              complete = true;
          }
        }
      } else if ( graph->impossible[*input] )
      {
        ret.skip_to = input - begin_ptr;
      }
    }

    if ( !matched && graph->impossible[*input] )
    {
      for ( i = 0; i < graph->v[0].n_count; i++ )
      {
        if ( direction == DRE2_LEFT && graph->v[graph->v[0].n[i]].c == DRE2_BOL )
        {
          ret.skip_to = length;
          break;
        }
      }
    }

    if ( complete )
    {
      ret.match = input;
      ret.assertion_match = assertion_match;
      if ( !( graph->options & DRE2_GREEDY ) )
      {
        for ( i = 0; i < iter; i++ )
          state[r_temp[i]] = false;
        return ret;
      }
    }

    // Reset the state lookup table.
    for ( i = 0; i < iter; i++ )
      state[r_temp[i]] = false;

    l_iter = iter;

    swapper = reachable;
    reachable = r_temp;
    r_temp = swapper;

    // Increment/Decrement input.
    if ( !assertion_match )
    {
      if ( direction == DRE2_LEFT )
        *input--;
      else
        *input++;
    }

    // If none of the active states matched, the regex failed to match.
    if ( matched == false )
      return ret;
  }
  return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rcx, %r13
movq %rdx, 0x30(%rsp)
movq %rsi, %rbx
movq 0xd0(%rsp), %rax
movq $0x0, 0x10(%rdi)
movl $0xffffffff, 0x8(%rdi)  # imm = 0xFFFFFFFF
movq %rdi, 0x10(%rsp)
movl $0x0, (%rdi)
movslq %r8d, %rdx
movq %rdx, %rcx
shlq $0x6, %rcx
testl %r9d, %r9d
movq (%rsi), %rbp
leaq 0x18(%rbp,%rcx), %rsi
leaq 0x20(%rbp,%rcx), %rdi
leaq 0x8(%rbp,%rcx), %r11
leaq 0x10(%rbp,%rcx), %r10
cmoveq %rsi, %r11
cmoveq %rdi, %r10
movq (%r11), %rcx
movl (%r10), %r14d
testl %edx, %edx
je 0x60b8
movl 0x8(%rbx), %edx
decl %edx
cmpl %r8d, %edx
jne 0x60cf
testl %r14d, %r14d
jle 0x60da
xorl %edx, %edx
movl (%rcx,%rdx,4), %esi
movl %esi, (%rax,%rdx,4)
incq %rdx
cmpq %rdx, %r14
jne 0x60bf
jmp 0x60dd
movl %r8d, (%rax)
movl $0x1, %r14d
jmp 0x60dd
xorl %r14d, %r14d
movq 0xd8(%rsp), %r11
movq 0xc8(%rsp), %rcx
movq %rcx, 0x20(%rsp)
xorl %edx, %edx
testl %r9d, %r9d
sete %dl
movslq 0xc0(%rsp), %rcx
movq %rcx, 0x40(%rsp)
decl %ecx
movslq %ecx, %rcx
movq %rcx, 0x38(%rsp)
shll $0x4, %edx
leaq 0x8(%rdx), %rcx
movq %rcx, 0x70(%rsp)
addq $0x10, %rdx
movq %rdx, 0x78(%rsp)
xorl %r8d, %r8d
movq %rbp, 0x58(%rsp)
movq %rbx, 0x50(%rsp)
movq 0x20(%rsp), %r15
movq %rax, 0x20(%rsp)
movb $0x1, %dil
testl %r14d, %r14d
jg 0x6195
movb $0x1, %al
xorl %r14d, %r14d
movzbl (%r13), %ecx
cmpl $0x0, 0x464(%rbx,%rcx,4)
je 0x63f0
movslq 0x10(%rbp), %rcx
testq %rcx, %rcx
jle 0x63f0
xorl %edx, %edx
testl %r9d, %r9d
jne 0x6188
movq 0x8(%rbp), %rsi
movslq (%rsi,%rdx,4), %rsi
shlq $0x6, %rsi
cmpl $-0x12, (%rbp,%rsi)
je 0x63de
incq %rdx
cmpq %rdx, %rcx
jne 0x616c
jmp 0x63f0
cmpl $0x1, %r9d
sete %al
testl %r9d, %r9d
sete %cl
movq %r13, %rsi
subq 0x30(%rsp), %rsi
sete %dil
movq %rsi, 0x48(%rsp)
incq %rsi
movq %rsi, 0x28(%rsp)
sete %dl
andb %cl, %dl
andb %al, %dil
orb %dl, %dil
movb %dil, 0x3(%rsp)
movl %r14d, %r12d
xorl %ecx, %ecx
movl $0x0, 0xc(%rsp)
movl $0x0, 0x4(%rsp)
xorl %r14d, %r14d
movq %r15, 0x18(%rsp)
movq %r12, 0x68(%rsp)
movq %r13, 0x60(%rsp)
movq 0x20(%rsp), %rax
movq %rcx, 0x80(%rsp)
movslq (%rax,%rcx,4), %rdx
shlq $0x6, %rdx
movl (%rbp,%rdx), %eax
leal 0x12(%rax), %ecx
cmpl $0xf, %ecx
setb %dil
movl $0x4003, %r15d          # imm = 0x4003
shrl %cl, %r15d
leaq (%rdx,%rbp), %rsi
andb %dil, %r15b
cmpl $-0x12, %eax
je 0x6275
cmpl $-0x11, %eax
je 0x625d
cmpl $-0x4, %eax
jne 0x628f
movzbl (%r13), %ecx
testl %ecx, %ecx
je 0x6329
cmpl $0xa, %ecx
jne 0x6310
movb $0xa, %cl
movq 0x28(%rsp), %rax
cmpq 0x40(%rsp), %rax
jne 0x6293
jmp 0x6329
movzbl (%r13), %ecx
testl %ecx, %ecx
je 0x6329
cmpl $0xa, %ecx
je 0x6329
jmp 0x6293
cmpb $0x0, 0x3(%rsp)
jne 0x6329
movb (%r13), %al
movl %eax, 0x8(%rsp)
movq 0x18(%rsp), %r15
jmp 0x62eb
movb (%r13), %cl
movl %ecx, 0x8(%rsp)
movzbl %cl, %edx
movq %rbx, %rdi
movl %r9d, %r13d
movq %r11, %rbp
movq %r8, %r12
movq %rsi, %rbx
callq 0x2100
movq %rbx, %rsi
movq %r12, %r8
movq 0x68(%rsp), %r12
movq %rbp, %r11
movl %r13d, %r9d
movq 0x60(%rsp), %r13
movq 0x50(%rsp), %rbx
movq 0x58(%rsp), %rbp
testl %eax, %eax
movl %r8d, %ecx
movl $0x1, %edx
cmovnel %edx, %ecx
testb %r15b, %r15b
cmovel %r8d, %ecx
testl %eax, %eax
movq 0x18(%rsp), %r15
jne 0x633d
movzbl 0x8(%rsp), %eax
cmpl $0x0, 0x464(%rbx,%rax,4)
je 0x63af
movq 0x10(%rsp), %rax
movq 0x48(%rsp), %rcx
movl %ecx, 0x8(%rax)
jmp 0x63af
cmpb $0x20, %cl
jne 0x6293
movq 0x28(%rsp), %rax
cmpq 0x38(%rsp), %rax
jne 0x6293
testb %r15b, %r15b
movl $0x1, %eax
cmovnel %eax, %r8d
movl %r8d, %ecx
movq 0x18(%rsp), %r15
movq 0x78(%rsp), %rax
movslq (%rsi,%rax), %rax
movl $0x1, 0x4(%rsp)
testq %rax, %rax
jle 0x63ac
movq 0x70(%rsp), %rdx
movq (%rsi,%rdx), %rdx
xorl %esi, %esi
movslq (%rdx,%rsi,4), %r8
cmpl $0x0, (%r11,%r8,4)
jne 0x63a4
leal 0x1(%r14), %edi
movl $0x1, (%r11,%r8,4)
movl (%rdx,%rsi,4), %r8d
movslq %r14d, %r10
movl %r8d, (%r15,%r10,4)
cmpl $0x1, %r9d
jne 0x6394
movl 0x8(%rbx), %r10d
decl %r10d
cmpl %r10d, %r8d
je 0x6399
jmp 0x63a1
orl %r9d, %r8d
jne 0x63a1
movl $0x1, 0xc(%rsp)
movl %edi, %r14d
incq %rsi
cmpq %rsi, %rax
jne 0x635e
movl %ecx, %r8d
movq 0x80(%rsp), %rcx
incq %rcx
cmpq %r12, %rcx
jne 0x61f2
cmpl $0x0, 0xc(%rsp)
sete %al
cmpl $0x0, 0x4(%rsp)
je 0x63d6
xorl %edi, %edi
jmp 0x63f0
movb $0x1, %dil
jmp 0x614a
movq 0x10(%rsp), %rcx
movl 0xc0(%rsp), %edx
movl %edx, 0x8(%rcx)
movb $0x1, %dil
testb %al, %al
jne 0x6409
movq 0x10(%rsp), %rax
movq %r13, 0x10(%rax)
movl %r8d, (%rax)
testb $0x1, 0x43c(%rbx)
je 0x6447
testl %r14d, %r14d
jle 0x6427
movl %r14d, %eax
xorl %ecx, %ecx
movslq (%r15,%rcx,4), %rdx
movl $0x0, (%r11,%rdx,4)
incq %rcx
cmpq %rcx, %rax
jne 0x6413
testl %r8d, %r8d
jne 0x6439
testl %r9d, %r9d
je 0x6436
incq %r13
jmp 0x6439
decq %r13
movq %r15, %rax
testb %dil, %dil
je 0x6133
jmp 0x6465
testl %r14d, %r14d
jle 0x6465
movl %r14d, %eax
xorl %ecx, %ecx
movslq (%r15,%rcx,4), %rdx
movl $0x0, (%r11,%rdx,4)
incq %rcx
cmpq %rcx, %rax
jne 0x6451
movq 0x10(%rsp), %rax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq