// File: /workspace/github_cpp_makefile_star2_O3/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 0x444b(%rip), %rdi      # 0x81a0
addq %rax, %rdi
movq 0x90(%rbx), %rsi
callq 0x41b0
movb $0x1, 0x7d(%rbx)
movl 0x80(%rbx), %eax
subl %eax, 0x44d4(%rip)      # 0x8248
movslq 0x84(%rbx), %r14
xorl %esi, %esi
testq %r14, %r14
sete %sil
movl 0x78(%rbx), %ecx
leaq 0x44be(%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 0x3daa
movb $0x1, 0x44d2(%rip)      # 0x827c
movq 0x98(%rbx), %rax
movq 0xa0(%rbx), %rdx
cmpq %rax, %rdx
je 0x3f8f
xorl %r12d, %r12d
movq (%rax,%r12,8), %rcx
cmpb $0x1, 0x6a(%rcx)
jne 0x3dd8
cmpb $0x0, 0x6b(%rcx)
jne 0x3f79
movslq 0x84(%rbx), %rdx
xorl %esi, %esi
testq %rdx, %rdx
sete %sil
movl 0x6c(%rcx,%rsi,4), %r13d
movl 0x6c(%rcx,%rdx,4), %edx
testl %edx, %edx
je 0x3e3e
cmpl $0x1, %edx
jne 0x3e9e
movq 0x78(%rcx), %rdx
movq 0x80(%rcx), %rsi
subq %rdx, %rsi
je 0x3e9e
sarq $0x3, %rsi
cmpq $0x1, %rsi
adcq $0x0, %rsi
xorl %r8d, %r8d
movq (%rdx,%r8,8), %rdi
cmpb $0x0, 0x7d(%rdi)
jne 0x3e34
cmpl 0x84(%rdi), %r14d
jne 0x3e89
incq %r8
cmpq %r8, %rsi
jne 0x3e21
jmp 0x3e9e
movq 0x78(%rcx), %rdx
cmpq %rdx, 0x80(%rcx)
je 0x3e9e
xorl %r15d, %r15d
movq (%rdx,%r15,8), %rdi
cmpb $0x0, 0x7d(%rdi)
jne 0x3e69
movl $0x1, %esi
callq 0x412a
movq 0x98(%rbx), %rax
incq %r15
movq (%rax,%r12,8), %rcx
movq 0x78(%rcx), %rdx
movq 0x80(%rcx), %rsi
subq %rdx, %rsi
sarq $0x3, %rsi
cmpq %r15, %rsi
ja 0x3e4e
jmp 0x3e9e
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x412a
movq 0x98(%rbx), %rax
movq (%rax,%r12,8), %rcx
xorl %edx, %edx
cmpl $0x0, 0x84(%rbx)
sete %dl
decl 0x6c(%rcx,%rdx,4)
movslq 0x84(%rbx), %rdx
incl 0x6c(%rcx,%rdx,4)
cmpl $0x1, %r13d
je 0x3f09
cmpl $0x2, %r13d
jne 0x3f69
movq 0x78(%rcx), %rdx
movq 0x80(%rcx), %rsi
subq %rdx, %rsi
je 0x3f69
sarq $0x3, %rsi
cmpq $0x1, %rsi
adcq $0x0, %rsi
xorl %r8d, %r8d
movq (%rdx,%r8,8), %rdi
cmpb $0x0, 0x7d(%rdi)
jne 0x3eff
cmpl 0x84(%rdi), %r14d
je 0x3f54
incq %r8
cmpq %r8, %rsi
jne 0x3eec
jmp 0x3f69
movq 0x78(%rcx), %rdx
cmpq %rdx, 0x80(%rcx)
je 0x3f69
xorl %r15d, %r15d
movq (%rdx,%r15,8), %rdi
cmpb $0x0, 0x7d(%rdi)
jne 0x3f34
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x412a
movq 0x98(%rbx), %rax
incq %r15
movq (%rax,%r12,8), %rcx
movq 0x78(%rcx), %rdx
movq 0x80(%rcx), %rsi
subq %rdx, %rsi
sarq $0x3, %rsi
cmpq %r15, %rsi
ja 0x3f19
jmp 0x3f69
movl $0x1, %esi
callq 0x412a
movq 0x98(%rbx), %rax
movq (%rax,%r12,8), %rcx
movq -0x30(%rbp), %rdx
movb $0x1, 0x6a(%rcx,%rdx)
movq 0xa0(%rbx), %rdx
incq %r12
movq %rdx, %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %r12, %rcx
ja 0x3dc4
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq