// File: /workspace/github_c_makefile_star2_O3/bobrippling[P]tim/window.c
// Function: window_add_neighbour
void window_add_neighbour(window *to, enum neighbour dir, window *new)
{
	window_evict(new);

	switch(dir){
		case neighbour_left:
		case neighbour_right:
		{
			window *topmost;
			for(topmost = to; topmost->neighbours.above; topmost = topmost->neighbours.above);

			window **pdest = (dir == neighbour_right
					? &topmost->neighbours.right
					: &topmost->neighbours.left);

			window *dest = *pdest;

			if(!dest){
				*pdest = new;
				if(dir == neighbour_right)
					new->neighbours.left = topmost;
				else
					new->neighbours.right = topmost;
			}else{
				/* walk down until we find an entry where we left */
				while(dest->neighbours.below
				&& dest->ui_start.y <= new->ui_start.y)
				{
					dest = dest->neighbours.below;
				}

				window *replace = dest->neighbours.below;
				dest->neighbours.below = new;
				if(replace)
					replace->neighbours.above = new;

				new->neighbours.above = dest;
				new->neighbours.below = replace;
			}
			break;
		}
		case neighbour_down:
		{
			window *evicted = to->neighbours.below;

			to->neighbours.below = new;
			new->neighbours.above = to;

			new->neighbours.below = evicted;
			if(evicted)
				evicted->neighbours.above = new;
			break;
		}
		case neighbour_up:
		{
			window *up = to->neighbours.above;
			if(up){
				/* insert in the chain */
				new->neighbours.above = up;
				up->neighbours.below = new;

				to->neighbours.above = new;
				new->neighbours.below = to;
			}else{
				/* rewrite left and right pointers */
				new->neighbours.left = to->neighbours.left;
				to->neighbours.left = NULL;
				new->neighbours.right = to->neighbours.right;
				to->neighbours.right = NULL;

				if(new->neighbours.right)
					new->neighbours.right->neighbours.left = new;
				if(new->neighbours.left)
					new->neighbours.left->neighbours.right = new;

				new->neighbours.below = to;
				to->neighbours.above = new;
			}
			break;
		}
	}
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rdx, %rbx
movl %esi, %r15d
movq %rdi, %r14
movq %rdx, %rdi
callq 0xd533
leal -0x2(%r15), %eax
cmpl $0x2, %eax
jb 0xd704
testl %r15d, %r15d
je 0xd741
cmpl $0x1, %r15d
jne 0xd7be
movq 0x58(%r14), %rax
movq %rbx, 0x58(%r14)
movq %r14, 0x60(%rbx)
movq %rax, 0x58(%rbx)
testq %rax, %rax
je 0xd7be
movq %rbx, 0x60(%rax)
jmp 0xd7be
movq %r14, %rcx
movq 0x60(%r14), %r14
testq %r14, %r14
jne 0xd704
xorl %edx, %edx
cmpl $0x3, %r15d
sete %dl
movq 0x48(%rcx,%rdx,8), %rax
testq %rax, %rax
je 0xd75c
movq %rax, %rcx
movq 0x58(%rax), %rax
testq %rax, %rax
je 0xd774
movl 0xc(%rcx), %edx
cmpl 0xc(%rbx), %edx
jle 0xd723
movq %rbx, 0x58(%rcx)
leaq 0x60(%rax), %rdx
jmp 0xd778
movq 0x60(%r14), %rax
testq %rax, %rax
je 0xd785
movq %rax, 0x60(%rbx)
movq %rbx, 0x58(%rax)
movq %rbx, 0x60(%r14)
movq %r14, 0x58(%rbx)
jmp 0xd7be
leaq 0x48(,%rdx,8), %rax
movq %rbx, (%rcx,%rax)
cmpl $0x3, %r15d
jne 0xd7ba
movq %rcx, 0x48(%rbx)
jmp 0xd7be
leaq 0x58(%rcx), %rdx
movq %rbx, (%rdx)
movq %rcx, 0x60(%rbx)
movq %rax, 0x58(%rbx)
jmp 0xd7be
movups 0x48(%r14), %xmm0
movups %xmm0, 0x48(%rbx)
xorps %xmm0, %xmm0
movups %xmm0, 0x48(%r14)
movq 0x50(%rbx), %rax
testq %rax, %rax
je 0xd7a3
movq %rbx, 0x48(%rax)
movq 0x48(%rbx), %rax
testq %rax, %rax
je 0xd7b0
movq %rbx, 0x50(%rax)
movq %r14, 0x58(%rbx)
movq %rbx, 0x60(%r14)
jmp 0xd7be
movq %rcx, 0x50(%rbx)
popq %rbx
popq %r14
popq %r15
retq