ldexp.S revision 1.10 1 1.10 joerg /* $NetBSD: ldexp.S,v 1.10 2014/09/17 11:01:05 joerg 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.9 matt #if 0
39 1.9 matt RCSID("from: @(#)ldexp.s 8.1 (Berkeley) 6/4/93")
40 1.9 matt #else
41 1.10 joerg RCSID("$NetBSD: ldexp.S,v 1.10 2014/09/17 11:01:05 joerg Exp $")
42 1.9 matt #endif
43 1.1 glass #endif /* LIBC_SCCS and not lint */
44 1.5 jonathan
45 1.1 glass #define DEXP_INF 0x7ff
46 1.1 glass #define DEXP_BIAS 1023
47 1.1 glass #define DEXP_MIN -1022
48 1.1 glass #define DEXP_MAX 1023
49 1.1 glass #define DFRAC_BITS 52
50 1.1 glass #define DIMPL_ONE 0x00100000
51 1.1 glass #define DLEAD_ZEROS 31 - 20
52 1.1 glass #define STICKYBIT 1
53 1.1 glass #define GUARDBIT 0x80000000
54 1.1 glass #define DSIGNAL_NAN 0x00040000
55 1.1 glass #define DQUIET_NAN0 0x0007ffff
56 1.1 glass #define DQUIET_NAN1 0xffffffff
57 1.1 glass
58 1.1 glass /*
59 1.1 glass * double ldexp(x, N)
60 1.1 glass * double x; int N;
61 1.1 glass *
62 1.1 glass * Return x * (2**N), for integer values N.
63 1.1 glass */
64 1.3 mycroft LEAF(ldexp)
65 1.1 glass mfc1 v1, $f13 # get MSW of x
66 1.1 glass mfc1 t3, $f12 # get LSW of x
67 1.1 glass sll t1, v1, 1 # get x exponent
68 1.1 glass srl t1, t1, 32 - 11
69 1.1 glass beq t1, DEXP_INF, 9f # is it a NAN or infinity?
70 1.1 glass beq t1, zero, 1f # zero or denormalized number?
71 1.1 glass addu t1, t1, a2 # scale exponent
72 1.1 glass sll v0, a2, 20 # position N for addition
73 1.1 glass bge t1, DEXP_INF, 8f # overflow?
74 1.1 glass addu v0, v0, v1 # multiply by (2**N)
75 1.1 glass ble t1, zero, 4f # underflow?
76 1.1 glass mtc1 v0, $f1 # save MSW of result
77 1.1 glass mtc1 t3, $f0 # save LSW of result
78 1.1 glass j ra
79 1.1 glass 1:
80 1.1 glass sll t2, v1, 32 - 20 # get x fraction
81 1.1 glass srl t2, t2, 32 - 20
82 1.1 glass srl t0, v1, 31 # get x sign
83 1.1 glass bne t2, zero, 1f
84 1.1 glass beq t3, zero, 9f # result is zero
85 1.1 glass 1:
86 1.1 glass /*
87 1.1 glass * Find out how many leading zero bits are in t2,t3 and put in t9.
88 1.1 glass */
89 1.1 glass move v0, t2
90 1.1 glass move t9, zero
91 1.1 glass bne t2, zero, 1f
92 1.1 glass move v0, t3
93 1.1 glass addu t9, 32
94 1.1 glass 1:
95 1.6 thorpej srl ta0, v0, 16
96 1.6 thorpej bne ta0, zero, 1f
97 1.1 glass addu t9, 16
98 1.1 glass sll v0, 16
99 1.1 glass 1:
100 1.6 thorpej srl ta0, v0, 24
101 1.6 thorpej bne ta0, zero, 1f
102 1.1 glass addu t9, 8
103 1.1 glass sll v0, 8
104 1.1 glass 1:
105 1.6 thorpej srl ta0, v0, 28
106 1.6 thorpej bne ta0, zero, 1f
107 1.1 glass addu t9, 4
108 1.1 glass sll v0, 4
109 1.1 glass 1:
110 1.6 thorpej srl ta0, v0, 30
111 1.6 thorpej bne ta0, zero, 1f
112 1.1 glass addu t9, 2
113 1.1 glass sll v0, 2
114 1.1 glass 1:
115 1.6 thorpej srl ta0, v0, 31
116 1.6 thorpej bne ta0, zero, 1f
117 1.1 glass addu t9, 1
118 1.1 glass /*
119 1.1 glass * Now shift t2,t3 the correct number of bits.
120 1.1 glass */
121 1.1 glass 1:
122 1.1 glass subu t9, t9, DLEAD_ZEROS # dont count normal leading zeros
123 1.1 glass li t1, DEXP_MIN + DEXP_BIAS
124 1.1 glass subu t1, t1, t9 # adjust exponent
125 1.1 glass addu t1, t1, a2 # scale exponent
126 1.1 glass li v0, 32
127 1.1 glass blt t9, v0, 1f
128 1.1 glass subu t9, t9, v0 # shift fraction left >= 32 bits
129 1.1 glass sll t2, t3, t9
130 1.1 glass move t3, zero
131 1.1 glass b 2f
132 1.1 glass 1:
133 1.1 glass subu v0, v0, t9 # shift fraction left < 32 bits
134 1.1 glass sll t2, t2, t9
135 1.6 thorpej srl ta0, t3, v0
136 1.6 thorpej or t2, t2, ta0
137 1.1 glass sll t3, t3, t9
138 1.1 glass 2:
139 1.1 glass bge t1, DEXP_INF, 8f # overflow?
140 1.1 glass ble t1, zero, 4f # underflow?
141 1.1 glass sll t2, t2, 32 - 20 # clear implied one bit
142 1.1 glass srl t2, t2, 32 - 20
143 1.1 glass 3:
144 1.1 glass sll t1, t1, 31 - 11 # reposition exponent
145 1.1 glass sll t0, t0, 31 # reposition sign
146 1.1 glass or t0, t0, t1 # put result back together
147 1.1 glass or t0, t0, t2
148 1.1 glass mtc1 t0, $f1 # save MSW of result
149 1.1 glass mtc1 t3, $f0 # save LSW of result
150 1.1 glass j ra
151 1.1 glass 4:
152 1.1 glass li v0, 0x80000000
153 1.1 glass ble t1, -52, 7f # is result too small for denorm?
154 1.1 glass sll t2, v1, 31 - 20 # clear exponent, extract fraction
155 1.1 glass or t2, t2, v0 # set implied one bit
156 1.1 glass blt t1, -30, 2f # will all bits in t3 be shifted out?
157 1.1 glass srl t2, t2, 31 - 20 # shift fraction back to normal position
158 1.1 glass subu t1, t1, 1
159 1.6 thorpej sll ta0, t2, t1 # shift right t2,t3 based on exponent
160 1.1 glass srl t8, t3, t1 # save bits shifted out
161 1.1 glass negu t1
162 1.1 glass srl t3, t3, t1
163 1.6 thorpej or t3, t3, ta0
164 1.1 glass srl t2, t2, t1
165 1.1 glass bge t8, zero, 1f # does result need to be rounded?
166 1.1 glass addu t3, t3, 1 # round result
167 1.6 thorpej sltu ta0, t3, 1
168 1.1 glass sll t8, t8, 1
169 1.6 thorpej addu t2, t2, ta0
170 1.1 glass bne t8, zero, 1f # round result to nearest
171 1.1 glass and t3, t3, ~1
172 1.1 glass 1:
173 1.1 glass mtc1 t3, $f0 # save denormalized result (LSW)
174 1.1 glass mtc1 t2, $f1 # save denormalized result (MSW)
175 1.1 glass bge v1, zero, 1f # should result be negative?
176 1.1 glass neg.d $f0, $f0 # negate result
177 1.1 glass 1:
178 1.1 glass j ra
179 1.1 glass 2:
180 1.1 glass mtc1 zero, $f1 # exponent and upper fraction
181 1.1 glass addu t1, t1, 20 # compute amount to shift right by
182 1.1 glass sll t8, t2, t1 # save bits shifted out
183 1.1 glass negu t1
184 1.1 glass srl t3, t2, t1
185 1.1 glass bge t8, zero, 1f # does result need to be rounded?
186 1.1 glass addu t3, t3, 1 # round result
187 1.6 thorpej sltu ta0, t3, 1
188 1.1 glass sll t8, t8, 1
189 1.6 thorpej mtc1 ta0, $f1 # exponent and upper fraction
190 1.1 glass bne t8, zero, 1f # round result to nearest
191 1.1 glass and t3, t3, ~1
192 1.1 glass 1:
193 1.1 glass mtc1 t3, $f0
194 1.1 glass bge v1, zero, 1f # is result negative?
195 1.1 glass neg.d $f0, $f0 # negate result
196 1.1 glass 1:
197 1.1 glass j ra
198 1.1 glass 7:
199 1.1 glass mtc1 zero, $f0 # result is zero
200 1.1 glass mtc1 zero, $f1
201 1.1 glass beq t0, zero, 1f # is result positive?
202 1.1 glass neg.d $f0, $f0 # negate result
203 1.1 glass 1:
204 1.1 glass j ra
205 1.1 glass 8:
206 1.1 glass li t1, 0x7ff00000 # result is infinity (MSW)
207 1.1 glass mtc1 t1, $f1
208 1.1 glass mtc1 zero, $f0 # result is infinity (LSW)
209 1.1 glass bge v1, zero, 1f # should result be negative infinity?
210 1.1 glass neg.d $f0, $f0 # result is negative infinity
211 1.1 glass 1:
212 1.10 joerg add.d $f0, $f0, $f0 # cause overflow faults if enabled
213 1.1 glass j ra
214 1.1 glass 9:
215 1.1 glass mov.d $f0, $f12 # yes, result is just x
216 1.1 glass j ra
217 1.3 mycroft END(ldexp)
218