// File: /workspace/github_c_makefile_star2_O3/genometools[P]genometools/src/extended/rmq.c
// Function: gt_rmq_new
GtRMQ* gt_rmq_new(const GtRMQvaluetype *data, GtUword size)
{
  GtRMQ *rmq;
  GtRMQvaluetype *rp;
  GtUword i, j,
                z = 0,            /* index in array a */
                start,            /* start of current block */
                end,              /* end of current block */
                q,                /* position in catalan triangle */
                p,                /* --------- " ---------------- */
                *gstack,
                gstacksize,
                g, /* first position to the left of i where a[g[i]] < a[i] */
                dist = 1UL; /* always 2^(j-1) */

  rmq = gt_calloc((size_t) 1, sizeof (*rmq));
  rmq->memorycount += sizeof (*rmq);
  rmq->arr_ptr = data;
  rmq->n = size;
  rmq->nb = gt_rmq_block(size-1) + 1;     /* number of blocks */
  rmq->nsb = gt_rmq_superblock(size-1)+1; /* number of superblocks */
  rmq->nmb = gt_rmq_microblock(size-1)+1; /* number of microblocks */

  /* The following is necessary because we've fixed s, s' and s'' according to
      the computer's word size and NOT according to the input size. This may
      cause the (super-)block-size to be too big, or, in other words, the
      array too small. If this code is compiled on a 32-bit computer, this
      happens iff n < 113. For such small instances it isn't advisable anyway
      to use this data structure, because simpler methods are faster and less
      space consuming. */
  if (rmq->nb < GT_RMQ_superblocksize/(GT_MULT2(GT_RMQ_blocksize)))
  {
    rmq->M = NULL;
    rmq->Mprime = NULL;
    rmq->type = NULL;
    rmq->Prec = NULL;
    rmq->naive_impl = true;
    return rmq;
  }
  rmq->naive_impl = false;
  /* Type-calculation for the microblocks and pre-computation of
      in-microblock-queries: */
  rmq->type = rmq_calloc(rmq,(size_t) rmq->nmb, sizeof (*rmq->type));

  /* prec[i]: the jth bit is 1 iff j is 1. pos. to the left of i
      where a[j] < a[i]  */
  gt_assert(GT_RMQ_microblocksize < (GtUword) GT_RMQ_CATALAN_MAX);
  rmq->Prec = rmq_calloc(rmq,(size_t) gt_rmq_catalan[GT_RMQ_microblocksize]
                                                    [GT_RMQ_microblocksize],
                         sizeof (*rmq->Prec));
  for (i = 0; i < gt_rmq_catalan[GT_RMQ_microblocksize][GT_RMQ_microblocksize];
       i++)
  {
    rmq->Prec[i] = rmq_calloc(rmq,(size_t) GT_RMQ_microblocksize,
                              sizeof (**rmq->Prec));
    rmq->Prec[i][0] = 1U; /* init with impossible value */
  }

  rp = rmq_calloc(rmq,(size_t) GT_RMQ_microblocksize+1, sizeof (*rp));
       /* rp: rightmost path in Cartesian tree */
  rp[0] = 0; /* originally LONG_MIN, but for GtUword 0 suffices */
  gstack = rmq_calloc(rmq,(size_t) GT_RMQ_microblocksize, sizeof (*gstack));

  for (i = 0; i < rmq->nmb; i++)
  {          /* step through microblocks */
    start = z;                              /* init start */
    end = start + GT_RMQ_microblocksize;    /* end of block (not inclusive) */
    if (end > size) end = size;       /* last block could be smaller than s */

    /* compute block type as in Fischer/Heun CPM'06: */
    q = GT_RMQ_microblocksize;          /* init q */
    p = GT_RMQ_microblocksize - 1;      /* init p */
    rmq->type[i] = 0;                 /* init type (will be increased!) */
    rp[1] = rmq->arr_ptr[z];          /* init rightmost path */
    while (++z < end)
    {   /* step through current block: */
      p--;
      while (rp[q-p-1] > rmq->arr_ptr[z])
      {
        rmq->type[i] += gt_rmq_catalan[p][q]; /* update type */
        q--;
      }
      gt_assert(q > p);
      rp[q-p] = rmq->arr_ptr[z]; /* add last element to rightmost path */
    }

    /* precompute in-block-queries for this microblock (if necessary) */
    /* as in Alstrup et al. SPAA'02: */
    if (rmq->Prec[rmq->type[i]][0] == 1U)
     {
      rmq->Prec[rmq->type[i]][0] = 0U;
      gstacksize = 0;
      for (j = start; j < end; j++)
      {
        while (gstacksize > 0U &&
               rmq->arr_ptr[j] < rmq->arr_ptr[gstack[gstacksize-1]]) {
          gstacksize--;
        }
        if (gstacksize > 0U)
        {
          g = gstack[gstacksize-1];
          rmq->Prec[rmq->type[i]][j-start]
            = rmq->Prec[rmq->type[i]][g-start] |
              (unsigned char) (1 << (g % GT_RMQ_microblocksize));
        } else
        {
          rmq->Prec[rmq->type[i]][j-start] = 0;
        }
        gstack[gstacksize++] = j;
      }
    }
  }
  gt_free(rp);
  gt_free(gstack);

  /* space for out-of-block- and out-of-superblock-queries: */
  rmq->M_depth = (GtUword) floor(GT_LOG2(((double) GT_RMQ_superblocksize
                                               / (double) GT_RMQ_blocksize)));
  rmq->M = rmq_calloc(rmq,(size_t) rmq->M_depth, sizeof (*rmq->M));
  rmq->M[0] = rmq_calloc(rmq,(size_t) rmq->nb, sizeof (**rmq->M));
  rmq->Mprime_depth = (GtUword) floor(GT_LOG2((double) rmq->nsb)) + 1;
  rmq->Mprime = rmq_calloc(rmq,(size_t) rmq->Mprime_depth,
                           sizeof (*rmq->Mprime));
  rmq->Mprime[0] = rmq_calloc(rmq,(size_t) rmq->nsb, sizeof (**rmq->Mprime));

  /* fill 0'th rows of M and Mprime: */
  z = 0; /* minimum in current block */
  q = 0; /* pos. of min in current superblock */
  g = 0; /* number of current superblock */
  for (i = 0; i < rmq->nb; i++)
  { /* step through blocks */
    start = z;              /* init start */
    p = start;              /* init minimum */
    end = start + GT_RMQ_blocksize;   /* end of block (not inclusive!) */
    if (end > size)
      end = size;   /* last block could be smaller than blocksize! */
    if (rmq->arr_ptr[z] < rmq->arr_ptr[q])
      q = z; /* update minimum in superblock */

    while (++z < end)
    { /* step through current block: */
      if (rmq->arr_ptr[z] < rmq->arr_ptr[p])
        p = z; /* update minimum in block */
      if (rmq->arr_ptr[z] < rmq->arr_ptr[q])
        q = z; /* update minimum in superblock */
    }
    rmq->M[0][i] = (unsigned char) (p-start); /* store index of block-minimum
                                                  (offset!) */
    if (z % GT_RMQ_superblocksize == 0 || z == size)
    {  /* end of superblock? */
      rmq->Mprime[0][g++] = q;       /* store index of superblock-minimum */
      q = z;
    }
  }

  /* fill M: */
  for (j = 1UL; j < rmq->M_depth; j++)
  {
    rmq->M[j] = rmq_calloc(rmq,(size_t) rmq->nb, sizeof (**rmq->M));
    for (i = 0; i < rmq->nb - dist; i++)
    { /* be careful: loop may go too far */
      rmq->M[j][i] = rmq->arr_ptr[gt_rmq_trueindex(rmq, j-1, i)] <=
                     rmq->arr_ptr[gt_rmq_trueindex(rmq, j-1,i+dist)]
                       ? rmq->M[j-1][i]
                       : (unsigned char) (rmq->M[j-1][i+dist] +
                                          GT_RMQ_MUL_blocksize(dist)); /* add
                                                                  'skipped'
                                                                  elements
                                                                  in a */
    }
    for (i = rmq->nb - dist; i < rmq->nb; i++)
    {
      rmq->M[j][i] = rmq->M[j-1][i]; /* fill overhang */
    }
    dist *= 2;
  }

  /* fill M': */
  dist = 1UL; /* always 2^(j-1) */
  for (j = 1UL; j < rmq->Mprime_depth; j++)
  {
    rmq->Mprime[j] = rmq_calloc(rmq,(size_t) rmq->nsb, sizeof (**rmq->Mprime));
    for (i = 0; i < rmq->nsb - dist; i++)
    {
      rmq->Mprime[j][i] =
         (rmq->arr_ptr[rmq->Mprime[j-1][i]] <=
          rmq->arr_ptr[rmq->Mprime[j-1][i+dist]]) ? rmq->Mprime[j-1][i]
                                                  : rmq->Mprime[j-1][i+dist];
    }
    for (i = rmq->nsb - dist; i < rmq->nsb; i++)
    {
      rmq->Mprime[j][i] = rmq->Mprime[j-1][i]; /* overhang */
    }
    dist *= 2;
  }
  return rmq;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rsi, %r13
movq %rdi, %r15
leaq 0x22114b(%rip), %rdx    # 0x3905b4
movl $0x1, %edi
movl $0x68, %esi
movl $0x178, %ecx            # imm = 0x178
callq 0x10436a
movq %rax, %rbx
movq 0x58(%rax), %rax
addq $0x68, %rax
movq %rax, 0x58(%rbx)
movq %r15, (%rbx)
movq %r13, 0x8(%rbx)
leaq -0x1(%r13), %rcx
movq %rcx, %rdx
shrq $0x4, %rdx
incq %rdx
movq %rdx, 0x40(%rbx)
movq %rcx, %rdx
shrq $0x8, %rdx
incq %rdx
movq %rdx, 0x48(%rbx)
movq %rcx, %rdi
shrq $0x3, %rdi
incq %rdi
movq %rdi, 0x50(%rbx)
cmpq $0x6f, %rcx
ja 0x16f4e3
xorl %eax, %eax
movq %rax, 0x10(%rbx)
movq %rax, 0x20(%rbx)
xorpd %xmm0, %xmm0
movupd %xmm0, 0x30(%rbx)
movb $0x1, 0x60(%rbx)
jmp 0x16fa64
movb $0x0, 0x60(%rbx)
leaq (%rax,%rdi,2), %rax
movq %rax, 0x58(%rbx)
leaq 0x2210be(%rip), %r15    # 0x3905b4
movl $0x2, %esi
movq %r15, %rdx
movl $0x166, %ecx            # imm = 0x166
callq 0x10436a
movq %rax, 0x30(%rbx)
addq $0x2cb0, 0x58(%rbx)     # imm = 0x2CB0
movl $0x596, %edi            # imm = 0x596
movl $0x8, %esi
movq %r15, %rdx
movl $0x166, %ecx            # imm = 0x166
callq 0x10436a
movq %rax, 0x38(%rbx)
xorl %r14d, %r14d
movl $0x8, %esi
movl $0x1, %edx
movq %rbx, %rdi
callq 0x16fa7b
movq 0x38(%rbx), %rcx
movq %rax, (%rcx,%r14,8)
movq 0x38(%rbx), %rax
movq (%rax,%r14,8), %rax
movb $0x1, (%rax)
incq %r14
cmpq $0x596, %r14            # imm = 0x596
jne 0x16f532
addq $0x24, 0x58(%rbx)
leaq 0x221045(%rip), %r12    # 0x3905b4
movl $0x9, %edi
movl $0x4, %esi
movq %r12, %rdx
movl $0x166, %ecx            # imm = 0x166
callq 0x10436a
movq %rax, %r15
movl $0x0, (%rax)
addq $0x40, 0x58(%rbx)
movl $0x8, %edi
movl $0x8, %esi
movq %r12, %rdx
movl $0x166, %ecx            # imm = 0x166
callq 0x10436a
movq %rax, %r12
cmpq $0x0, 0x50(%rbx)
movq %r13, 0x8(%rsp)
je 0x16f72d
leaq 0x4(%r15), %rax
movq %rax, 0x18(%rsp)
xorl %edi, %edi
xorl %esi, %esi
movq %rdi, %rbp
leaq 0x8(%rdi), %r9
cmpq %r13, %r9
cmovaeq %r13, %r9
movq 0x30(%rbx), %rax
movq %rax, 0x20(%rsp)
movw $0x0, (%rax,%rsi,2)
movq (%rbx), %r10
movl (%r10,%rdi,4), %eax
movl %eax, 0x4(%r15)
incq %rdi
cmpq %r9, %rdi
jae 0x16f695
movq %rbp, 0x10(%rsp)
movl $0x8, %r11d
movl $0x7, %r13d
movq $-0x7, %rdx
xorl %ebp, %ebp
leaq 0x221370(%rip), %r14    # 0x390990
decq %r13
movl (%r10,%rdi,4), %eax
movq %r11, %r8
subq %r13, %r8
cmpl %eax, -0x4(%r15,%r8,4)
jbe 0x16f662
leaq (%r11,%rdx), %r8
movq 0x18(%rsp), %rcx
leaq (%rcx,%r8,4), %rcx
movq %rcx, %r8
addw (%r14,%r11,8), %bp
decq %r11
addq $-0x4, %rcx
cmpl %eax, -0x8(%r8)
ja 0x16f641
movq 0x20(%rsp), %r8
movw %bp, (%r8,%rsi,2)
jmp 0x16f666
leaq (%r15,%r8,4), %rcx
cmpq %r13, %r11
jbe 0x16fa76
movl %eax, (%rcx)
incq %rdi
incq %rdx
addq $-0x88, %r14
cmpq %r9, %rdi
jne 0x16f620
movzwl %bp, %eax
movq %r9, %rdi
movq 0x8(%rsp), %r13
movq 0x10(%rsp), %rbp
jmp 0x16f697
xorl %eax, %eax
movq 0x38(%rbx), %rcx
movq (%rcx,%rax,8), %rax
cmpb $0x1, (%rax)
jne 0x16f720
movb $0x0, (%rax)
cmpq %r9, %rbp
jae 0x16f720
xorl %r10d, %r10d
movq %rbp, %rdx
testq %r10, %r10
je 0x16f6ce
movq (%rbx), %rax
movl (%rax,%rdx,4), %r8d
movq -0x8(%r12,%r10,8), %rcx
cmpl (%rax,%rcx,4), %r8d
jae 0x16f6e5
decq %r10
jne 0x16f6be
movq 0x30(%rbx), %rax
movq 0x38(%rbx), %rcx
movzwl (%rax,%rsi,2), %eax
movq (%rcx,%rax,8), %rcx
xorl %eax, %eax
xorl %r10d, %r10d
jmp 0x16f707
movq 0x30(%rbx), %rax
movq 0x38(%rbx), %r8
movzwl (%rax,%rsi,2), %r11d
movq %rcx, %r14
andb $0x7, %cl
movb $0x1, %al
shlb %cl, %al
movq (%r8,%r11,8), %rcx
subq %rbp, %r14
orb (%rcx,%r14), %al
movq %rdx, %r8
subq %rbp, %r8
movb %al, (%rcx,%r8)
movq %rdx, (%r12,%r10,8)
incq %r10
incq %rdx
cmpq %r9, %rdx
jne 0x16f6b2
incq %rsi
cmpq 0x50(%rbx), %rsi
jb 0x16f5cb
leaq 0x220e80(%rip), %r13    # 0x3905b4
movq %r15, %rdi
movq %r13, %rsi
movl $0x1d9, %edx            # imm = 0x1D9
callq 0x1045eb
movq %r12, %rdi
movq %r13, %rsi
movl $0x1da, %edx            # imm = 0x1DA
callq 0x1045eb
movq $0x4, 0x18(%rbx)
addq $0x20, 0x58(%rbx)
movl $0x4, %edi
movl $0x8, %esi
movq %r13, %rdx
movl $0x166, %ecx            # imm = 0x166
callq 0x10436a
movq %rax, 0x10(%rbx)
movq 0x40(%rbx), %rdi
addq %rdi, 0x58(%rbx)
movl $0x1, %esi
movq %r13, %rdx
movl $0x166, %ecx            # imm = 0x166
callq 0x10436a
movq 0x10(%rbx), %rcx
movq %rax, (%rcx)
movsd 0x48(%rbx), %xmm1
unpcklps 0x1d8137(%rip), %xmm1   # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x1d813f(%rip), %xmm1   # 0x3478f0
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
callq 0x17610
divsd 0x1fc5ce(%rip), %xmm0   # 0x36bd98
callq 0x17d40
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x1d853d(%rip), %xmm0   # 0x347d20
cvttsd2si %xmm0, %rsi
andq %rcx, %rsi
orq %rax, %rsi
incq %rsi
movq %rsi, 0x28(%rbx)
movl $0x8, %edx
movq %rbx, %rdi
callq 0x16fa7b
movq %rax, 0x20(%rbx)
movq 0x48(%rbx), %rsi
movl $0x8, %edx
movq %rbx, %rdi
callq 0x16fa7b
movq 0x20(%rbx), %rcx
movq %rax, (%rcx)
cmpq $0x0, 0x40(%rbx)
je 0x16f8d9
xorl %eax, %eax
xorl %edx, %edx
xorl %r8d, %r8d
xorl %ecx, %ecx
movq 0x8(%rsp), %r15
leaq 0x10(%r8), %rsi
cmpq %r15, %rsi
cmovaeq %r15, %rsi
movq (%rbx), %r9
movl (%r9,%r8,4), %edi
cmpl (%r9,%rdx,4), %edi
cmovbq %r8, %rdx
leaq 0x1(%r8), %rdi
cmpq %rsi, %rdi
jae 0x16f88f
movq %r8, %r11
movl (%r9,%rdi,4), %ebp
movq %rdi, %r10
cmpl (%r9,%r11,4), %ebp
jb 0x16f86d
movq %r11, %r10
movq %rdi, %r14
cmpl (%r9,%rdx,4), %ebp
jb 0x16f879
movq %rdx, %r14
incq %rdi
movq %r10, %r11
movq %r14, %rdx
cmpq %rdi, %rsi
jne 0x16f85d
movq %r14, %rdx
movq %rsi, %rdi
jmp 0x16f892
movq %r8, %r10
subl %r8d, %r10d
movq 0x10(%rbx), %rsi
movq (%rsi), %rsi
movb %r10b, (%rsi,%rcx)
testb %dil, %dil
setne %sil
cmpq %r15, %rdi
setne %r8b
testb %sil, %r8b
jne 0x16f8c4
movq 0x20(%rbx), %rsi
movq (%rsi), %rsi
movq %rdx, (%rsi,%rax,8)
incq %rax
movq %rdi, %rdx
incq %rcx
movq 0x40(%rbx), %rsi
movq %rdi, %r8
cmpq %rsi, %rcx
jb 0x16f837
jmp 0x16f8db
xorl %esi, %esi
cmpq $0x2, 0x18(%rbx)
jb 0x16f9af
movl $0x1, %r14d
movl $0x1, %r15d
movl $0x1, %edx
movq %rbx, %rdi
callq 0x16fa7b
movq 0x10(%rbx), %rcx
movq %rax, (%rcx,%r15,8)
movq 0x40(%rbx), %rsi
cmpq %r14, %rsi
jne 0x16f918
xorl %r8d, %r8d
jmp 0x16f99a
movl %r14d, %eax
shlb $0x4, %al
movq %r14, %rcx
shlq $0x6, %rcx
xorl %edx, %edx
xorl %edi, %edi
movq (%rbx), %r10
movq 0x10(%rbx), %rsi
movq -0x8(%rsi,%r15,8), %r9
movzbl (%r9,%rdi), %r8d
addq %rdi, %r9
leaq (%r10,%r8,4), %r11
movl (%rdx,%r11), %r11d
movzbl (%r14,%r9), %r9d
leaq (%r10,%r9,4), %r10
addq %rcx, %r10
cmpl (%rdx,%r10), %r11d
jbe 0x16f95e
addb %al, %r9b
movzbl %r9b, %r8d
movq (%rsi,%r15,8), %rsi
movb %r8b, (%rsi,%rdi)
incq %rdi
movq 0x40(%rbx), %rsi
movq %rsi, %r8
subq %r14, %r8
addq $0x40, %rdx
cmpq %r8, %rdi
jb 0x16f929
jmp 0x16f99a
movq 0x10(%rbx), %rax
movq -0x8(%rax,%r15,8), %rcx
movq (%rax,%r15,8), %rax
movb (%rcx,%r8), %cl
movb %cl, (%rax,%r8)
incq %r8
movq 0x40(%rbx), %rsi
cmpq %rsi, %r8
jb 0x16f97e
addq %r14, %r14
incq %r15
cmpq 0x18(%rbx), %r15
jb 0x16f8f2
cmpq $0x2, 0x28(%rbx)
jb 0x16fa64
movq 0x48(%rbx), %rsi
movl $0x1, %r14d
movl $0x1, %r15d
movl $0x8, %edx
movq %rbx, %rdi
callq 0x16fa7b
movq 0x20(%rbx), %rcx
movq %rax, (%rcx,%r15,8)
movq 0x48(%rbx), %rsi
cmpq %r14, %rsi
jne 0x16f9ec
xorl %eax, %eax
jmp 0x16fa2e
movq (%rbx), %rcx
movq 0x20(%rbx), %rax
movq -0x8(%rax,%r15,8), %rdx
movq (%rax,%r15,8), %rdi
leaq (%rdx,%r14,8), %r8
xorl %r9d, %r9d
movq (%rdx,%r9,8), %rax
movl (%rcx,%rax,4), %r10d
movq (%r8,%r9,8), %rsi
cmpl (%rcx,%rsi,4), %r10d
ja 0x16fa18
movq %rax, %rsi
movq %rsi, (%rdi,%r9,8)
incq %r9
movq 0x48(%rbx), %rsi
movq %rsi, %rax
subq %r14, %rax
cmpq %rax, %r9
jb 0x16fa03
cmpq %rsi, %rax
jae 0x16fa54
movq 0x20(%rbx), %rdx
movq -0x8(%rdx,%r15,8), %rcx
movq (%rdx,%r15,8), %rdx
movq (%rcx,%rax,8), %rsi
movq %rsi, (%rdx,%rax,8)
incq %rax
movq 0x48(%rbx), %rsi
cmpq %rsi, %rax
jb 0x16fa40
addq %r14, %r14
incq %r15
cmpq 0x28(%rbx), %r15
jb 0x16f9ca
movq %rbx, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x523ef