home *** CD-ROM | disk | FTP | other *** search
- *
- * $VER: acos.s 33.1 (22.1.97)
- *
- * Calculates the arccosine of the source
- *
- * Version history:
- *
- * 33.1 22.1.97 (c) Motorola
- *
- * - snipped from M68060SP sources
- *
-
- machine 68040
- fpu 1
-
- XDEF _acos
- XDEF @acos
-
- XREF @atan
-
- *************************************************************************
- * acos(): computes the inverse cosine of a normalized input *
- * *
- * INPUT *************************************************************** *
- * fp0 = extended precision input *
- * *
- * OUTPUT ************************************************************** *
- * fp0 = arccos(X) *
- * *
- * ACCURACY and MONOTONICITY ******************************************* *
- * The returned result is within 3 ulps in 64 significant bit, *
- * i.e. within 0.5001 ulp to 53 bits if the result is subsequently *
- * rounded to double precision. The result is provably monotonic *
- * in double precision. *
- * *
- * ALGORITHM *********************************************************** *
- * *
- * ACOS *
- * 1. If |X| >= 1, go to 3. *
- * *
- * 2. (|X| < 1) Calculate acos(X) by *
- * z := (1-X) / (1+X) *
- * acos(X) = 2 * atan( sqrt(z) ). *
- * Exit. *
- * *
- * 3. If |X| > 1, go to 5. *
- * *
- * 4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit. *
- * *
- * 5. (|X| > 1) Generate an invalid operation by 0 * infinity. *
- * Exit. *
- * *
- *************************************************************************
-
- PI dc.l $40000000,$C90FDAA2,$2168C235,$00000000
-
- _acos
- fmove.d (4,sp),fp0
- @acos
- fmove.x fp0,-(sp)
- move.l (sp),d1 ; pack exp w/ upper 16 fraction
- move.w (4,sp),d1
- and.l #$7FFFFFFF,d1
- cmp.l #$3FFF8000,d1
- bge.b .ACOSBIG
-
- ;--THIS IS THE USUAL CASE, |X| < 1
- ;--ACOS(X) = 2 * ATAN( SQRT( (1-X)/(1+X) ) )
-
- .ACOSMAIN
- lea (12,sp),sp
- fmove.s #$3F800000,fp1
- fadd.x fp0,fp1 ; 1+X
- fneg.x fp0 ; -X
- fadd.s #$3F800000,fp0 ; 1-X
- fdiv.x fp1,fp0 ; (1-X)/(1+X)
- fsqrt.x fp0 ; SQRT((1-X)/(1+X))
- jsr @atan ; ATAN(SQRT([1-X]/[1+X]))
-
- fadd.x fp0,fp0 ; 2 * ATAN( STUFF )
- rts
-
- .ACOSBIG
- fabs.x fp0
- fcmp.s #$3f800000,fp0
- fbgt .operr
-
- ;--|X| = 1, ACOS(X) = 0 OR PI
- tst.b (sp) ; is X positive or negative?
- bpl.b .ACOSP1
-
- ;--X = -1
- ;Returns PI and inexact exception
- .ACOSM1
- fmove.x (PI,pc),fp0 ; load PI
- .operr lea (12,sp),sp
- rts
- .ACOSP1 fmove.s #0,fp0
- lea (12,sp),sp
- rts
-