// File: /workspace/github_cpp_makefile_star2_O1/dcarrey[P]hgt-detection/./fonctions.cpp
// Function: findBestHGT_nombreLimite(DescTree*, DescTree*, int*, int, InputTree, InputTree, Parameters, HGT*)
int findBestHGT_nombreLimite(struct DescTree *DTSpecies,struct DescTree *DTGene,int * tab_branches,int nb_branches,struct InputTree SpeciesTree,struct InputTree GeneTree,struct Parameters param,struct HGT *aHGT){

	struct InputTree tmpTree;
	int i,j,k,l,first=1,ret=0;
	int size = SpeciesTree.size;
	int ktSpecies;
	struct CRITERIA aCrit,aCritRef;
	
	initInputTree(&tmpTree);

	//printf("\ndebut findBestHgt");
	//== compute criteria
	InitCriteria(&aCrit,size);
	InitCriteria(&aCritRef,size);
	computeCriteria(SpeciesTree.ADD,GeneTree.ADD,size,&aCrit,SpeciesTree.LONGUEUR,SpeciesTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
	computeCriteria(SpeciesTree.ADD,GeneTree.ADD,size,&aCritRef,SpeciesTree.LONGUEUR,SpeciesTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
	loadCriteria(aCrit,aHGT);

	/*DTGene = (struct DescTree*)malloc((2*GeneTree.size-2-GeneTree.kt+1)*sizeof(struct DescTree));
	RechercherBipartition(GeneTree.ARETE,GeneTree.ADD,GeneTree.Root,GeneTree.Adjacence,DTGene,GeneTree.size,GeneTree.kt);	

	DTSpecies = (struct DescTree*)malloc((2*SpeciesTree.size-2-SpeciesTree.kt+1)*sizeof(struct DescTree));
	RechercherBipartition(SpeciesTree.ARETE,SpeciesTree.ADD,SpeciesTree.Root,SpeciesTree.Adjacence,DTSpecies,SpeciesTree.size,SpeciesTree.kt);*/
	//printf("\nRF = %d , LS = %lf , BD = %lf , QD = %d",aCrit.RF,aCrit.LS,aCrit.BD,aCrit.QD);

	/*for(i=1;i<=2*SpeciesTree.size-3-SpeciesTree.kt;i++)
		printf("\n%d-%d -->%lf",SpeciesTree.ARETE[2*i-1],SpeciesTree.ARETE[2*i-2],SpeciesTree.LONGUEUR[i-1]);
	printf("\n");*/

	//== Test all possible HGT
	for(i=1;i<=nb_branches;i++){
		for(j=1;j<=nb_branches;j++){
			if(isAValidHGT(SpeciesTree,tab_branches[i],tab_branches[j])==1 && i!=j ){
				//printf("\n%d-%d -->%d--%d",SpeciesTree.ARETE[2*tab_branches[i]-1],SpeciesTree.ARETE[2*tab_branches[i]-2],SpeciesTree.ARETE[2*tab_branches[j]-1],SpeciesTree.ARETE[2*tab_branches[j]-2]);
			
				copyInputTree(&tmpTree,SpeciesTree,0,0);

				if(strcmp(param.subtree,"yes") == 0)
					if(TestSubTreeConstraint(SpeciesTree,tab_branches[i],tab_branches[j],DTSpecies,DTGene) == 0) {
						continue;
						//FreeMemory_InputTree(&tmpTree);
						tmpTree.ADD = NULL;
						tmpTree.ARETE = NULL;
						
					}

				applyHGT(GeneTree.ADD,&tmpTree,tab_branches[i],tab_branches[j]);
				AdjustBranchLength(&tmpTree,GeneTree,0,1);
	
				computeCriteria(tmpTree.ADD,GeneTree.ADD,size,&aCrit,tmpTree.LONGUEUR,tmpTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);

				ret += TestCriterionAndUpdate(&first,param.criterion,aCrit,aHGT,tab_branches[i],tab_branches[j],0,0);
				if(aHGT->crit.RF == 0 /*|| aHGT->crit.LS < epsilon */|| aHGT->crit.BD == 0 || aHGT->crit.QD == 0) { i=j=(int)INFINI;}

			}
		}
		
	}
	/*if(ret > 0 )
		findListSpecies(aHGT,DTSpecies,SpeciesTree);*/
	
/*	deleteBipartition(DTSpecies,SpeciesTree);
	deleteBipartition(DTGene,GeneTree);*/
	FreeCriteria(&aCrit,size);
	FreeCriteria(&aCritRef,size);
	FreeMemory_InputTree(&tmpTree,tmpTree.size);

	//printf("\nfin findBestHgt");
	return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1c8, %rsp            # imm = 0x1C8
movq %r8, %rbx
movl %ecx, -0x2c(%rbp)
movq %rdx, %r13
movq %rsi, -0x58(%rbp)
movq %rdi, -0x50(%rbp)
movl $0x1, %eax
movl %eax, -0x44(%rbp)
movl 0x10(%rbp), %r15d
xorl %eax, %eax
movq %rax, -0xc0(%rbp)
xorps %xmm0, %xmm0
movups %xmm0, -0xa0(%rbp)
movq $0x0, -0x38(%rbp)
movq %rax, -0x90(%rbp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0xa8(%rbp)
movl %eax, -0xc8(%rbp)
movl $0x0, -0x80(%rbp)
movups %xmm0, -0xb8(%rbp)
leaq -0x128(%rbp), %rdi
movl %r15d, %esi
callq 0xb933
leaq -0x188(%rbp), %rdi
movl %r15d, %esi
callq 0xb933
movq 0x18(%rbp), %r14
movq 0x70(%rbp), %r12
movq %r14, %rdi
movq %r12, %rsi
movl %r15d, %edx
leaq -0x128(%rbp), %rcx
callq 0x8d82
movq %r14, %rdi
movq %r12, -0x68(%rbp)
movq %r12, %rsi
movl %r15d, -0x30(%rbp)
movl %r15d, %edx
leaq -0x188(%rbp), %rcx
callq 0x8d82
movl $0x1, %ecx
leaq -0x128(%rbp), %rax
movsd (%rax), %xmm0
movsd 0x10(%rax), %xmm1
movq 0x30(%rax), %rax
movsd %xmm0, 0x20(%rbx)
movq %rax, 0x50(%rbx)
movsd %xmm1, 0x30(%rbx)
movq %rbx, -0x70(%rbp)
movl %ecx, (%rbx)
cmpl $0x0, -0x2c(%rbp)
jle 0xc5ab
leaq 0xc0(%rbp), %rax
leaq 0x10(%rbp), %rbx
addq $0x3fc, %rax            # imm = 0x3FC
movq %rax, -0x60(%rbp)
movq $0x0, -0x38(%rbp)
movl $0x1, %r14d
movq %rcx, -0x40(%rbp)
movslq %ecx, %r15
movl (%r13,%r15,4), %eax
movslq %r14d, %r12
movl (%r13,%r12,4), %edx
movl $0xb, %ecx
movq %rsp, %rdi
movq %rbx, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %eax, %edi
movl %edx, %esi
callq 0xa4c5
testl %eax, %eax
sete %al
cmpl %r12d, %r15d
sete %cl
orb %al, %cl
jne 0xc582
movl $0xb, %ecx
movq %rsp, %rdi
movq %rbx, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0xc8(%rbp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xa621
leaq 0xc0(%rbp), %rax
cmpl $0x736579, 0xe9e(%rax)  # imm = 0x736579
jne 0xc4bd
movl (%r13,%r15,4), %eax
movl (%r13,%r12,4), %edx
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x10(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %eax, %edi
movl %edx, %esi
movq -0x50(%rbp), %rdx
movq -0x58(%rbp), %rcx
callq 0x8016
testl %eax, %eax
je 0xc57e
movl (%r13,%r15,4), %edx
movl (%r13,%r12,4), %ecx
movq %rbx, %rsi
callq 0x8e8a
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x68(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0xb80c
movq -0xc0(%rbp), %rdi
movq -0x68(%rbp), %rsi
movl -0x30(%rbp), %edx
leaq -0x128(%rbp), %rbx
movq %rbx, %rcx
callq 0x8d82
movl (%r13,%r15,4), %eax
movl (%r13,%r12,4), %r8d
movl $0xc, %ecx
movq %rsp, %rdi
movq %rbx, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl $0x0, 0x60(%rsp)
leaq -0x44(%rbp), %rdi
movq -0x60(%rbp), %rsi
movq -0x70(%rbp), %r15
movq %r15, %rdx
movl %eax, %ecx
xorl %r9d, %r9d
callq 0xa331
movq -0x38(%rbp), %rcx
addl %eax, %ecx
movq %rcx, -0x38(%rbp)
cmpl $0x0, 0x50(%r15)
je 0xc566
movsd 0x30(%r15), %xmm0
ucomisd 0x8b0e(%rip), %xmm0     # 0x15070
jne 0xc577
jp 0xc577
movl $0xf423f, %r14d         # imm = 0xF423F
movl $0xf423f, %ecx          # imm = 0xF423F
leaq 0x10(%rbp), %rbx
jmp 0xc586
cmpl $0x0, 0x54(%r15)
je 0xc566
leaq 0x10(%rbp), %rbx
movq -0x40(%rbp), %rcx
leal 0x1(%r14), %eax
cmpl -0x2c(%rbp), %r14d
movl %eax, %r14d
jl 0xc419
leal 0x1(%rcx), %eax
movl $0x1, %r14d
cmpl -0x2c(%rbp), %ecx
movl %eax, %ecx
jl 0xc419
leaq -0x128(%rbp), %rdi
movl -0x30(%rbp), %ebx
movl %ebx, %esi
callq 0xb9fb
leaq -0x188(%rbp), %rdi
movl %ebx, %esi
callq 0xb9fb
leaq -0xc8(%rbp), %rdi
movl (%rdi), %esi
callq 0xb0f6
movq -0x38(%rbp), %rax
addq $0x1c8, %rsp            # imm = 0x1C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq