// File: /workspace/github_c_makefile_star2_O0/CarlosLunaMota[P]BinaryTrees/BinaryTrees.c
// Function: rb_tree_diff
rb_tree *rb_tree_diff(const rb_tree *tree_1, const rb_tree *tree_2) {

    rb_tree *tree = NULL;
    rb_node *pred_1;
    rb_node *node_1;
    rb_node *pred_2;
    rb_node *node_2;
    void    *data;
    int      comp;

    // Sanity check:
    assert(tree_1 != NULL);
    assert(tree_2 != NULL);

    // Create a new tree:
    tree = new_rb_tree(tree_1->comp);
    if (tree == NULL) { return NULL; }

    // Special case: Both trees are the same
    if (tree_1 == tree_2) { return tree; }

    // Special case: tree_1 is empty
    if (rb_tree_is_empty(tree_1) == YES) { return tree; }

    // Go to the smallest element of tree_1 while right-threading your path:
    node_1 = tree_1->root;
    if (node_1 != NULL) {
        while (node_1->left != NULL) {
            pred_1 = node_1->left;
            while (pred_1->right != NULL) { pred_1 = pred_1->right; }
            pred_1->right = node_1;
            node_1        = node_1->left;
        }
    }

    // Go to the smallest element of tree_2 while right-threading your path:
    node_2 = tree_2->root;
    if (node_2 != NULL) {
        while (node_2->left != NULL) {
            pred_2 = node_2->left;
            while (pred_2->right != NULL) { pred_2 = pred_2->right; }
            pred_2->right = node_2;
            node_2        = node_2->left;
        }
    }
    
    // Until we have exhausted at least one of the trees:
    while (node_1 != NULL && node_2 != NULL) {

        // compare both nodes:
        comp = (tree->comp)(node_1->data, node_2->data);

        if (comp < 0) {

            // insert node_1->data in tree /////////////////////////////////////
            data = node_1->data;
            data = rb_tree_insert_max(tree, data);
            assert(data == NULL);
            ////////////////////////////////////////////////////////////////////

            // advance node_1 //////////////////////////////////////////////////
            node_1 = node_1->right;
            if (node_1 != NULL) {
                while (node_1->left != NULL) {
                    pred_1 = node_1->left;
                    while (pred_1->right != NULL && pred_1->right != node_1) {
                        pred_1 = pred_1->right;
                    }
                    if (pred_1->right == NULL) {
                        pred_1->right = node_1;
                        node_1        = node_1->left;
                    } else {
                        pred_1->right = NULL;
                        break;
                    }
                }
            }
            ////////////////////////////////////////////////////////////////////

        } else if (comp > 0) {

            // advance node_2 //////////////////////////////////////////////////
            node_2 = node_2->right;
            if (node_2 != NULL) {
                while (node_2->left != NULL) {
                    pred_2 = node_2->left;
                    while (pred_2->right != NULL && pred_2->right != node_2) {
                        pred_2 = pred_2->right;
                    }
                    if (pred_2->right == NULL) {
                        pred_2->right = node_2;
                        node_2        = node_2->left;
                    } else {
                        pred_2->right = NULL;
                        break;
                    }
                }
            }
            ////////////////////////////////////////////////////////////////////

        } else {

            // advance node_1 //////////////////////////////////////////////////
            node_1 = node_1->right;
            if (node_1 != NULL) {
                while (node_1->left != NULL) {
                    pred_1 = node_1->left;
                    while (pred_1->right != NULL && pred_1->right != node_1) {
                        pred_1 = pred_1->right;
                    }
                    if (pred_1->right == NULL) {
                        pred_1->right = node_1;
                        node_1        = node_1->left;
                    } else {
                        pred_1->right = NULL;
                        break;
                    }
                }
            }
            ////////////////////////////////////////////////////////////////////

            // advance node_2 //////////////////////////////////////////////////
            node_2 = node_2->right;
            if (node_2 != NULL) {
                while (node_2->left != NULL) {
                    pred_2 = node_2->left;
                    while (pred_2->right != NULL && pred_2->right != node_2) {
                        pred_2 = pred_2->right;
                    }
                    if (pred_2->right == NULL) {
                        pred_2->right = node_2;
                        node_2        = node_2->left;
                    } else {
                        pred_2->right = NULL;
                        break;
                    }
                }
            }
            ////////////////////////////////////////////////////////////////////
        }
    }

    // Insert all remaining data from tree_1:
    while (node_1 != NULL) {

        // insert node_1->data in tree /////////////////////////////////////////
        data = node_1->data;
        data = rb_tree_insert_max(tree, data);
        assert(data == NULL);
        ////////////////////////////////////////////////////////////////////////

        // advance node_1 //////////////////////////////////////////////////////
        node_1 = node_1->right;
        if (node_1 != NULL) {
            while (node_1->left != NULL) {
                pred_1 = node_1->left;
                while (pred_1->right != NULL && pred_1->right != node_1) {
                    pred_1 = pred_1->right;
                }
                if (pred_1->right == NULL) {
                    pred_1->right = node_1;
                    node_1        = node_1->left;
                } else {
                    pred_1->right = NULL;
                    break;
                }
            }
        }
        ////////////////////////////////////////////////////////////////////////
    }

    // We need to traverse tree_2 completely to restore the modified pointers:
    while (node_2 != NULL) {

        // advance node_2 //////////////////////////////////////////////////////
        node_2 = node_2->right;
        if (node_2 != NULL) {
            while (node_2->left != NULL) {
                pred_2 = node_2->left;
                while (pred_2->right != NULL && pred_2->right != node_2) {
                    pred_2 = pred_2->right;
                }
                if (pred_2->right == NULL) {
                    pred_2->right = node_2;
                    node_2        = node_2->left;
                } else {
                    pred_2->right = NULL;
                    break;
                }
            }
        }
        ////////////////////////////////////////////////////////////////////////
    }

    // Return the resulting tree:
    return tree;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x12e41
jmp 0x12e60
leaq 0x36bd(%rip), %rdi      # 0x16505
leaq 0x33ad(%rip), %rsi      # 0x161fc
movl $0xefc, %edx            # imm = 0xEFC
leaq 0x3bd6(%rip), %rcx      # 0x16a31
callq 0x1060
cmpq $0x0, -0x18(%rbp)
je 0x12e69
jmp 0x12e88
leaq 0x36dd(%rip), %rdi      # 0x1654d
leaq 0x3385(%rip), %rsi      # 0x161fc
movl $0xefd, %edx            # imm = 0xEFD
leaq 0x3bae(%rip), %rcx      # 0x16a31
callq 0x1060
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xfe40
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0x12ead
movq $0x0, -0x8(%rbp)
jmp 0x1348c
movq -0x10(%rbp), %rax
cmpq -0x18(%rbp), %rax
jne 0x12ec4
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x1348c
movq -0x10(%rbp), %rdi
callq 0x10ae0
cmpl $0x1, %eax
jne 0x12edf
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x1348c
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x12f3f
jmp 0x12ef3
movq -0x30(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x12f3d
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x12f23
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x12f0a
movq -0x30(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x12ef3
jmp 0x12f3f
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x12f9f
jmp 0x12f53
movq -0x40(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x12f9d
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x12f83
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
jmp 0x12f6a
movq -0x40(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x12f53
jmp 0x12f9f
jmp 0x12fa1
xorl %eax, %eax
cmpq $0x0, -0x30(%rbp)
movb %al, -0x4d(%rbp)
je 0x12fb8
cmpq $0x0, -0x40(%rbp)
setne %al
movb %al, -0x4d(%rbp)
movb -0x4d(%rbp), %al
testb $0x1, %al
jne 0x12fc4
jmp 0x132d6
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x30(%rbp), %rcx
movq (%rcx), %rdi
movq -0x40(%rbp), %rcx
movq (%rcx), %rsi
callq *%rax
movl %eax, -0x4c(%rbp)
cmpl $0x0, -0x4c(%rbp)
jge 0x130d5
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x20(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x100a0
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x1300e
jmp 0x1302d
leaq 0x3744(%rip), %rdi      # 0x16759
leaq 0x31e0(%rip), %rsi      # 0x161fc
movl $0xf2a, %edx            # imm = 0xF2A
leaq 0x3a09(%rip), %rcx      # 0x16a31
callq 0x1060
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x130d0
jmp 0x13046
movq -0x30(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x130ce
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x10(%rcx)
movb %al, -0x4e(%rbp)
je 0x1307f
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x30(%rbp), %rax
setne %al
movb %al, -0x4e(%rbp)
movb -0x4e(%rbp), %al
testb $0x1, %al
jne 0x13088
jmp 0x13096
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x1305d
movq -0x28(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x130bb
movq -0x30(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x130c9
movq -0x28(%rbp), %rax
movq $0x0, 0x10(%rax)
jmp 0x130ce
jmp 0x13046
jmp 0x130d0
jmp 0x132d1
cmpl $0x0, -0x4c(%rbp)
jle 0x13187
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x13182
jmp 0x130f8
movq -0x40(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x13180
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x10(%rcx)
movb %al, -0x4f(%rbp)
je 0x13131
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x40(%rbp), %rax
setne %al
movb %al, -0x4f(%rbp)
movb -0x4f(%rbp), %al
testb $0x1, %al
jne 0x1313a
jmp 0x13148
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
jmp 0x1310f
movq -0x38(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x1316d
movq -0x40(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x1317b
movq -0x38(%rbp), %rax
movq $0x0, 0x10(%rax)
jmp 0x13180
jmp 0x130f8
jmp 0x13182
jmp 0x132cf
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x1322a
jmp 0x131a0
movq -0x30(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x13228
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x10(%rcx)
movb %al, -0x50(%rbp)
je 0x131d9
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x30(%rbp), %rax
setne %al
movb %al, -0x50(%rbp)
movb -0x50(%rbp), %al
testb $0x1, %al
jne 0x131e2
jmp 0x131f0
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x131b7
movq -0x28(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x13215
movq -0x30(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x13223
movq -0x28(%rbp), %rax
movq $0x0, 0x10(%rax)
jmp 0x13228
jmp 0x131a0
jmp 0x1322a
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x132cd
jmp 0x13243
movq -0x40(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x132cb
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x10(%rcx)
movb %al, -0x51(%rbp)
je 0x1327c
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x40(%rbp), %rax
setne %al
movb %al, -0x51(%rbp)
movb -0x51(%rbp), %al
testb $0x1, %al
jne 0x13285
jmp 0x13293
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
jmp 0x1325a
movq -0x38(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x132b8
movq -0x40(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x132c6
movq -0x38(%rbp), %rax
movq $0x0, 0x10(%rax)
jmp 0x132cb
jmp 0x13243
jmp 0x132cd
jmp 0x132cf
jmp 0x132d1
jmp 0x12fa1
jmp 0x132d8
cmpq $0x0, -0x30(%rbp)
je 0x133cf
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x20(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x100a0
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x13308
jmp 0x13327
leaq 0x344a(%rip), %rdi      # 0x16759
leaq 0x2ee6(%rip), %rsi      # 0x161fc
movl $0xf85, %edx            # imm = 0xF85
leaq 0x370f(%rip), %rcx      # 0x16a31
callq 0x1060
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x133ca
jmp 0x13340
movq -0x30(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x133c8
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x10(%rcx)
movb %al, -0x52(%rbp)
je 0x13379
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x30(%rbp), %rax
setne %al
movb %al, -0x52(%rbp)
movb -0x52(%rbp), %al
testb $0x1, %al
jne 0x13382
jmp 0x13390
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x13357
movq -0x28(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x133b5
movq -0x30(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x133c3
movq -0x28(%rbp), %rax
movq $0x0, 0x10(%rax)
jmp 0x133c8
jmp 0x13340
jmp 0x133ca
jmp 0x132d8
jmp 0x133d1
cmpq $0x0, -0x40(%rbp)
je 0x13484
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x1347f
jmp 0x133f5
movq -0x40(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x1347d
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x10(%rcx)
movb %al, -0x53(%rbp)
je 0x1342e
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x40(%rbp), %rax
setne %al
movb %al, -0x53(%rbp)
movb -0x53(%rbp), %al
testb $0x1, %al
jne 0x13437
jmp 0x13445
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
jmp 0x1340c
movq -0x38(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x1346a
movq -0x40(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x13478
movq -0x38(%rbp), %rax
movq $0x0, 0x10(%rax)
jmp 0x1347d
jmp 0x133f5
jmp 0x1347f
jmp 0x133d1
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)