// File: /workspace/github_c_makefile_star2_O1/genometools[P]genometools/src/external/tre/lib/tre-compile.c
// Function: tre_copy_ast
static reg_errcode_t
tre_copy_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
	     int flags, int *pos_add, tre_tag_direction_t *tag_directions,
	     tre_ast_node_t **copy, int *max_pos)
{
  reg_errcode_t status = REG_OK;
  int bottom = tre_stack_num_objects(stack);
  int num_copied = 0;
  int first_tag = 1;
  tre_ast_node_t **result = copy;
  tre_copyast_symbol_t symbol;

  STACK_PUSH(stack, voidptr, ast);
  STACK_PUSH(stack, int, COPY_RECURSE);

  while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
    {
      tre_ast_node_t *node;
      if (status != REG_OK)
	break;

      symbol = (tre_copyast_symbol_t)tre_stack_pop_int(stack);
      switch (symbol)
	{
	case COPY_SET_RESULT_PTR:
	  result = tre_stack_pop_voidptr(stack);
	  break;
	case COPY_RECURSE:
	  node = tre_stack_pop_voidptr(stack);
	  switch (node->type)
	    {
	    case LITERAL:
	      {
		tre_literal_t *lit = node->obj;
		int pos = lit->position;
		int min = lit->code_min;
		int max = lit->code_max;
		if (!(IS_SPECIAL(lit)) || IS_BACKREF(lit))
		  {
		    /* XXX - e.g. [ab] has only one position but two
		       nodes, so we are creating holes in the state space
		       here.  Not fatal, just wastes memory. */
		    pos += *pos_add;
		    num_copied++;
		  }
		else if (IS_TAG(lit) && (flags & COPY_REMOVE_TAGS))
		  {
		    /* Change this tag to empty. */
		    min = EMPTY;
		    max = pos = -1;
		  }
		else if (IS_TAG(lit) && (flags & COPY_MAXIMIZE_FIRST_TAG)
			 && first_tag)
		  {
		    /* Maximize the first tag. */
		    tag_directions[max] = TRE_TAG_MAXIMIZE;
		    first_tag = 0;
		  }
		*result = tre_ast_new_literal(mem, min, max, pos);
		if (*result == NULL)
		  status = REG_ESPACE;

		if (pos > *max_pos)
		  *max_pos = pos;
		break;
	      }
	    case UNION:
	      {
		tre_union_t *uni = node->obj;
		tre_union_t *tmp;
		*result = tre_ast_new_union(mem, uni->left, uni->right);
		if (*result == NULL)
		  {
		    status = REG_ESPACE;
		    break;
		  }
		tmp = (*result)->obj;
		result = &tmp->left;
		STACK_PUSHX(stack, voidptr, uni->right);
		STACK_PUSHX(stack, int, COPY_RECURSE);
		STACK_PUSHX(stack, voidptr, &tmp->right);
		STACK_PUSHX(stack, int, COPY_SET_RESULT_PTR);
		STACK_PUSHX(stack, voidptr, uni->left);
		STACK_PUSHX(stack, int, COPY_RECURSE);
		break;
	      }
	    case CATENATION:
	      {
		tre_catenation_t *cat = node->obj;
		tre_catenation_t *tmp;
		*result = tre_ast_new_catenation(mem, cat->left, cat->right);
		if (*result == NULL)
		  {
		    status = REG_ESPACE;
		    break;
		  }
		tmp = (*result)->obj;
		tmp->left = NULL;
		tmp->right = NULL;
		result = &tmp->left;

		STACK_PUSHX(stack, voidptr, cat->right);
		STACK_PUSHX(stack, int, COPY_RECURSE);
		STACK_PUSHX(stack, voidptr, &tmp->right);
		STACK_PUSHX(stack, int, COPY_SET_RESULT_PTR);
		STACK_PUSHX(stack, voidptr, cat->left);
		STACK_PUSHX(stack, int, COPY_RECURSE);
		break;
	      }
	    case ITERATION:
	      {
		tre_iteration_t *iter = node->obj;
		STACK_PUSHX(stack, voidptr, iter->arg);
		STACK_PUSHX(stack, int, COPY_RECURSE);
		*result = tre_ast_new_iter(mem, iter->arg, iter->min,
					   iter->max, iter->minimal);
		if (*result == NULL)
		  {
		    status = REG_ESPACE;
		    break;
		  }
		iter = (*result)->obj;
		result = &iter->arg;
		break;
	      }
	    default:
	      assert(0);
	      break;
	    }
	  break;
	}
    }
  *pos_add += num_copied;
  return status;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r9, 0x20(%rsp)
movq %r8, 0x18(%rsp)
movl %ecx, 0x14(%rsp)
movq %rdx, %rbx
movq %rsi, %r15
movq %rdi, 0x8(%rsp)
movq %rsi, %rdi
callq 0x97b6b
movl %eax, %r13d
movq %r15, %rdi
movq %rbx, %rsi
callq 0x97c0f
movl $0x0, (%rsp)
movq %r15, %rdi
xorl %esi, %esi
callq 0x97b6f
movl %eax, %ebp
testl %eax, %eax
jne 0x92818
movq 0x68(%rsp), %r12
movq 0x60(%rsp), %r14
movl $0x1, 0x4(%rsp)
movl $0x0, (%rsp)
movq %r15, %rdi
callq 0x97b6b
cmpl %r13d, %eax
jle 0x92816
movq %r15, %rdi
callq 0x97c14
xorl %ebp, %ebp
testl %eax, %eax
je 0x92624
cmpl $0x1, %eax
jne 0x9280c
movq %r15, %rdi
callq 0x97c28
movq %rax, %r14
jmp 0x9280c
movq %r15, %rdi
callq 0x97c28
movl (%rax), %ecx
cmpq $0x3, %rcx
ja 0x92833
leaq 0x64a61(%rip), %rdx     # 0xf70a0
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movq 0x8(%rax), %rax
movl 0x10(%rax), %ebx
movq (%rax), %rsi
movq 0x8(%rax), %rdx
testq %rsi, %rsi
sets %al
cmpq $-0x4, %rsi
setne %cl
testb %cl, %al
jne 0x9278c
movq 0x18(%rsp), %rax
addl (%rax), %ebx
incl (%rsp)
jmp 0x927e3
movq 0x8(%rax), %rbx
movq (%rbx), %rsi
movq %r15, %rdi
callq 0x97c0f
testl %eax, %eax
jne 0x9277b
movq %r15, %rdi
xorl %esi, %esi
callq 0x97b6f
testl %eax, %eax
jne 0x9277b
movq (%rbx), %rsi
movl 0x8(%rbx), %edx
movl 0xc(%rbx), %ecx
movzbl 0x10(%rbx), %r8d
andl $0x1, %r8d
movq 0x8(%rsp), %rdi
callq 0xb2875
movq %rax, (%r14)
testq %rax, %rax
je 0x92782
movq 0x8(%rax), %r14
jmp 0x9280c
movq 0x8(%rax), %rbx
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
movq 0x8(%rsp), %rdi
callq 0xb28cd
movq %rax, (%r14)
testq %rax, %rax
je 0x92782
movq 0x8(%rax), %r14
jmp 0x92723
movq 0x8(%rax), %rbx
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
movq 0x8(%rsp), %rdi
callq 0xb290c
movq %rax, (%r14)
testq %rax, %rax
je 0x92782
movq 0x8(%rax), %r14
xorps %xmm0, %xmm0
movups %xmm0, (%r14)
movq 0x8(%rbx), %rsi
movq %r15, %rdi
callq 0x97c0f
testl %eax, %eax
jne 0x9277b
movq %r15, %rdi
xorl %esi, %esi
callq 0x97b6f
testl %eax, %eax
jne 0x9277b
leaq 0x8(%r14), %rsi
movq %r15, %rdi
callq 0x97c0f
testl %eax, %eax
jne 0x9277b
movq %r15, %rdi
movl $0x1, %esi
callq 0x97b6f
testl %eax, %eax
jne 0x9277b
movq (%rbx), %rsi
movq %r15, %rdi
callq 0x97c0f
testl %eax, %eax
jne 0x9277b
movq %r15, %rdi
xorl %esi, %esi
callq 0x97b6f
movl %eax, %ebp
jmp 0x9280c
movl $0xc, %ebp
jmp 0x9280c
cmpq $-0x3, %rsi
sete %al
movl 0x14(%rsp), %ecx
testb %al, %cl
jne 0x927d4
movl %ecx, %eax
shrb %al
cmpq $-0x3, %rsi
sete %cl
cmpl $0x0, 0x4(%rsp)
setne %dil
andb %al, %dil
andb %cl, %dil
cmpb $0x1, %dil
jne 0x927e3
movslq %edx, %rax
movq 0x20(%rsp), %rcx
movl $0x1, (%rcx,%rax,4)
movl $0x0, 0x4(%rsp)
jmp 0x927e3
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movq 0x8(%rsp), %rdi
movl %ebx, %ecx
callq 0xb282e
movq %rax, (%r14)
testq %rax, %rax
movl $0x0, %ebp
movl $0xc, %eax
cmovel %eax, %ebp
cmpl (%r12), %ebx
jle 0x9280c
movl %ebx, (%r12)
testl %ebp, %ebp
je 0x925ec
jmp 0x92818
xorl %ebp, %ebp
movq 0x18(%rsp), %rax
movl (%rsp), %ecx
addl %ecx, (%rax)
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x5faf2(%rip), %rdi     # 0xf232c
leaq 0x648c2(%rip), %rsi     # 0xf7103
leaq 0x649cb(%rip), %rcx     # 0xf7213
movl $0x30f, %edx            # imm = 0x30F
callq 0xb400