// File: tomfunkhouser[P]gaps/pkgs/fglut/freeglut_geometry.c
// Function: glutSolidSphere
void FGAPIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
{
    int i,j;

    /* Adjust z and radius as stacks are drawn. */

    double z0,z1;
    double r0,r1;

    /* Pre-computed circle */

    double *sint1,*cost1;
    double *sint2,*cost2;

    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidSphere" );

    fghCircleTable(&sint1,&cost1,-slices);
    fghCircleTable(&sint2,&cost2,stacks*2);

    /* The top stack is covered with a triangle fan */

    z0 = 1.0;
    z1 = cost2[(stacks>0)?1:0];
    r0 = 0.0;
    r1 = sint2[(stacks>0)?1:0];

    glBegin(GL_TRIANGLE_FAN);

        glNormal3d(0,0,1);
        glVertex3d(0,0,radius);

        for (j=slices; j>=0; j--)
        {
            glNormal3d(cost1[j]*r1,        sint1[j]*r1,        z1       );
            glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius);
        }

    glEnd();

    /* Cover each stack with a quad strip, except the top and bottom stacks */

    for( i=1; i<stacks-1; i++ )
    {
        z0 = z1; z1 = cost2[i+1];
        r0 = r1; r1 = sint2[i+1];

        glBegin(GL_QUAD_STRIP);

            for(j=0; j<=slices; j++)
            {
                glNormal3d(cost1[j]*r1,        sint1[j]*r1,        z1       );
                glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius);
                glNormal3d(cost1[j]*r0,        sint1[j]*r0,        z0       );
                glVertex3d(cost1[j]*r0*radius, sint1[j]*r0*radius, z0*radius);
            }

        glEnd();
    }

    /* The bottom stack is covered with a triangle fan */

    z0 = z1;
    r0 = r1;

    glBegin(GL_TRIANGLE_FAN);

        glNormal3d(0,0,-1);
        glVertex3d(0,0,-radius);

        for (j=0; j<=slices; j++)
        {
            glNormal3d(cost1[j]*r0,        sint1[j]*r0,        z0       );
            glVertex3d(cost1[j]*r0*radius, sint1[j]*r0*radius, z0*radius);
        }

    glEnd();

    /* Release sin and cos tables */

    free(sint1);
    free(cost1);
    free(sint2);
    free(cost2);
}

