/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */ #include .data pinf: .long 0xFF800000 NaN: .long 0xFFC00000 temp: .long 0, 0 onethird: .long 1431655765 two54: .long 0x5A800000 a0: .float +1.87277957900533E+00 a1: .float -1.87243905326548E+00 a2: .float +1.60286399719912E+00 a3: .float -7.46198924594210E-01 a4: .float +1.42994392730009E-01 b0: .float 14. b1: .float -7. b2: .float +2. one9th: .tfloat +0.11111111111111111111 .text .globl _cbrt _cbrt: movl 8(%esp), %eax movl %eax, %ecx /* Save sign */ andl $0x7FFFFFFF, %eax /* fabs */ movl %eax, 8(%esp) cmpl $0x7FF00000, %eax /* Control flows straight through for */ jae abarg /* normal args: 0 < fabs(x) < +inf */ testl $0x7FF00000, %eax jz verysmall mull onethird addl $0x2A9F7893, %edx movl %edx, temp+4 /* First approximation good */ /* to 5.5 bits */ have55: fldl 4(%esp) fld1 fdivp /* recip */ fldl temp /* Load approximation */ /* 4rd-order minimax to 24 bits */ fld %st(0) /* x x recip */ fmul %st(1) /* x^2 x recip */ fmul %st(1) /* x^3 x recip */ fmul %st(2) /* y x recip */ fld %st(0) /* y y x recip */ fmuls a4 /* P1' y x recip */ fadds a3 /* P1 y x recip */ fmul %st(1) /* P2' y x recip */ fadds a2 /* P2 y x recip */ fmul %st(1) /* P3' y x recip */ fadds a1 /* P3 y x recip */ fmulp /* P4' x recip */ fadds a0 /* P4 x recip */ fmulp /* x' recip */ /* 2nd-order Taylor to 64 bits */ fld %st(0) /* x x recip */ fmul %st(1) /* x^2 x recip */ fmul %st(1) /* x^3 x recip */ fmul %st(2) /* y x recip */ ffree %st(2) /* y x */ fld %st(0) /* y y x */ fmuls b2 fadds b1 fmulp /* ccc x */ fadds b0 /* P(y) x */ fmulp /* x'' */ fldt one9th fmulp cleanup: /* Restore sign */ testl %ecx, %ecx jns end fchs end: ret verysmall: /* Exponent is 0 */ movl 8(%esp), %eax testl %eax, %eax jnz denormal movl 4(%esp), %eax testl %eax, %eax jz special /* x = 0 */ denormal: fldl 4(%esp) fmuls two54 /* Multiply by 2^54 to normalize */ fstpl temp movl temp+4, %eax mull onethird addl $0x297F7893, %edx /* Undo 2^54 multiplier */ movl %edx, temp+4 /* First approximation to 5.5 bits */ movl $0, temp jmp have55 abarg: /* x = inf, or NaN */ testl $0x000FFFFF, %eax jnz badarg movl 4(%esp), %eax testl %eax, %eax jz special badarg: /* arg is negative or NaN */ movl $1, _errno flds NaN ret special: fldl 4(%esp) /* x = 0 or inf: just load x */ jmp cleanup