Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | | | slog2.sa 3.1 12/10/90 | | The entry point slog10 computes the base-10 | logarithm of an input argument X. | slog10d does the same except the input value is a | denormalized number. | sLog2 and sLog2d are the base-2 analogues. | | INPUT: Double-extended value in memory location pointed to | by address register a0. | | OUTPUT: log_10(X) or log_2(X) returned in floating-point | register fp0. | | ACCURACY and MONOTONICITY: The returned result is within 1.7 | ulps in 64 significant bit, i.e. within 0.5003 ulp | to 53 bits if the result is subsequently rounded | to double precision. The result is provably monotonic | in double precision. | | SPEED: Two timings are measured, both in the copy-back mode. | The first one is measured when the function is invoked | the first time (so the instructions and data are not | in cache), and the second one is measured when the | function is reinvoked at the same input argument. | | ALGORITHM and IMPLEMENTATION NOTES: | | slog10d: | | Step 0. If X < 0, create a NaN and raise the invalid operation | flag. Otherwise, save FPCR in D1; set FpCR to default. | Notes: Default means round-to-nearest mode, no floating-point | traps, and precision control = double extended. | | Step 1. Call slognd to obtain Y = log(X), the natural log of X. | Notes: Even if X is denormalized, log(X) is always normalized. | | Step 2. Compute log_10(X) = log(X) * (1/log(10)). | 2.1 Restore the user FPCR | 2.2 Return ans := Y * INV_L10. | | | slog10: | | Step 0. If X < 0, create a NaN and raise the invalid operation | flag. Otherwise, save FPCR in D1; set FpCR to default. | Notes: Default means round-to-nearest mode, no floating-point | traps, and precision control = double extended. | | Step 1. Call sLogN to obtain Y = log(X), the natural log of X. | | Step 2. Compute log_10(X) = log(X) * (1/log(10)). | 2.1 Restore the user FPCR | 2.2 Return ans := Y * INV_L10. | | | sLog2d: | | Step 0. If X < 0, create a NaN and raise the invalid operation | flag. Otherwise, save FPCR in D1; set FpCR to default. | Notes: Default means round-to-nearest mode, no floating-point | traps, and precision control = double extended. | | Step 1. Call slognd to obtain Y = log(X), the natural log of X. | Notes: Even if X is denormalized, log(X) is always normalized. | | Step 2. Compute log_10(X) = log(X) * (1/log(2)). | 2.1 Restore the user FPCR | 2.2 Return ans := Y * INV_L2. | | | sLog2: | | Step 0. If X < 0, create a NaN and raise the invalid operation | flag. Otherwise, save FPCR in D1; set FpCR to default. | Notes: Default means round-to-nearest mode, no floating-point | traps, and precision control = double extended. | | Step 1. If X is not an integer power of two, i.e., X != 2^k, | go to Step 3. | | Step 2. Return k. | 2.1 Get integer k, X = 2^k. | 2.2 Restore the user FPCR. | 2.3 Return ans := convert-to-double-extended(k). | | Step 3. Call sLogN to obtain Y = log(X), the natural log of X. | | Step 4. Compute log_2(X) = log(X) * (1/log(2)). | 4.1 Restore the user FPCR | 4.2 Return ans := Y * INV_L2. | | Copyright (C) Motorola, Inc. 1990 | All Rights Reserved | | For details on the license for this file, please see the | file, README, in this same directory. |SLOG2 idnt 2,1 | Motorola 040 Floating Point Software Package |section 8 |xref t_frcinx |xref t_operr |xref slogn |xref slognd INV_L10: .long 0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000 INV_L2: .long 0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000 .global slog10d slog10d: |--entry point for Log10(X), X is denormalized movel (%a0),%d0 blt invalid movel %d1,-(%sp) clrl %d1 bsr slognd | ...log(X), X denorm. fmovel (%sp)+,%fpcr fmulx INV_L10,%fp0 bra t_frcinx .global slog10 slog10: |--entry point for Log10(X), X is normalized movel (%a0),%d0 blt invalid movel %d1,-(%sp) clrl %d1 bsr slogn | ...log(X), X normal. fmovel (%sp)+,%fpcr fmulx INV_L10,%fp0 bra t_frcinx .global slog2d slog2d: |--entry point for Log2(X), X is denormalized movel (%a0),%d0 blt invalid movel %d1,-(%sp) clrl %d1 bsr slognd | ...log(X), X denorm. fmovel (%sp)+,%fpcr fmulx INV_L2,%fp0 bra t_frcinx .global slog2 slog2: |--entry point for Log2(X), X is normalized movel (%a0),%d0 blt invalid movel 8(%a0),%d0 bnes continue | ...X is not 2^k movel 4(%a0),%d0 andl #0x7FFFFFFF,%d0 tstl %d0 bnes continue |--X = 2^k. movew (%a0),%d0 andl #0x00007FFF,%d0 subl #0x3FFF,%d0 fmovel %d1,%fpcr fmovel %d0,%fp0 bra t_frcinx continue: movel %d1,-(%sp) clrl %d1 bsr slogn | ...log(X), X normal. fmovel (%sp)+,%fpcr fmulx INV_L2,%fp0 bra t_frcinx invalid: bra t_operr |end |