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