// File: /workspace/github_c_makefile_star2_O2/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, 0x8(%rsp)
movq %rdx, %rbx
movq %rsi, %r15
movq %rdi, 0x10(%rsp)
movq 0x60(%rsp), %r14
movq %rsi, %rdi
callq 0x77b02
movl %eax, %r13d
movq %r15, %rdi
movq %rbx, %rsi
callq 0x77b9f
movl $0x0, 0xc(%rsp)
movq %r15, %rdi
xorl %esi, %esi
callq 0x77b06
movl %eax, %ebp
pushq $0x1
popq %rax
leaq 0x6d2ca(%rip), %r12     # 0xe0374
movl %eax, 0x4(%rsp)
testl %ebp, %ebp
jne 0x732f3
movq %r15, %rdi
callq 0x77b02
cmpl %r13d, %eax
jle 0x732f3
movq %r15, %rdi
callq 0x77ba4
testl %eax, %eax
je 0x730ec
movl $0x0, %ebp
cmpl $0x1, %eax
jne 0x730ae
movq %r15, %rdi
callq 0x77bb8
movq %rax, %r14
xorl %ebp, %ebp
jmp 0x730ae
movq %r15, %rdi
callq 0x77bb8
movl (%rax), %ecx
cmpq $0x3, %rcx
ja 0x7330f
movslq (%r12,%rcx,4), %rcx
addq %r12, %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 0x73273
movq 0x18(%rsp), %rax
addl (%rax), %ebx
incl 0xc(%rsp)
jmp 0x732c2
movq 0x8(%rax), %rbx
movq (%rbx), %rsi
movq %r15, %rdi
callq 0x77b9f
movl %eax, %ebp
testl %eax, %eax
jne 0x730ae
movq %r15, %rdi
xorl %esi, %esi
callq 0x77b06
movl %eax, %ebp
testl %eax, %eax
jne 0x730ae
movq (%rbx), %rsi
movl 0x8(%rbx), %edx
movl 0xc(%rbx), %ecx
movzbl 0x10(%rbx), %r8d
andl $0x1, %r8d
movq 0x10(%rsp), %rdi
callq 0x95a9c
movq %rax, (%r14)
pushq $0xc
popq %rbp
testq %rax, %rax
je 0x730ae
movq 0x8(%rax), %r14
xorl %ebp, %ebp
jmp 0x730ae
movq 0x8(%rax), %rbx
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
movq 0x10(%rsp), %rdi
callq 0x95aec
movq %rax, (%r14)
pushq $0xc
popq %rbp
testq %rax, %rax
je 0x730ae
movq 0x8(%rax), %r14
jmp 0x731f8
movq 0x8(%rax), %rbx
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
movq 0x10(%rsp), %rdi
callq 0x95b23
movq %rax, (%r14)
pushq $0xc
popq %rbp
testq %rax, %rax
je 0x730ae
movq 0x8(%rax), %r14
xorps %xmm0, %xmm0
movups %xmm0, (%r14)
movq 0x8(%rbx), %rsi
movq %r15, %rdi
callq 0x77b9f
movl %eax, %ebp
testl %eax, %eax
jne 0x730ae
movq %r15, %rdi
xorl %esi, %esi
callq 0x77b06
movl %eax, %ebp
testl %eax, %eax
jne 0x730ae
leaq 0x8(%r14), %rsi
movq %r15, %rdi
callq 0x77b9f
movl %eax, %ebp
testl %eax, %eax
jne 0x730ae
movq %r15, %rdi
pushq $0x1
popq %rsi
callq 0x77b06
movl %eax, %ebp
testl %eax, %eax
jne 0x730ae
movq (%rbx), %rsi
movq %r15, %rdi
callq 0x77b9f
movl %eax, %ebp
testl %eax, %eax
jne 0x730ae
movq %r15, %rdi
xorl %esi, %esi
callq 0x77b06
movl %eax, %ebp
jmp 0x730ae
cmpq $-0x3, %rsi
sete %al
testb %al, 0x8(%rsp)
jne 0x732b9
cmpq $-0x3, %rsi
jne 0x732c2
movl 0x8(%rsp), %eax
shrb %al
cmpl $0x0, 0x4(%rsp)
setne %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x732b2
movslq %edx, %rax
movq 0x20(%rsp), %rcx
movl $0x1, (%rcx,%rax,4)
movl $0x0, 0x4(%rsp)
pushq $-0x3
popq %rax
movl %eax, %esi
jmp 0x732c2
pushq $-0x1
popq %rax
movl %eax, %ebx
movl %eax, %esi
movl %eax, %edx
movq 0x10(%rsp), %rdi
movl %ebx, %ecx
callq 0x95a69
movq %rax, (%r14)
testq %rax, %rax
movl $0x0, %ebp
pushq $0xc
popq %rax
cmovel %eax, %ebp
movq 0x68(%rsp), %rax
cmpl (%rax), %ebx
jle 0x730ae
movl %ebx, (%rax)
jmp 0x730ae
movq 0x18(%rsp), %rax
movl 0xc(%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 0x6832b(%rip), %rdi     # 0xdb641
leaq 0x6d0b6(%rip), %rsi     # 0xe03d3
leaq 0x6d1bf(%rip), %rcx     # 0xe04e3
movl $0x30f, %edx            # imm = 0x30F
callq 0xb400