// File: /workspace/github_c_makefile_star2_O1/icebert[P]pblat/lib/rbTree.c
// Function: rbTreeAdd
void *rbTreeAdd(struct rbTree *t, void *item)
/* rbTreeAdd() - Inserts an item into the red-black tree pointed to by t,
 * according the the value its key.  The key of an item in the red-black
 * tree must be unique among items in the tree.  If an item with the same key
 * already exists in the tree, a pointer to that item is returned.  Otherwise,
 * NULL is returned, indicating insertion was successful.
 */
{
struct rbTreeNode *x, *p, *q, *m, **attachX;
int (* compare)(void *, void *);
int cmpResult;
rbTreeColor col;
struct rbTreeNode **stack = NULL;
int tos;

tos = 0;    
if((p = t->root) != NULL) 
    {
    compare = t->compare;
    stack = t->stack;

    /* Repeatedly explore either the left branch or the right branch
     * depending on the value of the key, until an empty branch is chosen.
     */
    for(;;) 
        {
	stack[tos++] = p;
	cmpResult = compare(item, p->item);
	if(cmpResult < 0) 
	    {
	    p = p->left;
	    if(!p) 
	        {
		p = stack[--tos];
		attachX = &p->left;
		break;
		}
	    }
	else if(cmpResult > 0) 
	    {
	    p = p->right;
	    if(!p) 
	        {
		p = stack[--tos];
		attachX = &p->right;
		break;
		}
	    }
	else 
	    {
	    return p->item;
	    }
	}
    col = rbTreeRed;
    }
else 
    {
    attachX = &t->root;
    col = rbTreeBlack;
    }

/* Allocate new node and place it in tree. */
if ((x = t->freeList) != NULL)
    t->freeList = x->right;
else
    lmAllocVar(t->lm, x);
x->left = x->right = NULL;
x->item = item;
x->color = col;
*attachX = x;
t->n++;

/* Restructuring or recolouring will be needed if node x and its parent, p,
 * are both red.
 */
if(tos > 0) 
    {
    while(p->color == rbTreeRed) 
	{  /* Double red problem. */

	/* Obtain a pointer to p's parent, m, and sibling, q. */
	m = stack[--tos];
	q = p == m->left ? m->right : m->left;
	
	/* Determine whether restructuring or recolouring is needed. */
	if(!q || q->color == rbTreeBlack) 
	    {
	    /* Sibling is black.  ==>  Perform restructuring. */
	    
	    /* Restructure according to the left to right order, of nodes
	     * m, p, and x.
	     */
	    m = restructure(t, tos, m, p, x);
	    m->color = rbTreeBlack;
	    m->left->color = m->right->color = rbTreeRed;

	    /* Restructuring eliminates the double red problem. */
	    break;
	    }
	/* else just need to flip color */
	
	/* Sibling is also red.  ==>  Perform recolouring. */
	p->color = rbTreeBlack;
	q->color = rbTreeBlack;

	if(tos == 0) break;  /* The root node always remains black. */
	    
	m->color = rbTreeRed;

	/* Continue, checking colouring higher up. */
	x = m;
	p = stack[--tos];
	}
    }

return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r15
movq %rdi, %rbx
movq 0x8(%rdi), %r14
testq %r14, %r14
je 0x3a8f1
movq 0x18(%rbx), %rbp
movq 0x20(%rbx), %r12
xorl %r13d, %r13d
movq %r14, (%r12,%r13,8)
movq 0x18(%r14), %rsi
movq %r15, %rdi
callq *%rbp
testl %eax, %eax
js 0x3a8e4
je 0x3a905
movq 0x8(%r14), %r14
testq %r14, %r14
jne 0x3a8ec
jmp 0x3a90e
movq (%r14), %r14
testq %r14, %r14
je 0x3a91a
incq %r13
jmp 0x3a8c6
leaq 0x8(%rbx), %rcx
xorl %r14d, %r14d
movl $0x1, %ebp
xorl %r12d, %r12d
xorl %r13d, %r13d
jmp 0x3a923
movq 0x18(%r14), %rax
jmp 0x3aa0a
movq (%r12,%r13,8), %r14
leaq 0x8(%r14), %rcx
xorl %ebp, %ebp
jmp 0x3a923
movq (%r12,%r13,8), %r14
xorl %ebp, %ebp
movq %r14, %rcx
movq 0x30(%rbx), %r8
testq %r8, %r8
je 0x3a936
movq 0x8(%r8), %rax
movq %rax, 0x30(%rbx)
jmp 0x3a94f
movq 0x28(%rbx), %rdi
movl $0x20, %esi
movq %rcx, (%rsp)
callq 0x2bfa9
movq (%rsp), %rcx
movq %rax, %r8
xorps %xmm0, %xmm0
movups %xmm0, (%r8)
movq %r15, 0x18(%r8)
movl %ebp, 0x10(%r8)
movq %r8, (%rcx)
incl 0x10(%rbx)
xorl %eax, %eax
testl %r13d, %r13d
je 0x3aa0a
cmpl $0x0, 0x10(%r14)
jne 0x3aa0a
leaq 0x10(%r14), %r11
movl %r13d, %ecx
leaq (%r12,%rcx,8), %rdi
movq $-0x1, %r9
movl $0x1, %r10d
xorl %esi, %esi
movq (%rdi,%r9,8), %rdx
movq (%rdx), %r15
cmpq %r15, %r14
jne 0x3a9a4
movq 0x8(%rdx), %r15
testq %r15, %r15
je 0x3a9e2
cmpl $0x1, 0x10(%r15)
je 0x3a9e2
movq %rcx, %r8
movl %r10d, (%r11)
movl %r10d, 0x10(%r15)
addq %r9, %r8
je 0x3aa0a
movl $0x0, 0x10(%rdx)
movq -0x8(%rdi,%r9,8), %r14
leaq 0x10(%r14), %r11
addl $0x2, %esi
addq $-0x2, %r9
cmpl $0x0, 0x10(%r14)
movq %rdx, %r8
je 0x3a994
jmp 0x3aa0a
notl %esi
addl %ecx, %esi
movq %rbx, %rdi
movq %r14, %rcx
callq 0x3aa19
movq %rax, %rcx
movl $0x1, 0x10(%rax)
movq 0x8(%rax), %rdx
xorl %eax, %eax
movl %eax, 0x10(%rdx)
movq (%rcx), %rcx
movl %eax, 0x10(%rcx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq