// File: FreeSlave[P]vhlt/hlbsp/solidbsp.cpp
// Function: FaceSide(face_s*, plane_t const*, double*)
static int      FaceSide(face_t* in, const dplane_t* const split
#ifdef HLBSP_AVOIDEPSILONSPLIT
						 , double *epsilonsplit = NULL
#endif
						 )
{
#ifdef HLBSP_AVOIDEPSILONSPLIT
	const vec_t		epsilonmin = 0.002, epsilonmax = 0.2;
	vec_t			d_front, d_back;
#else
    int             frontcount, backcount;
#endif
    vec_t           dot;
    int             i;
    vec_t*          p;

#ifdef HLBSP_AVOIDEPSILONSPLIT
	d_front = d_back = 0;
#else
    frontcount = backcount = 0;
#endif

    // axial planes are fast
    if (split->type <= last_axial)
    {
        vec_t           splitGtEp = split->dist + ON_EPSILON;   // Invariant moved out of loop
        vec_t           splitLtEp = split->dist - ON_EPSILON;   // Invariant moved out of loop

        for (i = 0, p = in->pts[0] + split->type; i < in->numpoints; i++, p += 3)
        {
#ifdef HLBSP_AVOIDEPSILONSPLIT
			dot = *p - split->dist;
			if (dot > d_front)
				d_front = dot;
			if (dot < d_back)
				d_back = dot;
#else
            if (*p > splitGtEp)
            {
                if (backcount)
                {
                    return SIDE_ON;
                }
                frontcount = 1;
            }
            else if (*p < splitLtEp)
            {
                if (frontcount)
                {
                    return SIDE_ON;
                }
                backcount = 1;
            }
#endif
        }
    }
    else
    {
        // sloping planes take longer
        for (i = 0, p = in->pts[0]; i < in->numpoints; i++, p += 3)
        {
            dot = DotProduct(p, split->normal);
            dot -= split->dist;
#ifdef HLBSP_AVOIDEPSILONSPLIT
			if (dot > d_front)
				d_front = dot;
			if (dot < d_back)
				d_back = dot;
#else
            if (dot > ON_EPSILON)
            {
                if (backcount)
                {
                    return SIDE_ON;
                }
                frontcount = 1;
            }
            else if (dot < -ON_EPSILON)
            {
                if (frontcount)
                {
                    return SIDE_ON;
                }
                backcount = 1;
            }
#endif
        }
    }
#ifdef HLBSP_AVOIDEPSILONSPLIT
	if (d_front <= ON_EPSILON)
	{
		if (d_front > epsilonmin || d_back > -epsilonmax)
		{
			if (epsilonsplit)
				(*epsilonsplit)++;
		}
		return SIDE_BACK;
	}
	if (d_back >= -ON_EPSILON)
	{
		if (d_back < -epsilonmin || d_front < epsilonmax)
		{
			if (epsilonsplit)
				(*epsilonsplit)++;
		}
		return SIDE_FRONT;
	}
	if (d_front < epsilonmax || d_back > -epsilonmax)
	{
		if (epsilonsplit)
			(*epsilonsplit)++;
	}
	return SIDE_ON;
#else

    if (!frontcount)
    {
        return SIDE_BACK;
    }
    if (!backcount)
    {
        return SIDE_FRONT;
    }

    return SIDE_ON;
#endif
}