// Assembly:
subq $0x58, %rsp
movsd %xmm0, 0x50(%rsp)
movl %edi, 0x4c(%rsp)
movl %esi, 0x48(%rsp)
leaq 0x725c7(%rip), %rax     # 0x1fa390
cmpb $0x0, 0x1c(%rax)
jne 0x187de4
leaq 0x15afc(%rip), %rdi     # 0x19d8d2
leaq 0x273cc(%rip), %rsi     # 0x1af1a9
movb $0x0, %al
callq 0x17de70
xorl %edx, %edx
subl 0x4c(%rsp), %edx
leaq 0x18(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x188210
movl 0x48(%rsp), %edx
shll %edx
leaq 0x8(%rsp), %rdi
movq %rsp, %rsi
callq 0x188210
movsd 0x61fc(%rip), %xmm0     # 0x18e010
movsd %xmm0, 0x38(%rsp)
movq (%rsp), %rax
movl 0x48(%rsp), %esi
xorl %ecx, %ecx
movl $0x1, %edx
cmpl $0x0, %esi
cmovgl %edx, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x30(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x28(%rsp)
movq 0x8(%rsp), %rax
movl 0x48(%rsp), %esi
xorl %ecx, %ecx
movl $0x1, %edx
cmpl $0x0, %esi
cmovgl %edx, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x20(%rsp)
movl $0x6, %edi
callq 0x221b0
xorps %xmm1, %xmm1
movsd 0x6191(%rip), %xmm2     # 0x18e010
movaps %xmm1, %xmm0
callq 0x22330
movsd 0x50(%rsp), %xmm2
xorps %xmm1, %xmm1
movaps %xmm1, %xmm0
callq 0x23020
movl 0x4c(%rsp), %eax
movl %eax, 0x40(%rsp)
cmpl $0x0, 0x40(%rsp)
jl 0x187f37
movq 0x10(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x20(%rsp), %xmm0
movq 0x18(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x20(%rsp), %xmm1
movsd 0x30(%rsp), %xmm2
callq 0x22330
movq 0x10(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x20(%rsp), %xmm0
mulsd 0x50(%rsp), %xmm0
movq 0x18(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x20(%rsp), %xmm1
mulsd 0x50(%rsp), %xmm1
movsd 0x30(%rsp), %xmm2
mulsd 0x50(%rsp), %xmm2
callq 0x23020
movl 0x40(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x40(%rsp)
jmp 0x187ea0
callq 0x22de0
movl $0x1, 0x44(%rsp)
movl 0x44(%rsp), %eax
movl 0x48(%rsp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x1880df
movsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x38(%rsp)
movq (%rsp), %rax
movl 0x44(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x30(%rsp)
movsd 0x20(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
movq 0x8(%rsp), %rax
movl 0x44(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x20(%rsp)
movl $0x8, %edi
callq 0x221b0
movl $0x0, 0x40(%rsp)
movl 0x40(%rsp), %eax
cmpl 0x4c(%rsp), %eax
jg 0x1880ca
movq 0x10(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x20(%rsp), %xmm0
movq 0x18(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x20(%rsp), %xmm1
movsd 0x30(%rsp), %xmm2
callq 0x22330
movq 0x10(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x20(%rsp), %xmm0
mulsd 0x50(%rsp), %xmm0
movq 0x18(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x20(%rsp), %xmm1
mulsd 0x50(%rsp), %xmm1
movsd 0x30(%rsp), %xmm2
mulsd 0x50(%rsp), %xmm2
callq 0x23020
movq 0x10(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x28(%rsp), %xmm0
movq 0x18(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x28(%rsp), %xmm1
movsd 0x38(%rsp), %xmm2
callq 0x22330
movq 0x10(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x28(%rsp), %xmm0
mulsd 0x50(%rsp), %xmm0
movq 0x18(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x28(%rsp), %xmm1
mulsd 0x50(%rsp), %xmm1
movsd 0x38(%rsp), %xmm2
mulsd 0x50(%rsp), %xmm2
callq 0x23020
movl 0x40(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x40(%rsp)
jmp 0x187fb4
callq 0x22de0
movl 0x44(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44(%rsp)
jmp 0x187f44
movsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x38(%rsp)
movsd 0x20(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
movl $0x6, %edi
callq 0x221b0
xorps %xmm1, %xmm1
movsd 0x64a4(%rip), %xmm2     # 0x18e5b0
movaps %xmm1, %xmm0
callq 0x22330
movsd 0x50(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm2
xorps %xmm1, %xmm1
movaps %xmm1, %xmm0
callq 0x23020
movl $0x0, 0x40(%rsp)
movl 0x40(%rsp), %eax
cmpl 0x4c(%rsp), %eax
jg 0x1881de
movq 0x10(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x28(%rsp), %xmm0
movq 0x18(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x28(%rsp), %xmm1
movsd 0x38(%rsp), %xmm2
callq 0x22330
movq 0x10(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x28(%rsp), %xmm0
mulsd 0x50(%rsp), %xmm0
movq 0x18(%rsp), %rax
movslq 0x40(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x28(%rsp), %xmm1
mulsd 0x50(%rsp), %xmm1
movsd 0x38(%rsp), %xmm2
mulsd 0x50(%rsp), %xmm2
callq 0x23020
movl 0x40(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x40(%rsp)
jmp 0x188144
callq 0x22de0
movq 0x18(%rsp), %rdi
callq 0x22c30
movq 0x10(%rsp), %rdi
callq 0x22c30
movq 0x8(%rsp), %rdi
callq 0x22c30
movq (%rsp), %rdi
callq 0x22c30
addq $0x58, %rsp
retq
nop