// File: /workspace/github_c_makefile_star2_O2/CarlosLunaMota[P]BinaryTrees/BinaryTrees.c
// Function: splay
static inline void splay(sp_tree *tree, const void *data) {

    sp_node  root;
    sp_node *left;
    sp_node *right;
    sp_node *node;
    sp_node *temp;
    int      comp;

    // Sanity checks:
    assert(tree != NULL);
    assert(data != NULL);

    // Initialize:
    root.right = root.left = NULL;
    left = right = &root;
    node = tree->root;
    if (node == NULL) { return; }

    for (;;) {

        // Compare "data":
        comp = (tree->comp)(data, node->data);  

        // If "data" is smaller:
        if (comp < 0) {                         
            if (node->left == NULL) { break; }

            // Rotate right if needed:
            if ((tree->comp)(data, node->left->data) < 0) {
                temp        = node->left;
                node->left  = temp->right;
                temp->right = node;
                node        = temp;
                if (node->left == NULL) { break; }
            }

            // Link right:
            right->left = node;
            right       = node;
            node        = node->left;

        // If "data" is bigger:
        } else if (comp > 0) {
            if (node->right == NULL) { break; }

            // Rotate left if needed:
            if ((tree->comp)(data, node->right->data) > 0) {
                temp        = node->right;
                node->right = temp->left;
                temp->left  = node;
                node        = temp;
                if (node->right == NULL) { break; }
            }

            // Link left:
            left->right = node;
            left        = node;
            node        = node->right;

        // If we have found "data":
        } else { break; }
    }

    // Assemble:
    left->right = node->left;
    right->left = node->right;
    node->left  = root.right;
    node->right = root.left;
    tree->root  = node;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x20, %rsp
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rsp)
movq (%rdi), %r13
testq %r13, %r13
je 0xb5ed
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x8(%rsp), %r15
movq %r15, %r12
movq (%r13), %rsi
movq %r14, %rdi
callq *0x8(%rbx)
testl %eax, %eax
js 0xb581
je 0xb5c4
movq 0x10(%r13), %rax
testq %rax, %rax
je 0xb5c4
movq (%rax), %rsi
movq %r14, %rdi
callq *0x8(%rbx)
testl %eax, %eax
jle 0xb573
movq 0x10(%r13), %rax
movq 0x8(%rax), %rcx
movq %rcx, 0x10(%r13)
movq %r13, 0x8(%rax)
cmpq $0x0, 0x10(%rax)
movq %rax, %r13
je 0xb5c7
movq %r13, 0x10(%r12)
leaq 0x10(%r13), %rax
movq %r13, %r12
jmp 0xb5bc
movq 0x8(%r13), %rax
testq %rax, %rax
je 0xb5c4
movq (%rax), %rsi
movq %r14, %rdi
callq *0x8(%rbx)
testl %eax, %eax
jns 0xb5b1
movq 0x8(%r13), %rax
movq 0x10(%rax), %rcx
movq %rcx, 0x8(%r13)
movq %r13, 0x10(%rax)
cmpq $0x0, 0x8(%rax)
movq %rax, %r13
je 0xb5c7
movq %r13, 0x8(%r15)
leaq 0x8(%r13), %rax
movq %r13, %r15
movq (%rax), %r13
jmp 0xb52f
movq %r13, %rax
movq 0x8(%rax), %rcx
movq %rcx, 0x10(%r12)
movq 0x10(%rax), %rcx
movq %rcx, 0x8(%r15)
movq 0x18(%rsp), %rcx
movq %rcx, 0x8(%rax)
movq 0x10(%rsp), %rcx
movq %rcx, 0x10(%rax)
movq %rax, (%rbx)
addq $0x20, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq