// File: 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
subq $0x60, %rsp
leaq 0xcfa1(%rip), %rdi      # 0x11200
callq 0x5360
cmpq $0x0, %rax
jne 0x4289
leaq 0xcf8f(%rip), %rdi      # 0x11200
addq $0x30, %rdi
callq 0x5360
cmpq $0x0, %rax
jne 0x4289
movb $0x0, -0x1(%rbp)
jmp 0x44a7
leaq -0x20(%rbp), %rax
movq %rax, %rcx
addq $0x10, %rcx
movq %rcx, -0x48(%rbp)
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
movq %rdi, -0x50(%rbp)
callq 0x5380
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
addq $0x8, %rax
cmpq %rcx, %rax
movq %rax, -0x40(%rbp)
jne 0x429c
leaq 0xcf3b(%rip), %rdi      # 0x11200
callq 0x5360
cmpq $0x0, %rax
je 0x42f0
leaq 0xcf29(%rip), %rdi      # 0x11200
callq 0x53a0
movq %rax, -0x28(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x53d0
movq (%rax), %rax
movq %rax, -0x20(%rbp)
leaq 0xcf09(%rip), %rdi      # 0x11200
addq $0x30, %rdi
callq 0x5360
cmpq $0x0, %rax
je 0x432a
leaq 0xcef3(%rip), %rdi      # 0x11200
addq $0x30, %rdi
callq 0x53a0
movq %rax, -0x30(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x53d0
movq (%rax), %rax
movq %rax, -0x18(%rbp)
leaq 0xcecf(%rip), %rdi      # 0x11200
callq 0x5360
cmpq $0x0, %rax
jne 0x4345
movl $0x1, -0x34(%rbp)
jmp 0x436f
leaq 0xceb4(%rip), %rdi      # 0x11200
addq $0x30, %rdi
callq 0x5360
cmpq $0x0, %rax
jne 0x4364
movl $0x0, -0x34(%rbp)
jmp 0x436d
movl 0xcf6e(%rip), %eax      # 0x112d8
movl %eax, -0x34(%rbp)
jmp 0x436f
cmpl $0x0, 0xcf62(%rip)      # 0x112d8
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0xcf52(%rip)      # 0x112d8
movslq -0x34(%rbp), %rax
leaq -0x20(%rbp), %rdi
shlq $0x3, %rax
addq %rax, %rdi
callq 0x5400
movq 0x8(%rax), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0x4530
testb $0x1, %al
jne 0x449a
movq -0x10(%rbp), %rsi
movq -0x10(%rbp), %rax
movl 0x84(%rax), %edx
movq -0x10(%rbp), %rax
movl 0x78(%rax), %ecx
movl 0xcedd(%rip), %r8d      # 0x112ac
movl 0xceda(%rip), %r9d      # 0x112b0
leaq 0x6dd5(%rip), %rdi      # 0xb1b2
movb $0x0, %al
callq 0x2040
cmpl $0x0, -0x34(%rbp)
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x34(%rbp)
movslq -0x34(%rbp), %rax
leaq -0x20(%rbp), %rdi
shlq $0x3, %rax
addq %rax, %rdi
callq 0x5400
movq 0x8(%rax), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0x4530
testb $0x1, %al
jne 0x4498
movq -0x10(%rbp), %rsi
movq -0x10(%rbp), %rax
movl 0x84(%rax), %edx
movq -0x10(%rbp), %rax
movl 0x78(%rax), %ecx
movl 0xce72(%rip), %r8d      # 0x112ac
movl 0xce6f(%rip), %r9d      # 0x112b0
leaq 0x6d6a(%rip), %rdi      # 0xb1b2
movb $0x0, %al
callq 0x2040
leaq 0x6db0(%rip), %rdi      # 0xb206
movb $0x0, %al
callq 0x2040
leaq 0xcd9c(%rip), %rdi      # 0x11200
callq 0x5360
movq %rax, -0x58(%rbp)
leaq 0xcd8c(%rip), %rdi      # 0x11200
addq $0x30, %rdi
callq 0x5360
movq -0x58(%rbp), %rsi
movq %rax, %rdx
leaq 0x6daf(%rip), %rdi      # 0xb23a
movb $0x0, %al
callq 0x2040
movb $0x0, -0x1(%rbp)
jmp 0x44a7
jmp 0x449a
movq -0x10(%rbp), %rdi
callq 0x5420
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)