// File: /workspace/github_cpp_makefile_star2_O1/searsm8[P]FM_Partitioning/fmpart.cpp
// Function: CELL::changePartition()
void changePartition()
	{		
		//remove the cell from the bucket i.e. "lock" the cell until the next pass
		gain_bucket[partition].erase(gain_itr);				
		locked = true;	
		
		//update cut_size. cutsize is reduced by the gain of the moved cell.
		cut_size -= gain;		
			
		int base_partition = partition;
		
		//change partition for this cell
		partition_area[partition] -= area; //decrease area in old partition
		partition = !partition;		
		partition_area[partition] += area; //increase area in new partition
		
		if(gain < 0)
			positive_gains_exhausted = true;
											
		//Update the gain of all neighboring cells		
		//Loop through all nets the cell is on. Update gains for neighboring cells on critical nets
		for(int i = 0; i < net_list.size(); i++)
		{						
			//if the net has a locked (or fixed) cell in both partitions,
			//then the net is "dead" and cannot cause any change in cutstate (prevents wasting time)
			if(net_list[i]->has_locked[0] && net_list[i]->has_locked[1])
			{				
				continue;
			}
							
			//create "From" and "To" partition counts
			int from = net_list[i]->partition_count[!partition];   //i.e. F(n), where the cell came from
			int to   = net_list[i]->partition_count[partition];    //i.e. T(n), where the cell is going to
			
		//check critical nets before the move
			if(to == 0)
			{
			//increment gain on all free cells on this net
				for(int k = 0; k < net_list[i]->cell_list.size(); k++)
				{
					if((!net_list[i]->cell_list[k]->locked))		
					{
						net_list[i]->cell_list[k]->updateGain(1);
					}
				}
			}								
			else if (to == 1)
			{
			//decrement gain of the only "to" cell
				for(int k = 0; k < net_list[i]->cell_list.size(); k++)
				{
					if(!net_list[i]->cell_list[k]->locked && base_partition != net_list[i]->cell_list[k]->partition)
					{						
						net_list[i]->cell_list[k]->updateGain(-1);
						break;
					}
				}
			}
							
			//update from and to counts
			from--;
			net_list[i]->partition_count[!partition]--;
			to++;
			net_list[i]->partition_count[partition]++;
			
			//check critical nets after the move
			if(from == 0)
			{ 
			//decrement gain on all free cells on this net
				for(int k = 0; k < net_list[i]->cell_list.size(); k++)
				{
					if(!net_list[i]->cell_list[k]->locked)		
					{
						net_list[i]->cell_list[k]->updateGain(-1);
					}
				}
			}								
			else if (from == 1)
			{
			//increment gain of the only "from" cell
				for(int k = 0; k < net_list[i]->cell_list.size(); k++)
				{
					if(!net_list[i]->cell_list[k]->locked && base_partition == net_list[i]->cell_list[k]->partition)
					{
						net_list[i]->cell_list[k]->updateGain(1);
						break;
					}
				}
			}
			
			//update the has_locked member for this net for the "To" partition
			net_list[i]->has_locked[!base_partition] = true;
		}	
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movslq 0x84(%rdi), %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x442b(%rip), %rdi      # 0x81a0
addq %rax, %rdi
movq 0x90(%rbx), %rsi
callq 0x41e4
movb $0x1, 0x7d(%rbx)
movl 0x80(%rbx), %eax
subl %eax, 0x44b4(%rip)      # 0x8248
movslq 0x84(%rbx), %r14
xorl %esi, %esi
testq %r14, %r14
sete %sil
movl 0x78(%rbx), %ecx
leaq 0x449e(%rip), %rdx      # 0x824c
subl %ecx, (%rdx,%r14,4)
movl %esi, 0x84(%rbx)
movq %rsi, -0x30(%rbp)
addl %ecx, (%rdx,%rsi,4)
testl %eax, %eax
jns 0x3dca
movb $0x1, 0x44b2(%rip)      # 0x827c
movq 0x98(%rbx), %rax
cmpq %rax, 0xa0(%rbx)
je 0x3fc3
xorl %r12d, %r12d
movq (%rax,%r12,8), %rcx
cmpb $0x1, 0x6a(%rcx)
jne 0x3df5
cmpb $0x0, 0x6b(%rcx)
jne 0x3fa2
movslq 0x84(%rbx), %rax
xorl %edx, %edx
testq %rax, %rax
sete %dl
movl 0x6c(%rcx,%rdx,4), %r13d
movl 0x6c(%rcx,%rax,4), %eax
testl %eax, %eax
je 0x3e59
cmpl $0x1, %eax
jne 0x3eb9
movq 0x78(%rcx), %rax
movq 0x80(%rcx), %rcx
subq %rax, %rcx
je 0x3eb9
sarq $0x3, %rcx
cmpq $0x1, %rcx
adcq $0x0, %rcx
xorl %edx, %edx
movq (%rax,%rdx,8), %rdi
cmpb $0x0, 0x7d(%rdi)
jne 0x3e4f
cmpl 0x84(%rdi), %r14d
jne 0x3eaf
incq %rdx
cmpq %rdx, %rcx
jne 0x3e3c
jmp 0x3eb9
movq 0x98(%rbx), %rax
movq (%rax,%r12,8), %rcx
movq 0x78(%rcx), %rax
cmpq %rax, 0x80(%rcx)
je 0x3eb9
xorl %r15d, %r15d
movq (%rax,%r15,8), %rdi
cmpb $0x0, 0x7d(%rdi)
jne 0x3e88
movl $0x1, %esi
callq 0x415e
incq %r15
movq 0x98(%rbx), %rax
movq (%rax,%r12,8), %rcx
movq 0x78(%rcx), %rax
movq 0x80(%rcx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %r15, %rcx
ja 0x3e74
jmp 0x3eb9
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x415e
movq 0x98(%rbx), %rax
movq (%rax,%r12,8), %rcx
xorl %eax, %eax
cmpl $0x0, 0x84(%rbx)
sete %al
decl 0x6c(%rcx,%rax,4)
movslq 0x84(%rbx), %rax
incl 0x6c(%rcx,%rax,4)
cmpl $0x1, %r13d
je 0x3f2e
cmpl $0x2, %r13d
jne 0x3f8e
movq 0x78(%rcx), %rax
movq 0x80(%rcx), %rcx
subq %rax, %rcx
je 0x3f8e
sarq $0x3, %rcx
cmpq $0x1, %rcx
adcq $0x0, %rcx
xorl %edx, %edx
movq (%rax,%rdx,8), %rdi
cmpb $0x0, 0x7d(%rdi)
jne 0x3f24
cmpl 0x84(%rdi), %r14d
je 0x3f84
incq %rdx
cmpq %rdx, %rcx
jne 0x3f11
jmp 0x3f8e
movq 0x98(%rbx), %rax
movq (%rax,%r12,8), %rcx
movq 0x78(%rcx), %rax
cmpq %rax, 0x80(%rcx)
je 0x3f8e
xorl %r15d, %r15d
movq (%rax,%r15,8), %rdi
cmpb $0x0, 0x7d(%rdi)
jne 0x3f5d
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x415e
incq %r15
movq 0x98(%rbx), %rax
movq (%rax,%r12,8), %rcx
movq 0x78(%rcx), %rax
movq 0x80(%rcx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %r15, %rcx
ja 0x3f49
jmp 0x3f8e
movl $0x1, %esi
callq 0x415e
movq 0x98(%rbx), %rax
movq (%rax,%r12,8), %rax
movq -0x30(%rbp), %rcx
movb $0x1, 0x6a(%rax,%rcx)
incq %r12
movq 0x98(%rbx), %rax
movq 0xa0(%rbx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %r12, %rcx
ja 0x3de1
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq