// File: /workspace/github_c_makefile_star2_O2/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 $0x18, %rsp
movq %rsi, %r14
movq %rdi, %r15
leaq 0x21e94c(%rip), %rdx    # 0x3308f2
pushq $0x1
popq %rdi
pushq $0x68
popq %rsi
movl $0x178, %ecx            # imm = 0x178
callq 0x9334a
movq %rax, %rbx
addq $0x68, 0x58(%rax)
movq %r15, (%rax)
movq %r14, 0x8(%rax)
leaq -0x1(%r14), %rax
movq %rax, %rcx
shrq $0x4, %rcx
incq %rcx
movq %rcx, 0x40(%rbx)
movq %rax, %rcx
shrq $0x8, %rcx
incq %rcx
movq %rcx, 0x48(%rbx)
movq %rax, %rsi
shrq $0x3, %rsi
incq %rsi
movq %rsi, 0x50(%rbx)
cmpq $0x6f, %rax
ja 0x112022
andq $0x0, 0x10(%rbx)
andq $0x0, 0x20(%rbx)
xorpd %xmm0, %xmm0
movupd %xmm0, 0x30(%rbx)
movb $0x1, 0x60(%rbx)
movq %rbx, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movb $0x0, 0x60(%rbx)
pushq $0x2
popq %rdx
movq %rbx, %rdi
callq 0x1124e3
movq %rax, 0x30(%rbx)
pushq $0x8
popq %r13
movl $0x596, %esi            # imm = 0x596
movq %rbx, %rdi
movq %r13, %rdx
callq 0x1124e3
movq %rax, 0x38(%rbx)
xorl %r15d, %r15d
pushq $0x1
popq %r12
cmpq $0x596, %r15            # imm = 0x596
je 0x112083
movq %rbx, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0x1124e3
movq 0x38(%rbx), %rcx
movq %rax, (%rcx,%r15,8)
movq 0x38(%rbx), %rax
movq (%rax,%r15,8), %rax
movb $0x1, (%rax)
incq %r15
jmp 0x112054
pushq $0x9
popq %rsi
pushq $0x4
popq %rdx
movq %rbx, %rdi
callq 0x1124e3
movq %rax, %r15
andl $0x0, (%rax)
movq %rbx, %rdi
movq %r13, %rsi
movq %r13, %rdx
callq 0x1124e3
movq %rax, %r13
movq %r15, 0x8(%rsp)
addq $-0x18, %r15
movq %r15, 0x10(%rsp)
xorl %edx, %edx
xorl %r8d, %r8d
cmpq 0x50(%rbx), %rdx
jae 0x1121cc
leaq 0x8(%r8), %r9
cmpq %r14, %r9
cmovaeq %r14, %r9
movq 0x30(%rbx), %rcx
andw $0x0, (%rcx,%rdx,2)
movq (%rbx), %r11
movl (%r11,%r8,4), %eax
movq 0x8(%rsp), %rsi
movl %eax, 0x4(%rsi)
xorl %ebp, %ebp
movq 0x10(%rsp), %rax
leaq 0x21ebda(%rip), %rdi    # 0x330cd0
movq %r8, %r10
pushq $0x8
popq %rsi
pushq $0x7
popq %r15
incq %r10
cmpq %r9, %r10
jae 0x11213d
decq %r15
movl (%r11,%r10,4), %r12d
cmpl %r12d, -0x4(%rax,%rsi,4)
jbe 0x112123
addw (%rdi,%rsi,8), %bp
movw %bp, (%rcx,%rdx,2)
decq %rsi
jmp 0x11210f
cmpq %r15, %rsi
jbe 0x1124ab
movl %r12d, (%rax,%rsi,4)
addq $-0x88, %rdi
addq $0x4, %rax
jmp 0x112100
movq 0x38(%rbx), %rax
movzwl %bp, %ecx
movq (%rax,%rcx,8), %rax
cmpb $0x1, (%rax)
jne 0x1121c1
movb $0x0, (%rax)
movq %r8, %r11
xorl %ebp, %ebp
cmpq %r9, %r11
jae 0x1121c1
incq %rbp
cmpq $0x1, %rbp
je 0x112179
movq (%rbx), %rax
movl (%rax,%r11,4), %esi
movq -0x10(%r13,%rbp,8), %rcx
cmpl (%rax,%rcx,4), %esi
jae 0x11218d
decq %rbp
jmp 0x11215d
movq 0x30(%rbx), %rax
movq 0x38(%rbx), %rcx
movzwl (%rax,%rdx,2), %eax
movq (%rcx,%rax,8), %rcx
xorl %eax, %eax
jmp 0x1121ae
movq 0x30(%rbx), %rax
movq 0x38(%rbx), %rsi
movzwl (%rax,%rdx,2), %edi
movq %rcx, %r15
andb $0x7, %cl
movb $0x1, %al
shlb %cl, %al
movq (%rsi,%rdi,8), %rcx
subq %r8, %r15
orb (%rcx,%r15), %al
movq %r11, %rsi
subq %r8, %rsi
movb %al, (%rcx,%rsi)
movq %r11, -0x8(%r13,%rbp,8)
incq %r11
jmp 0x112155
incq %rdx
movq %r10, %r8
jmp 0x1120bb
leaq 0x21e71f(%rip), %r12    # 0x3308f2
movq 0x8(%rsp), %rdi
movq %r12, %rsi
movl $0x1d9, %edx            # imm = 0x1D9
callq 0x936f9
movq %r13, %rdi
movq %r12, %rsi
movl $0x1da, %edx            # imm = 0x1DA
callq 0x936f9
movq $0x4, 0x18(%rbx)
pushq $0x4
popq %rsi
pushq $0x8
popq %r12
movq %rbx, %rdi
movq %r12, %rdx
callq 0x1124e3
movq %rax, 0x10(%rbx)
movq 0x40(%rbx), %rsi
pushq $0x1
popq %r15
movq %rbx, %rdi
movq %r15, %rdx
callq 0x1124e3
movq 0x10(%rbx), %rcx
movq %rax, (%rcx)
movsd 0x48(%rbx), %xmm1
unpcklps 0x1d56a7(%rip), %xmm1   # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x1d56af(%rip), %xmm1   # 0x2e78f0
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
callq 0x175e0
divsd 0x21001e(%rip), %xmm0   # 0x322278
callq 0x17cc0
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x1d5aad(%rip), %xmm0   # 0x2e7d20
cvttsd2si %xmm0, %rsi
andq %rcx, %rsi
orq %rax, %rsi
incq %rsi
movq %rsi, 0x28(%rbx)
movq %rbx, %rdi
movq %r12, %rdx
callq 0x1124e3
movq %rax, 0x20(%rbx)
movq 0x48(%rbx), %rsi
movq %rbx, %rdi
movq %r12, %rdx
callq 0x1124e3
movq 0x20(%rbx), %rcx
movq %rax, (%rcx)
xorl %eax, %eax
xorl %edi, %edi
xorl %edx, %edx
xorl %ecx, %ecx
movq 0x40(%rbx), %rsi
cmpq %rsi, %rax
jae 0x112353
leaq 0x10(%rdi), %r8
cmpq %r14, %r8
cmovaeq %r14, %r8
movq (%rbx), %r9
movl (%r9,%rdi,4), %esi
cmpl (%r9,%rdx,4), %esi
cmovbq %rdi, %rdx
leaq 0x1(%rdi), %rsi
movq %rsi, %r10
movq %rdi, %r11
cmpq %r8, %r10
jae 0x11230f
movl (%r9,%r10,4), %ebp
movq %r10, %r12
cmpl (%r9,%r11,4), %ebp
jb 0x1122f8
movq %r11, %r12
movq %r10, %r11
cmpl (%r9,%rdx,4), %ebp
jb 0x112304
movq %rdx, %r11
incq %r10
movq %r11, %rdx
movq %r12, %r11
jmp 0x1122e3
cmpq %rsi, %r8
cmovaq %r8, %rsi
subl %edi, %r11d
movq 0x10(%rbx), %rdi
movq (%rdi), %rdi
movb %r11b, (%rdi,%rax)
testb %sil, %sil
setne %dil
cmpq %r14, %rsi
setne %r8b
testb %dil, %r8b
jne 0x112348
movq 0x20(%rbx), %rdi
movq (%rdi), %rdi
movq %rdx, (%rdi,%rcx,8)
incq %rcx
movq %rsi, %rdx
incq %rax
movq %rsi, %rdi
jmp 0x1122b2
movq %r15, %r14
movq %r15, %r12
cmpq 0x18(%rbx), %r14
jae 0x112408
movq %rbx, %rdi
movq %r15, %rdx
callq 0x1124e3
movq 0x10(%rbx), %rcx
movq %rax, (%rcx,%r14,8)
movl %r12d, %eax
shlb $0x4, %al
movq %r12, %rcx
shlq $0x6, %rcx
xorl %edx, %edx
xorl %edi, %edi
movq 0x40(%rbx), %rsi
movq %rsi, %r8
subq %r12, %r8
cmpq %r8, %rdi
jae 0x1123f8
movq (%rbx), %r10
movq 0x10(%rbx), %rsi
movq -0x8(%rsi,%r14,8), %r9
movzbl (%r9,%rdi), %r8d
addq %rdi, %r9
leaq (%r10,%r8,4), %r11
movl (%rdx,%r11), %r11d
movzbl (%r12,%r9), %r9d
leaq (%r10,%r9,4), %r10
addq %rcx, %r10
cmpl (%rdx,%r10), %r11d
jbe 0x1123cb
addb %al, %r9b
movzbl %r9b, %r8d
movq (%rsi,%r14,8), %rsi
movb %r8b, (%rsi,%rdi)
incq %rdi
addq $0x40, %rdx
jmp 0x112387
movq 0x10(%rbx), %rax
movq -0x8(%rax,%r14,8), %rcx
movq (%rax,%r14,8), %rax
movb (%rcx,%r8), %cl
movb %cl, (%rax,%r8)
incq %r8
movq 0x40(%rbx), %rsi
cmpq %rsi, %r8
jb 0x1123dc
addq %r12, %r12
incq %r14
jmp 0x112359
pushq $0x1
popq %r15
pushq $0x8
popq %r14
movq %r15, %r12
cmpq 0x28(%rbx), %r15
jae 0x112010
movq 0x48(%rbx), %rsi
movq %rbx, %rdi
movq %r14, %rdx
callq 0x1124e3
movq 0x20(%rbx), %rcx
movq %rax, (%rcx,%r15,8)
leaq (,%r12,8), %rax
xorl %ecx, %ecx
movq 0x48(%rbx), %rsi
movq %rsi, %rdx
subq %r12, %rdx
cmpq %rdx, %rcx
jae 0x11249b
movq (%rbx), %r8
movq 0x20(%rbx), %rdx
movq -0x8(%rdx,%r15,8), %rsi
leaq (%rsi,%rcx,8), %r9
movq (%rsi,%rcx,8), %rdi
movl (%r8,%rdi,4), %r10d
movq (%rax,%r9), %rsi
cmpl (%r8,%rsi,4), %r10d
ja 0x112472
movq %rdi, %rsi
movq (%rdx,%r15,8), %rdx
movq %rsi, (%rdx,%rcx,8)
incq %rcx
jmp 0x11243e
movq 0x20(%rbx), %rax
movq -0x8(%rax,%r15,8), %rcx
movq (%rax,%r15,8), %rax
movq (%rcx,%rdx,8), %rcx
movq %rcx, (%rax,%rdx,8)
incq %rdx
movq 0x48(%rbx), %rsi
cmpq %rsi, %rdx
jb 0x11247f
addq %r12, %r12
incq %r15
jmp 0x112413
movq 0x325ab6(%rip), %rax    # 0x437f68
movq (%rax), %rdi
leaq 0x1d2b57(%rip), %rsi    # 0x2e5013
leaq 0x21e442(%rip), %rdx    # 0x330905
leaq 0x21e441(%rip), %rcx    # 0x33090b
leaq 0x21e421(%rip), %r8     # 0x3308f2
movl $0x1bb, %r9d            # imm = 0x1BB
xorl %eax, %eax
callq 0x17a50
callq 0x17390