// File: 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:
subq $0x28, %rsp
movq %rdi, 0x20(%rsp)
movq %rsi, 0x18(%rsp)
movq 0x20(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rdx
movq 0x18(%rsp), %rcx
xorl %eax, %eax
cmpq 0x8(%rdx), %rcx
movb %al, 0x7(%rsp)
je 0x48e22
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
cmpl $0x0, 0x18(%rax)
sete %al
movb %al, 0x7(%rsp)
movb 0x7(%rsp), %al
testb $0x1, %al
jne 0x48e2f
jmp 0x4900d
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x18(%rsp), %rcx
movq 0x30(%rcx), %rcx
movq 0x30(%rcx), %rcx
cmpq 0x20(%rcx), %rax
jne 0x48f2d
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x30(%rax), %rax
movq 0x28(%rax), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, 0x10(%rsp)
je 0x48ebc
movq 0x10(%rsp), %rax
cmpl $0x0, 0x18(%rax)
jne 0x48ebc
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movl $0x1, 0x18(%rax)
movq 0x10(%rsp), %rax
movl $0x1, 0x18(%rax)
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x30(%rax), %rax
movl $0x0, 0x18(%rax)
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x30(%rax), %rax
movq %rax, 0x18(%rsp)
jmp 0x48f28
movq 0x18(%rsp), %rax
movq 0x18(%rsp), %rcx
movq 0x30(%rcx), %rcx
cmpq 0x28(%rcx), %rax
jne 0x48eed
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rsi
callq 0x49030
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movl $0x1, 0x18(%rax)
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x30(%rax), %rax
movl $0x0, 0x18(%rax)
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x30(%rax), %rsi
callq 0x49130
jmp 0x49008
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x30(%rax), %rax
movq 0x20(%rax), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, 0x10(%rsp)
je 0x48f9a
movq 0x10(%rsp), %rax
cmpl $0x0, 0x18(%rax)
jne 0x48f9a
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movl $0x1, 0x18(%rax)
movq 0x10(%rsp), %rax
movl $0x1, 0x18(%rax)
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x30(%rax), %rax
movl $0x0, 0x18(%rax)
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x30(%rax), %rax
movq %rax, 0x18(%rsp)
jmp 0x49006
movq 0x18(%rsp), %rax
movq 0x18(%rsp), %rcx
movq 0x30(%rcx), %rcx
cmpq 0x20(%rcx), %rax
jne 0x48fcb
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rsi
callq 0x49130
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movl $0x1, 0x18(%rax)
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x30(%rax), %rax
movl $0x0, 0x18(%rax)
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x30(%rax), %rsi
callq 0x49030
jmp 0x49008
jmp 0x48df8
movq 0x8(%rsp), %rax
movq 0x8(%rax), %rax
movl $0x1, 0x18(%rax)
addq $0x28, %rsp
retq
nopw %cs:(%rax,%rax)