// File: /workspace/github_cpp_makefile_star2_O1/CMU-SAFARI[P]MQSim/src/sim/EventTree.cpp
// Function: MQSimEngine::EventTree::RestoreAfterInsert(MQSimEngine::EventTreeNode*)
void EventTree::RestoreAfterInsert(EventTreeNode* x)
	{
		// x and y are used as variable names for brevity, in a more formal
		// implementation, you should probably change the names

		EventTreeNode* y;

		// maintain red-black tree properties after adding x
		while (x != rbTree && x->Parent->Color == 0) {
			// Parent node is .Colored red; 
			// determine traversal path
			// is it on the Left or Right subtree?
			if (x->Parent == x->Parent->Parent->Left) {	
				// get uncle
				y = x->Parent->Parent->Right;
				if (y != NULL && y->Color == 0)
				{	// uncle is red; change x's Parent and uncle to black
					x->Parent->Color = 1;
					y->Color = 1;
					// grandparent must be red. Why? Every red node that is not 
					// a leaf has only black children 
					x->Parent->Parent->Color = 0;
					x = x->Parent->Parent;	// continue loop with grandparent
				} else {
					// uncle is black; determine if x is greater than Parent
					if (x == x->Parent->Right)
					{	// yes, x is greater than Parent; rotate Left
						// make x a Left child
						x = x->Parent;
						RotateLeft(x);
					}
					// no, x is less than Parent
					x->Parent->Color = 1;	// make Parent black
					x->Parent->Parent->Color = 0;		// make grandparent black
					RotateRight(x->Parent->Parent);					// rotate right
				}
			} else {
				// x's Parent is on the Right subtree
				// this code is the same as above with "Left" and "Right" swapped
				y = x->Parent->Parent->Left;
				if (y != NULL && y->Color == 0) {
					x->Parent->Color = 1;
					y->Color = 1;
					x->Parent->Parent->Color = 0;
					x = x->Parent->Parent;
				} else {
					if (x == x->Parent->Left) {
						x = x->Parent;
						RotateRight(x);
					}
					x->Parent->Color = 1;
					x->Parent->Parent->Color = 0;
					RotateLeft(x->Parent->Parent);
				}
			}
		}

		// rbTree should always be black
		rbTree->Color = 1;
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq 0x8(%rdi), %rcx
cmpq %rsi, %rcx
je 0x28e08
movq %rsi, %r14
movq 0x30(%rsi), %r15
cmpl $0x0, 0x18(%r15)
jne 0x28e08
movq %rdi, %rbx
leaq 0x18(%r15), %rax
movl $0x1, %ebp
movq 0x30(%r15), %rcx
movq 0x20(%rcx), %rdx
cmpq %rdx, %r15
je 0x28d9a
testq %rdx, %rdx
je 0x28d66
cmpl $0x0, 0x18(%rdx)
je 0x28ddd
cmpq 0x20(%r15), %r14
jne 0x28d7a
movq %rbx, %rdi
movq %r15, %rsi
callq 0x28e74
movq %r15, %r14
movq 0x30(%r14), %rax
movl $0x1, 0x18(%rax)
movq 0x30(%rax), %rsi
movl $0x0, 0x18(%rsi)
movq %rbx, %rdi
callq 0x28e1a
jmp 0x28dec
movq 0x28(%rcx), %rdx
testq %rdx, %rdx
je 0x28da9
cmpl $0x0, 0x18(%rdx)
je 0x28ddd
cmpq 0x28(%r15), %r14
jne 0x28dbd
movq %rbx, %rdi
movq %r15, %rsi
callq 0x28e1a
movq %r15, %r14
movq 0x30(%r14), %rax
movl $0x1, 0x18(%rax)
movq 0x30(%rax), %rsi
movl $0x0, 0x18(%rsi)
movq %rbx, %rdi
callq 0x28e74
jmp 0x28dec
movl %ebp, (%rax)
movl %ebp, 0x18(%rdx)
movl $0x0, 0x18(%rcx)
movq %rcx, %r14
movq 0x8(%rbx), %rcx
cmpq %rcx, %r14
je 0x28e08
movq 0x30(%r14), %r15
leaq 0x18(%r15), %rax
cmpl $0x0, 0x18(%r15)
je 0x28d4e
movl $0x1, 0x18(%rcx)
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq