// File: /workspace/github_cpp_makefile_star2_O2/searsm8[P]FM_Partitioning/fmpart.cpp
// Function: performNextMove()
bool performNextMove()
{	
	if(gain_bucket[0].size() == 0 && gain_bucket[1].size() == 0) //if no more cell in gain bucket, end the pass
		return false;
		
	CELL* base_cell;	
	multimap <int, CELL*>::iterator itr [2]; //iterator for the gain buckets	
	
	if(gain_bucket[0].size() != 0)
		itr[0] = --gain_bucket[0].end(); //pointer to highest gain cell in partition 0
	if(gain_bucket[1].size() != 0)
		itr[1] = --gain_bucket[1].end();
		
	int from_partition;
			
	//if there is nothing left in one of the gain_buckets, use the other bucket
	if(gain_bucket[0].size() == 0) //if no cells in bucket 0
		from_partition = 1;
	else if(gain_bucket[1].size() == 0) //if no cells in bucket 1
		from_partition = 0;
	else from_partition = base_partition;
	
	base_partition = !base_partition; //pick from alternating partitions to make large nets dead faster		
	
	base_cell = itr[from_partition]->second; //pick the highest gain cell as default 

//if the highest gain cell would cause imbalance, pick another cell that doesn't imbalance
if(!cellCanMove(base_cell))
{
	printf("Cannot move %s (Partition: %d, Area: %d) due to imbalance.\tP0 Area: %d\tP1 Area: %d\n", base_cell->name, base_cell->partition, base_cell->area, partition_area[0], partition_area[1]);
		//pick the highest gain cell from the other partition
		from_partition = !from_partition;
		base_cell = itr[from_partition]->second;
		
		if(!cellCanMove(base_cell)) //if the highest gain cell in BOTH partitions would cause an imbalance, no legal moves. End the pass
		{
			printf("Cannot move %s (Partition: %d, Area: %d) due to imbalance.\tP0 Area: %d\tP1 Area: %d\n", base_cell->name, base_cell->partition, base_cell->area, partition_area[0], partition_area[1]);
			printf("No legal moves remain. Both would cause imbalance!\n");
			printf("gain_bucket[0].size() = %d\t gain_bucket[1].size() = %d\n", gain_bucket[0].size(), gain_bucket[1].size());
			return false;
		}
}

	(*base_cell).changePartition();
	
	//return true indicating a successful move
	return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
subq $0x10, %rsp
movq 0x5052(%rip), %rbx      # 0x81d8
movq 0x507b(%rip), %r14      # 0x8208
movq %rbx, %rax
orq %r14, %rax
jne 0x319d
xorl %r14d, %r14d
jmp 0x32b1
xorps %xmm0, %xmm0
movaps %xmm0, -0x20(%rbp)
testq %rbx, %rbx
je 0x31b9
leaq 0x5008(%rip), %rdi      # 0x81b8
callq 0x21a0
movq %rax, -0x20(%rbp)
testq %r14, %r14
je 0x31ce
leaq 0x5023(%rip), %rdi      # 0x81e8
callq 0x21a0
movq %rax, -0x18(%rbp)
xorl %eax, %eax
testq %r14, %r14
movl 0x50af(%rip), %ecx      # 0x8288
cmovnel %ecx, %eax
testq %rbx, %rbx
pushq $0x1
popq %r14
cmovnel %eax, %r14d
xorl %eax, %eax
testl %ecx, %ecx
sete %al
movl %eax, 0x5094(%rip)      # 0x8288
movslq %r14d, %rax
movq -0x20(%rbp,%rax,8), %rax
movq 0x28(%rax), %rbx
movq %rbx, %rdi
callq 0x3321
testb %al, %al
jne 0x3251
movl 0x78(%rbx), %ecx
movl 0x84(%rbx), %edx
movl 0x5040(%rip), %r8d      # 0x825c
movl 0x503d(%rip), %r9d      # 0x8260
leaq 0x1f57(%rip), %rdi      # 0x5181
movq %rbx, %rsi
xorl %eax, %eax
callq 0x2040
xorl %eax, %eax
testl %r14d, %r14d
sete %al
movq -0x20(%rbp,%rax,8), %rax
movq 0x28(%rax), %rbx
movq %rbx, %rdi
callq 0x3321
testb %al, %al
je 0x325e
movq %rbx, %rdi
callq 0x38e4
movb $0x1, %r14b
jmp 0x32b1
movl 0x78(%rbx), %ecx
movl 0x84(%rbx), %edx
movl 0x4fee(%rip), %r8d      # 0x825c
movl 0x4feb(%rip), %r9d      # 0x8260
leaq 0x1f05(%rip), %rdi      # 0x5181
xorl %r14d, %r14d
movq %rbx, %rsi
xorl %eax, %eax
callq 0x2040
leaq 0x216b(%rip), %rdi      # 0x53fb
callq 0x2210
movq 0x4f3c(%rip), %rsi      # 0x81d8
movq 0x4f65(%rip), %rdx      # 0x8208
leaq 0x1f2b(%rip), %rdi      # 0x51d5
xorl %eax, %eax
callq 0x2040
movl %r14d, %eax
addq $0x10, %rsp
popq %rbx
popq %r14
popq %rbp
retq