Commit | Line | Data |
---|---|---|
8abee3ed | 1 | /*- |
fa70763b KB |
2 | * Copyright (c) 1991, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
8abee3ed KB |
4 | * |
5 | * This code is derived from software contributed to Berkeley by | |
6 | * Ralph Campbell. | |
7 | * | |
ad787160 C |
8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | |
15 | * documentation and/or other materials provided with the distribution. | |
16 | * 3. All advertising materials mentioning features or use of this software | |
17 | * must display the following acknowledgement: | |
18 | * This product includes software developed by the University of | |
19 | * California, Berkeley and its contributors. | |
20 | * 4. Neither the name of the University nor the names of its contributors | |
21 | * may be used to endorse or promote products derived from this software | |
22 | * without specific prior written permission. | |
23 | * | |
24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
34 | * SUCH DAMAGE. | |
8abee3ed KB |
35 | */ |
36 | ||
073522ce | 37 | #include <machine/machAsmDefs.h> |
f1e99c02 | 38 | |
8abee3ed | 39 | #if defined(LIBC_SCCS) && !defined(lint) |
ad787160 | 40 | ASMSTR("@(#)ldexp.s 8.1 (Berkeley) 6/4/93") |
8abee3ed KB |
41 | #endif /* LIBC_SCCS and not lint */ |
42 | ||
f721e2f5 RC |
43 | #define DEXP_INF 0x7ff |
44 | #define DEXP_BIAS 1023 | |
45 | #define DEXP_MIN -1022 | |
46 | #define DEXP_MAX 1023 | |
47 | #define DFRAC_BITS 52 | |
48 | #define DIMPL_ONE 0x00100000 | |
49 | #define DLEAD_ZEROS 31 - 20 | |
50 | #define STICKYBIT 1 | |
51 | #define GUARDBIT 0x80000000 | |
52 | #define DSIGNAL_NAN 0x00040000 | |
53 | #define DQUIET_NAN0 0x0007ffff | |
54 | #define DQUIET_NAN1 0xffffffff | |
8abee3ed KB |
55 | |
56 | /* | |
f721e2f5 RC |
57 | * double ldexp(x, N) |
58 | * double x; int N; | |
59 | * | |
60 | * Return x * (2**N), for integer values N. | |
8abee3ed KB |
61 | */ |
62 | LEAF(ldexp) | |
f721e2f5 RC |
63 | mfc1 v1, $f13 # get MSW of x |
64 | mfc1 t3, $f12 # get LSW of x | |
65 | sll t1, v1, 1 # get x exponent | |
66 | srl t1, t1, 32 - 11 | |
67 | beq t1, DEXP_INF, 9f # is it a NAN or infinity? | |
68 | beq t1, zero, 1f # zero or denormalized number? | |
69 | addu t1, t1, a2 # scale exponent | |
70 | sll v0, a2, 20 # position N for addition | |
71 | bge t1, DEXP_INF, 8f # overflow? | |
72 | addu v0, v0, v1 # multiply by (2**N) | |
73 | ble t1, zero, 4f # underflow? | |
74 | mtc1 v0, $f1 # save MSW of result | |
75 | mtc1 t3, $f0 # save LSW of result | |
8abee3ed | 76 | j ra |
f721e2f5 RC |
77 | 1: |
78 | sll t2, v1, 32 - 20 # get x fraction | |
79 | srl t2, t2, 32 - 20 | |
80 | srl t0, v1, 31 # get x sign | |
81 | bne t2, zero, 1f | |
82 | beq t3, zero, 9f # result is zero | |
83 | 1: | |
84 | /* | |
85 | * Find out how many leading zero bits are in t2,t3 and put in t9. | |
86 | */ | |
87 | move v0, t2 | |
88 | move t9, zero | |
89 | bne t2, zero, 1f | |
90 | move v0, t3 | |
91 | addu t9, 32 | |
92 | 1: | |
93 | srl t4, v0, 16 | |
94 | bne t4, zero, 1f | |
95 | addu t9, 16 | |
96 | sll v0, 16 | |
97 | 1: | |
98 | srl t4, v0, 24 | |
99 | bne t4, zero, 1f | |
100 | addu t9, 8 | |
101 | sll v0, 8 | |
102 | 1: | |
103 | srl t4, v0, 28 | |
104 | bne t4, zero, 1f | |
105 | addu t9, 4 | |
106 | sll v0, 4 | |
107 | 1: | |
108 | srl t4, v0, 30 | |
109 | bne t4, zero, 1f | |
110 | addu t9, 2 | |
111 | sll v0, 2 | |
112 | 1: | |
113 | srl t4, v0, 31 | |
114 | bne t4, zero, 1f | |
115 | addu t9, 1 | |
116 | /* | |
117 | * Now shift t2,t3 the correct number of bits. | |
118 | */ | |
119 | 1: | |
d3f8a1f6 | 120 | subu t9, t9, DLEAD_ZEROS # dont count normal leading zeros |
f721e2f5 RC |
121 | li t1, DEXP_MIN + DEXP_BIAS |
122 | subu t1, t1, t9 # adjust exponent | |
123 | addu t1, t1, a2 # scale exponent | |
124 | li v0, 32 | |
125 | blt t9, v0, 1f | |
126 | subu t9, t9, v0 # shift fraction left >= 32 bits | |
127 | sll t2, t3, t9 | |
128 | move t3, zero | |
129 | b 2f | |
130 | 1: | |
131 | subu v0, v0, t9 # shift fraction left < 32 bits | |
132 | sll t2, t2, t9 | |
133 | srl t4, t3, v0 | |
134 | or t2, t2, t4 | |
135 | sll t3, t3, t9 | |
8abee3ed | 136 | 2: |
f721e2f5 RC |
137 | bge t1, DEXP_INF, 8f # overflow? |
138 | ble t1, zero, 4f # underflow? | |
139 | sll t2, t2, 32 - 20 # clear implied one bit | |
140 | srl t2, t2, 32 - 20 | |
8abee3ed | 141 | 3: |
f721e2f5 RC |
142 | sll t1, t1, 31 - 11 # reposition exponent |
143 | sll t0, t0, 31 # reposition sign | |
144 | or t0, t0, t1 # put result back together | |
145 | or t0, t0, t2 | |
146 | mtc1 t0, $f1 # save MSW of result | |
147 | mtc1 t3, $f0 # save LSW of result | |
148 | j ra | |
149 | 4: | |
150 | li v0, 0x80000000 | |
151 | ble t1, -52, 7f # is result too small for denorm? | |
152 | sll t2, v1, 31 - 20 # clear exponent, extract fraction | |
153 | or t2, t2, v0 # set implied one bit | |
154 | blt t1, -30, 2f # will all bits in t3 be shifted out? | |
155 | srl t2, t2, 31 - 20 # shift fraction back to normal position | |
156 | subu t1, t1, 1 | |
157 | sll t4, t2, t1 # shift right t2,t3 based on exponent | |
158 | srl t8, t3, t1 # save bits shifted out | |
159 | negu t1 | |
160 | srl t3, t3, t1 | |
161 | or t3, t3, t4 | |
162 | srl t2, t2, t1 | |
163 | bge t8, zero, 1f # does result need to be rounded? | |
164 | addu t3, t3, 1 # round result | |
165 | sltu t4, t3, 1 | |
166 | sll t8, t8, 1 | |
167 | addu t2, t2, t4 | |
168 | bne t8, zero, 1f # round result to nearest | |
169 | and t3, t3, ~1 | |
170 | 1: | |
171 | mtc1 t3, $f0 # save denormalized result (LSW) | |
172 | mtc1 t2, $f1 # save denormalized result (MSW) | |
173 | bge v1, zero, 1f # should result be negative? | |
174 | neg.d $f0, $f0 # negate result | |
175 | 1: | |
176 | j ra | |
177 | 2: | |
178 | mtc1 zero, $f1 # exponent and upper fraction | |
179 | addu t1, t1, 20 # compute amount to shift right by | |
180 | sll t8, t2, t1 # save bits shifted out | |
181 | negu t1 | |
182 | srl t3, t2, t1 | |
183 | bge t8, zero, 1f # does result need to be rounded? | |
184 | addu t3, t3, 1 # round result | |
185 | sltu t4, t3, 1 | |
186 | sll t8, t8, 1 | |
187 | mtc1 t4, $f1 # exponent and upper fraction | |
188 | bne t8, zero, 1f # round result to nearest | |
189 | and t3, t3, ~1 | |
190 | 1: | |
191 | mtc1 t3, $f0 | |
192 | bge v1, zero, 1f # is result negative? | |
193 | neg.d $f0, $f0 # negate result | |
194 | 1: | |
8abee3ed | 195 | j ra |
8abee3ed | 196 | 7: |
f721e2f5 | 197 | mtc1 zero, $f0 # result is zero |
8abee3ed | 198 | mtc1 zero, $f1 |
f721e2f5 RC |
199 | beq t0, zero, 1f # is result positive? |
200 | neg.d $f0, $f0 # negate result | |
201 | 1: | |
202 | j ra | |
8abee3ed | 203 | 8: |
f721e2f5 RC |
204 | li t1, 0x7ff00000 # result is infinity (MSW) |
205 | mtc1 t1, $f1 | |
206 | mtc1 zero, $f0 # result is infinity (LSW) | |
207 | bge v1, zero, 1f # should result be negative infinity? | |
208 | neg.d $f0, $f0 # result is negative infinity | |
209 | 1: | |
210 | add.d $f0, $f0 # cause overflow faults if enabled | |
8abee3ed | 211 | j ra |
8abee3ed | 212 | 9: |
f721e2f5 | 213 | mov.d $f0, $f12 # yes, result is just x |
8abee3ed | 214 | j ra |
8abee3ed | 215 | END(ldexp) |