// Assembly:
movq %rdi, -0x10(%rsp)
movq %rsi, -0x18(%rsp)
movq %rdx, -0x20(%rsp)
movsd 0xde31(%rip), %xmm0     # 0x3b908
movsd %xmm0, -0x28(%rsp)
movsd 0xde1b(%rip), %xmm0     # 0x3b900
movsd %xmm0, -0x30(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x40(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x38(%rsp)
movq -0x18(%rsp), %rax
cmpl $0x2, 0x38(%rax)
jg 0x2dbe7
movq -0x18(%rsp), %rax
movsd 0xbae7(%rip), %xmm0     # 0x39600
addsd 0x30(%rax), %xmm0
movsd %xmm0, -0x60(%rsp)
movq -0x18(%rsp), %rax
movsd 0x30(%rax), %xmm0
movsd 0xbaca(%rip), %xmm1     # 0x39600
subsd %xmm1, %xmm0
movsd %xmm0, -0x68(%rsp)
movl $0x0, -0x4c(%rsp)
movq -0x10(%rsp), %rax
addq $0x38, %rax
movq -0x18(%rsp), %rcx
movslq 0x38(%rcx), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x58(%rsp)
movl -0x4c(%rsp), %eax
movq -0x10(%rsp), %rcx
cmpl 0x2c(%rcx), %eax
jge 0x2dbe2
movq -0x58(%rsp), %rax
movsd (%rax), %xmm0
movq -0x18(%rsp), %rax
subsd 0x30(%rax), %xmm0
movsd %xmm0, -0x48(%rsp)
movsd -0x48(%rsp), %xmm0
ucomisd -0x38(%rsp), %xmm0
jbe 0x2dba7
movsd -0x48(%rsp), %xmm0
movsd %xmm0, -0x38(%rsp)
movsd -0x48(%rsp), %xmm1
movsd -0x40(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x2dbc5
movsd -0x48(%rsp), %xmm0
movsd %xmm0, -0x40(%rsp)
jmp 0x2dbc7
movl -0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rsp)
movq -0x58(%rsp), %rax
addq $0x18, %rax
movq %rax, -0x58(%rsp)
jmp 0x2db66
jmp 0x2dcd3
movl $0x0, -0x4c(%rsp)
movq -0x10(%rsp), %rax
addq $0x38, %rax
movq %rax, -0x58(%rsp)
movl -0x4c(%rsp), %eax
movq -0x10(%rsp), %rcx
cmpl 0x2c(%rcx), %eax
jge 0x2dcd1
movq -0x58(%rsp), %rax
movsd (%rax), %xmm1
movq -0x18(%rsp), %rax
movsd (%rax), %xmm2
movq -0x58(%rsp), %rax
movsd 0x8(%rax), %xmm0
movq -0x18(%rsp), %rax
mulsd 0x8(%rax), %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movq -0x58(%rsp), %rax
movsd 0x10(%rax), %xmm0
movq -0x18(%rsp), %rax
movsd 0x10(%rax), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x48(%rsp)
movq -0x18(%rsp), %rax
movsd 0x30(%rax), %xmm1
movsd -0x48(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, -0x48(%rsp)
movsd -0x48(%rsp), %xmm0
ucomisd -0x38(%rsp), %xmm0
jbe 0x2dc93
movsd -0x48(%rsp), %xmm0
movsd %xmm0, -0x38(%rsp)
movsd -0x48(%rsp), %xmm1
movsd -0x40(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x2dcb1
movsd -0x48(%rsp), %xmm0
movsd %xmm0, -0x40(%rsp)
jmp 0x2dcb3
movl -0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rsp)
movq -0x58(%rsp), %rax
addq $0x18, %rax
movq %rax, -0x58(%rsp)
jmp 0x2dbfd
jmp 0x2dcd3
movsd 0xb925(%rip), %xmm0     # 0x39600
ucomisd -0x38(%rsp), %xmm0
jb 0x2dd37
movsd -0x38(%rsp), %xmm0
movsd 0xdc17(%rip), %xmm1     # 0x3b908
ucomisd %xmm1, %xmm0
ja 0x2dd0b
movsd -0x40(%rsp), %xmm0
movsd 0xdc0b(%rip), %xmm1     # 0x3b910
ucomisd %xmm1, %xmm0
jbe 0x2dd2a
cmpq $0x0, -0x20(%rsp)
je 0x2dd28
movq -0x20(%rsp), %rax
movsd 0xb428(%rip), %xmm0     # 0x39148
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
jmp 0x2dd2a
movl $0x1, -0x4(%rsp)
jmp 0x2dddf
movsd -0x40(%rsp), %xmm0
movsd 0xb8d3(%rip), %xmm1     # 0x39618
ucomisd %xmm1, %xmm0
jb 0x2dd94
movsd 0xdbc5(%rip), %xmm0     # 0x3b918
ucomisd -0x40(%rsp), %xmm0
ja 0x2dd6b
movsd 0xdb9d(%rip), %xmm0     # 0x3b900
ucomisd -0x38(%rsp), %xmm0
jbe 0x2dd8a
cmpq $0x0, -0x20(%rsp)
je 0x2dd88
movq -0x20(%rsp), %rax
movsd 0xb3c8(%rip), %xmm0     # 0x39148
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
jmp 0x2dd8a
movl $0x0, -0x4(%rsp)
jmp 0x2dddf
movsd 0xdb64(%rip), %xmm0     # 0x3b900
ucomisd -0x38(%rsp), %xmm0
ja 0x2ddb8
movsd -0x40(%rsp), %xmm0
movsd 0xdb5e(%rip), %xmm1     # 0x3b910
ucomisd %xmm1, %xmm0
jbe 0x2ddd7
cmpq $0x0, -0x20(%rsp)
je 0x2ddd5
movq -0x20(%rsp), %rax
movsd 0xb37b(%rip), %xmm0     # 0x39148
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
jmp 0x2ddd7
movl $0x2, -0x4(%rsp)
movl -0x4(%rsp), %eax
retq
nopw %cs:(%rax,%rax)