// File: /workspace/github_c_makefile_star2_O3/jflatow[P]jfdb/src/trie.c
// Function: splice_new
static JFT_Status splice_new(JFT_Cursor *cursors,
                             JFT_MergeContext *ctx,
                             JFT_Phase phase) {
  // determine what to do based on the most recent / highest precedence cursor
  // (cursors should be given in order of recency / precedence)
  JFT_MergeFrame *frame = ctx->frame;
  JFT_Mask active = frame->active;
  JFT_Amount b = ffsll(active);
  JFT_Cursor *cursor = cursors + b - 1;
  JFT_Cons *cons = (JFT_Cons *)ctx->acc;
  JFT_Buffer *buf = cons->buffer;
  JFT_NodeType type = JFT_node_type(cursor->node);

  if (phase == Out) {
    // do nothing during phase out, except finishing touches
    // copy the changed root data back into the buffer
    if (type == Root) {
      JFT_Root *root = (JFT_Root *)buf->data;
      root->extent = buf->mark;
      root->numPrimary = cons->root.numPrimary;
      root->numIndices = cons->root.numIndices;
      root->maxIndices = cons->root.maxIndices;
      root->maxKeySize = ctx->maxKeySize;
    }
    return Ok;
  }

  if (type == Root) {
    // on the root: make space for the new root in buffer
    // root is a parent, mark it's offset before writing
    frame->offset = buf->mark;
    if (!make_root(buf))
      return ENoMem;

    // keep a root in cons and update it later (NB: cannot rely on buf pointers)
    // allocate memory to store the compressed stem before we write it
    cons->root.head = JFT_head(Root, False, 0, 0, 0);
    cons->stem = (JFT_Stem) {.data = malloc(ctx->maxKeySize)};
    if (cons->stem.data == NULL)
      return ENoMem;

    // allocate the iterators for indices
    cons->iters = malloc(ctx->numCursors * sizeof(JFT_Iter));

    // allocate the offset translation tables for indices (if we are translating)
    if (!(ctx->flags & JFT_FLAGS_ATOM)) {
      cons->TLBs = malloc(ctx->numCursors * sizeof(JFT_Offset *));
      cons->TLBSizes = calloc(ctx->numCursors, sizeof(JFT_Count));
      for (JFT_Amount k = 0; k < ctx->numCursors; k++)
        cons->TLBs[k] = malloc(2 * ((JFT_Root *)cursors[k].root)->numPrimary * sizeof(JFT_Offset));
    }

    // step into the tree
    return Step;
  }

  // add the symbol to the budding stem
  // if its a keyspace, mark the keyspace in the cons
  if (cursor->symbol == JFT_SYMBOL_PRIMARY ||
      cursor->symbol == JFT_SYMBOL_INDICES) {
      cons->stem.pre = cons->keySpace = cursor->symbol;
      cons->stem.size++;
  } else {
      cons->stem.data[cons->stem.size - (cons->stem.pre ? 1 : 0)] = cursor->symbol;
      cons->stem.size++;
  }

  // if cursor is on a terminal node: overwrite
  if (JFT_cursor_at_terminal(cursor)) {
    int doTranslate = !(ctx->flags & JFT_FLAGS_ATOM);
    JFT_Leaf leaf = JFT_leaf(cursor->node);
    // simply skip empty leaves: the offset in parent will remain zero and thus will not branch
    // eventually (next merge), the node will get phased out of the trie completely
    if ((ctx->flags & JFT_FLAGS_PRUNE) && leaf.size == 0)
      return Next;

    if (cons->keySpace == JFT_SYMBOL_PRIMARY) {
      // at value node
      // if we are translating, store the translation of old value offset to new
      if (doTranslate) {
        cons->TLBs[b - 1][cons->TLBSizes[b - 1]++] = cursor->node - cursor->root;
        cons->TLBs[b - 1][cons->TLBSizes[b - 1]++] = buf->mark;
      }

      // emit the leaf node
      frame->offset = buf->mark;
      if (!make_leaf(buf, (frame - 1)->offset, &cons->stem, &leaf))
        return ENoMem;

      cons->root.numPrimary++;
    } else {
      // at index node
      // wrap each cursors' words in an iterator
      // which yields batches of sorted (maybe translated) words
      JFT_Count maxWords = 0, numWords = 0;
      do {
        cursor = cursors + b - 1;
        leaf = JFT_leaf(cursor->node);
        if (!(JFT_cursor_at_terminal(cursor)))
          break;
        if (doTranslate) {
          // use a translation iterator, translates a static size batch at a time
          cons->iters[b - 1] = JFT_iter_trans(leaf, cons->TLBs[b - 1], cons->TLBSizes[b - 1]);
        } else {
          // use an iterator that just returns the raw leaf words in one batch
          cons->iters[b - 1] = JFT_iter_leaf(leaf);
        }
        maxWords += leaf.size;
      } while ((b = ffsll(active &= active - 1)));

      // emit the leaf node using an upper bound on the number of words
      frame->offset = buf->mark;
      if (!(prep_leaf(buf, (frame - 1)->offset, &cons->stem, maxWords)))
        return ENoMem;

      // write the indices, count the actual words
      JFT_Iter i = JFT_iter_any(cons->iters, frame->active ^ active);
      do {
        JFT_buffer_paste(buf, i.batch.data, i.batch.size * sizeof(JFT_Word));
        numWords += i.batch.size;
      } while (JFT_iter_next(&i));

      // correct the leaf node using the actual number of words
      edit_leaf(buf, frame->offset, &cons->stem, maxWords, numWords);

      if (numWords > cons->root.maxIndices)
        cons->root.maxIndices = numWords;
      cons->root.numIndices++;
    }

    // reset the bud
    cons->stem.pre = 0;
    cons->stem.size = 0;

    // done with this subtree
    return Next;
  }

  // cursor is non-terminal, maybe emit a branch
  // look at the other cursors and count # unique subsequent symbols
  JFT_Range range = {.min = 255, .max = 0};
  JFT_SymbolSet set = {};
  int count;
  do {
    if (cursor->symbol != JFT_SYMBOL_ANY)
      JFT_cursor_mark_subsequent(cursor, &range, &set);
    b = ffsll(active &= active - 1);
  } while (b && !JFT_cursor_at_terminal(cursor = cursors + b - 1));

  if ((count = JFT_symbol_set_count(&set)) > 1) {
    // more than one possible symbol: emit a branch node
    frame->offset = buf->mark;
    if (!make_branch(buf, (frame - 1)->offset, &cons->stem, &range, &set, count))
      return ENoMem;

    // reset the bud
    cons->stem.pre = 0;
    cons->stem.size = 0;
  }
  return Step;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xf8, %rsp
movq %rsi, %r15
movq %rdi, %r14
movq 0x8(%rsi), %r11
movq 0x20(%rsi), %r12
movq 0x8(%r11), %rbp
bsfq %rbp, %rcx
movq $-0x1, %rax
cmovneq %rcx, %rax
incq %rax
imulq $0x38, %rax, %rdi
movq (%r12), %rbx
movq -0x30(%r14,%rdi), %rcx
movq (%rcx), %rsi
cmpl $-0x1, %edx
je 0x435b
shrq $0x3e, %rsi
jne 0x4393
movq 0x10(%rbx), %rax
movq %rax, 0x18(%r11)
movl $0x30, %esi
movq %rbx, %rdi
callq *0x20(%rbx)
movl $0x5, %r13d
testq %rbx, %rbx
je 0x4a6b
testl %eax, %eax
jne 0x4a6b
movq 0x10(%rbx), %rax
movq 0x18(%rbx), %rcx
pxor %xmm0, %xmm0
movdqu %xmm0, 0x20(%rcx,%rax)
movdqu %xmm0, 0x10(%rcx,%rax)
movdqu %xmm0, (%rcx,%rax)
addq $0x30, 0x10(%rbx)
je 0x4a6b
xorl %ebx, %ebx
movq %rbx, 0x10(%r12)
movzwl 0x10(%r15), %edi
callq 0x1150
movq %rbx, 0x40(%r12)
movw $0x0, 0x48(%r12)
movq %rax, 0x50(%r12)
testq %rax, %rax
je 0x4a6b
movq 0x18(%r15), %rbx
imulq $0xc8, %rbx, %rdi
callq 0x1150
movq %rax, 0x58(%r12)
movl $0x1, %r13d
testb $0x4, 0x28(%r15)
jne 0x4a6b
leaq (,%rbx,8), %rdi
callq 0x1150
movq %rax, 0x60(%r12)
movl $0x4, %esi
movq %rbx, %rdi
callq 0x1120
movq %rax, 0x68(%r12)
testq %rbx, %rbx
je 0x4a6b
xorl %r15d, %r15d
movq (%r14), %rax
movl 0x20(%rax), %edi
addl %edi, %edi
shlq $0x3, %rdi
callq 0x1150
movq 0x60(%r12), %rcx
movq %rax, (%rcx,%r15,8)
incq %r15
addq $0x38, %r14
cmpq %r15, %rbx
jne 0x4330
jmp 0x4a6b
xorl %r13d, %r13d
shrq $0x3e, %rsi
jne 0x4a6b
movq 0x10(%rbx), %rax
movq 0x18(%rbx), %rcx
movq %rax, 0x18(%rcx)
movq 0x30(%r12), %rax
movq %rax, 0x20(%rcx)
movl 0x38(%r12), %eax
movl %eax, 0x28(%rcx)
movzwl 0x10(%r15), %eax
movw %ax, 0x2c(%rcx)
jmp 0x4a6b
leaq (%r14,%rdi), %rsi
movq -0x8(%rsi), %rdx
leaq 0x5(%rdx), %r8
cmpq $0x1, %r8
ja 0x43b7
movq %rdx, 0x8(%r12)
movq %rdx, 0x40(%r12)
incw 0x48(%r12)
jmp 0x43da
movq 0x50(%r12), %rcx
cmpq $0x1, 0x40(%r12)
movzwl 0x48(%r12), %r8d
adcq $-0x1, %rcx
movb %dl, (%rcx,%r8)
incw 0x48(%r12)
movq -0x30(%rsi), %rcx
leaq (%r14,%rdi), %rdx
addq $-0x38, %rdx
movabsq $-0x4000000000000001, %r13 # imm = 0xBFFFFFFFFFFFFFFF
movq (%rcx), %rdi
movq %rdi, %r8
shrq $0x3e, %r8
cmpl $0x3, %r8d
jb 0x44b3
movzwl -0x20(%rsi), %r8d
decq %r8
cmpq %r8, -0x10(%rsi)
jne 0x44b3
movq %r12, 0x8(%rsp)
movl 0x28(%r15), %esi
movl %esi, 0x14(%rsp)
movq %rdi, %r15
shrq $0x28, %r15
movl $0xff, %esi
andl %esi, %r15d
shrq $0x30, %rdi
andl $0xfff, %edi            # imm = 0xFFF
leaq (%rcx,%rdi), %r12
addq $0x8, %r12
cmpl %esi, %r15d
jne 0x444d
movl (%r12), %r15d
addq $0x4, %r12
movl $0x2, %r13d
testb $0x2, 0x14(%rsp)
je 0x4463
testl %r15d, %r15d
je 0x4a6b
movq 0x8(%rsp), %rsi
cmpq $-0x5, 0x8(%rsi)
jne 0x4797
testb $0x4, 0x14(%rsp)
jne 0x49d7
subq (%rdx), %rcx
movq 0x8(%rsp), %r9
movq 0x60(%r9), %rdx
movq 0x68(%r9), %rsi
movq -0x8(%rdx,%rax,8), %rdx
movl -0x4(%rsi,%rax,4), %edi
leal 0x1(%rdi), %r8d
movq %rcx, (%rdx,%rdi,8)
movq 0x10(%rbx), %rcx
addl $0x2, %edi
movl %edi, -0x4(%rsi,%rax,4)
movq %rcx, (%rdx,%r8,8)
jmp 0x49e0
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
movaps %xmm0, 0x30(%rsp)
movl $0xff, %eax
xorl %edi, %edi
leaq 0x1f12(%rip), %r9       # 0x63e0
cmpq $-0x1, 0x30(%rdx)
je 0x45a3
movq 0x28(%rdx), %rsi
movzwl 0x18(%rdx), %ecx
decq %rcx
cmpq %rcx, %rsi
jne 0x4560
movq 0x8(%rdx), %rsi
movq (%rsi), %r8
movq %r8, %rcx
shrq $0x3e, %rcx
cmpq $0x2, %rcx
je 0x45dd
cmpl $0x1, %ecx
jne 0x45a3
movq %r8, %rcx
shrq $0x28, %rcx
testb %cl, %cl
je 0x45a3
shrq $0x30, %r8
andl $0xfff, %r8d            # imm = 0xFFF
leaq (%rsi,%r8), %rdx
addq $0x8, %rdx
movzbl %cl, %esi
xorl %r8d, %r8d
movzbl (%rdx,%r8), %ecx
cmpq %rcx, %rax
cmovaeq %rcx, %rax
cmpq %rcx, %rdi
cmovbeq %rcx, %rdi
movl $0x1, %r10d
shlq %cl, %r10
shrl $0x6, %ecx
orq %r10, 0x30(%rsp,%rcx,8)
incq %r8
cmpq %r8, %rsi
jne 0x4532
jmp 0x45a3
incq %rsi
movq 0x10(%rdx), %rcx
testq %rcx, %rcx
je 0x457d
testq %rsi, %rsi
je 0x4584
movq 0x20(%rdx), %rcx
addq %rcx, %rsi
decq %rsi
jmp 0x4581
addq 0x20(%rdx), %rsi
movzbl (%rsi), %ecx
cmpq %rcx, %rax
cmovaeq %rcx, %rax
cmpq %rcx, %rdi
cmovbeq %rcx, %rdi
movl $0x1, %edx
shlq %cl, %rdx
shrq $0x6, %rcx
orq %rdx, 0x30(%rsp,%rcx,8)
leaq -0x1(%rbp), %rcx
andq %rcx, %rbp
je 0x4644
bsfq %rbp, %rcx
imulq $0x38, %rcx, %rcx
leaq (%r14,%rcx), %rdx
movq 0x8(%r14,%rcx), %rcx
cmpq %r13, (%rcx)
jbe 0x44ce
movzwl 0x18(%rdx), %ecx
decq %rcx
cmpq %rcx, 0x28(%rdx)
jne 0x44ce
jmp 0x4644
movq %r8, %rcx
shrq $0x28, %rcx
movzbl %cl, %edx
shll $0x4, %edx
movq (%rdx,%r9), %rcx
movq 0x8(%rdx,%r9), %rdx
cmpq %rdx, %rcx
ja 0x45a3
shrq $0x30, %r8
andl $0xfff, %r8d            # imm = 0xFFF
addq %r8, %rsi
addq $0x8, %rsi
cmpq $0x0, (%rsi)
je 0x4633
cmpq %rcx, %rax
cmovaeq %rcx, %rax
cmpq %rcx, %rdi
cmovbeq %rcx, %rdi
movl $0x1, %r8d
shlq %cl, %r8
movq %rcx, %r10
shrq $0x6, %r10
orq %r8, 0x30(%rsp,%r10,8)
incq %rcx
addq $0x8, %rsi
cmpq %rdx, %rcx
jbe 0x460a
jmp 0x45a3
movdqa 0x30(%rsp), %xmm0
movdqa 0x40(%rsp), %xmm1
movdqa %xmm1, %xmm2
psrlw $0x1, %xmm2
movdqa 0x1e2f(%rip), %xmm3     # 0x6490
pand %xmm3, %xmm2
psubb %xmm2, %xmm1
movdqa 0x1e2f(%rip), %xmm2     # 0x64a0
movdqa %xmm1, %xmm4
pand %xmm2, %xmm4
psrlw $0x2, %xmm1
pand %xmm2, %xmm1
paddb %xmm4, %xmm1
movdqa %xmm1, %xmm4
psrlw $0x4, %xmm4
paddb %xmm1, %xmm4
movdqa 0x1e15(%rip), %xmm1     # 0x64b0
pand %xmm1, %xmm4
movdqa %xmm0, %xmm5
psrlw $0x1, %xmm5
pand %xmm3, %xmm5
psubb %xmm5, %xmm0
movdqa %xmm0, %xmm3
pand %xmm2, %xmm3
psrlw $0x2, %xmm0
pand %xmm2, %xmm0
paddb %xmm3, %xmm0
movdqa %xmm0, %xmm2
psrlw $0x4, %xmm2
paddb %xmm0, %xmm2
pand %xmm1, %xmm2
paddb %xmm4, %xmm2
pxor %xmm0, %xmm0
psadbw %xmm2, %xmm0
pshufd $0xee, %xmm0, %xmm1     # xmm1 = xmm0[2,3,2,3]
paddq %xmm0, %xmm1
movd %xmm1, %r8d
movl $0x1, %r13d
cmpl $0x2, %r8d
jb 0x4a6b
movq 0x10(%rbx), %rcx
movq %rcx, 0x18(%r11)
movq -0x8(%r11), %rsi
leaq 0x40(%r12), %rdx
cmpl $0x10, %r8d
jb 0x4761
movl $0x1, %ecx
xorl %r10d, %r10d
cmpq 0x10(%r10,%r9), %rax
jb 0x472d
cmpq 0x18(%r10,%r9), %rdi
jbe 0x4770
incl %ecx
addq $0x10, %r10
cmpq $0x40, %r10
jne 0x471f
cmpl $0x20, %r8d
jb 0x4761
movl $0x5, %ecx
xorl %r10d, %r10d
cmpq 0x50(%r10,%r9), %rax
jb 0x4755
cmpq 0x58(%r10,%r9), %rdi
jbe 0x4770
incl %ecx
addq $0x10, %r10
cmpq $0x60, %r10
jne 0x4747
leaq 0x30(%rsp), %rcx
movq %rbx, %rdi
callq 0x5779
jmp 0x4778
movq %rbx, %rdi
callq 0x5a09
testq %rax, %rax
je 0x4a34
movq $0x0, 0x40(%r12)
movw $0x0, 0x48(%r12)
jmp 0x4a6b
movq %r11, 0x20(%rsp)
xorl %ecx, %ecx
movq 0x8(%rsp), %r12
imulq $0x38, %rax, %r8
movq -0x30(%r14,%r8), %rsi
movq (%rsi), %rdx
movq %rdx, %r15
shrq $0x28, %r15
movl $0xff, %r9d
andl %r9d, %r15d
movq %rdx, %rdi
shrq $0x30, %rdi
andl $0xfff, %edi            # imm = 0xFFF
leaq (%rsi,%rdi), %r13
addq $0x8, %r13
cmpl %r9d, %r15d
jne 0x47e1
movl (%r13), %r15d
addq $0x4, %r13
movabsq $-0x4000000000000001, %rsi # imm = 0xBFFFFFFFFFFFFFFF
cmpq %rsi, %rdx
jbe 0x4910
addq %r14, %r8
movzwl -0x20(%r8), %edx
decq %rdx
cmpq %rdx, -0x10(%r8)
jne 0x4910
movl %ecx, 0x18(%rsp)
movq 0x58(%r12), %rcx
testb $0x4, 0x14(%rsp)
jne 0x48b8
leaq -0x1(%rax), %rdx
imulq $0xc8, %rdx, %rdx
movq 0x60(%r12), %rsi
movq 0x68(%r12), %rdi
movq -0x8(%rsi,%rax,8), %rsi
movq %rsi, 0x28(%rsp)
movl -0x4(%rdi,%rax,4), %eax
movl %eax, 0x1c(%rsp)
leaq 0x8(%rcx,%rdx), %r12
leaq 0x689(%rip), %rax       # 0x4ed9
movq %rax, -0x8(%r12)
movl $0x98, %edx
movq %r12, %rdi
xorl %esi, %esi
callq 0x10f0
movl %r15d, 0x98(%r12)
movl $0x0, 0x9c(%r12)
movq %r13, 0xa0(%r12)
movq 0x28(%rsp), %rax
movq %rax, 0xa8(%r12)
movl 0x1c(%rsp), %eax
movl %eax, 0xb0(%r12)
movq $0x0, 0xb4(%r12)
movl $0xffffffff, 0xbc(%r12) # imm = 0xFFFFFFFF
movq 0x8(%rsp), %r12
jmp 0x48f0
imulq $0xc8, %rax, %rax
leaq (%rcx,%rax), %rdi
addq $-0xb0, %rdi
leaq 0x605(%rip), %rax       # 0x4ed6
movq %rax, -0x18(%rdi)
movl $0x0, -0x10(%rdi)
movl %r15d, -0xc(%rdi)
movq %r13, -0x8(%rdi)
movl $0xb0, %edx
xorl %esi, %esi
callq 0x10f0
movl 0x18(%rsp), %ecx
addl %r15d, %ecx
leaq -0x1(%rbp), %rax
andq %rax, %rbp
bsfq %rbp, %rax
incq %rax
testq %rbp, %rbp
jne 0x47a3
xorl %ebp, %ebp
movq 0x10(%rbx), %rax
movq 0x20(%rsp), %r13
movq %rax, 0x18(%r13)
movq -0x8(%r13), %rsi
leaq 0x40(%r12), %rdx
movq %rbx, %rdi
movl %ecx, 0x18(%rsp)
callq 0x5444
testq %rax, %rax
je 0x4a34
movq 0x58(%r12), %r12
xorq 0x8(%r13), %rbp
leaq 0x38(%rsp), %r14
xorl %r15d, %r15d
movl $0xc0, %edx
movq %r14, %rdi
xorl %esi, %esi
callq 0x10f0
leaq 0x696(%rip), %rax       # 0x4ff8
movq %rax, -0x8(%r14)
movq %r12, 0x98(%r14)
movq %rbp, 0xa0(%r14)
movq %rbp, 0xa8(%r14)
leaq 0x30(%rsp), %r14
movq 0x40(%rsp), %rsi
movl 0x3c(%rsp), %r12d
shlq $0x3, %r12
movq 0x18(%rbx), %rdi
addq 0x10(%rbx), %rdi
movq %r12, %rdx
callq 0x1140
addq %r12, 0x10(%rbx)
addl 0x3c(%rsp), %r15d
movl $0x0, 0x38(%rsp)
movq %r14, %rdi
callq *0x30(%rsp)
testl %eax, %eax
jne 0x4980
movq 0x18(%rbx), %rax
addq 0x18(%r13), %rax
cmpl $0xfe, 0x18(%rsp)
ja 0x4a3c
movb %r15b, 0x5(%rax)
movq 0x8(%rsp), %rdx
jmp 0x4a4a
movq 0x10(%rbx), %rcx
movq 0x8(%rsp), %r9
movq %rcx, 0x18(%r11)
movq -0x8(%r11), %rsi
leaq 0x40(%r9), %rdx
movq %rbx, %rdi
movl %r15d, %ecx
callq 0x5444
testl %r15d, %r15d
je 0x4a25
movq 0x10(%rbx), %rdx
movq 0x18(%rbx), %rcx
movl %r15d, %esi
xorl %edi, %edi
movq (%r12,%rdi,8), %r8
movq %r8, (%rcx,%rdx)
movq 0x10(%rbx), %rdx
addq $0x8, %rdx
movq %rdx, 0x10(%rbx)
incq %rdi
cmpq %rdi, %rsi
jne 0x4a09
testq %rax, %rax
je 0x4a34
movq 0x8(%rsp), %rdx
incl 0x30(%rdx)
jmp 0x4a5d
movl $0x5, %r13d
jmp 0x4a6b
movq 0x8(%rsp), %rdx
movzwl 0x48(%rdx), %ecx
movl %r15d, 0x8(%rax,%rcx)
movl $0x2, %r13d
cmpl 0x38(%rdx), %r15d
jbe 0x4a5a
movl %r15d, 0x38(%rdx)
incl 0x34(%rdx)
movq $0x0, 0x40(%rdx)
movw $0x0, 0x48(%rdx)
movl %r13d, %eax
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq