diff options
| -rw-r--r-- | lib/msun/i387/e_acos.S | 18 | ||||
| -rw-r--r-- | lib/msun/i387/e_asin.S | 16 | 
2 files changed, 23 insertions, 11 deletions
diff --git a/lib/msun/i387/e_acos.S b/lib/msun/i387/e_acos.S index 84cb54273d56..774c65918967 100644 --- a/lib/msun/i387/e_acos.S +++ b/lib/msun/i387/e_acos.S @@ -37,14 +37,20 @@  RCSID("$FreeBSD$") -/* acos = atan (sqrt(1 - x^2) / x) */ +/* + * acos(x) = atan2(sqrt(1  - x^2, x). + * Actually evaluate (1 - x^2) as (1 - x) * (1 + x) to avoid loss of + * precision when |x| is nearly 1. + */  ENTRY(__ieee754_acos)  	fldl	4(%esp)			/* x */ -	fst	%st(1) -	fmul	%st(0)			/* x^2 */ -	fld1				 -	fsubp				/* 1 - x^2 */ -	fsqrt				/* sqrt (1 - x^2) */ +	fld1 +	fld	%st(0) +	fsub	%st(2)			/* 1 - x */ +	fxch	%st(1) +	fadd	%st(2)			/* 1 + x */ +	fmulp	%st(1)			/* (1 - x) * (1 + x) */ +	fsqrt  	fxch	%st(1)  	fpatan  	ret diff --git a/lib/msun/i387/e_asin.S b/lib/msun/i387/e_asin.S index 5b2a1bdaeb3f..de031cf9f4bc 100644 --- a/lib/msun/i387/e_asin.S +++ b/lib/msun/i387/e_asin.S @@ -37,13 +37,19 @@  RCSID("$FreeBSD$") -/* asin = atan (x / sqrt(1 - x^2)) */ +/* + * asin(x) = atan2(x, sqrt(1  - x^2). + * Actually evaluate (1 - x^2) as (1 - x) * (1 + x) to avoid loss of + * precision when |x| is nearly 1. + */  ENTRY(__ieee754_asin)  	fldl	4(%esp)			/* x */ -	fst	%st(1) -	fmul	%st(0)			/* x^2 */  	fld1 -	fsubp				/* 1 - x^2 */ -	fsqrt				/* sqrt (1 - x^2) */ +	fld	%st(0) +	fsub	%st(2)			/* 1 - x */ +	fxch	%st(1) +	fadd	%st(2)			/* 1 + x */ +	fmulp	%st(1)			/* (1 - x) * (1 + x) */ +	fsqrt  	fpatan  	ret  | 
