// File: /workspace/github_c_makefile_star2_O0/archer1357[P]Offline-Raytracer/kdtree.c
// Function: findSplitPlane
bool findSplitPlane(const struct BoundingBox *bounds,
                    const unsigned int *primInds,int primsNum,
                    const float *minBound,const float *maxBound,
                    float emptyBonus,float traversalCost,float isectCost,
                    int *badRefines,
                    int *axisOut,float *splitOut,
                    unsigned int **leftInds,int *leftIndsNum,
                    unsigned int **rightInds,int *rightIndsNum) {

  int bestAxis,bestOffset,axis,retries,i;
  float bestCost,oldCost,totalSa,invTotalSa;
  struct BoundingEdge *edges[3];

  bestAxis=-1;
  bestOffset=-1;
  bestCost=INFINITY;
  oldCost=isectCost*(float)primsNum;

  totalSa=calcBoundingBoxSa(minBound,maxBound);
  invTotalSa=1.0f/totalSa;
  axis=calcBoundingBoxMaximumExtent(minBound,maxBound);

  edges[0]=0;
  edges[1]=0;
  edges[2]=0;

  for(retries=0;retries<3;retries++) {
    int nBelow,nAbove;

    //
    edges[axis]=(struct BoundingEdge*)
      malloc(sizeof(struct BoundingEdge)*primsNum*2);

    //
    for(i=0;i<primsNum;i++) {
      int v;
      v=primInds[i];

      edges[axis][2*i].type=0;
      edges[axis][2*i].val=bounds[v].start[axis];
      edges[axis][2*i].primInd=v;

      edges[axis][2*i+1].type=1;
      edges[axis][2*i+1].val=bounds[v].end[axis];
      edges[axis][2*i+1].primInd=v;
    }

    qsort(edges[axis],primsNum*2,
          sizeof(struct BoundingEdge),
          boundingEdgeCompare);

    //
    nBelow=0;
    nAbove=primsNum;


    //
    for(i=0;i<2*primsNum;i++) {
      float edget,cost;

      if(edges[axis][i].type==1) {
        nAbove--;
      }

      edget=edges[axis][i].val;

      if(calcSaCost(axis,edget,nAbove,nBelow,
                    invTotalSa,minBound,maxBound,
                    emptyBonus,traversalCost,isectCost,
                    &cost)) {
        // printf("cost %g\n",(double)cost);
        //update best split if lowest score so far
        if(cost < bestCost) {
          bestCost=cost;
          bestAxis=axis;
          bestOffset=i;
        }
      }

      if(edges[axis][i].type==0) {
        nBelow++;
      }
    }

    //
    if(bestAxis == -1 && retries < 2) {
      axis = (axis+1) % 3;
      continue;
    }

    if(bestCost > oldCost) {
      ++(*badRefines);
    }
    // printf("br %i\n",*badRefines);
    if((bestCost>(4.0f*oldCost) && primsNum<16) ||
       bestAxis == -1
       // || (*badRefines) == 3
       ) {
      free(edges[0]);
      free(edges[1]);
      free(edges[2]);
      return false;
    }

    break;
  }

  *axisOut=bestAxis;
  *splitOut=edges[bestAxis][bestOffset].val;

  *leftInds=0;
  *rightInds=0;
  *leftIndsNum=0;
  *rightIndsNum=0;

  for(i=0;i<bestOffset;i++) {
    if(edges[bestAxis][i].type==0) {
      (*leftIndsNum)++;
    }
  }

  for(i=bestOffset+1;i<2*primsNum;i++) {
    if(edges[bestAxis][i].type==1) {
      (*rightIndsNum)++;
    }
  }

  if(*leftIndsNum != 0) {
    *leftInds=(unsigned int*)malloc(sizeof(int)*(*leftIndsNum));
  }

  if(*rightIndsNum != 0) {
    *rightInds=(unsigned int*)malloc(sizeof(int)*(*rightIndsNum));
  }

  int n0,n1;
  n0=0;
  n1=0;

  for(i=0;i<bestOffset;i++) {
    if(edges[bestAxis][i].type==0) {
      (*leftInds)[n0++]=edges[bestAxis][i].primInd;
    }
  }

  for(i=bestOffset+1;i<2*primsNum;i++) {
    if(edges[bestAxis][i].type==1) {
      (*rightInds)[n1++]=edges[bestAxis][i].primInd;
    }
  }

  free(edges[0]);
  free(edges[1]);
  free(edges[2]);
  return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq 0x38(%rbp), %rax
movq 0x30(%rbp), %rax
movq 0x28(%rbp), %rax
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movss %xmm0, -0x34(%rbp)
movss %xmm1, -0x38(%rbp)
movss %xmm2, -0x3c(%rbp)
movq %r9, -0x48(%rbp)
movl $0xffffffff, -0x4c(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x50(%rbp) # imm = 0xFFFFFFFF
movss 0xdac31(%rip), %xmm0    # 0x4e4910
movss %xmm0, -0x60(%rbp)
movss -0x3c(%rbp), %xmm0
cvtsi2ssl -0x1c(%rbp), %xmm1
mulss %xmm1, %xmm0
movss %xmm0, -0x64(%rbp)
movq -0x28(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x409940
movss %xmm0, -0x68(%rbp)
movss 0xd9773(%rip), %xmm0    # 0x4e3484
divss -0x68(%rbp), %xmm0
movss %xmm0, -0x6c(%rbp)
movq -0x28(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x4099d0
movl %eax, -0x54(%rbp)
movq $0x0, -0x90(%rbp)
movq $0x0, -0x88(%rbp)
movq $0x0, -0x80(%rbp)
movl $0x0, -0x58(%rbp)
cmpl $0x3, -0x58(%rbp)
jge 0x40a092
movslq -0x1c(%rbp), %rax
imulq $0xc, %rax, %rdi
shlq %rdi
callq 0x452d20
movq %rax, %rcx
movslq -0x54(%rbp), %rax
movq %rcx, -0x90(%rbp,%rax,8)
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x409eb5
movq -0x18(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x9c(%rbp)
movslq -0x54(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movl -0x5c(%rbp), %ecx
shll %ecx
movslq %ecx, %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl $0x0, (%rax)
movq -0x10(%rbp), %rax
movslq -0x9c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movslq -0x54(%rbp), %rcx
movss (%rax,%rcx,4), %xmm0
movslq -0x54(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movl -0x5c(%rbp), %ecx
shll %ecx
movslq %ecx, %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss %xmm0, 0x4(%rax)
movl -0x9c(%rbp), %ecx
movslq -0x54(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movl -0x5c(%rbp), %edx
shll %edx
movslq %edx, %rdx
imulq $0xc, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x8(%rax)
movslq -0x54(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movl -0x5c(%rbp), %ecx
shll %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl $0x1, (%rax)
movq -0x10(%rbp), %rax
movslq -0x9c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movslq -0x54(%rbp), %rcx
movss 0xc(%rax,%rcx,4), %xmm0
movslq -0x54(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movl -0x5c(%rbp), %ecx
shll %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss %xmm0, 0x4(%rax)
movl -0x9c(%rbp), %ecx
movslq -0x54(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movl -0x5c(%rbp), %edx
shll %edx
addl $0x1, %edx
movslq %edx, %rdx
imulq $0xc, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x8(%rax)
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x409d80
movslq -0x54(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rdi
movl -0x1c(%rbp), %eax
shll %eax
movslq %eax, %rsi
movl $0xc, %edx
leaq -0x615(%rip), %rcx      # 0x4098c0
callq 0x4343b0
movl $0x0, -0x94(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x98(%rbp)
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
movl -0x1c(%rbp), %ecx
shll %ecx
cmpl %ecx, %eax
jge 0x40a000
movslq -0x54(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movslq -0x5c(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
cmpl $0x1, (%rax)
jne 0x409f2f
movl -0x98(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x98(%rbp)
movslq -0x54(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movslq -0x5c(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss 0x4(%rax), %xmm0
movss %xmm0, -0xa0(%rbp)
movl -0x54(%rbp), %edi
movss -0xa0(%rbp), %xmm0
movl -0x98(%rbp), %esi
movl -0x94(%rbp), %edx
movss -0x6c(%rbp), %xmm1
movq -0x28(%rbp), %rcx
movq -0x30(%rbp), %r8
movss -0x34(%rbp), %xmm2
movss -0x38(%rbp), %xmm3
movss -0x3c(%rbp), %xmm4
leaq -0xa4(%rbp), %r9
callq 0x409a60
testb $0x1, %al
jne 0x409f98
jmp 0x409fc5
movss -0xa4(%rbp), %xmm1
movss -0x60(%rbp), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x409fc3
movss -0xa4(%rbp), %xmm0
movss %xmm0, -0x60(%rbp)
movl -0x54(%rbp), %eax
movl %eax, -0x4c(%rbp)
movl -0x5c(%rbp), %eax
movl %eax, -0x50(%rbp)
jmp 0x409fc5
movslq -0x54(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movslq -0x5c(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
cmpl $0x0, (%rax)
jne 0x409ff0
movl -0x94(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x94(%rbp)
jmp 0x409ff2
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x409ef4
cmpl $-0x1, -0x4c(%rbp)
jne 0x40a01f
cmpl $0x2, -0x58(%rbp)
jge 0x40a01f
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %edx, -0x54(%rbp)
jmp 0x40a084
movss -0x60(%rbp), %xmm0
ucomiss -0x64(%rbp), %xmm0
jbe 0x40a035
movq -0x48(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movss -0x60(%rbp), %xmm0
movss 0xda8d2(%rip), %xmm1    # 0x4e4914
mulss -0x64(%rbp), %xmm1
ucomiss %xmm1, %xmm0
jbe 0x40a052
cmpl $0x10, -0x1c(%rbp)
jl 0x40a058
cmpl $-0x1, -0x4c(%rbp)
jne 0x40a082
movq -0x90(%rbp), %rdi
callq 0x453060
movq -0x88(%rbp), %rdi
callq 0x453060
movq -0x80(%rbp), %rdi
callq 0x453060
movb $0x0, -0x1(%rbp)
jmp 0x40a2da
jmp 0x40a092
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x409d50
movl -0x4c(%rbp), %ecx
movq 0x10(%rbp), %rax
movl %ecx, (%rax)
movslq -0x4c(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movslq -0x50(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss 0x4(%rax), %xmm0
movq 0x18(%rbp), %rax
movss %xmm0, (%rax)
movq 0x20(%rbp), %rax
movq $0x0, (%rax)
movq 0x30(%rbp), %rax
movq $0x0, (%rax)
movq 0x28(%rbp), %rax
movl $0x0, (%rax)
movq 0x38(%rbp), %rax
movl $0x0, (%rax)
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
cmpl -0x50(%rbp), %eax
jge 0x40a12c
movslq -0x4c(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movslq -0x5c(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
cmpl $0x0, (%rax)
jne 0x40a11f
movq 0x28(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x40a121
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x40a0f0
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
movl -0x1c(%rbp), %ecx
shll %ecx
cmpl %ecx, %eax
jge 0x40a175
movslq -0x4c(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movslq -0x5c(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
cmpl $0x1, (%rax)
jne 0x40a168
movq 0x38(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x40a16a
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x40a135
movq 0x28(%rbp), %rax
cmpl $0x0, (%rax)
je 0x40a198
movq 0x28(%rbp), %rax
movslq (%rax), %rdi
shlq $0x2, %rdi
callq 0x452d20
movq %rax, %rcx
movq 0x20(%rbp), %rax
movq %rcx, (%rax)
movq 0x38(%rbp), %rax
cmpl $0x0, (%rax)
je 0x40a1bb
movq 0x38(%rbp), %rax
movslq (%rax), %rdi
shlq $0x2, %rdi
callq 0x452d20
movq %rax, %rcx
movq 0x30(%rbp), %rax
movq %rcx, (%rax)
movl $0x0, -0xa8(%rbp)
movl $0x0, -0xac(%rbp)
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
cmpl -0x50(%rbp), %eax
jge 0x40a23f
movslq -0x4c(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movslq -0x5c(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
cmpl $0x0, (%rax)
jne 0x40a232
movslq -0x4c(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movslq -0x5c(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl 0x8(%rax), %edx
movq 0x20(%rbp), %rax
movq (%rax), %rax
movl -0xa8(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0xa8(%rbp)
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
jmp 0x40a234
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x40a1d6
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
movl -0x1c(%rbp), %ecx
shll %ecx
cmpl %ecx, %eax
jge 0x40a2b5
movslq -0x4c(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movslq -0x5c(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
cmpl $0x1, (%rax)
jne 0x40a2a8
movslq -0x4c(%rbp), %rax
movq -0x90(%rbp,%rax,8), %rax
movslq -0x5c(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl 0x8(%rax), %edx
movq 0x30(%rbp), %rax
movq (%rax), %rax
movl -0xac(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0xac(%rbp)
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
jmp 0x40a2aa
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x40a248
movq -0x90(%rbp), %rdi
callq 0x453060
movq -0x88(%rbp), %rdi
callq 0x453060
movq -0x80(%rbp), %rdi
callq 0x453060
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xb0, %rsp
popq %rbp
retq
nopl (%rax,%rax)