// File: /workspace/github_c_makefile_star2_O3/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 $0x38, %rsp
movq %r9, %r14
movq %r8, 0x28(%rsp)
movl %ecx, %r12d
movq %rdx, %rbx
movq %rsi, %r15
movq %rdi, %r13
movq %rsi, %rdi
callq 0x970a3
movl %eax, 0x24(%rsp)
movq %r15, %rdi
movq %rbx, %rsi
callq 0x97147
movl $0x0, 0xc(%rsp)
movq %r15, %rdi
xorl %esi, %esi
callq 0x970a7
testl %eax, %eax
je 0x91f01
movl %eax, %ebp
movq 0x28(%rsp), %rax
movl 0xc(%rsp), %ecx
addl %ecx, (%rax)
movl %ebp, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r13, 0x10(%rsp)
movl %r12d, 0x20(%rsp)
movq %r14, 0x30(%rsp)
movq 0x78(%rsp), %r12
movq 0x70(%rsp), %r14
movl $0x1, 0x1c(%rsp)
movl $0x0, 0xc(%rsp)
movl 0x24(%rsp), %r13d
movq %r15, %rdi
callq 0x970a3
cmpl %r13d, %eax
jle 0x9216e
movq %r15, %rdi
callq 0x9714c
xorl %ebp, %ebp
testl %eax, %eax
je 0x91f67
cmpl $0x1, %eax
jne 0x92161
movq %r15, %rdi
callq 0x97160
movq %rax, %r14
jmp 0x92161
movq %r15, %rdi
callq 0x97160
movl (%rax), %ecx
cmpq $0x3, %rcx
ja 0x9217f
leaq 0x650a2(%rip), %rdx     # 0xf7024
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 0x920de
movq 0x28(%rsp), %rax
addl (%rax), %ebx
incl 0xc(%rsp)
jmp 0x92138
movq 0x8(%rax), %rbx
movq (%rbx), %rsi
movq %r15, %rdi
callq 0x97147
testl %eax, %eax
jne 0x91ee3
movq %r15, %rdi
xorl %esi, %esi
callq 0x970a7
testl %eax, %eax
jne 0x91ee3
movq (%rbx), %rsi
movl 0x8(%rbx), %edx
movl 0xc(%rbx), %ecx
movzbl 0x10(%rbx), %r8d
andl $0x1, %r8d
movq 0x10(%rsp), %rdi
callq 0xb1d2b
movq %rax, (%r14)
testq %rax, %rax
je 0x92175
movq 0x8(%rax), %r14
jmp 0x92161
movq 0x8(%rax), %rbx
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
movq 0x10(%rsp), %rdi
callq 0xb1d7f
movq %rax, (%r14)
testq %rax, %rax
je 0x92175
movq 0x8(%rax), %r14
jmp 0x9206b
movq 0x8(%rax), %rbx
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
movq 0x10(%rsp), %rdi
callq 0xb1dba
movq %rax, (%r14)
testq %rax, %rax
je 0x92175
movq 0x8(%rax), %r14
xorps %xmm0, %xmm0
movups %xmm0, (%r14)
movq 0x8(%rbx), %rsi
movq %r15, %rdi
callq 0x97147
testl %eax, %eax
jne 0x91ee3
movq %r15, %rdi
xorl %esi, %esi
callq 0x970a7
testl %eax, %eax
jne 0x91ee3
leaq 0x8(%r14), %rsi
movq %r15, %rdi
callq 0x97147
testl %eax, %eax
jne 0x91ee3
movq %r15, %rdi
movl $0x1, %esi
callq 0x970a7
testl %eax, %eax
jne 0x91ee3
movq (%rbx), %rsi
movq %r15, %rdi
callq 0x97147
testl %eax, %eax
jne 0x91ee3
movq %r15, %rdi
xorl %esi, %esi
callq 0x970a7
movl %eax, %ebp
jmp 0x92161
cmpq $-0x3, %rsi
sete %al
movl 0x20(%rsp), %ecx
testb %al, %cl
jne 0x92129
cmpq $-0x3, %rsi
movq 0x10(%rsp), %rdi
jne 0x9213d
movl %ecx, %eax
shrb %al
cmpl $0x0, 0x1c(%rsp)
setne %cl
andb %al, %cl
movl $0xfffffffd, %esi       # imm = 0xFFFFFFFD
cmpb $0x1, %cl
jne 0x9213d
movslq %edx, %rax
movq 0x30(%rsp), %rcx
movl $0x1, (%rcx,%rax,4)
movl $0x0, 0x1c(%rsp)
jmp 0x9213d
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movq 0x10(%rsp), %rdi
movl %ebx, %ecx
callq 0xb1cf6
movq %rax, (%r14)
testq %rax, %rax
movl $0x0, %ebp
movl $0xc, %eax
cmovel %eax, %ebp
cmpl (%r12), %ebx
jle 0x92161
movl %ebx, (%r12)
testl %ebp, %ebp
je 0x91f2f
jmp 0x91ee5
xorl %ebp, %ebp
jmp 0x91ee5
movl $0xc, %ebp
jmp 0x91ee5
leaq 0x60156(%rip), %rdi     # 0xf22dc
leaq 0x64ef6(%rip), %rsi     # 0xf7083
leaq 0x64fff(%rip), %rcx     # 0xf7193
movl $0x30f, %edx            # imm = 0x30F
callq 0xb400