// File: /workspace/github_c_makefile_star2_O1/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 0x2221e4(%rip), %rdx    # 0x3999dc
movl $0x1, %edi
movl $0x68, %esi
movl $0x178, %ecx            # imm = 0x178
callq 0x1093ef
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 0x177872
xorl %eax, %eax
movq %rax, 0x10(%rbx)
movq %rax, 0x20(%rbx)
xorpd %xmm0, %xmm0
movupd %xmm0, 0x30(%rbx)
movb $0x1, 0x60(%rbx)
jmp 0x177deb
movb $0x0, 0x60(%rbx)
testq %rbx, %rbx
je 0x177e02
leaq (%rax,%rdi,2), %rax
movq %rax, 0x58(%rbx)
leaq 0x22214e(%rip), %r15    # 0x3999dc
movl $0x2, %esi
movq %r15, %rdx
movl $0x166, %ecx            # imm = 0x166
callq 0x1093ef
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 0x1093ef
movq %rax, 0x38(%rbx)
xorl %r14d, %r14d
movl $0x8, %esi
movl $0x1, %edx
movq %rbx, %rdi
callq 0x177e07
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 0x1778ca
addq $0x24, 0x58(%rbx)
leaq 0x2220d5(%rip), %r12    # 0x3999dc
movl $0x9, %edi
movl $0x4, %esi
movq %r12, %rdx
movl $0x166, %ecx            # imm = 0x166
callq 0x1093ef
movq %rax, %r14
movl $0x0, (%rax)
addq $0x40, 0x58(%rbx)
movl $0x8, %edi
movl $0x8, %esi
movq %r12, %rdx
movl $0x166, %ecx            # imm = 0x166
callq 0x1093ef
movq %r14, %rdi
movq %rax, %r12
cmpq $0x0, 0x50(%rbx)
je 0x177ad6
leaq 0x4(%rdi), %rax
movq %rax, 0x20(%rsp)
xorl %r9d, %r9d
xorl %esi, %esi
movq %rdi, (%rsp)
movq %r13, 0x10(%rsp)
leaq 0x8(%r9), %r8
cmpq %r13, %r8
cmovaeq %r13, %r8
movq 0x30(%rbx), %rcx
movw $0x0, (%rcx,%rsi,2)
movq (%rbx), %r10
movl (%r10,%r9,4), %eax
movl %eax, 0x4(%rdi)
movq %r9, 0x18(%rsp)
incq %r9
cmpq %r8, %r9
movq %r8, 0x8(%rsp)
jae 0x177a27
movl $0x8, %r11d
movl $0x7, %r13d
movq $-0x7, %rbp
leaq 0x2223f6(%rip), %rdx    # 0x399db0
decq %r13
movl (%r10,%r9,4), %r14d
movq %r11, %rax
subq %r13, %rax
cmpl %r14d, -0x4(%rdi,%rax,4)
jbe 0x177a05
movzwl (%rcx,%rsi,2), %r8d
leaq (%r11,%rbp), %rax
movq 0x20(%rsp), %rdi
leaq (%rdi,%rax,4), %r15
movq %r15, %rax
addw (%rdx,%r11,8), %r8w
decq %r11
addq $-0x4, %r15
cmpl %r14d, -0x8(%rax)
ja 0x1779e0
movw %r8w, (%rcx,%rsi,2)
movq (%rsp), %rdi
movq 0x8(%rsp), %r8
jmp 0x177a09
leaq (%rdi,%rax,4), %r15
cmpq %r13, %r11
jbe 0x177dfd
movl %r14d, (%r15)
incq %r9
incq %rbp
addq $-0x88, %rdx
cmpq %r8, %r9
jne 0x1779ba
movq 0x38(%rbx), %rax
movzwl (%rcx,%rsi,2), %ecx
movq (%rax,%rcx,8), %rax
cmpb $0x1, (%rax)
movq 0x10(%rsp), %r13
movq 0x18(%rsp), %r15
jne 0x177ac9
movb $0x0, (%rax)
cmpq %r8, %r15
jae 0x177ac9
xorl %r11d, %r11d
movq %r15, %r10
testq %r11, %r11
je 0x177a72
movq (%rbx), %rax
movl (%rax,%r10,4), %edx
movq -0x8(%r12,%r11,8), %rcx
cmpl (%rax,%rcx,4), %edx
jae 0x177a86
decq %r11
jne 0x177a60
xorl %r11d, %r11d
movq 0x30(%rbx), %rax
movq 0x38(%rbx), %rcx
movzwl (%rax,%rsi,2), %eax
movq (%rcx,%rax,8), %rcx
xorl %eax, %eax
jmp 0x177ab1
movq 0x30(%rbx), %rax
movq 0x38(%rbx), %rdx
movzwl (%rax,%rsi,2), %r8d
movq %rcx, %r14
andb $0x7, %cl
movb $0x1, %al
shlb %cl, %al
movq (%rdx,%r8,8), %rcx
movq 0x8(%rsp), %r8
movq (%rsp), %rdi
subq %r15, %r14
orb (%rcx,%r14), %al
movq %r10, %rdx
subq %r15, %rdx
movb %al, (%rcx,%rdx)
movq %r10, (%r12,%r11,8)
incq %r11
incq %r10
cmpq %r8, %r10
jne 0x177a54
incq %rsi
cmpq 0x50(%rbx), %rsi
jb 0x17796b
movq %r13, %r15
leaq 0x221efc(%rip), %r13    # 0x3999dc
movq %r13, %rsi
movl $0x1d9, %edx            # imm = 0x1D9
callq 0x109670
movq %r12, %rdi
movq %r13, %rsi
movl $0x1da, %edx            # imm = 0x1DA
callq 0x109670
movq $0x4, 0x18(%rbx)
addq $0x20, 0x58(%rbx)
movl $0x4, %edi
movl $0x8, %esi
movq %r13, %rdx
movl $0x166, %ecx            # imm = 0x166
callq 0x1093ef
movq %rax, 0x10(%rbx)
movq 0x40(%rbx), %rdi
addq %rdi, 0x58(%rbx)
movl $0x1, %esi
movq %r13, %rdx
movl $0x166, %ecx            # imm = 0x166
callq 0x1093ef
movq 0x10(%rbx), %rcx
movq %rax, (%rcx)
movsd 0x48(%rbx), %xmm1
unpcklps 0x1d8d8e(%rip), %xmm1   # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x1d8d96(%rip), %xmm1   # 0x3508f0
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
callq 0x17610
divsd 0x1fd475(%rip), %xmm0   # 0x374fe8
callq 0x17d40
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x1d9194(%rip), %xmm0   # 0x350d20
cvttsd2si %xmm0, %rsi
andq %rcx, %rsi
orq %rax, %rsi
incq %rsi
movq %rsi, 0x28(%rbx)
movl $0x8, %edx
movq %rbx, %rdi
callq 0x177e07
movq %rax, 0x20(%rbx)
movq 0x48(%rbx), %rsi
movl $0x8, %edx
movq %rbx, %rdi
callq 0x177e07
movq 0x20(%rbx), %rcx
movq %rax, (%rcx)
cmpq $0x0, 0x40(%rbx)
je 0x177c77
xorl %eax, %eax
xorl %edx, %edx
xorl %edi, %edi
xorl %ecx, %ecx
leaq 0x10(%rdi), %r8
cmpq %r15, %r8
cmovaeq %r15, %r8
movq (%rbx), %r9
movl (%r9,%rdi,4), %esi
cmpl (%r9,%rdx,4), %esi
cmovbq %rdi, %rdx
leaq 0x1(%rdi), %rsi
cmpq %r8, %rsi
jae 0x177c32
movq %rdi, %r11
movl (%r9,%rsi,4), %ebp
movq %rsi, %r10
cmpl (%r9,%r11,4), %ebp
jb 0x177c10
movq %r11, %r10
movq %rsi, %r14
cmpl (%r9,%rdx,4), %ebp
jb 0x177c1c
movq %rdx, %r14
incq %rsi
movq %r10, %r11
movq %r14, %rdx
cmpq %rsi, %r8
jne 0x177c00
movq %r14, %rdx
movq %r8, %rsi
jmp 0x177c35
movq %rdi, %r10
subl %edi, %r10d
movq 0x10(%rbx), %rdi
movq (%rdi), %rdi
movb %r10b, (%rdi,%rcx)
testb %sil, %sil
setne %dil
cmpq %r15, %rsi
setne %r8b
testb %dil, %r8b
jne 0x177c67
movq 0x20(%rbx), %rdi
movq (%rdi), %rdi
movq %rdx, (%rdi,%rax,8)
incq %rax
movq %rsi, %rdx
incq %rcx
movq %rsi, %rdi
cmpq 0x40(%rbx), %rcx
jb 0x177bda
cmpq $0x2, 0x18(%rbx)
jb 0x177d3f
movl $0x1, %r14d
movl $0x1, %r15d
movq 0x40(%rbx), %rsi
movl $0x1, %edx
movq %rbx, %rdi
callq 0x177e07
movq 0x10(%rbx), %rcx
movq %rax, (%rcx,%r15,8)
movq 0x40(%rbx), %rdi
subq %r14, %rdi
je 0x177d29
movl %r14d, %eax
shlb $0x4, %al
movq %r14, %rcx
shlq $0x6, %rcx
xorl %edx, %edx
xorl %esi, %esi
movq (%rbx), %r10
movq 0x10(%rbx), %rdi
movq -0x8(%rdi,%r15,8), %r9
movzbl (%r9,%rsi), %r8d
addq %rsi, %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 0x177cf6
addb %al, %r9b
movzbl %r9b, %r8d
movq (%rdi,%r15,8), %rdi
movb %r8b, (%rdi,%rsi)
incq %rsi
movq 0x40(%rbx), %rdi
subq %r14, %rdi
addq $0x40, %rdx
cmpq %rdi, %rsi
jb 0x177cc1
jmp 0x177d29
movq 0x10(%rbx), %rax
movq -0x8(%rax,%r15,8), %rcx
movq (%rax,%r15,8), %rax
movb (%rcx,%rdi), %cl
movb %cl, (%rax,%rdi)
incq %rdi
cmpq 0x40(%rbx), %rdi
jb 0x177d13
addq %r14, %r14
incq %r15
cmpq 0x18(%rbx), %r15
jb 0x177c8e
cmpq $0x2, 0x28(%rbx)
jb 0x177deb
movl $0x1, %r14d
movl $0x1, %r15d
movq 0x48(%rbx), %rsi
movl $0x8, %edx
movq %rbx, %rdi
callq 0x177e07
movq 0x20(%rbx), %rcx
movq %rax, (%rcx,%r15,8)
movq 0x48(%rbx), %rax
subq %r14, %rax
je 0x177db7
movq (%rbx), %rcx
movq 0x20(%rbx), %rax
movq -0x8(%rax,%r15,8), %rdx
movq (%rax,%r15,8), %rsi
leaq (%rdx,%r14,8), %rdi
xorl %r8d, %r8d
movq (%rdx,%r8,8), %rax
movl (%rcx,%rax,4), %r10d
movq (%rdi,%r8,8), %r9
cmpl (%rcx,%r9,4), %r10d
ja 0x177da4
movq %rax, %r9
movq %r9, (%rsi,%r8,8)
incq %r8
movq 0x48(%rbx), %rax
subq %r14, %rax
cmpq %rax, %r8
jb 0x177d8f
cmpq 0x48(%rbx), %rax
jae 0x177ddb
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
cmpq 0x48(%rbx), %rax
jb 0x177dca
addq %r14, %r14
incq %r15
cmpq 0x28(%rbx), %r15
jb 0x177d56
movq %rbx, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x5331d
callq 0x53356