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