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