162306a36Sopenharmony_ci| 262306a36Sopenharmony_ci| sacos.sa 3.3 12/19/90 362306a36Sopenharmony_ci| 462306a36Sopenharmony_ci| Description: The entry point sAcos computes the inverse cosine of 562306a36Sopenharmony_ci| an input argument; sAcosd does the same except for denormalized 662306a36Sopenharmony_ci| input. 762306a36Sopenharmony_ci| 862306a36Sopenharmony_ci| Input: Double-extended number X in location pointed to 962306a36Sopenharmony_ci| by address register a0. 1062306a36Sopenharmony_ci| 1162306a36Sopenharmony_ci| Output: The value arccos(X) returned in floating-point register Fp0. 1262306a36Sopenharmony_ci| 1362306a36Sopenharmony_ci| Accuracy and Monotonicity: The returned result is within 3 ulps in 1462306a36Sopenharmony_ci| 64 significant bit, i.e. within 0.5001 ulp to 53 bits if the 1562306a36Sopenharmony_ci| result is subsequently rounded to double precision. The 1662306a36Sopenharmony_ci| result is provably monotonic in double precision. 1762306a36Sopenharmony_ci| 1862306a36Sopenharmony_ci| Speed: The program sCOS takes approximately 310 cycles. 1962306a36Sopenharmony_ci| 2062306a36Sopenharmony_ci| Algorithm: 2162306a36Sopenharmony_ci| 2262306a36Sopenharmony_ci| ACOS 2362306a36Sopenharmony_ci| 1. If |X| >= 1, go to 3. 2462306a36Sopenharmony_ci| 2562306a36Sopenharmony_ci| 2. (|X| < 1) Calculate acos(X) by 2662306a36Sopenharmony_ci| z := (1-X) / (1+X) 2762306a36Sopenharmony_ci| acos(X) = 2 * atan( sqrt(z) ). 2862306a36Sopenharmony_ci| Exit. 2962306a36Sopenharmony_ci| 3062306a36Sopenharmony_ci| 3. If |X| > 1, go to 5. 3162306a36Sopenharmony_ci| 3262306a36Sopenharmony_ci| 4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit. 3362306a36Sopenharmony_ci| 3462306a36Sopenharmony_ci| 5. (|X| > 1) Generate an invalid operation by 0 * infinity. 3562306a36Sopenharmony_ci| Exit. 3662306a36Sopenharmony_ci| 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci| Copyright (C) Motorola, Inc. 1990 3962306a36Sopenharmony_ci| All Rights Reserved 4062306a36Sopenharmony_ci| 4162306a36Sopenharmony_ci| For details on the license for this file, please see the 4262306a36Sopenharmony_ci| file, README, in this same directory. 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci|SACOS idnt 2,1 | Motorola 040 Floating Point Software Package 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci |section 8 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ciPI: .long 0x40000000,0xC90FDAA2,0x2168C235,0x00000000 4962306a36Sopenharmony_ciPIBY2: .long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci |xref t_operr 5262306a36Sopenharmony_ci |xref t_frcinx 5362306a36Sopenharmony_ci |xref satan 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci .global sacosd 5662306a36Sopenharmony_cisacosd: 5762306a36Sopenharmony_ci|--ACOS(X) = PI/2 FOR DENORMALIZED X 5862306a36Sopenharmony_ci fmovel %d1,%fpcr | ...load user's rounding mode/precision 5962306a36Sopenharmony_ci fmovex PIBY2,%fp0 6062306a36Sopenharmony_ci bra t_frcinx 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci .global sacos 6362306a36Sopenharmony_cisacos: 6462306a36Sopenharmony_ci fmovex (%a0),%fp0 | ...LOAD INPUT 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci movel (%a0),%d0 | ...pack exponent with upper 16 fraction 6762306a36Sopenharmony_ci movew 4(%a0),%d0 6862306a36Sopenharmony_ci andil #0x7FFFFFFF,%d0 6962306a36Sopenharmony_ci cmpil #0x3FFF8000,%d0 7062306a36Sopenharmony_ci bges ACOSBIG 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci|--THIS IS THE USUAL CASE, |X| < 1 7362306a36Sopenharmony_ci|--ACOS(X) = 2 * ATAN( SQRT( (1-X)/(1+X) ) ) 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci fmoves #0x3F800000,%fp1 7662306a36Sopenharmony_ci faddx %fp0,%fp1 | ...1+X 7762306a36Sopenharmony_ci fnegx %fp0 | ... -X 7862306a36Sopenharmony_ci fadds #0x3F800000,%fp0 | ...1-X 7962306a36Sopenharmony_ci fdivx %fp1,%fp0 | ...(1-X)/(1+X) 8062306a36Sopenharmony_ci fsqrtx %fp0 | ...SQRT((1-X)/(1+X)) 8162306a36Sopenharmony_ci fmovemx %fp0-%fp0,(%a0) | ...overwrite input 8262306a36Sopenharmony_ci movel %d1,-(%sp) |save original users fpcr 8362306a36Sopenharmony_ci clrl %d1 8462306a36Sopenharmony_ci bsr satan | ...ATAN(SQRT([1-X]/[1+X])) 8562306a36Sopenharmony_ci fmovel (%sp)+,%fpcr |restore users exceptions 8662306a36Sopenharmony_ci faddx %fp0,%fp0 | ...2 * ATAN( STUFF ) 8762306a36Sopenharmony_ci bra t_frcinx 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ciACOSBIG: 9062306a36Sopenharmony_ci fabsx %fp0 9162306a36Sopenharmony_ci fcmps #0x3F800000,%fp0 9262306a36Sopenharmony_ci fbgt t_operr |cause an operr exception 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci|--|X| = 1, ACOS(X) = 0 OR PI 9562306a36Sopenharmony_ci movel (%a0),%d0 | ...pack exponent with upper 16 fraction 9662306a36Sopenharmony_ci movew 4(%a0),%d0 9762306a36Sopenharmony_ci cmpl #0,%d0 |D0 has original exponent+fraction 9862306a36Sopenharmony_ci bgts ACOSP1 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci|--X = -1 10162306a36Sopenharmony_ci|Returns PI and inexact exception 10262306a36Sopenharmony_ci fmovex PI,%fp0 10362306a36Sopenharmony_ci fmovel %d1,%FPCR 10462306a36Sopenharmony_ci fadds #0x00800000,%fp0 |cause an inexact exception to be put 10562306a36Sopenharmony_ci| ;into the 040 - will not trap until next 10662306a36Sopenharmony_ci| ;fp inst. 10762306a36Sopenharmony_ci bra t_frcinx 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ciACOSP1: 11062306a36Sopenharmony_ci fmovel %d1,%FPCR 11162306a36Sopenharmony_ci fmoves #0x00000000,%fp0 11262306a36Sopenharmony_ci rts |Facos ; of +1 is exact 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci |end 115