162306a36Sopenharmony_ci| 262306a36Sopenharmony_ci| slog2.sa 3.1 12/10/90 362306a36Sopenharmony_ci| 462306a36Sopenharmony_ci| The entry point slog10 computes the base-10 562306a36Sopenharmony_ci| logarithm of an input argument X. 662306a36Sopenharmony_ci| slog10d does the same except the input value is a 762306a36Sopenharmony_ci| denormalized number. 862306a36Sopenharmony_ci| sLog2 and sLog2d are the base-2 analogues. 962306a36Sopenharmony_ci| 1062306a36Sopenharmony_ci| INPUT: Double-extended value in memory location pointed to 1162306a36Sopenharmony_ci| by address register a0. 1262306a36Sopenharmony_ci| 1362306a36Sopenharmony_ci| OUTPUT: log_10(X) or log_2(X) returned in floating-point 1462306a36Sopenharmony_ci| register fp0. 1562306a36Sopenharmony_ci| 1662306a36Sopenharmony_ci| ACCURACY and MONOTONICITY: The returned result is within 1.7 1762306a36Sopenharmony_ci| ulps in 64 significant bit, i.e. within 0.5003 ulp 1862306a36Sopenharmony_ci| to 53 bits if the result is subsequently rounded 1962306a36Sopenharmony_ci| to double precision. The result is provably monotonic 2062306a36Sopenharmony_ci| in double precision. 2162306a36Sopenharmony_ci| 2262306a36Sopenharmony_ci| SPEED: Two timings are measured, both in the copy-back mode. 2362306a36Sopenharmony_ci| The first one is measured when the function is invoked 2462306a36Sopenharmony_ci| the first time (so the instructions and data are not 2562306a36Sopenharmony_ci| in cache), and the second one is measured when the 2662306a36Sopenharmony_ci| function is reinvoked at the same input argument. 2762306a36Sopenharmony_ci| 2862306a36Sopenharmony_ci| ALGORITHM and IMPLEMENTATION NOTES: 2962306a36Sopenharmony_ci| 3062306a36Sopenharmony_ci| slog10d: 3162306a36Sopenharmony_ci| 3262306a36Sopenharmony_ci| Step 0. If X < 0, create a NaN and raise the invalid operation 3362306a36Sopenharmony_ci| flag. Otherwise, save FPCR in D1; set FpCR to default. 3462306a36Sopenharmony_ci| Notes: Default means round-to-nearest mode, no floating-point 3562306a36Sopenharmony_ci| traps, and precision control = double extended. 3662306a36Sopenharmony_ci| 3762306a36Sopenharmony_ci| Step 1. Call slognd to obtain Y = log(X), the natural log of X. 3862306a36Sopenharmony_ci| Notes: Even if X is denormalized, log(X) is always normalized. 3962306a36Sopenharmony_ci| 4062306a36Sopenharmony_ci| Step 2. Compute log_10(X) = log(X) * (1/log(10)). 4162306a36Sopenharmony_ci| 2.1 Restore the user FPCR 4262306a36Sopenharmony_ci| 2.2 Return ans := Y * INV_L10. 4362306a36Sopenharmony_ci| 4462306a36Sopenharmony_ci| 4562306a36Sopenharmony_ci| slog10: 4662306a36Sopenharmony_ci| 4762306a36Sopenharmony_ci| Step 0. If X < 0, create a NaN and raise the invalid operation 4862306a36Sopenharmony_ci| flag. Otherwise, save FPCR in D1; set FpCR to default. 4962306a36Sopenharmony_ci| Notes: Default means round-to-nearest mode, no floating-point 5062306a36Sopenharmony_ci| traps, and precision control = double extended. 5162306a36Sopenharmony_ci| 5262306a36Sopenharmony_ci| Step 1. Call sLogN to obtain Y = log(X), the natural log of X. 5362306a36Sopenharmony_ci| 5462306a36Sopenharmony_ci| Step 2. Compute log_10(X) = log(X) * (1/log(10)). 5562306a36Sopenharmony_ci| 2.1 Restore the user FPCR 5662306a36Sopenharmony_ci| 2.2 Return ans := Y * INV_L10. 5762306a36Sopenharmony_ci| 5862306a36Sopenharmony_ci| 5962306a36Sopenharmony_ci| sLog2d: 6062306a36Sopenharmony_ci| 6162306a36Sopenharmony_ci| Step 0. If X < 0, create a NaN and raise the invalid operation 6262306a36Sopenharmony_ci| flag. Otherwise, save FPCR in D1; set FpCR to default. 6362306a36Sopenharmony_ci| Notes: Default means round-to-nearest mode, no floating-point 6462306a36Sopenharmony_ci| traps, and precision control = double extended. 6562306a36Sopenharmony_ci| 6662306a36Sopenharmony_ci| Step 1. Call slognd to obtain Y = log(X), the natural log of X. 6762306a36Sopenharmony_ci| Notes: Even if X is denormalized, log(X) is always normalized. 6862306a36Sopenharmony_ci| 6962306a36Sopenharmony_ci| Step 2. Compute log_10(X) = log(X) * (1/log(2)). 7062306a36Sopenharmony_ci| 2.1 Restore the user FPCR 7162306a36Sopenharmony_ci| 2.2 Return ans := Y * INV_L2. 7262306a36Sopenharmony_ci| 7362306a36Sopenharmony_ci| 7462306a36Sopenharmony_ci| sLog2: 7562306a36Sopenharmony_ci| 7662306a36Sopenharmony_ci| Step 0. If X < 0, create a NaN and raise the invalid operation 7762306a36Sopenharmony_ci| flag. Otherwise, save FPCR in D1; set FpCR to default. 7862306a36Sopenharmony_ci| Notes: Default means round-to-nearest mode, no floating-point 7962306a36Sopenharmony_ci| traps, and precision control = double extended. 8062306a36Sopenharmony_ci| 8162306a36Sopenharmony_ci| Step 1. If X is not an integer power of two, i.e., X != 2^k, 8262306a36Sopenharmony_ci| go to Step 3. 8362306a36Sopenharmony_ci| 8462306a36Sopenharmony_ci| Step 2. Return k. 8562306a36Sopenharmony_ci| 2.1 Get integer k, X = 2^k. 8662306a36Sopenharmony_ci| 2.2 Restore the user FPCR. 8762306a36Sopenharmony_ci| 2.3 Return ans := convert-to-double-extended(k). 8862306a36Sopenharmony_ci| 8962306a36Sopenharmony_ci| Step 3. Call sLogN to obtain Y = log(X), the natural log of X. 9062306a36Sopenharmony_ci| 9162306a36Sopenharmony_ci| Step 4. Compute log_2(X) = log(X) * (1/log(2)). 9262306a36Sopenharmony_ci| 4.1 Restore the user FPCR 9362306a36Sopenharmony_ci| 4.2 Return ans := Y * INV_L2. 9462306a36Sopenharmony_ci| 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci| Copyright (C) Motorola, Inc. 1990 9762306a36Sopenharmony_ci| All Rights Reserved 9862306a36Sopenharmony_ci| 9962306a36Sopenharmony_ci| For details on the license for this file, please see the 10062306a36Sopenharmony_ci| file, README, in this same directory. 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci|SLOG2 idnt 2,1 | Motorola 040 Floating Point Software Package 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci |section 8 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci |xref t_frcinx 10762306a36Sopenharmony_ci |xref t_operr 10862306a36Sopenharmony_ci |xref slogn 10962306a36Sopenharmony_ci |xref slognd 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ciINV_L10: .long 0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ciINV_L2: .long 0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci .global slog10d 11662306a36Sopenharmony_cislog10d: 11762306a36Sopenharmony_ci|--entry point for Log10(X), X is denormalized 11862306a36Sopenharmony_ci movel (%a0),%d0 11962306a36Sopenharmony_ci blt invalid 12062306a36Sopenharmony_ci movel %d1,-(%sp) 12162306a36Sopenharmony_ci clrl %d1 12262306a36Sopenharmony_ci bsr slognd | ...log(X), X denorm. 12362306a36Sopenharmony_ci fmovel (%sp)+,%fpcr 12462306a36Sopenharmony_ci fmulx INV_L10,%fp0 12562306a36Sopenharmony_ci bra t_frcinx 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci .global slog10 12862306a36Sopenharmony_cislog10: 12962306a36Sopenharmony_ci|--entry point for Log10(X), X is normalized 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci movel (%a0),%d0 13262306a36Sopenharmony_ci blt invalid 13362306a36Sopenharmony_ci movel %d1,-(%sp) 13462306a36Sopenharmony_ci clrl %d1 13562306a36Sopenharmony_ci bsr slogn | ...log(X), X normal. 13662306a36Sopenharmony_ci fmovel (%sp)+,%fpcr 13762306a36Sopenharmony_ci fmulx INV_L10,%fp0 13862306a36Sopenharmony_ci bra t_frcinx 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci .global slog2d 14262306a36Sopenharmony_cislog2d: 14362306a36Sopenharmony_ci|--entry point for Log2(X), X is denormalized 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci movel (%a0),%d0 14662306a36Sopenharmony_ci blt invalid 14762306a36Sopenharmony_ci movel %d1,-(%sp) 14862306a36Sopenharmony_ci clrl %d1 14962306a36Sopenharmony_ci bsr slognd | ...log(X), X denorm. 15062306a36Sopenharmony_ci fmovel (%sp)+,%fpcr 15162306a36Sopenharmony_ci fmulx INV_L2,%fp0 15262306a36Sopenharmony_ci bra t_frcinx 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci .global slog2 15562306a36Sopenharmony_cislog2: 15662306a36Sopenharmony_ci|--entry point for Log2(X), X is normalized 15762306a36Sopenharmony_ci movel (%a0),%d0 15862306a36Sopenharmony_ci blt invalid 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci movel 8(%a0),%d0 16162306a36Sopenharmony_ci bnes continue | ...X is not 2^k 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci movel 4(%a0),%d0 16462306a36Sopenharmony_ci andl #0x7FFFFFFF,%d0 16562306a36Sopenharmony_ci tstl %d0 16662306a36Sopenharmony_ci bnes continue 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci|--X = 2^k. 16962306a36Sopenharmony_ci movew (%a0),%d0 17062306a36Sopenharmony_ci andl #0x00007FFF,%d0 17162306a36Sopenharmony_ci subl #0x3FFF,%d0 17262306a36Sopenharmony_ci fmovel %d1,%fpcr 17362306a36Sopenharmony_ci fmovel %d0,%fp0 17462306a36Sopenharmony_ci bra t_frcinx 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cicontinue: 17762306a36Sopenharmony_ci movel %d1,-(%sp) 17862306a36Sopenharmony_ci clrl %d1 17962306a36Sopenharmony_ci bsr slogn | ...log(X), X normal. 18062306a36Sopenharmony_ci fmovel (%sp)+,%fpcr 18162306a36Sopenharmony_ci fmulx INV_L2,%fp0 18262306a36Sopenharmony_ci bra t_frcinx 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ciinvalid: 18562306a36Sopenharmony_ci bra t_operr 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci |end 188