File indexing completed on 2025-05-11 08:23:49
0001 #include "fpsp-namespace.h"
0002 //
0003 //
0004 // slog2.sa 3.1 12/10/90
0005 //
0006 // The entry point slog10 computes the base-10
0007 // logarithm of an input argument X.
0008 // slog10d does the same except the input value is a
0009 // denormalized number.
0010 // sLog2 and sLog2d are the base-2 analogues.
0011 //
0012 // INPUT: Double-extended value in memory location pointed to
0013 // by address register a0.
0014 //
0015 // OUTPUT: log_10(X) or log_2(X) returned in floating-point
0016 // register fp0.
0017 //
0018 // ACCURACY and MONOTONICITY: The returned result is within 1.7
0019 // ulps in 64 significant bit, i.e. within 0.5003 ulp
0020 // to 53 bits if the result is subsequently rounded
0021 // to double precision. The result is provably monotonic
0022 // in double precision.
0023 //
0024 // SPEED: Two timings are measured, both in the copy-back mode.
0025 // The first one is measured when the function is invoked
0026 // the first time (so the instructions and data are not
0027 // in cache), and the second one is measured when the
0028 // function is reinvoked at the same input argument.
0029 //
0030 // ALGORITHM and IMPLEMENTATION NOTES:
0031 //
0032 // slog10d:
0033 //
0034 // Step 0. If X < 0, create a NaN and raise the invalid operation
0035 // flag. Otherwise, save FPCR in D1; set FpCR to default.
0036 // Notes: Default means round-to-nearest mode, no floating-point
0037 // traps, and precision control = double extended.
0038 //
0039 // Step 1. Call slognd to obtain Y = log(X), the natural log of X.
0040 // Notes: Even if X is denormalized, log(X) is always normalized.
0041 //
0042 // Step 2. Compute log_10(X) = log(X) * (1/log(10)).
0043 // 2.1 Restore the user FPCR
0044 // 2.2 Return ans := Y * INV_L10.
0045 //
0046 //
0047 // slog10:
0048 //
0049 // Step 0. If X < 0, create a NaN and raise the invalid operation
0050 // flag. Otherwise, save FPCR in D1; set FpCR to default.
0051 // Notes: Default means round-to-nearest mode, no floating-point
0052 // traps, and precision control = double extended.
0053 //
0054 // Step 1. Call sLogN to obtain Y = log(X), the natural log of X.
0055 //
0056 // Step 2. Compute log_10(X) = log(X) * (1/log(10)).
0057 // 2.1 Restore the user FPCR
0058 // 2.2 Return ans := Y * INV_L10.
0059 //
0060 //
0061 // sLog2d:
0062 //
0063 // Step 0. If X < 0, create a NaN and raise the invalid operation
0064 // flag. Otherwise, save FPCR in D1; set FpCR to default.
0065 // Notes: Default means round-to-nearest mode, no floating-point
0066 // traps, and precision control = double extended.
0067 //
0068 // Step 1. Call slognd to obtain Y = log(X), the natural log of X.
0069 // Notes: Even if X is denormalized, log(X) is always normalized.
0070 //
0071 // Step 2. Compute log_10(X) = log(X) * (1/log(2)).
0072 // 2.1 Restore the user FPCR
0073 // 2.2 Return ans := Y * INV_L2.
0074 //
0075 //
0076 // sLog2:
0077 //
0078 // Step 0. If X < 0, create a NaN and raise the invalid operation
0079 // flag. Otherwise, save FPCR in D1; set FpCR to default.
0080 // Notes: Default means round-to-nearest mode, no floating-point
0081 // traps, and precision control = double extended.
0082 //
0083 // Step 1. If X is not an integer power of two, i.e., X != 2^k,
0084 // go to Step 3.
0085 //
0086 // Step 2. Return k.
0087 // 2.1 Get integer k, X = 2^k.
0088 // 2.2 Restore the user FPCR.
0089 // 2.3 Return ans := convert-to-double-extended(k).
0090 //
0091 // Step 3. Call sLogN to obtain Y = log(X), the natural log of X.
0092 //
0093 // Step 4. Compute log_2(X) = log(X) * (1/log(2)).
0094 // 4.1 Restore the user FPCR
0095 // 4.2 Return ans := Y * INV_L2.
0096 //
0097
0098 // Copyright (C) Motorola, Inc. 1990
0099 // All Rights Reserved
0100 //
0101 // THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
0102 // The copyright notice above does not evidence any
0103 // actual or intended publication of such source code.
0104
0105 //SLOG2 idnt 2,1 | Motorola 040 Floating Point Software Package
0106
0107 |section 8
0108
0109 |xref t_frcinx
0110 |xref t_operr
0111 |xref slogn
0112 |xref slognd
0113
0114 INV_L10: .long 0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000
0115
0116 INV_L2: .long 0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000
0117
0118 .global slog10d
0119 slog10d:
0120 //--entry point for Log10(X), X is denormalized
0121 movel (%a0),%d0
0122 blt invalid
0123 movel %d1,-(%sp)
0124 clrl %d1
0125 bsr slognd // ...log(X), X denorm.
0126 fmovel (%sp)+,%fpcr
0127 fmulx INV_L10,%fp0
0128 bra t_frcinx
0129
0130 .global slog10
0131 slog10:
0132 //--entry point for Log10(X), X is normalized
0133
0134 movel (%a0),%d0
0135 blt invalid
0136 movel %d1,-(%sp)
0137 clrl %d1
0138 bsr slogn // ...log(X), X normal.
0139 fmovel (%sp)+,%fpcr
0140 fmulx INV_L10,%fp0
0141 bra t_frcinx
0142
0143
0144 .global slog2d
0145 slog2d:
0146 //--entry point for Log2(X), X is denormalized
0147
0148 movel (%a0),%d0
0149 blt invalid
0150 movel %d1,-(%sp)
0151 clrl %d1
0152 bsr slognd // ...log(X), X denorm.
0153 fmovel (%sp)+,%fpcr
0154 fmulx INV_L2,%fp0
0155 bra t_frcinx
0156
0157 .global slog2
0158 slog2:
0159 //--entry point for Log2(X), X is normalized
0160 movel (%a0),%d0
0161 blt invalid
0162
0163 movel 8(%a0),%d0
0164 bnes continue // ...X is not 2^k
0165
0166 movel 4(%a0),%d0
0167 andl #0x7FFFFFFF,%d0
0168 tstl %d0
0169 bnes continue
0170
0171 //--X = 2^k.
0172 movew (%a0),%d0
0173 andl #0x00007FFF,%d0
0174 subl #0x3FFF,%d0
0175 fmovel %d1,%fpcr
0176 fmovel %d0,%fp0
0177 bra t_frcinx
0178
0179 continue:
0180 movel %d1,-(%sp)
0181 clrl %d1
0182 bsr slogn // ...log(X), X normal.
0183 fmovel (%sp)+,%fpcr
0184 fmulx INV_L2,%fp0
0185 bra t_frcinx
0186
0187 invalid:
0188 bra t_operr
0189
0190 |end