// File: /workspace/github_cpp_makefile_star2_O3/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 0x4c6d(%rip), %rbx      # 0x81c8
movq 0x4c96(%rip), %r14      # 0x81f8
movq %rbx, %rax
orq %r14, %rax
jne 0x3572
xorl %r14d, %r14d
jmp 0x3688
xorps %xmm0, %xmm0
movaps %xmm0, -0x20(%rbp)
testq %rbx, %rbx
je 0x358e
leaq 0x4c23(%rip), %rdi      # 0x81a8
callq 0x2190
movq %rax, -0x20(%rbp)
testq %r14, %r14
je 0x35a3
leaq 0x4c3e(%rip), %rdi      # 0x81d8
callq 0x2190
movq %rax, -0x18(%rbp)
xorl %eax, %eax
testq %r14, %r14
movl 0x4cca(%rip), %ecx      # 0x8278
cmovnel %ecx, %eax
testq %rbx, %rbx
movl $0x1, %r14d
cmovnel %eax, %r14d
xorl %eax, %eax
testl %ecx, %ecx
sete %al
movl %eax, 0x4cad(%rip)      # 0x8278
movslq %r14d, %rax
movq -0x20(%rbp,%rax,8), %rax
movq 0x28(%rax), %rbx
movq %rbx, %rdi
callq 0x36f8
testb %al, %al
jne 0x3628
movl 0x78(%rbx), %ecx
movl 0x84(%rbx), %edx
movl 0x4c59(%rip), %r8d      # 0x824c
movl 0x4c56(%rip), %r9d      # 0x8250
leaq 0x1b80(%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 0x36f8
testb %al, %al
je 0x3635
movq %rbx, %rdi
callq 0x3d2e
movb $0x1, %r14b
jmp 0x3688
movl 0x78(%rbx), %ecx
movl 0x84(%rbx), %edx
movl 0x4c07(%rip), %r8d      # 0x824c
movl 0x4c04(%rip), %r9d      # 0x8250
leaq 0x1b2e(%rip), %rdi      # 0x5181
xorl %r14d, %r14d
movq %rbx, %rsi
xorl %eax, %eax
callq 0x2040
leaq 0x1d94(%rip), %rdi      # 0x53fb
callq 0x21f0
movq 0x4b55(%rip), %rsi      # 0x81c8
movq 0x4b7e(%rip), %rdx      # 0x81f8
leaq 0x1b54(%rip), %rdi      # 0x51d5
xorl %eax, %eax
callq 0x2040
movl %r14d, %eax
addq $0x10, %rsp
popq %rbx
popq %r14
popq %rbp
retq